OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 3465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3476 } | 3476 } |
3477 | 3477 |
3478 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 3478 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
3479 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx | 3479 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx |
3480 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx | 3480 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx |
3481 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax | 3481 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax |
3482 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx | 3482 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx |
3483 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi | 3483 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi |
3484 Label miss; | 3484 Label miss; |
3485 | 3485 |
| 3486 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { |
| 3487 // Current stack layout: |
| 3488 // - esp[8] -- value |
| 3489 // - esp[4] -- slot |
| 3490 // - esp[0] -- return address |
| 3491 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); |
| 3492 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
| 3493 if (in_frame) { |
| 3494 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); |
| 3495 // If the vector is not on the stack, then insert the vector beneath |
| 3496 // return address in order to prepare for calling handler with |
| 3497 // StoreWithVector calling convention. |
| 3498 __ push(Operand(esp, 0)); |
| 3499 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); |
| 3500 __ RecordComment("]"); |
| 3501 } else { |
| 3502 __ mov(vector, Operand(esp, 1 * kPointerSize)); |
| 3503 } |
| 3504 __ mov(slot, Operand(esp, 2 * kPointerSize)); |
| 3505 __ mov(value, Operand(esp, 3 * kPointerSize)); |
| 3506 } |
| 3507 |
3486 __ push(value); | 3508 __ push(value); |
3487 | 3509 |
3488 Register scratch = value; | 3510 Register scratch = value; |
3489 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 3511 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
3490 FixedArray::kHeaderSize)); | 3512 FixedArray::kHeaderSize)); |
3491 | 3513 |
3492 // Is it a weak cell? | 3514 // Is it a weak cell? |
3493 Label try_array; | 3515 Label try_array; |
3494 Label not_array, smi_key, key_okay; | 3516 Label not_array, smi_key, key_okay; |
3495 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 3517 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3617 __ JumpIfSmi(cached_map, &pop_and_miss); | 3639 __ JumpIfSmi(cached_map, &pop_and_miss); |
3618 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister())); | 3640 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister())); |
3619 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map); | 3641 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map); |
3620 | 3642 |
3621 // Call store transition handler using StoreTransitionDescriptor calling | 3643 // Call store transition handler using StoreTransitionDescriptor calling |
3622 // convention. | 3644 // convention. |
3623 __ pop(key); | 3645 __ pop(key); |
3624 __ pop(vector); | 3646 __ pop(vector); |
3625 __ pop(receiver); | 3647 __ pop(receiver); |
3626 __ pop(value); | 3648 __ pop(value); |
3627 { | 3649 // Ensure that the transition handler we are going to call has the same |
3628 // Put vector and slot beneath return address. | 3650 // number of stack arguments which means that we don't have to adapt them |
3629 __ push(vector); | 3651 // before the call. |
3630 __ push(Operand(esp, 1 * kPointerSize)); // push return address | 3652 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
3631 __ mov(Operand(esp, 2 * kPointerSize), slot); | 3653 STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3); |
3632 } | 3654 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - |
| 3655 StoreWithVectorDescriptor::kValue == |
| 3656 StoreTransitionDescriptor::kParameterCount - |
| 3657 StoreTransitionDescriptor::kValue); |
| 3658 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - |
| 3659 StoreWithVectorDescriptor::kSlot == |
| 3660 StoreTransitionDescriptor::kParameterCount - |
| 3661 StoreTransitionDescriptor::kSlot); |
| 3662 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - |
| 3663 StoreWithVectorDescriptor::kVector == |
| 3664 StoreTransitionDescriptor::kParameterCount - |
| 3665 StoreTransitionDescriptor::kVector); |
3633 __ jmp(Operand::StaticVariable(virtual_register)); | 3666 __ jmp(Operand::StaticVariable(virtual_register)); |
3634 | 3667 |
3635 __ bind(&prepare_next); | 3668 __ bind(&prepare_next); |
3636 __ add(counter, Immediate(Smi::FromInt(3))); | 3669 __ add(counter, Immediate(Smi::FromInt(3))); |
3637 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 3670 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); |
3638 __ j(less, &next_loop); | 3671 __ j(less, &next_loop); |
3639 | 3672 |
3640 // We exhausted our array of map handler pairs. | 3673 // We exhausted our array of map handler pairs. |
3641 __ bind(&pop_and_miss); | 3674 __ bind(&pop_and_miss); |
3642 __ pop(key); | 3675 __ pop(key); |
3643 __ pop(vector); | 3676 __ pop(vector); |
3644 __ pop(receiver); | 3677 __ pop(receiver); |
3645 __ jmp(miss); | 3678 __ jmp(miss); |
3646 | 3679 |
3647 __ bind(&load_smi_map); | 3680 __ bind(&load_smi_map); |
3648 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | 3681 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
3649 __ jmp(&compare_map); | 3682 __ jmp(&compare_map); |
3650 } | 3683 } |
3651 | 3684 |
3652 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 3685 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
3653 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx | 3686 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx |
3654 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx | 3687 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx |
3655 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax | 3688 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax |
3656 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx | 3689 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx |
3657 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi | 3690 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi |
3658 Label miss; | 3691 Label miss; |
3659 | 3692 |
| 3693 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { |
| 3694 // Current stack layout: |
| 3695 // - esp[8] -- value |
| 3696 // - esp[4] -- slot |
| 3697 // - esp[0] -- return address |
| 3698 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); |
| 3699 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
| 3700 if (in_frame) { |
| 3701 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); |
| 3702 // If the vector is not on the stack, then insert the vector beneath |
| 3703 // return address in order to prepare for calling handler with |
| 3704 // StoreWithVector calling convention. |
| 3705 __ push(Operand(esp, 0)); |
| 3706 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); |
| 3707 __ RecordComment("]"); |
| 3708 } else { |
| 3709 __ mov(vector, Operand(esp, 1 * kPointerSize)); |
| 3710 } |
| 3711 __ mov(slot, Operand(esp, 2 * kPointerSize)); |
| 3712 __ mov(value, Operand(esp, 3 * kPointerSize)); |
| 3713 } |
| 3714 |
3660 __ push(value); | 3715 __ push(value); |
3661 | 3716 |
3662 Register scratch = value; | 3717 Register scratch = value; |
3663 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 3718 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
3664 FixedArray::kHeaderSize)); | 3719 FixedArray::kHeaderSize)); |
3665 | 3720 |
3666 // Is it a weak cell? | 3721 // Is it a weak cell? |
3667 Label try_array; | 3722 Label try_array; |
3668 Label not_array, smi_key, key_okay; | 3723 Label not_array, smi_key, key_okay; |
3669 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 3724 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
(...skipping 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5248 kStackUnwindSpace, nullptr, return_value_operand, | 5303 kStackUnwindSpace, nullptr, return_value_operand, |
5249 NULL); | 5304 NULL); |
5250 } | 5305 } |
5251 | 5306 |
5252 #undef __ | 5307 #undef __ |
5253 | 5308 |
5254 } // namespace internal | 5309 } // namespace internal |
5255 } // namespace v8 | 5310 } // namespace v8 |
5256 | 5311 |
5257 #endif // V8_TARGET_ARCH_X87 | 5312 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |