Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 16099006: Fix the hole loading optimization. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-instructions.cc ('k') | src/lithium.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5058 matching lines...) Expand 10 before | Expand all | Expand 10 after
5069 5069
5070 5070
5071 void LCodeGen::EmitNumberUntagDNoSSE2(Register input_reg, 5071 void LCodeGen::EmitNumberUntagDNoSSE2(Register input_reg,
5072 Register temp_reg, 5072 Register temp_reg,
5073 bool deoptimize_on_undefined, 5073 bool deoptimize_on_undefined,
5074 bool deoptimize_on_minus_zero, 5074 bool deoptimize_on_minus_zero,
5075 LEnvironment* env, 5075 LEnvironment* env,
5076 NumberUntagDMode mode) { 5076 NumberUntagDMode mode) {
5077 Label load_smi, done; 5077 Label load_smi, done;
5078 5078
5079 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 5079 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE >
5080 NUMBER_CANDIDATE_IS_ANY_TAGGED);
5081 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
5080 // Smi check. 5082 // Smi check.
5081 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 5083 __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
5082 5084
5083 // Heap number map check. 5085 // Heap number map check.
5084 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5086 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5085 factory()->heap_number_map()); 5087 factory()->heap_number_map());
5086 if (deoptimize_on_undefined) { 5088 if (deoptimize_on_undefined) {
5087 DeoptimizeIf(not_equal, env); 5089 DeoptimizeIf(not_equal, env);
5088 } else { 5090 } else {
5089 Label heap_number; 5091 Label heap_number, convert;
5090 __ j(equal, &heap_number, Label::kNear); 5092 __ j(equal, &heap_number, Label::kNear);
5091 5093
5094 // Convert undefined (or hole) to NaN.
5092 __ cmp(input_reg, factory()->undefined_value()); 5095 __ cmp(input_reg, factory()->undefined_value());
5096 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
5097 __ j(equal, &convert, Label::kNear);
5098 __ cmp(input_reg, factory()->the_hole_value());
5099 }
5093 DeoptimizeIf(not_equal, env); 5100 DeoptimizeIf(not_equal, env);
5094 5101
5095 // Convert undefined to NaN. 5102 __ bind(&convert);
5096 ExternalReference nan = 5103 ExternalReference nan =
5097 ExternalReference::address_of_canonical_non_hole_nan(); 5104 ExternalReference::address_of_canonical_non_hole_nan();
5098 __ fld_d(Operand::StaticVariable(nan)); 5105 __ fld_d(Operand::StaticVariable(nan));
5099 __ jmp(&done, Label::kNear); 5106 __ jmp(&done, Label::kNear);
5107
5100 __ bind(&heap_number); 5108 __ bind(&heap_number);
5101 } 5109 }
5102 // Heap number to x87 conversion. 5110 // Heap number to x87 conversion.
5103 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5111 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5104 if (deoptimize_on_minus_zero) { 5112 if (deoptimize_on_minus_zero) {
5105 __ fldz(); 5113 __ fldz();
5106 __ FCmp(); 5114 __ FCmp();
5107 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); 5115 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
5108 __ j(not_zero, &done, Label::kNear); 5116 __ j(not_zero, &done, Label::kNear);
5109 5117
5110 // Use general purpose registers to check if we have -0.0 5118 // Use general purpose registers to check if we have -0.0
5111 __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); 5119 __ mov(temp_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
5112 __ test(temp_reg, Immediate(HeapNumber::kSignMask)); 5120 __ test(temp_reg, Immediate(HeapNumber::kSignMask));
5113 __ j(zero, &done, Label::kNear); 5121 __ j(zero, &done, Label::kNear);
5114 5122
5115 // Pop FPU stack before deoptimizing. 5123 // Pop FPU stack before deoptimizing.
5116 __ fstp(0); 5124 __ fstp(0);
5117 DeoptimizeIf(not_zero, env); 5125 DeoptimizeIf(not_zero, env);
5118 } 5126 }
5119 __ jmp(&done, Label::kNear); 5127 __ jmp(&done, Label::kNear);
5120 } else if (mode == NUMBER_CANDIDATE_IS_SMI_OR_HOLE) {
5121 __ test(input_reg, Immediate(kSmiTagMask));
5122 DeoptimizeIf(not_equal, env);
5123 } else if (mode == NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE) {
5124 __ test(input_reg, Immediate(kSmiTagMask));
5125 __ j(zero, &load_smi);
5126 ExternalReference hole_nan_reference =
5127 ExternalReference::address_of_the_hole_nan();
5128 __ fld_d(Operand::StaticVariable(hole_nan_reference));
5129 __ jmp(&done, Label::kNear);
5130 } else { 5128 } else {
5131 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5129 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5132 } 5130 }
5133 5131
5134 __ bind(&load_smi); 5132 __ bind(&load_smi);
5135 __ SmiUntag(input_reg); // Untag smi before converting to float. 5133 __ SmiUntag(input_reg); // Untag smi before converting to float.
5136 __ push(input_reg); 5134 __ push(input_reg);
5137 __ fild_s(Operand(esp, 0)); 5135 __ fild_s(Operand(esp, 0));
5138 __ pop(input_reg); 5136 __ pop(input_reg);
5139 __ SmiTag(input_reg); // Retag smi. 5137 __ SmiTag(input_reg); // Retag smi.
5140 __ bind(&done); 5138 __ bind(&done);
5141 } 5139 }
5142 5140
5143 5141
5144 void LCodeGen::EmitNumberUntagD(Register input_reg, 5142 void LCodeGen::EmitNumberUntagD(Register input_reg,
5145 Register temp_reg, 5143 Register temp_reg,
5146 XMMRegister result_reg, 5144 XMMRegister result_reg,
5147 bool deoptimize_on_undefined, 5145 bool deoptimize_on_undefined,
5148 bool deoptimize_on_minus_zero, 5146 bool deoptimize_on_minus_zero,
5149 LEnvironment* env, 5147 LEnvironment* env,
5150 NumberUntagDMode mode) { 5148 NumberUntagDMode mode) {
5151 Label load_smi, done; 5149 Label load_smi, done;
5152 5150
5153 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { 5151 STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE >
5152 NUMBER_CANDIDATE_IS_ANY_TAGGED);
5153 if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
5154 // Smi check. 5154 // Smi check.
5155 __ JumpIfSmi(input_reg, &load_smi, Label::kNear); 5155 __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
5156 5156
5157 // Heap number map check. 5157 // Heap number map check.
5158 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5158 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5159 factory()->heap_number_map()); 5159 factory()->heap_number_map());
5160 if (deoptimize_on_undefined) { 5160 if (deoptimize_on_undefined) {
5161 DeoptimizeIf(not_equal, env); 5161 DeoptimizeIf(not_equal, env);
5162 } else { 5162 } else {
5163 Label heap_number; 5163 Label heap_number, convert;
5164 __ j(equal, &heap_number, Label::kNear); 5164 __ j(equal, &heap_number, Label::kNear);
5165 5165
5166 // Convert undefined (and hole) to NaN.
5166 __ cmp(input_reg, factory()->undefined_value()); 5167 __ cmp(input_reg, factory()->undefined_value());
5168 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
5169 __ j(equal, &convert, Label::kNear);
5170 __ cmp(input_reg, factory()->the_hole_value());
5171 }
5167 DeoptimizeIf(not_equal, env); 5172 DeoptimizeIf(not_equal, env);
5168 5173
5169 // Convert undefined to NaN. 5174 __ bind(&convert);
5170 ExternalReference nan = 5175 ExternalReference nan =
5171 ExternalReference::address_of_canonical_non_hole_nan(); 5176 ExternalReference::address_of_canonical_non_hole_nan();
5172 __ movdbl(result_reg, Operand::StaticVariable(nan)); 5177 __ movdbl(result_reg, Operand::StaticVariable(nan));
5173 __ jmp(&done, Label::kNear); 5178 __ jmp(&done, Label::kNear);
5174 5179
5175 __ bind(&heap_number); 5180 __ bind(&heap_number);
5176 } 5181 }
5177 // Heap number to XMM conversion. 5182 // Heap number to XMM conversion.
5178 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5183 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
5179 if (deoptimize_on_minus_zero) { 5184 if (deoptimize_on_minus_zero) {
5180 XMMRegister xmm_scratch = xmm0; 5185 XMMRegister xmm_scratch = xmm0;
5181 __ xorps(xmm_scratch, xmm_scratch); 5186 __ xorps(xmm_scratch, xmm_scratch);
5182 __ ucomisd(result_reg, xmm_scratch); 5187 __ ucomisd(result_reg, xmm_scratch);
5183 __ j(not_zero, &done, Label::kNear); 5188 __ j(not_zero, &done, Label::kNear);
5184 __ movmskpd(temp_reg, result_reg); 5189 __ movmskpd(temp_reg, result_reg);
5185 __ test_b(temp_reg, 1); 5190 __ test_b(temp_reg, 1);
5186 DeoptimizeIf(not_zero, env); 5191 DeoptimizeIf(not_zero, env);
5187 } 5192 }
5188 __ jmp(&done, Label::kNear); 5193 __ jmp(&done, Label::kNear);
5189 } else if (mode == NUMBER_CANDIDATE_IS_SMI_OR_HOLE) {
5190 __ test(input_reg, Immediate(kSmiTagMask));
5191 DeoptimizeIf(not_equal, env);
5192 } else if (mode == NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE) {
5193 __ test(input_reg, Immediate(kSmiTagMask));
5194 __ j(zero, &load_smi);
5195 ExternalReference hole_nan_reference =
5196 ExternalReference::address_of_the_hole_nan();
5197 __ movdbl(result_reg, Operand::StaticVariable(hole_nan_reference));
5198 __ jmp(&done, Label::kNear);
5199 } else { 5194 } else {
5200 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); 5195 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
5201 } 5196 }
5202 5197
5203 // Smi to XMM conversion 5198 // Smi to XMM conversion
5204 __ bind(&load_smi); 5199 __ bind(&load_smi);
5205 __ SmiUntag(input_reg); // Untag smi before converting to float. 5200 __ SmiUntag(input_reg); // Untag smi before converting to float.
5206 __ cvtsi2sd(result_reg, Operand(input_reg)); 5201 __ cvtsi2sd(result_reg, Operand(input_reg));
5207 __ SmiTag(input_reg); // Retag smi. 5202 __ SmiTag(input_reg); // Retag smi.
5208 __ bind(&done); 5203 __ bind(&done);
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
5488 LOperand* result = instr->result(); 5483 LOperand* result = instr->result();
5489 ASSERT(result->IsDoubleRegister()); 5484 ASSERT(result->IsDoubleRegister());
5490 5485
5491 Register input_reg = ToRegister(input); 5486 Register input_reg = ToRegister(input);
5492 bool deoptimize_on_minus_zero = 5487 bool deoptimize_on_minus_zero =
5493 instr->hydrogen()->deoptimize_on_minus_zero(); 5488 instr->hydrogen()->deoptimize_on_minus_zero();
5494 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg; 5489 Register temp_reg = deoptimize_on_minus_zero ? ToRegister(temp) : no_reg;
5495 5490
5496 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED; 5491 NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
5497 HValue* value = instr->hydrogen()->value(); 5492 HValue* value = instr->hydrogen()->value();
5498 if (value->type().IsSmi()) { 5493 if (value->representation().IsSmi()) {
5499 if (value->IsLoadKeyed()) { 5494 mode = NUMBER_CANDIDATE_IS_SMI;
5500 HLoadKeyed* load = HLoadKeyed::cast(value); 5495 } else if (value->IsLoadKeyed()) {
5501 if (load->UsesMustHandleHole()) { 5496 HLoadKeyed* load = HLoadKeyed::cast(value);
5502 if (load->hole_mode() == ALLOW_RETURN_HOLE) { 5497 if (load->UsesMustHandleHole()) {
5503 mode = NUMBER_CANDIDATE_IS_SMI_CONVERT_HOLE; 5498 mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE;
5504 } else {
5505 mode = NUMBER_CANDIDATE_IS_SMI_OR_HOLE;
5506 }
5507 } else {
5508 mode = NUMBER_CANDIDATE_IS_SMI;
5509 }
5510 } else {
5511 mode = NUMBER_CANDIDATE_IS_SMI;
5512 } 5499 }
5513 } 5500 }
5514 5501
5515 if (CpuFeatures::IsSupported(SSE2)) { 5502 if (CpuFeatures::IsSupported(SSE2)) {
5516 CpuFeatureScope scope(masm(), SSE2); 5503 CpuFeatureScope scope(masm(), SSE2);
5517 XMMRegister result_reg = ToDoubleRegister(result); 5504 XMMRegister result_reg = ToDoubleRegister(result);
5518 EmitNumberUntagD(input_reg, 5505 EmitNumberUntagD(input_reg,
5519 temp_reg, 5506 temp_reg,
5520 result_reg, 5507 result_reg,
5521 instr->hydrogen()->deoptimize_on_undefined(), 5508 instr->hydrogen()->deoptimize_on_undefined(),
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after
6576 FixedArray::kHeaderSize - kPointerSize)); 6563 FixedArray::kHeaderSize - kPointerSize));
6577 __ bind(&done); 6564 __ bind(&done);
6578 } 6565 }
6579 6566
6580 6567
6581 #undef __ 6568 #undef __
6582 6569
6583 } } // namespace v8::internal 6570 } } // namespace v8::internal
6584 6571
6585 #endif // V8_TARGET_ARCH_IA32 6572 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.cc ('k') | src/lithium.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698