Commit 8bdbfc02 authored by vegorov@chromium.org's avatar vegorov@chromium.org

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
parent b6911b55
...@@ -1752,6 +1752,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { ...@@ -1752,6 +1752,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; } LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; } LOperand* value() { return inputs_[2]; }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
}; };
......
...@@ -3624,7 +3624,6 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( ...@@ -3624,7 +3624,6 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
Register scratch = scratch0(); Register scratch = scratch0();
bool key_is_constant = instr->key()->IsConstantOperand(); bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0; int constant_key = 0;
Label not_nan;
// Calculate the effective address of the slot in the array to store the // Calculate the effective address of the slot in the array to store the
// double value. // double value.
...@@ -3647,13 +3646,15 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( ...@@ -3647,13 +3646,15 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
} }
// Check for NaN. All NaNs must be canonicalized. if (instr->NeedsCanonicalization()) {
__ VFPCompareAndSetFlags(value, value); // Check for NaN. All NaNs must be canonicalized.
__ VFPCompareAndSetFlags(value, value);
// Only load canonical NaN if the comparison above set the overflow. // Only load canonical NaN if the comparison above set the overflow.
__ Vmov(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double(), vs); __ Vmov(value,
FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
vs);
}
__ bind(&not_nan);
__ vstr(value, scratch, 0); __ vstr(value, scratch, 0);
} }
......
...@@ -2093,6 +2093,17 @@ HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) { ...@@ -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) \ #define H_CONSTANT_INT32(val) \
new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \ new(zone) HConstant(FACTORY->NewNumberFromInt(val, TENURED), \
Representation::Integer32()) Representation::Integer32())
......
...@@ -4226,6 +4226,8 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { ...@@ -4226,6 +4226,8 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
return StoringValueNeedsWriteBarrier(value()); return StoringValueNeedsWriteBarrier(value());
} }
bool NeedsCanonicalization();
virtual void PrintDataTo(StringStream* stream); virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement) DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
......
...@@ -3469,15 +3469,18 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { ...@@ -3469,15 +3469,18 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
void LCodeGen::DoStoreKeyedFastDoubleElement( void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) { LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value()); XMMRegister value = ToDoubleRegister(instr->value());
Label have_value;
__ ucomisd(value, value); if (instr->NeedsCanonicalization()) {
__ j(parity_odd, &have_value); // NaN. Label have_value;
ExternalReference canonical_nan_reference = __ ucomisd(value, value);
ExternalReference::address_of_canonical_non_hole_nan(); __ j(parity_odd, &have_value); // NaN.
__ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
__ bind(&have_value); 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( Operand double_store_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
......
...@@ -1800,6 +1800,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { ...@@ -1800,6 +1800,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; } LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; } LOperand* value() { return inputs_[2]; }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
}; };
......
...@@ -3430,16 +3430,20 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { ...@@ -3430,16 +3430,20 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) {
void LCodeGen::DoStoreKeyedFastDoubleElement( void LCodeGen::DoStoreKeyedFastDoubleElement(
LStoreKeyedFastDoubleElement* instr) { LStoreKeyedFastDoubleElement* instr) {
XMMRegister value = ToDoubleRegister(instr->value()); XMMRegister value = ToDoubleRegister(instr->value());
Label have_value;
__ ucomisd(value, value); if (instr->NeedsCanonicalization()) {
__ j(parity_odd, &have_value); // NaN. Label have_value;
__ Set(kScratchRegister, BitCast<uint64_t>( __ ucomisd(value, value);
FixedDoubleArray::canonical_not_the_hole_nan_as_double())); __ j(parity_odd, &have_value); // NaN.
__ movq(value, kScratchRegister);
__ Set(kScratchRegister, BitCast<uint64_t>(
FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
__ movq(value, kScratchRegister);
__ bind(&have_value);
}
__ bind(&have_value);
Operand double_store_operand = BuildFastArrayOperand( Operand double_store_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag); FixedDoubleArray::kHeaderSize - kHeapObjectTag);
......
...@@ -1720,6 +1720,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> { ...@@ -1720,6 +1720,8 @@ class LStoreKeyedFastDoubleElement: public LTemplateInstruction<0, 3, 0> {
LOperand* elements() { return inputs_[0]; } LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; } LOperand* value() { return inputs_[2]; }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment