Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index 85e7ac0bf08d4bb4cca0678b7e6fd528cf2304f4..10539814e18ecde5f0bcd860f3cbe6ab4f44c479 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2375,11 +2375,20 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { |
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
Register result = ToRegister(instr->result()); |
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
+ // Sign extend key because it could be a 32 bit negative value |
+ // and the dehoisted address computation happens in 64 bits. |
+ Register key_reg = ToRegister(instr->key()); |
+ __ movsxlq(key_reg, key_reg); |
+ } |
+ |
// Load the result. |
__ movq(result, |
- BuildFastArrayOperand(instr->elements(), instr->key(), |
+ BuildFastArrayOperand(instr->elements(), |
+ instr->key(), |
FAST_ELEMENTS, |
- FixedArray::kHeaderSize - kHeapObjectTag)); |
+ FixedArray::kHeaderSize - kHeapObjectTag, |
+ instr->additional_index())); |
// Check for the hole value. |
if (instr->hydrogen()->RequiresHoleCheck()) { |
@@ -2393,19 +2402,30 @@ void LCodeGen::DoLoadKeyedFastDoubleElement( |
LLoadKeyedFastDoubleElement* instr) { |
XMMRegister result(ToDoubleRegister(instr->result())); |
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
+ // Sign extend key because it could be a 32 bit negative value |
+ // and the dehoisted address computation happens in 64 bits |
+ Register key_reg = ToRegister(instr->key()); |
+ __ movsxlq(key_reg, key_reg); |
+ } |
+ |
int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag + |
sizeof(kHoleNanLower32); |
Operand hole_check_operand = BuildFastArrayOperand( |
instr->elements(), |
instr->key(), |
FAST_DOUBLE_ELEMENTS, |
- offset); |
+ offset, |
+ instr->additional_index()); |
__ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); |
DeoptimizeIf(equal, instr->environment()); |
Operand double_load_operand = BuildFastArrayOperand( |
- instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, |
- FixedDoubleArray::kHeaderSize - kHeapObjectTag); |
+ instr->elements(), |
+ instr->key(), |
+ FAST_DOUBLE_ELEMENTS, |
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
+ instr->additional_index()); |
__ movsd(result, double_load_operand); |
} |
@@ -2414,7 +2434,8 @@ Operand LCodeGen::BuildFastArrayOperand( |
LOperand* elements_pointer, |
LOperand* key, |
ElementsKind elements_kind, |
- uint32_t offset) { |
+ uint32_t offset, |
+ uint32_t additional_index) { |
Register elements_pointer_reg = ToRegister(elements_pointer); |
int shift_size = ElementsKindToShiftSize(elements_kind); |
if (key->IsConstantOperand()) { |
@@ -2423,11 +2444,14 @@ Operand LCodeGen::BuildFastArrayOperand( |
Abort("array index constant value too big"); |
} |
return Operand(elements_pointer_reg, |
- constant_value * (1 << shift_size) + offset); |
+ ((constant_value + additional_index) << shift_size) |
+ + offset); |
} else { |
ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); |
- return Operand(elements_pointer_reg, ToRegister(key), |
- scale_factor, offset); |
+ return Operand(elements_pointer_reg, |
+ ToRegister(key), |
+ scale_factor, |
+ offset + (additional_index << shift_size)); |
} |
} |
@@ -2436,7 +2460,17 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
LLoadKeyedSpecializedArrayElement* instr) { |
ElementsKind elements_kind = instr->elements_kind(); |
Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
- instr->key(), elements_kind, 0)); |
+ instr->key(), |
+ elements_kind, |
+ 0, |
+ instr->additional_index())); |
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
+ // Sign extend key because it could be a 32 bit negative value |
+ // and the dehoisted address computation happens in 64 bits |
+ Register key_reg = ToRegister(instr->key()); |
+ __ movsxlq(key_reg, key_reg); |
+ } |
+ |
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
XMMRegister result(ToDoubleRegister(instr->result())); |
__ movss(result, operand); |
@@ -3338,7 +3372,18 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
LStoreKeyedSpecializedArrayElement* instr) { |
ElementsKind elements_kind = instr->elements_kind(); |
Operand operand(BuildFastArrayOperand(instr->external_pointer(), |
- instr->key(), elements_kind, 0)); |
+ instr->key(), |
+ elements_kind, |
+ 0, |
+ instr->additional_index())); |
+ |
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
+ // Sign extend key because it could be a 32 bit negative value |
+ // and the dehoisted address computation happens in 64 bits |
+ Register key_reg = ToRegister(instr->key()); |
+ __ movsxlq(key_reg, key_reg); |
+ } |
+ |
if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
XMMRegister value(ToDoubleRegister(instr->value())); |
__ cvtsd2ss(value, value); |
@@ -3408,30 +3453,29 @@ void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
Register elements = ToRegister(instr->object()); |
Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
- // Do the store. |
- if (instr->key()->IsConstantOperand()) { |
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
- LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
- int offset = |
- ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; |
- __ movq(FieldOperand(elements, offset), value); |
- } else { |
- __ movq(FieldOperand(elements, |
- key, |
- times_pointer_size, |
- FixedArray::kHeaderSize), |
- value); |
+ Operand operand = |
+ BuildFastArrayOperand(instr->object(), |
+ instr->key(), |
+ FAST_ELEMENTS, |
+ FixedArray::kHeaderSize - kHeapObjectTag, |
+ instr->additional_index()); |
+ |
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
+ // Sign extend key because it could be a 32 bit negative value |
+ // and the dehoisted address computation happens in 64 bits |
+ Register key_reg = ToRegister(instr->key()); |
+ __ movsxlq(key_reg, key_reg); |
} |
+ __ movq(operand, value); |
+ |
if (instr->hydrogen()->NeedsWriteBarrier()) { |
+ ASSERT(!instr->key()->IsConstantOperand()); |
HType type = instr->hydrogen()->value()->type(); |
SmiCheck check_needed = |
type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
// Compute address of modified element and store it into key register. |
- __ lea(key, FieldOperand(elements, |
- key, |
- times_pointer_size, |
- FixedArray::kHeaderSize)); |
+ __ lea(key, operand); |
__ RecordWrite(elements, |
key, |
value, |
@@ -3460,8 +3504,19 @@ void LCodeGen::DoStoreKeyedFastDoubleElement( |
} |
Operand double_store_operand = BuildFastArrayOperand( |
- instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS, |
- FixedDoubleArray::kHeaderSize - kHeapObjectTag); |
+ instr->elements(), |
+ instr->key(), |
+ FAST_DOUBLE_ELEMENTS, |
+ FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
+ instr->additional_index()); |
+ |
+ if (instr->hydrogen()->IsDehoisted() && !instr->key()->IsConstantOperand()) { |
+ // Sign extend key because it could be a 32 bit negative value |
+ // and the dehoisted address computation happens in 64 bits |
+ Register key_reg = ToRegister(instr->key()); |
+ __ movsxlq(key_reg, key_reg); |
+ } |
+ |
__ movsd(double_store_operand, value); |
} |