From 81425a20b2c2aeb28a54fd95bb47569001ae70bf Mon Sep 17 00:00:00 2001 From: "olivf@chromium.org" Date: Fri, 13 Sep 2013 12:01:32 +0000 Subject: [PATCH] Intel: Branch reordering and port arm EmitNumberUntagD() Improvement R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/23872026 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16714 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/lithium-codegen-ia32.cc | 34 ++++++++++++++++++---------------- src/x64/lithium-codegen-x64.cc | 38 +++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 9727b84..7d7b51d 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -5308,7 +5308,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. @@ -5317,26 +5317,15 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, // Heap number map check. __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), factory()->heap_number_map()); - if (!can_convert_undefined_to_nan) { - DeoptimizeIf(not_equal, env); + if (can_convert_undefined_to_nan) { + __ j(not_equal, &convert, Label::kNear); } else { - Label heap_number, convert; - __ j(equal, &heap_number, Label::kNear); - - // Convert undefined (and hole) to NaN. - __ cmp(input_reg, factory()->undefined_value()); DeoptimizeIf(not_equal, env); - - __ bind(&convert); - ExternalReference nan = - ExternalReference::address_of_canonical_non_hole_nan(); - __ movdbl(result_reg, Operand::StaticVariable(nan)); - __ jmp(&done, Label::kNear); - - __ bind(&heap_number); } + // Heap number to XMM conversion. __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); + if (deoptimize_on_minus_zero) { XMMRegister xmm_scratch = xmm0; __ xorps(xmm_scratch, xmm_scratch); @@ -5347,6 +5336,19 @@ 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. + __ cmp(input_reg, factory()->undefined_value()); + DeoptimizeIf(not_equal, env); + + ExternalReference nan = + ExternalReference::address_of_canonical_non_hole_nan(); + __ movdbl(result_reg, Operand::StaticVariable(nan)); + __ jmp(&done, Label::kNear); + } } else { ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); } diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index a02a88e..6f4d3e3 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); } -- 2.7.4