| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "arm64/lithium-codegen-arm64.h" | 7 #include "arm64/lithium-codegen-arm64.h" |
| 8 #include "arm64/lithium-gap-resolver-arm64.h" | 8 #include "arm64/lithium-gap-resolver-arm64.h" |
| 9 #include "code-stubs.h" | 9 #include "code-stubs.h" |
| 10 #include "stub-cache.h" | 10 #include "stub-cache.h" |
| (...skipping 3355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3366 | 3366 |
| 3367 | 3367 |
| 3368 MemOperand LCodeGen::PrepareKeyedExternalArrayOperand( | 3368 MemOperand LCodeGen::PrepareKeyedExternalArrayOperand( |
| 3369 Register key, | 3369 Register key, |
| 3370 Register base, | 3370 Register base, |
| 3371 Register scratch, | 3371 Register scratch, |
| 3372 bool key_is_smi, | 3372 bool key_is_smi, |
| 3373 bool key_is_constant, | 3373 bool key_is_constant, |
| 3374 int constant_key, | 3374 int constant_key, |
| 3375 ElementsKind elements_kind, | 3375 ElementsKind elements_kind, |
| 3376 int additional_index) { | 3376 int base_offset) { |
| 3377 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3377 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3378 int additional_offset = additional_index << element_size_shift; | |
| 3379 if (IsFixedTypedArrayElementsKind(elements_kind)) { | |
| 3380 additional_offset += FixedTypedArrayBase::kDataOffset - kHeapObjectTag; | |
| 3381 } | |
| 3382 | 3378 |
| 3383 if (key_is_constant) { | 3379 if (key_is_constant) { |
| 3384 int key_offset = constant_key << element_size_shift; | 3380 int key_offset = constant_key << element_size_shift; |
| 3385 return MemOperand(base, key_offset + additional_offset); | 3381 return MemOperand(base, key_offset + base_offset); |
| 3386 } | 3382 } |
| 3387 | 3383 |
| 3388 if (key_is_smi) { | 3384 if (key_is_smi) { |
| 3389 __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift)); | 3385 __ Add(scratch, base, Operand::UntagSmiAndScale(key, element_size_shift)); |
| 3390 return MemOperand(scratch, additional_offset); | 3386 return MemOperand(scratch, base_offset); |
| 3391 } | 3387 } |
| 3392 | 3388 |
| 3393 if (additional_offset == 0) { | 3389 if (base_offset == 0) { |
| 3394 return MemOperand(base, key, SXTW, element_size_shift); | 3390 return MemOperand(base, key, SXTW, element_size_shift); |
| 3395 } | 3391 } |
| 3396 | 3392 |
| 3397 ASSERT(!AreAliased(scratch, key)); | 3393 ASSERT(!AreAliased(scratch, key)); |
| 3398 __ Add(scratch, base, additional_offset); | 3394 __ Add(scratch, base, base_offset); |
| 3399 return MemOperand(scratch, key, SXTW, element_size_shift); | 3395 return MemOperand(scratch, key, SXTW, element_size_shift); |
| 3400 } | 3396 } |
| 3401 | 3397 |
| 3402 | 3398 |
| 3403 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { | 3399 void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { |
| 3404 Register ext_ptr = ToRegister(instr->elements()); | 3400 Register ext_ptr = ToRegister(instr->elements()); |
| 3405 Register scratch; | 3401 Register scratch; |
| 3406 ElementsKind elements_kind = instr->elements_kind(); | 3402 ElementsKind elements_kind = instr->elements_kind(); |
| 3407 | 3403 |
| 3408 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); | 3404 bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi(); |
| 3409 bool key_is_constant = instr->key()->IsConstantOperand(); | 3405 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3410 Register key = no_reg; | 3406 Register key = no_reg; |
| 3411 int constant_key = 0; | 3407 int constant_key = 0; |
| 3412 if (key_is_constant) { | 3408 if (key_is_constant) { |
| 3413 ASSERT(instr->temp() == NULL); | 3409 ASSERT(instr->temp() == NULL); |
| 3414 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3410 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3415 if (constant_key & 0xf0000000) { | 3411 if (constant_key & 0xf0000000) { |
| 3416 Abort(kArrayIndexConstantValueTooBig); | 3412 Abort(kArrayIndexConstantValueTooBig); |
| 3417 } | 3413 } |
| 3418 } else { | 3414 } else { |
| 3419 scratch = ToRegister(instr->temp()); | 3415 scratch = ToRegister(instr->temp()); |
| 3420 key = ToRegister(instr->key()); | 3416 key = ToRegister(instr->key()); |
| 3421 } | 3417 } |
| 3422 | 3418 |
| 3423 MemOperand mem_op = | 3419 MemOperand mem_op = |
| 3424 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, | 3420 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, |
| 3425 key_is_constant, constant_key, | 3421 key_is_constant, constant_key, |
| 3426 elements_kind, | 3422 elements_kind, |
| 3427 instr->additional_index()); | 3423 instr->base_offset()); |
| 3428 | 3424 |
| 3429 if ((elements_kind == EXTERNAL_FLOAT32_ELEMENTS) || | 3425 if ((elements_kind == EXTERNAL_FLOAT32_ELEMENTS) || |
| 3430 (elements_kind == FLOAT32_ELEMENTS)) { | 3426 (elements_kind == FLOAT32_ELEMENTS)) { |
| 3431 DoubleRegister result = ToDoubleRegister(instr->result()); | 3427 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3432 __ Ldr(result.S(), mem_op); | 3428 __ Ldr(result.S(), mem_op); |
| 3433 __ Fcvt(result, result.S()); | 3429 __ Fcvt(result, result.S()); |
| 3434 } else if ((elements_kind == EXTERNAL_FLOAT64_ELEMENTS) || | 3430 } else if ((elements_kind == EXTERNAL_FLOAT64_ELEMENTS) || |
| 3435 (elements_kind == FLOAT64_ELEMENTS)) { | 3431 (elements_kind == FLOAT64_ELEMENTS)) { |
| 3436 DoubleRegister result = ToDoubleRegister(instr->result()); | 3432 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3437 __ Ldr(result, mem_op); | 3433 __ Ldr(result, mem_op); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3488 } | 3484 } |
| 3489 } | 3485 } |
| 3490 | 3486 |
| 3491 | 3487 |
| 3492 MemOperand LCodeGen::PrepareKeyedArrayOperand(Register base, | 3488 MemOperand LCodeGen::PrepareKeyedArrayOperand(Register base, |
| 3493 Register elements, | 3489 Register elements, |
| 3494 Register key, | 3490 Register key, |
| 3495 bool key_is_tagged, | 3491 bool key_is_tagged, |
| 3496 ElementsKind elements_kind, | 3492 ElementsKind elements_kind, |
| 3497 Representation representation, | 3493 Representation representation, |
| 3498 int additional_index) { | 3494 int base_offset) { |
| 3499 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && (kSmiTag == 0)); | 3495 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && (kSmiTag == 0)); |
| 3500 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3496 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3501 | 3497 |
| 3502 // Even though the HLoad/StoreKeyed instructions force the input | 3498 // Even though the HLoad/StoreKeyed instructions force the input |
| 3503 // representation for the key to be an integer, the input gets replaced during | 3499 // representation for the key to be an integer, the input gets replaced during |
| 3504 // bounds check elimination with the index argument to the bounds check, which | 3500 // bounds check elimination with the index argument to the bounds check, which |
| 3505 // can be tagged, so that case must be handled here, too. | 3501 // can be tagged, so that case must be handled here, too. |
| 3506 if (key_is_tagged) { | 3502 if (key_is_tagged) { |
| 3507 __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); | 3503 __ Add(base, elements, Operand::UntagSmiAndScale(key, element_size_shift)); |
| 3508 if (representation.IsInteger32()) { | 3504 if (representation.IsInteger32()) { |
| 3509 ASSERT(elements_kind == FAST_SMI_ELEMENTS); | 3505 ASSERT(elements_kind == FAST_SMI_ELEMENTS); |
| 3510 // Read or write only the most-significant 32 bits in the case of fast smi | 3506 // Read or write only the most-significant 32 bits in the case of fast smi |
| 3511 // arrays. | 3507 // arrays. |
| 3512 return UntagSmiFieldMemOperand(base, additional_index); | 3508 return UntagSmiMemOperand(base, base_offset); |
| 3513 } else { | 3509 } else { |
| 3514 return FieldMemOperand(base, additional_index); | 3510 return MemOperand(base, base_offset); |
| 3515 } | 3511 } |
| 3516 } else { | 3512 } else { |
| 3517 // Sign extend key because it could be a 32-bit negative value or contain | 3513 // Sign extend key because it could be a 32-bit negative value or contain |
| 3518 // garbage in the top 32-bits. The address computation happens in 64-bit. | 3514 // garbage in the top 32-bits. The address computation happens in 64-bit. |
| 3519 ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); | 3515 ASSERT((element_size_shift >= 0) && (element_size_shift <= 4)); |
| 3520 if (representation.IsInteger32()) { | 3516 if (representation.IsInteger32()) { |
| 3521 ASSERT(elements_kind == FAST_SMI_ELEMENTS); | 3517 ASSERT(elements_kind == FAST_SMI_ELEMENTS); |
| 3522 // Read or write only the most-significant 32 bits in the case of fast smi | 3518 // Read or write only the most-significant 32 bits in the case of fast smi |
| 3523 // arrays. | 3519 // arrays. |
| 3524 __ Add(base, elements, Operand(key, SXTW, element_size_shift)); | 3520 __ Add(base, elements, Operand(key, SXTW, element_size_shift)); |
| 3525 return UntagSmiFieldMemOperand(base, additional_index); | 3521 return UntagSmiMemOperand(base, base_offset); |
| 3526 } else { | 3522 } else { |
| 3527 __ Add(base, elements, additional_index - kHeapObjectTag); | 3523 __ Add(base, elements, base_offset); |
| 3528 return MemOperand(base, key, SXTW, element_size_shift); | 3524 return MemOperand(base, key, SXTW, element_size_shift); |
| 3529 } | 3525 } |
| 3530 } | 3526 } |
| 3531 } | 3527 } |
| 3532 | 3528 |
| 3533 | 3529 |
| 3534 void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { | 3530 void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { |
| 3535 Register elements = ToRegister(instr->elements()); | 3531 Register elements = ToRegister(instr->elements()); |
| 3536 DoubleRegister result = ToDoubleRegister(instr->result()); | 3532 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3537 MemOperand mem_op; | 3533 MemOperand mem_op; |
| 3538 | 3534 |
| 3539 if (instr->key()->IsConstantOperand()) { | 3535 if (instr->key()->IsConstantOperand()) { |
| 3540 ASSERT(instr->hydrogen()->RequiresHoleCheck() || | 3536 ASSERT(instr->hydrogen()->RequiresHoleCheck() || |
| 3541 (instr->temp() == NULL)); | 3537 (instr->temp() == NULL)); |
| 3542 | 3538 |
| 3543 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3539 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3544 if (constant_key & 0xf0000000) { | 3540 if (constant_key & 0xf0000000) { |
| 3545 Abort(kArrayIndexConstantValueTooBig); | 3541 Abort(kArrayIndexConstantValueTooBig); |
| 3546 } | 3542 } |
| 3547 int offset = FixedDoubleArray::OffsetOfElementAt(constant_key + | 3543 int offset = instr->base_offset() + constant_key * kDoubleSize; |
| 3548 instr->additional_index()); | 3544 mem_op = MemOperand(elements, offset); |
| 3549 mem_op = FieldMemOperand(elements, offset); | |
| 3550 } else { | 3545 } else { |
| 3551 Register load_base = ToRegister(instr->temp()); | 3546 Register load_base = ToRegister(instr->temp()); |
| 3552 Register key = ToRegister(instr->key()); | 3547 Register key = ToRegister(instr->key()); |
| 3553 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); | 3548 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| 3554 int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index()); | |
| 3555 mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, | 3549 mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, |
| 3556 instr->hydrogen()->elements_kind(), | 3550 instr->hydrogen()->elements_kind(), |
| 3557 instr->hydrogen()->representation(), | 3551 instr->hydrogen()->representation(), |
| 3558 offset); | 3552 instr->base_offset()); |
| 3559 } | 3553 } |
| 3560 | 3554 |
| 3561 __ Ldr(result, mem_op); | 3555 __ Ldr(result, mem_op); |
| 3562 | 3556 |
| 3563 if (instr->hydrogen()->RequiresHoleCheck()) { | 3557 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3564 Register scratch = ToRegister(instr->temp()); | 3558 Register scratch = ToRegister(instr->temp()); |
| 3565 // Detect the hole NaN by adding one to the integer representation of the | 3559 // Detect the hole NaN by adding one to the integer representation of the |
| 3566 // result, and checking for overflow. | 3560 // result, and checking for overflow. |
| 3567 STATIC_ASSERT(kHoleNanInt64 == 0x7fffffffffffffff); | 3561 STATIC_ASSERT(kHoleNanInt64 == 0x7fffffffffffffff); |
| 3568 __ Ldr(scratch, mem_op); | 3562 __ Ldr(scratch, mem_op); |
| 3569 __ Cmn(scratch, 1); | 3563 __ Cmn(scratch, 1); |
| 3570 DeoptimizeIf(vs, instr->environment()); | 3564 DeoptimizeIf(vs, instr->environment()); |
| 3571 } | 3565 } |
| 3572 } | 3566 } |
| 3573 | 3567 |
| 3574 | 3568 |
| 3575 void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) { | 3569 void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) { |
| 3576 Register elements = ToRegister(instr->elements()); | 3570 Register elements = ToRegister(instr->elements()); |
| 3577 Register result = ToRegister(instr->result()); | 3571 Register result = ToRegister(instr->result()); |
| 3578 MemOperand mem_op; | 3572 MemOperand mem_op; |
| 3579 | 3573 |
| 3580 Representation representation = instr->hydrogen()->representation(); | 3574 Representation representation = instr->hydrogen()->representation(); |
| 3581 if (instr->key()->IsConstantOperand()) { | 3575 if (instr->key()->IsConstantOperand()) { |
| 3582 ASSERT(instr->temp() == NULL); | 3576 ASSERT(instr->temp() == NULL); |
| 3583 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 3577 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 3584 int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 3578 int offset = instr->base_offset() + |
| 3585 instr->additional_index()); | 3579 ToInteger32(const_operand) * kPointerSize; |
| 3586 if (representation.IsInteger32()) { | 3580 if (representation.IsInteger32()) { |
| 3587 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); | 3581 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); |
| 3588 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && | 3582 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && |
| 3589 (kSmiTag == 0)); | 3583 (kSmiTag == 0)); |
| 3590 mem_op = UntagSmiFieldMemOperand(elements, offset); | 3584 mem_op = UntagSmiMemOperand(elements, offset); |
| 3591 } else { | 3585 } else { |
| 3592 mem_op = FieldMemOperand(elements, offset); | 3586 mem_op = MemOperand(elements, offset); |
| 3593 } | 3587 } |
| 3594 } else { | 3588 } else { |
| 3595 Register load_base = ToRegister(instr->temp()); | 3589 Register load_base = ToRegister(instr->temp()); |
| 3596 Register key = ToRegister(instr->key()); | 3590 Register key = ToRegister(instr->key()); |
| 3597 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); | 3591 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| 3598 int offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
| 3599 | 3592 |
| 3600 mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, | 3593 mem_op = PrepareKeyedArrayOperand(load_base, elements, key, key_is_tagged, |
| 3601 instr->hydrogen()->elements_kind(), | 3594 instr->hydrogen()->elements_kind(), |
| 3602 representation, offset); | 3595 representation, instr->base_offset()); |
| 3603 } | 3596 } |
| 3604 | 3597 |
| 3605 __ Load(result, mem_op, representation); | 3598 __ Load(result, mem_op, representation); |
| 3606 | 3599 |
| 3607 if (instr->hydrogen()->RequiresHoleCheck()) { | 3600 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 3608 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { | 3601 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { |
| 3609 DeoptimizeIfNotSmi(result, instr->environment()); | 3602 DeoptimizeIfNotSmi(result, instr->environment()); |
| 3610 } else { | 3603 } else { |
| 3611 DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, | 3604 DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, |
| 3612 instr->environment()); | 3605 instr->environment()); |
| (...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5130 } | 5123 } |
| 5131 } else { | 5124 } else { |
| 5132 key = ToRegister(instr->key()); | 5125 key = ToRegister(instr->key()); |
| 5133 scratch = ToRegister(instr->temp()); | 5126 scratch = ToRegister(instr->temp()); |
| 5134 } | 5127 } |
| 5135 | 5128 |
| 5136 MemOperand dst = | 5129 MemOperand dst = |
| 5137 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, | 5130 PrepareKeyedExternalArrayOperand(key, ext_ptr, scratch, key_is_smi, |
| 5138 key_is_constant, constant_key, | 5131 key_is_constant, constant_key, |
| 5139 elements_kind, | 5132 elements_kind, |
| 5140 instr->additional_index()); | 5133 instr->base_offset()); |
| 5141 | 5134 |
| 5142 if ((elements_kind == EXTERNAL_FLOAT32_ELEMENTS) || | 5135 if ((elements_kind == EXTERNAL_FLOAT32_ELEMENTS) || |
| 5143 (elements_kind == FLOAT32_ELEMENTS)) { | 5136 (elements_kind == FLOAT32_ELEMENTS)) { |
| 5144 DoubleRegister value = ToDoubleRegister(instr->value()); | 5137 DoubleRegister value = ToDoubleRegister(instr->value()); |
| 5145 DoubleRegister dbl_scratch = double_scratch(); | 5138 DoubleRegister dbl_scratch = double_scratch(); |
| 5146 __ Fcvt(dbl_scratch.S(), value); | 5139 __ Fcvt(dbl_scratch.S(), value); |
| 5147 __ Str(dbl_scratch.S(), dst); | 5140 __ Str(dbl_scratch.S(), dst); |
| 5148 } else if ((elements_kind == EXTERNAL_FLOAT64_ELEMENTS) || | 5141 } else if ((elements_kind == EXTERNAL_FLOAT64_ELEMENTS) || |
| 5149 (elements_kind == FLOAT64_ELEMENTS)) { | 5142 (elements_kind == FLOAT64_ELEMENTS)) { |
| 5150 DoubleRegister value = ToDoubleRegister(instr->value()); | 5143 DoubleRegister value = ToDoubleRegister(instr->value()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5195 void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) { | 5188 void LCodeGen::DoStoreKeyedFixedDouble(LStoreKeyedFixedDouble* instr) { |
| 5196 Register elements = ToRegister(instr->elements()); | 5189 Register elements = ToRegister(instr->elements()); |
| 5197 DoubleRegister value = ToDoubleRegister(instr->value()); | 5190 DoubleRegister value = ToDoubleRegister(instr->value()); |
| 5198 MemOperand mem_op; | 5191 MemOperand mem_op; |
| 5199 | 5192 |
| 5200 if (instr->key()->IsConstantOperand()) { | 5193 if (instr->key()->IsConstantOperand()) { |
| 5201 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 5194 int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 5202 if (constant_key & 0xf0000000) { | 5195 if (constant_key & 0xf0000000) { |
| 5203 Abort(kArrayIndexConstantValueTooBig); | 5196 Abort(kArrayIndexConstantValueTooBig); |
| 5204 } | 5197 } |
| 5205 int offset = FixedDoubleArray::OffsetOfElementAt(constant_key + | 5198 int offset = instr->base_offset() + constant_key * kDoubleSize; |
| 5206 instr->additional_index()); | 5199 mem_op = MemOperand(elements, offset); |
| 5207 mem_op = FieldMemOperand(elements, offset); | |
| 5208 } else { | 5200 } else { |
| 5209 Register store_base = ToRegister(instr->temp()); | 5201 Register store_base = ToRegister(instr->temp()); |
| 5210 Register key = ToRegister(instr->key()); | 5202 Register key = ToRegister(instr->key()); |
| 5211 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); | 5203 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| 5212 int offset = FixedDoubleArray::OffsetOfElementAt(instr->additional_index()); | |
| 5213 mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, | 5204 mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, |
| 5214 instr->hydrogen()->elements_kind(), | 5205 instr->hydrogen()->elements_kind(), |
| 5215 instr->hydrogen()->representation(), | 5206 instr->hydrogen()->representation(), |
| 5216 offset); | 5207 instr->base_offset()); |
| 5217 } | 5208 } |
| 5218 | 5209 |
| 5219 if (instr->NeedsCanonicalization()) { | 5210 if (instr->NeedsCanonicalization()) { |
| 5220 __ CanonicalizeNaN(double_scratch(), value); | 5211 __ CanonicalizeNaN(double_scratch(), value); |
| 5221 __ Str(double_scratch(), mem_op); | 5212 __ Str(double_scratch(), mem_op); |
| 5222 } else { | 5213 } else { |
| 5223 __ Str(value, mem_op); | 5214 __ Str(value, mem_op); |
| 5224 } | 5215 } |
| 5225 } | 5216 } |
| 5226 | 5217 |
| 5227 | 5218 |
| 5228 void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) { | 5219 void LCodeGen::DoStoreKeyedFixed(LStoreKeyedFixed* instr) { |
| 5229 Register value = ToRegister(instr->value()); | 5220 Register value = ToRegister(instr->value()); |
| 5230 Register elements = ToRegister(instr->elements()); | 5221 Register elements = ToRegister(instr->elements()); |
| 5231 Register scratch = no_reg; | 5222 Register scratch = no_reg; |
| 5232 Register store_base = no_reg; | 5223 Register store_base = no_reg; |
| 5233 Register key = no_reg; | 5224 Register key = no_reg; |
| 5234 MemOperand mem_op; | 5225 MemOperand mem_op; |
| 5235 | 5226 |
| 5236 if (!instr->key()->IsConstantOperand() || | 5227 if (!instr->key()->IsConstantOperand() || |
| 5237 instr->hydrogen()->NeedsWriteBarrier()) { | 5228 instr->hydrogen()->NeedsWriteBarrier()) { |
| 5238 scratch = ToRegister(instr->temp()); | 5229 scratch = ToRegister(instr->temp()); |
| 5239 } | 5230 } |
| 5240 | 5231 |
| 5241 Representation representation = instr->hydrogen()->value()->representation(); | 5232 Representation representation = instr->hydrogen()->value()->representation(); |
| 5242 if (instr->key()->IsConstantOperand()) { | 5233 if (instr->key()->IsConstantOperand()) { |
| 5243 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); | 5234 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
| 5244 int offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + | 5235 int offset = instr->base_offset() + |
| 5245 instr->additional_index()); | 5236 ToInteger32(const_operand) * kPointerSize; |
| 5246 store_base = elements; | 5237 store_base = elements; |
| 5247 if (representation.IsInteger32()) { | 5238 if (representation.IsInteger32()) { |
| 5248 ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); | 5239 ASSERT(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY); |
| 5249 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); | 5240 ASSERT(instr->hydrogen()->elements_kind() == FAST_SMI_ELEMENTS); |
| 5250 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && | 5241 STATIC_ASSERT((kSmiValueSize == 32) && (kSmiShift == 32) && |
| 5251 (kSmiTag == 0)); | 5242 (kSmiTag == 0)); |
| 5252 mem_op = UntagSmiFieldMemOperand(store_base, offset); | 5243 mem_op = UntagSmiMemOperand(store_base, offset); |
| 5253 } else { | 5244 } else { |
| 5254 mem_op = FieldMemOperand(store_base, offset); | 5245 mem_op = MemOperand(store_base, offset); |
| 5255 } | 5246 } |
| 5256 } else { | 5247 } else { |
| 5257 store_base = scratch; | 5248 store_base = scratch; |
| 5258 key = ToRegister(instr->key()); | 5249 key = ToRegister(instr->key()); |
| 5259 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); | 5250 bool key_is_tagged = instr->hydrogen()->key()->representation().IsSmi(); |
| 5260 int offset = FixedArray::OffsetOfElementAt(instr->additional_index()); | |
| 5261 | 5251 |
| 5262 mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, | 5252 mem_op = PrepareKeyedArrayOperand(store_base, elements, key, key_is_tagged, |
| 5263 instr->hydrogen()->elements_kind(), | 5253 instr->hydrogen()->elements_kind(), |
| 5264 representation, offset); | 5254 representation, instr->base_offset()); |
| 5265 } | 5255 } |
| 5266 | 5256 |
| 5267 __ Store(value, mem_op, representation); | 5257 __ Store(value, mem_op, representation); |
| 5268 | 5258 |
| 5269 if (instr->hydrogen()->NeedsWriteBarrier()) { | 5259 if (instr->hydrogen()->NeedsWriteBarrier()) { |
| 5270 ASSERT(representation.IsTagged()); | 5260 ASSERT(representation.IsTagged()); |
| 5271 // This assignment may cause element_addr to alias store_base. | 5261 // This assignment may cause element_addr to alias store_base. |
| 5272 Register element_addr = scratch; | 5262 Register element_addr = scratch; |
| 5273 SmiCheck check_needed = | 5263 SmiCheck check_needed = |
| 5274 instr->hydrogen()->value()->IsHeapObject() | 5264 instr->hydrogen()->value()->IsHeapObject() |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6005 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5995 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 6006 // Index is equal to negated out of object property index plus 1. | 5996 // Index is equal to negated out of object property index plus 1. |
| 6007 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5997 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 6008 __ Ldr(result, FieldMemOperand(result, | 5998 __ Ldr(result, FieldMemOperand(result, |
| 6009 FixedArray::kHeaderSize - kPointerSize)); | 5999 FixedArray::kHeaderSize - kPointerSize)); |
| 6010 __ Bind(deferred->exit()); | 6000 __ Bind(deferred->exit()); |
| 6011 __ Bind(&done); | 6001 __ Bind(&done); |
| 6012 } | 6002 } |
| 6013 | 6003 |
| 6014 } } // namespace v8::internal | 6004 } } // namespace v8::internal |
| OLD | NEW |