OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/arm64/lithium-codegen-arm64.h" | 7 #include "src/arm64/lithium-codegen-arm64.h" |
8 #include "src/arm64/lithium-gap-resolver-arm64.h" | 8 #include "src/arm64/lithium-gap-resolver-arm64.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
(...skipping 3507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3518 } | 3518 } |
3519 | 3519 |
3520 | 3520 |
3521 MemOperand LCodeGen::PrepareKeyedArrayOperand(Register base, | 3521 MemOperand LCodeGen::PrepareKeyedArrayOperand(Register base, |
3522 Register elements, | 3522 Register elements, |
3523 Register key, | 3523 Register key, |
3524 bool key_is_tagged, | 3524 bool key_is_tagged, |
3525 ElementsKind elements_kind, | 3525 ElementsKind elements_kind, |
3526 Representation representation, | 3526 Representation representation, |
3527 int base_offset) { | 3527 int base_offset) { |
3528 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && (kSmiTag == 0)); | 3528 STATIC_ASSERT((kSmiValueSize == kWRegSizeInBits) && (kSmiTag == 0)); |
3529 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3529 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
3530 | 3530 |
3531 // Even though the HLoad/StoreKeyed instructions force the input | 3531 // Even though the HLoad/StoreKeyed instructions force the input |
3532 // representation for the key to be an integer, the input gets replaced during | 3532 // representation for the key to be an integer, the input gets replaced during |
3533 // bounds check elimination with the index argument to the bounds check, which | 3533 // bounds check elimination with the index argument to the bounds check, which |
3534 // can be tagged, so that case must be handled here, too. | 3534 // can be tagged, so that case must be handled here, too. |
3535 if (key_is_tagged) { | 3535 if (key_is_tagged) { |
3536 __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); | 3536 __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); |
3537 if (representation.IsInteger32()) { | 3537 if (representation.IsInteger32()) { |
3538 ASSERT(elements_kind == FAST_SMI_ELEMENTS); | 3538 ASSERT(elements_kind == FAST_SMI_ELEMENTS); |
3539 // Read or write only the most-significant 32 bits in the case of fast smi | 3539 // Read or write only the smi payload in the case of fast smi arrays. |
3540 // arrays. | |
3541 return UntagSmiMemOperand(base, base_offset); | 3540 return UntagSmiMemOperand(base, base_offset); |
3542 } else { | 3541 } else { |
3543 return MemOperand(base, base_offset); | 3542 return MemOperand(base, base_offset); |
3544 } | 3543 } |
3545 } else { | 3544 } else { |
3546 // Sign extend key because it could be a 32-bit negative value or contain | 3545 // Sign extend key because it could be a 32-bit negative value or contain |
3547 // garbage in the top 32-bits. The address computation happens in 64-bit. | 3546 // garbage in the top 32-bits. The address computation happens in 64-bit. |
3548 ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); | 3547 ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); |
3549 if (representation.IsInteger32()) { | 3548 if (representation.IsInteger32()) { |
3550 ASSERT(elements_kind == FAST_SMI_ELEMENTS); | 3549 ASSERT(elements_kind == FAST_SMI_ELEMENTS); |
3551 // Read or write only the most-significant 32 bits in the case of fast smi | 3550 // Read or write only the smi payload in the case of fast smi arrays. |
3552 // arrays. | |
3553 __ Add(base, elements, Operand(key, SXTW, element_size_shift)); | 3551 __ Add(base, elements, Operand(key, SXTW, element_size_shift)); |
3554 return UntagSmiMemOperand(base, base_offset); | 3552 return UntagSmiMemOperand(base, base_offset); |
3555 } else { | 3553 } else { |
3556 __ Add(base, elements, base_offset); | 3554 __ Add(base, elements, base_offset); |
3557 return MemOperand(base, key, SXTW, element_size_shift); | 3555 return MemOperand(base, key, SXTW, element_size_shift); |
3558 } | 3556 } |
3559 } | 3557 } |
3560 } | 3558 } |
3561 | 3559 |
3562 | 3560 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3605 MemOperand mem_op; | 3603 MemOperand mem_op; |
3606 | 3604 |
3607 Representation representation = instr->hydrogen()->representation(); | 3605 Representation representation = instr->hydrogen()->representation(); |
3608 if (instr->key()->IsConstantOperand()) { | 3606 if (instr->key()->IsConstantOperand()) { |
3609 ASSERT(instr->temp() == NULL); | 3607 ASSERT(instr->temp() == NULL); |
3610 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3608 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
3611 int offset = instr->base_offset() + | 3609 int offset = instr->base_offset() + |
3612 ToInteger32(const_operand) * kPointerSize; | 3610 ToInteger32(const_operand) * kPointerSize; |
3613 if (representation.IsInteger32()) { | 3611 if (representation.IsInteger32()) { |
3614 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); | 3612 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); |
3615 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && | 3613 STATIC_ASSERT((kSmiValueSize == kWRegSizeInBits) && (kSmiTag == 0)); |
3616 (kSmiTag == 0)); | |
3617 mem_op = UntagSmiMemOperand(elements, offset); | 3614 mem_op = UntagSmiMemOperand(elements, offset); |
3618 } else { | 3615 } else { |
3619 mem_op = MemOperand(elements, offset); | 3616 mem_op = MemOperand(elements, offset); |
3620 } | 3617 } |
3621 } else { | 3618 } else { |
3622 Register load_base = ToRegister(instr->temp()); | 3619 Register load_base = ToRegister(instr->temp()); |
3623 Register key = ToRegister(instr->key()); | 3620 Register key = ToRegister(instr->key()); |
3624 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); | 3621 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
3625 | 3622 |
3626 mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, | 3623 mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3676 source = object; | 3673 source = object; |
3677 } else { | 3674 } else { |
3678 // Load the properties array, using result as a scratch register. | 3675 // Load the properties array, using result as a scratch register. |
3679 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 3676 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
3680 source = result; | 3677 source = result; |
3681 } | 3678 } |
3682 | 3679 |
3683 if (access.representation().IsSmi() && | 3680 if (access.representation().IsSmi() && |
3684 instr->hydrogen()->representation().IsInteger32()) { | 3681 instr->hydrogen()->representation().IsInteger32()) { |
3685 // Read int value directly from upper half of the smi. | 3682 // Read int value directly from upper half of the smi. |
3686 STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0); | 3683 STATIC_ASSERT((kSmiValueSize == kWRegSizeInBits) && (kSmiTag == 0)); |
3687 __ Load(result, UntagSmiFieldMemOperand(source, offset), | 3684 __ Load(result, UntagSmiFieldMemOperand(source, offset), |
3688 Representation::Integer32()); | 3685 Representation::Integer32()); |
3689 } else { | 3686 } else { |
3690 __ Load(result, FieldMemOperand(source, offset), access.representation()); | 3687 __ Load(result, FieldMemOperand(source, offset), access.representation()); |
3691 } | 3688 } |
3692 } | 3689 } |
3693 | 3690 |
3694 | 3691 |
3695 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { | 3692 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { |
3696 ASSERT(ToRegister(instr->context()).is(cp)); | 3693 ASSERT(ToRegister(instr->context()).is(cp)); |
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5279 | 5276 |
5280 Representation representation = instr->hydrogen()->value()->representation(); | 5277 Representation representation = instr->hydrogen()->value()->representation(); |
5281 if (instr->key()->IsConstantOperand()) { | 5278 if (instr->key()->IsConstantOperand()) { |
5282 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 5279 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
5283 int offset = instr->base_offset() + | 5280 int offset = instr->base_offset() + |
5284 ToInteger32(const_operand) * kPointerSize; | 5281 ToInteger32(const_operand) * kPointerSize; |
5285 store_base = elements; | 5282 store_base = elements; |
5286 if (representation.IsInteger32()) { | 5283 if (representation.IsInteger32()) { |
5287 ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 5284 ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
5288 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); | 5285 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); |
5289 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && | 5286 STATIC_ASSERT((kSmiValueSize == kWRegSizeInBits) && (kSmiTag == 0)); |
5290 (kSmiTag == 0)); | |
5291 mem_op = UntagSmiMemOperand(store_base, offset); | 5287 mem_op = UntagSmiMemOperand(store_base, offset); |
5292 } else { | 5288 } else { |
5293 mem_op = MemOperand(store_base, offset); | 5289 mem_op = MemOperand(store_base, offset); |
5294 } | 5290 } |
5295 } else { | 5291 } else { |
5296 store_base = scratch; | 5292 store_base = scratch; |
5297 key = ToRegister(instr->key()); | 5293 key = ToRegister(instr->key()); |
5298 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); | 5294 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
5299 | 5295 |
5300 mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, | 5296 mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5399 Register temp0 = ToRegister(instr->temp0()); | 5395 Register temp0 = ToRegister(instr->temp0()); |
5400 __ Ldr(temp0, FieldMemOperand(destination, offset)); | 5396 __ Ldr(temp0, FieldMemOperand(destination, offset)); |
5401 __ AssertSmi(temp0); | 5397 __ AssertSmi(temp0); |
5402 // If destination aliased temp0, restore it to the address calculated | 5398 // If destination aliased temp0, restore it to the address calculated |
5403 // earlier. | 5399 // earlier. |
5404 if (destination.Is(temp0)) { | 5400 if (destination.Is(temp0)) { |
5405 ASSERT(!access.IsInobject()); | 5401 ASSERT(!access.IsInobject()); |
5406 __ Ldr(destination, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5402 __ Ldr(destination, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5407 } | 5403 } |
5408 #endif | 5404 #endif |
5409 STATIC_ASSERT(kSmiValueSize == 32 && kSmiShift == 32 && kSmiTag == 0); | 5405 STATIC_ASSERT((kSmiValueSize == kWRegSizeInBits) && (kSmiTag == 0)); |
5410 __ Store(value, UntagSmiFieldMemOperand(destination, offset), | 5406 __ Store(value, UntagSmiFieldMemOperand(destination, offset), |
5411 Representation::Integer32()); | 5407 Representation::Integer32()); |
5412 } else { | 5408 } else { |
5413 __ Store(value, FieldMemOperand(destination, offset), representation); | 5409 __ Store(value, FieldMemOperand(destination, offset), representation); |
5414 } | 5410 } |
5415 if (instr->hydrogen()->NeedsWriteBarrier()) { | 5411 if (instr->hydrogen()->NeedsWriteBarrier()) { |
5416 __ RecordWriteField(destination, | 5412 __ RecordWriteField(destination, |
5417 offset, | 5413 offset, |
5418 value, // Clobbered. | 5414 value, // Clobbered. |
5419 ToRegister(instr->temp1()), // Clobbered. | 5415 ToRegister(instr->temp1()), // Clobbered. |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6042 Handle<ScopeInfo> scope_info = instr->scope_info(); | 6038 Handle<ScopeInfo> scope_info = instr->scope_info(); |
6043 __ Push(scope_info); | 6039 __ Push(scope_info); |
6044 __ Push(ToRegister(instr->function())); | 6040 __ Push(ToRegister(instr->function())); |
6045 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6041 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6046 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6042 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6047 } | 6043 } |
6048 | 6044 |
6049 | 6045 |
6050 | 6046 |
6051 } } // namespace v8::internal | 6047 } } // namespace v8::internal |
OLD | NEW |