Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index a02a88ea344d43b2296c987f0bcf4012ac47d19b..6f4d3e309f49a43dc5b4ff789eec3ee3fd8a93e5 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -4623,7 +4623,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, |
bool deoptimize_on_minus_zero, |
LEnvironment* env, |
NumberUntagDMode mode) { |
- Label load_smi, done; |
+ Label convert, load_smi, done; |
if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
// Smi check. |
@@ -4632,25 +4632,17 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, |
// Heap number map check. |
__ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
Heap::kHeapNumberMapRootIndex); |
- if (!can_convert_undefined_to_nan) { |
- DeoptimizeIf(not_equal, env); |
- } else { |
- Label heap_number, convert; |
- __ j(equal, &heap_number, Label::kNear); |
- // Convert undefined (and hole) to NaN. Compute NaN as 0/0. |
- __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); |
- DeoptimizeIf(not_equal, env); |
- |
- __ bind(&convert); |
- __ xorps(result_reg, result_reg); |
- __ divsd(result_reg, result_reg); |
- __ jmp(&done, Label::kNear); |
+ // On x64 it is safe to load at heap number offset before evaluating the map |
+ // check, since all heap objects are at least two words long. |
+ __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
- __ bind(&heap_number); |
+ if (can_convert_undefined_to_nan) { |
+ __ j(not_equal, &convert); |
+ } else { |
+ DeoptimizeIf(not_equal, env); |
} |
- // Heap number to XMM conversion. |
- __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
+ |
if (deoptimize_on_minus_zero) { |
XMMRegister xmm_scratch = xmm0; |
__ xorps(xmm_scratch, xmm_scratch); |
@@ -4661,6 +4653,18 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, |
DeoptimizeIf(not_zero, env); |
} |
__ jmp(&done, Label::kNear); |
+ |
+ if (can_convert_undefined_to_nan) { |
+ __ bind(&convert); |
+ |
+ // Convert undefined (and hole) to NaN. Compute NaN as 0/0. |
+ __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex); |
+ DeoptimizeIf(not_equal, env); |
+ |
+ __ xorps(result_reg, result_reg); |
+ __ divsd(result_reg, result_reg); |
+ __ jmp(&done, Label::kNear); |
+ } |
} else { |
ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); |
} |