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 |