Chromium Code Reviews| Index: src/arm64/lithium-codegen-arm64.cc |
| diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc |
| index dce5a1a0cde89999c4d8aa492368bfdb1dde81ab..3b5aabfdf5e0776cf16c721f48242b4529663d55 100644 |
| --- a/src/arm64/lithium-codegen-arm64.cc |
| +++ b/src/arm64/lithium-codegen-arm64.cc |
| @@ -3427,24 +3427,43 @@ void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { |
| } |
| -void LCodeGen::CalcKeyedArrayBaseRegister(Register base, |
| - Register elements, |
| - Register key, |
| - bool key_is_tagged, |
| - ElementsKind elements_kind) { |
| +MemOperand LCodeGen::PrepareKeyedArrayOperand(Register base, |
| + Register elements, |
| + Register key, |
| + bool key_is_tagged, |
| + ElementsKind elements_kind, |
| + Representation representation, |
| + int additional_index) { |
| + STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && (kSmiTag == 0)); |
| int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| + // Read or write only the most-significant 32 bits in the case of fast smi |
| + // arrays with integer inputs/outputs. |
| + bool int32_and_fast_smi = representation.IsInteger32() && |
|
ulan
2014/05/05 08:21:21
representation.IsInteger32() should imply (instr->
m.m.capewell
2014/05/06 13:20:45
Done.
|
| + (elements_kind == FAST_SMI_ELEMENTS); |
| + |
| // Even though the HLoad/StoreKeyed instructions force the input |
| // representation for the key to be an integer, the input gets replaced during |
| // bounds check elimination with the index argument to the bounds check, which |
| // can be tagged, so that case must be handled here, too. |
| if (key_is_tagged) { |
| __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); |
| + if (int32_and_fast_smi) { |
| + return UntagSmiFieldMemOperand(base, additional_index); |
| + } else { |
| + return FieldMemOperand(base, additional_index); |
| + } |
| } else { |
| // Sign extend key because it could be a 32-bit negative value or contain |
| // garbage in the top 32-bits. The address computation happens in 64-bit. |
| ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); |
| - __ Add(base, elements, Operand(key, SXTW, element_size_shift)); |
| + if (int32_and_fast_smi) { |
| + __ Add(base, elements, Operand(key, SXTW, element_size_shift)); |
| + return UntagSmiFieldMemOperand(base, additional_index); |
| + } else { |
| + __ Add(base, elements, additional_index - kHeapObjectTag); |
| + return MemOperand(base, key, SXTW, element_size_shift); |
| + } |
| } |
| } |
| @@ -3452,8 +3471,7 @@ void LCodeGen::CalcKeyedArrayBaseRegister(Register base, |
| void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { |
| Register elements = ToRegister(instr->elements()); |
| DoubleRegister result = ToDoubleRegister(instr->result()); |
| - Register load_base; |
| - int offset = 0; |
| + MemOperand mem_op; |
| if (instr->key()->IsConstantOperand()) { |
| ASSERT(instr->hydrogen()->RequiresHoleCheck() || |
| @@ -3463,27 +3481,30 @@ void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { |
| if (constant_key & 0xf0000000) { |
| Abort(kArrayIndexConstantValueTooBig); |
| } |
| - offset = FixedDoubleArray::OffsetOfElementAt(constant_key + |
| - instr->additional_index()); |
| - load_base = elements; |
| + int offset = FixedDoubleArray::OffsetOfElementAt(constant_key + |
| + instr->additional_index()); |
| + mem_op = FieldMemOperand(elements, offset); |
| } else { |
| - load_base = ToRegister(instr->temp()); |
| + Register load_base = ToRegister(instr->temp()); |
| Register key = ToRegister(instr->key()); |
| bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| - CalcKeyedArrayBaseRegister(load_base, elements, key, key_is_tagged, |
| - instr->hydrogen()->elements_kind()); |
| - offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index()); |
| + int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index()); |
| + mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, |
| + instr->hydrogen()->elements_kind(), |
| + instr->hydrogen()->representation(), |
| + offset); |
| } |
| - __ Ldr(result, FieldMemOperand(load_base, offset)); |
| + |
| + __ Ldr(result, mem_op); |
| if (instr->hydrogen()->RequiresHoleCheck()) { |
| Register scratch = ToRegister(instr->temp()); |
| - |
| - // TODO(all): Is it faster to reload this value to an integer register, or |
| - // move from fp to integer? |
| - __ Fmov(scratch, result); |
| - __ Cmp(scratch, kHoleNanInt64); |
| - DeoptimizeIf(eq, instr->environment()); |
| + // Detect the hole NaN by adding one to the integer representation of the |
| + // result, and checking for overflow. |
| + STATIC_ASSERT(kHoleNanInt64 == 0x7fffffffffffffff); |
| + __ Ldr(scratch, mem_op); |
| + __ Cmn(scratch, 1); |
| + DeoptimizeIf(vs, instr->environment()); |
| } |
| } |
| @@ -3491,35 +3512,35 @@ void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { |
| void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) { |
| Register elements = ToRegister(instr->elements()); |
| Register result = ToRegister(instr->result()); |
| - Register load_base; |
| - int offset = 0; |
| + MemOperand mem_op; |
| + Representation representation = instr->hydrogen()->representation(); |
| if (instr->key()->IsConstantOperand()) { |
| ASSERT(instr->temp() == NULL); |
| LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| - offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + |
| - instr->additional_index()); |
| - load_base = elements; |
| + int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + |
| + instr->additional_index()); |
| + if (representation.IsInteger32() && |
|
ulan
2014/05/05 08:21:21
representation.IsInteger32() should imply (instr->
m.m.capewell
2014/05/06 13:20:45
Done.
|
| + (instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS)) { |
| + STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && |
| + (kSmiTag == 0)); |
| + mem_op = UntagSmiFieldMemOperand(elements, offset); |
| + } else { |
| + mem_op = FieldMemOperand(elements, offset); |
| + } |
| } else { |
| - load_base = ToRegister(instr->temp()); |
| + Register load_base = ToRegister(instr->temp()); |
| Register key = ToRegister(instr->key()); |
| bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| - CalcKeyedArrayBaseRegister(load_base, elements, key, key_is_tagged, |
| - instr->hydrogen()->elements_kind()); |
| - offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
| - } |
| - Representation representation = instr->hydrogen()->representation(); |
| + int offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
| - if (representation.IsInteger32() && |
| - instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS) { |
| - STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0); |
| - __ Load(result, UntagSmiFieldMemOperand(load_base, offset), |
| - Representation::Integer32()); |
| - } else { |
| - __ Load(result, FieldMemOperand(load_base, offset), |
| - representation); |
| + mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, |
| + instr->hydrogen()->elements_kind(), |
| + representation, offset); |
| } |
| + __ Load(result, mem_op, representation); |
| + |
| if (instr->hydrogen()->RequiresHoleCheck()) { |
| if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| DeoptimizeIfNotSmi(result, instr->environment()); |
| @@ -5114,24 +5135,25 @@ void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) { |
| void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) { |
| Register elements = ToRegister(instr->elements()); |
| DoubleRegister value = ToDoubleRegister(instr->value()); |
| - Register store_base = no_reg; |
| - int offset = 0; |
| + MemOperand mem_op; |
| if (instr->key()->IsConstantOperand()) { |
| int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| if (constant_key & 0xf0000000) { |
| Abort(kArrayIndexConstantValueTooBig); |
| } |
| - offset = FixedDoubleArray::OffsetOfElementAt(constant_key + |
| - instr->additional_index()); |
| - store_base = elements; |
| + int offset = FixedDoubleArray::OffsetOfElementAt(constant_key + |
| + instr->additional_index()); |
| + mem_op = FieldMemOperand(elements, offset); |
| } else { |
| - store_base = ToRegister(instr->temp()); |
| + Register store_base = ToRegister(instr->temp()); |
| Register key = ToRegister(instr->key()); |
| bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| - CalcKeyedArrayBaseRegister(store_base, elements, key, key_is_tagged, |
| - instr->hydrogen()->elements_kind()); |
| - offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index()); |
| + int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index()); |
| + mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, |
| + instr->hydrogen()->elements_kind(), |
| + instr->hydrogen()->representation(), |
| + offset); |
| } |
| if (instr->NeedsCanonicalization()) { |
| @@ -5139,9 +5161,9 @@ void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) { |
| __ Fmov(dbl_scratch, |
| FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
| __ Fmaxnm(dbl_scratch, dbl_scratch, value); |
| - __ Str(dbl_scratch, FieldMemOperand(store_base, offset)); |
| + __ Str(dbl_scratch, mem_op); |
| } else { |
| - __ Str(value, FieldMemOperand(store_base, offset)); |
| + __ Str(value, mem_op); |
| } |
| } |
| @@ -5152,37 +5174,40 @@ void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) { |
| Register scratch = no_reg; |
| Register store_base = no_reg; |
| Register key = no_reg; |
| - int offset = 0; |
| + MemOperand mem_op; |
| if (!instr->key()->IsConstantOperand() || |
| instr->hydrogen()->NeedsWriteBarrier()) { |
| scratch = ToRegister(instr->temp()); |
| } |
| + Representation representation = instr->hydrogen()->value()->representation(); |
| if (instr->key()->IsConstantOperand()) { |
| LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| - offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + |
| - instr->additional_index()); |
| + int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + |
| + instr->additional_index()); |
| store_base = elements; |
| + if (representation.IsInteger32() && |
| + (instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS)) { |
|
ulan
2014/05/05 08:21:21
representation.IsInteger32() should imply (instr->
m.m.capewell
2014/05/06 13:20:45
Done.
|
| + STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && |
| + (kSmiTag == 0)); |
| + mem_op = UntagSmiFieldMemOperand(store_base, offset); |
| + } else { |
| + mem_op = FieldMemOperand(store_base, offset); |
| + } |
| } else { |
| store_base = scratch; |
| key = ToRegister(instr->key()); |
| bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| - CalcKeyedArrayBaseRegister(store_base, elements, key, key_is_tagged, |
| - instr->hydrogen()->elements_kind()); |
| - offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
| - } |
| - Representation representation = instr->hydrogen()->value()->representation(); |
| - if (representation.IsInteger32()) { |
| - ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
| - ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); |
|
ulan
2014/05/05 08:21:21
Can we keep these two asserts?
m.m.capewell
2014/05/06 13:20:45
Done.
|
| - STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0); |
| - __ Store(value, UntagSmiFieldMemOperand(store_base, offset), |
| - Representation::Integer32()); |
| - } else { |
| - __ Store(value, FieldMemOperand(store_base, offset), representation); |
| + int offset = FixedArray::OffsetOfElementAt(instr->additional_index()); |
| + |
| + mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, |
| + instr->hydrogen()->elements_kind(), |
| + representation, offset); |
| } |
| + __ Store(value, mem_op, representation); |
| + |
| if (instr->hydrogen()->NeedsWriteBarrier()) { |
| ASSERT(representation.IsTagged()); |
| // This assignment may cause element_addr to alias store_base. |
| @@ -5191,7 +5216,7 @@ void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) { |
| instr->hydrogen()->value()->IsHeapObject() |
| ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
| // Compute address of modified element and store it into key register. |
| - __ Add(element_addr, store_base, offset - kHeapObjectTag); |
| + __ Add(element_addr, store_base, mem_op.OffsetAsOperand()); |
|
ulan
2014/05/05 08:21:21
Using mem_op.base() instead of store_base would be
m.m.capewell
2014/05/06 13:20:45
Done.
|
| __ RecordWrite(elements, element_addr, value, GetLinkRegisterState(), |
| kSaveFPRegs, EMIT_REMEMBERED_SET, check_needed); |
| } |