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> {
LOperand* elements() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; }
bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
};
......
......@@ -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(&not_nan);
__ vstr(value, scratch, 0);
}
......
......@@ -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())
......
......@@ -4226,6 +4226,8 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
return StoringValueNeedsWriteBarrier(value());
}
bool NeedsCanonicalization();
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedFastDoubleElement)
......
......@@ -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,
......
......@@ -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(); }
};
......
......@@ -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<uint64_t>(
FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
__ movq(value, kScratchRegister);
__ ucomisd(value, value);
__ j(parity_odd, &have_value); // NaN.
__ 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(
instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag);
......
......@@ -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(); }
};
......
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