From 8bdbfc02e78034056cb405b52f2ceda063b664b3 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Wed, 11 Apr 2012 14:08:11 +0000 Subject: [PATCH] Skip canonicalization check in LStoreKeyedFastDoubleElement when it is not needed: - if value is a result of integer32 to double conversion (can't be NaN); - if value was loaded from fast double backing store (already canonicalized). R=danno@chromium.org Review URL: https://chromiumcodereview.appspot.com/10054009 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11278 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.h | 2 ++ src/arm/lithium-codegen-arm.cc | 15 ++++++++------- src/hydrogen-instructions.cc | 11 +++++++++++ src/hydrogen-instructions.h | 2 ++ src/ia32/lithium-codegen-ia32.cc | 17 ++++++++++------- src/ia32/lithium-ia32.h | 2 ++ src/x64/lithium-codegen-x64.cc | 18 +++++++++++------- src/x64/lithium-x64.h | 2 ++ 8 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index efe3ec3..ef87913 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -1752,6 +1752,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } + + bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 8d72294..147b02d 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -3624,7 +3624,6 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Register scratch = scratch0(); bool key_is_constant = instr->key()->IsConstantOperand(); int constant_key = 0; - Label not_nan; // Calculate the effective address of the slot in the array to store the // double value. @@ -3647,13 +3646,15 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); } - // Check for NaN. All NaNs must be canonicalized. - __ VFPCompareAndSetFlags(value, value); - - // Only load canonical NaN if the comparison above set the overflow. - __ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs); + if (instr->NeedsCanonicalization()) { + // Check for NaN. All NaNs must be canonicalized. + __ VFPCompareAndSetFlags(value, value); + // Only load canonical NaN if the comparison above set the overflow. + __ Vmov(value, + FixedDoubleArray::canonical_not_the_hole_nan_as_double(), + vs); + } - __ bind(¬_nan); __ vstr(value, scratch, 0); } diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 0184da9..b55d40e 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -2093,6 +2093,17 @@ HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) { } +bool HStoreKeyedFastDoubleElement::NeedsCanonicalization() { + // If value was loaded from unboxed double backing store or + // converted from an integer then we don't have to canonicalize it. + if (value()->IsLoadKeyedFastDoubleElement() || + (value()->IsChange() && HChange::cast(value())->from().IsInteger32())) { + return false; + } + return true; +} + + #define H_CONSTANT_INT32(val) \ new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ Representation::Integer32()) diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 6d450a2..1754ad4 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -4226,6 +4226,8 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { return StoringValueNeedsWriteBarrier(value()); } + bool NeedsCanonicalization(); + virtual void PrintDataTo(StringStream* stream); DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement) diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 4a7c364..6dadad6 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -3469,15 +3469,18 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { void LCodeGen::DoStoreKeyedFastDoubleElement( LStoreKeyedFastDoubleElement* instr) { XMMRegister value = ToDoubleRegister(instr->value()); - Label have_value; - __ ucomisd(value, value); - __ j(parity_odd, &have_value); // NaN. + if (instr->NeedsCanonicalization()) { + Label have_value; - ExternalReference canonical_nan_reference = - ExternalReference::address_of_canonical_non_hole_nan(); - __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); - __ bind(&have_value); + __ ucomisd(value, value); + __ j(parity_odd, &have_value); // NaN. + + ExternalReference canonical_nan_reference = + ExternalReference::address_of_canonical_non_hole_nan(); + __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); + __ bind(&have_value); + } Operand double_store_operand = BuildFastArrayOperand( instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 68ee468..1b1bd68 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -1800,6 +1800,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } + + bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 6fc4487..28c5304 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -3430,16 +3430,20 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { void LCodeGen::DoStoreKeyedFastDoubleElement( LStoreKeyedFastDoubleElement* instr) { XMMRegister value = ToDoubleRegister(instr->value()); - Label have_value; - __ ucomisd(value, value); - __ j(parity_odd, &have_value); // NaN. + if (instr->NeedsCanonicalization()) { + Label have_value; - __ Set(kScratchRegister, BitCast( - FixedDoubleArray::canonical_not_the_hole_nan_as_double())); - __ movq(value, kScratchRegister); + __ ucomisd(value, value); + __ j(parity_odd, &have_value); // NaN. + + __ Set(kScratchRegister, BitCast( + FixedDoubleArray::canonical_not_the_hole_nan_as_double())); + __ movq(value, kScratchRegister); + + __ bind(&have_value); + } - __ bind(&have_value); Operand double_store_operand = BuildFastArrayOperand( instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, FixedDoubleArray::kHeaderSize - kHeapObjectTag); diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 2287c5e..4865d41 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -1720,6 +1720,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { LOperand* elements() { return inputs_[0]; } LOperand* key() { return inputs_[1]; } LOperand* value() { return inputs_[2]; } + + bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); } }; -- 2.7.4