Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 2357323003: [ic][ia32][x87] Don't push/pop value/slot/vector in store handlers. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/external-reference-table.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_IA32 5 #if V8_TARGET_ARCH_IA32
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 3524 matching lines...) Expand 10 before | Expand all | Expand 10 after
3535 // value is on the stack already. 3535 // value is on the stack already.
3536 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, 3536 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
3537 Register key, Register vector, 3537 Register key, Register vector,
3538 Register slot, Register feedback, 3538 Register slot, Register feedback,
3539 bool is_polymorphic, Label* miss) { 3539 bool is_polymorphic, Label* miss) {
3540 // feedback initially contains the feedback array 3540 // feedback initially contains the feedback array
3541 Label next, next_loop, prepare_next; 3541 Label next, next_loop, prepare_next;
3542 Label load_smi_map, compare_map; 3542 Label load_smi_map, compare_map;
3543 Label start_polymorphic; 3543 Label start_polymorphic;
3544 Label pop_and_miss; 3544 Label pop_and_miss;
3545 ExternalReference virtual_register =
3546 ExternalReference::virtual_handler_register(masm->isolate());
3547 3545
3548 __ push(receiver); 3546 __ push(receiver);
3549 __ push(vector); 3547 // Value, vector and slot are passed on the stack, so no need to save/restore
3548 // them.
3550 3549
3551 Register receiver_map = receiver; 3550 Register receiver_map = receiver;
3552 Register cached_map = vector; 3551 Register cached_map = vector;
3553 3552
3554 // Receiver might not be a heap object. 3553 // Receiver might not be a heap object.
3555 __ JumpIfSmi(receiver, &load_smi_map); 3554 __ JumpIfSmi(receiver, &load_smi_map);
3556 __ mov(receiver_map, FieldOperand(receiver, 0)); 3555 __ mov(receiver_map, FieldOperand(receiver, 0));
3557 __ bind(&compare_map); 3556 __ bind(&compare_map);
3558 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0))); 3557 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
3559 3558
3560 // A named keyed store might have a 2 element array, all other cases can count 3559 // A named keyed store might have a 2 element array, all other cases can count
3561 // on an array with at least 2 {map, handler} pairs, so they can go right 3560 // on an array with at least 2 {map, handler} pairs, so they can go right
3562 // into polymorphic array handling. 3561 // into polymorphic array handling.
3563 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3562 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3564 __ j(not_equal, &start_polymorphic); 3563 __ j(not_equal, &start_polymorphic);
3565 3564
3566 // found, now call handler. 3565 // found, now call handler.
3567 Register handler = feedback; 3566 Register handler = feedback;
3568 DCHECK(handler.is(StoreWithVectorDescriptor::ValueRegister())); 3567 DCHECK(handler.is(StoreWithVectorDescriptor::ValueRegister()));
3569 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); 3568 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
3570 __ pop(vector);
3571 __ pop(receiver); 3569 __ pop(receiver);
3572 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); 3570 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
3573 __ mov(Operand::StaticVariable(virtual_register), handler); 3571 __ jmp(handler);
3574 __ pop(handler); // Pop "value".
3575 __ jmp(Operand::StaticVariable(virtual_register));
3576 3572
3577 // Polymorphic, we have to loop from 2 to N 3573 // Polymorphic, we have to loop from 2 to N
3578 __ bind(&start_polymorphic); 3574 __ bind(&start_polymorphic);
3579 __ push(key); 3575 __ push(key);
3580 Register counter = key; 3576 Register counter = key;
3581 __ mov(counter, Immediate(Smi::FromInt(2))); 3577 __ mov(counter, Immediate(Smi::FromInt(2)));
3582 3578
3583 if (!is_polymorphic) { 3579 if (!is_polymorphic) {
3584 // If is_polymorphic is false, we may only have a two element array. 3580 // If is_polymorphic is false, we may only have a two element array.
3585 // Check against length now in that case. 3581 // Check against length now in that case.
3586 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 3582 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
3587 __ j(greater_equal, &pop_and_miss); 3583 __ j(greater_equal, &pop_and_miss);
3588 } 3584 }
3589 3585
3590 __ bind(&next_loop); 3586 __ bind(&next_loop);
3591 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 3587 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
3592 FixedArray::kHeaderSize)); 3588 FixedArray::kHeaderSize));
3593 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3589 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3594 __ j(not_equal, &prepare_next); 3590 __ j(not_equal, &prepare_next);
3595 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, 3591 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size,
3596 FixedArray::kHeaderSize + kPointerSize)); 3592 FixedArray::kHeaderSize + kPointerSize));
3597 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); 3593 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
3598 __ pop(key); 3594 __ pop(key);
3599 __ pop(vector);
3600 __ pop(receiver); 3595 __ pop(receiver);
3601 __ mov(Operand::StaticVariable(virtual_register), handler); 3596 __ jmp(handler);
3602 __ pop(handler); // Pop "value".
3603 __ jmp(Operand::StaticVariable(virtual_register));
3604 3597
3605 __ bind(&prepare_next); 3598 __ bind(&prepare_next);
3606 __ add(counter, Immediate(Smi::FromInt(2))); 3599 __ add(counter, Immediate(Smi::FromInt(2)));
3607 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 3600 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
3608 __ j(less, &next_loop); 3601 __ j(less, &next_loop);
3609 3602
3610 // We exhausted our array of map handler pairs. 3603 // We exhausted our array of map handler pairs.
3611 __ bind(&pop_and_miss); 3604 __ bind(&pop_and_miss);
3612 __ pop(key); 3605 __ pop(key);
3613 __ pop(vector);
3614 __ pop(receiver); 3606 __ pop(receiver);
3615 __ jmp(miss); 3607 __ jmp(miss);
3616 3608
3617 __ bind(&load_smi_map); 3609 __ bind(&load_smi_map);
3618 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); 3610 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
3619 __ jmp(&compare_map); 3611 __ jmp(&compare_map);
3620 } 3612 }
3621 3613
3622 3614
3623 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, 3615 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
3624 Register key, Register vector, 3616 Register key, Register vector,
3625 Register slot, Register weak_cell, 3617 Register slot, Register weak_cell,
3626 Label* miss) { 3618 Label* miss) {
3627 // The store ic value is on the stack. 3619 // The store ic value is on the stack.
3628 DCHECK(weak_cell.is(StoreWithVectorDescriptor::ValueRegister())); 3620 DCHECK(weak_cell.is(StoreWithVectorDescriptor::ValueRegister()));
3629 ExternalReference virtual_register =
3630 ExternalReference::virtual_handler_register(masm->isolate());
3631 3621
3632 // feedback initially contains the feedback array 3622 // feedback initially contains the feedback array
3633 Label compare_smi_map; 3623 Label compare_smi_map;
3634 3624
3635 // Move the weak map into the weak_cell register. 3625 // Move the weak map into the weak_cell register.
3636 Register ic_map = weak_cell; 3626 Register ic_map = weak_cell;
3637 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); 3627 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset));
3638 3628
3639 // Receiver might not be a heap object. 3629 // Receiver might not be a heap object.
3640 __ JumpIfSmi(receiver, &compare_smi_map); 3630 __ JumpIfSmi(receiver, &compare_smi_map);
3641 __ cmp(ic_map, FieldOperand(receiver, 0)); 3631 __ cmp(ic_map, FieldOperand(receiver, 0));
3642 __ j(not_equal, miss); 3632 __ j(not_equal, miss);
3643 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, 3633 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
3644 FixedArray::kHeaderSize + kPointerSize)); 3634 FixedArray::kHeaderSize + kPointerSize));
3645 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); 3635 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
3646 // Put the store ic value back in it's register.
3647 __ mov(Operand::StaticVariable(virtual_register), weak_cell);
3648 __ pop(weak_cell); // Pop "value".
3649 // jump to the handler. 3636 // jump to the handler.
3650 __ jmp(Operand::StaticVariable(virtual_register)); 3637 __ jmp(weak_cell);
3651 3638
3652 // In microbenchmarks, it made sense to unroll this code so that the call to 3639 // In microbenchmarks, it made sense to unroll this code so that the call to
3653 // the handler is duplicated for a HeapObject receiver and a Smi receiver. 3640 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
3654 __ bind(&compare_smi_map); 3641 __ bind(&compare_smi_map);
3655 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); 3642 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex);
3656 __ j(not_equal, miss); 3643 __ j(not_equal, miss);
3657 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, 3644 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
3658 FixedArray::kHeaderSize + kPointerSize)); 3645 FixedArray::kHeaderSize + kPointerSize));
3659 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); 3646 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
3660 __ mov(Operand::StaticVariable(virtual_register), weak_cell);
3661 __ pop(weak_cell); // Pop "value".
3662 // jump to the handler. 3647 // jump to the handler.
3663 __ jmp(Operand::StaticVariable(virtual_register)); 3648 __ jmp(weak_cell);
3664 } 3649 }
3665 3650
3666 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 3651 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
3667 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx 3652 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx
3668 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx 3653 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx
3669 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax 3654 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax
3670 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx 3655 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx
3671 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi 3656 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi
3672 Label miss; 3657 Label miss;
3673 3658
3674 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { 3659 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) {
3675 // Current stack layout: 3660 // Current stack layout:
3676 // - esp[8] -- value 3661 // - esp[8] -- value
3677 // - esp[4] -- slot 3662 // - esp[4] -- slot
3678 // - esp[0] -- return address 3663 // - esp[0] -- return address
3679 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); 3664 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2);
3680 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); 3665 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
3681 if (in_frame) { 3666 if (in_frame) {
3682 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); 3667 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor");
3683 // If the vector is not on the stack, then insert the vector beneath 3668 // If the vector is not on the stack, then insert the vector beneath
3684 // return address in order to prepare for calling handler with 3669 // return address in order to prepare for calling handler with
3685 // StoreWithVector calling convention. 3670 // StoreWithVector calling convention.
3686 __ push(Operand(esp, 0)); 3671 __ push(Operand(esp, 0));
3687 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); 3672 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
3688 __ RecordComment("]"); 3673 __ RecordComment("]");
3689 } else { 3674 } else {
3690 __ mov(vector, Operand(esp, 1 * kPointerSize)); 3675 __ mov(vector, Operand(esp, 1 * kPointerSize));
3691 } 3676 }
3692 __ mov(slot, Operand(esp, 2 * kPointerSize)); 3677 __ mov(slot, Operand(esp, 2 * kPointerSize));
3693 __ mov(value, Operand(esp, 3 * kPointerSize));
3694 } 3678 }
3695 3679
3696 __ push(value);
3697
3698 Register scratch = value; 3680 Register scratch = value;
3699 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 3681 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
3700 FixedArray::kHeaderSize)); 3682 FixedArray::kHeaderSize));
3701 3683
3702 // Is it a weak cell? 3684 // Is it a weak cell?
3703 Label try_array; 3685 Label try_array;
3704 Label not_array, smi_key, key_okay; 3686 Label not_array, smi_key, key_okay;
3705 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); 3687 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
3706 __ j(not_equal, &try_array); 3688 __ j(not_equal, &try_array);
3707 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); 3689 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
3708 3690
3709 // Is it a fixed array? 3691 // Is it a fixed array?
3710 __ bind(&try_array); 3692 __ bind(&try_array);
3711 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); 3693 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
3712 __ j(not_equal, &not_array); 3694 __ j(not_equal, &not_array);
3713 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, true, 3695 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, true,
3714 &miss); 3696 &miss);
3715 3697
3716 __ bind(&not_array); 3698 __ bind(&not_array);
3717 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); 3699 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
3718 __ j(not_equal, &miss); 3700 __ j(not_equal, &miss);
3719 3701
3720 __ pop(value);
3721 __ push(slot);
3722 __ push(vector);
3723 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, slot, 3702 masm->isolate()->store_stub_cache()->GenerateProbe(masm, receiver, key, slot,
3724 no_reg); 3703 no_reg);
3725 __ pop(vector);
3726 __ pop(slot);
3727 Label no_pop_miss;
3728 __ jmp(&no_pop_miss);
3729
3730 __ bind(&miss); 3704 __ bind(&miss);
3731 __ pop(value);
3732 __ bind(&no_pop_miss);
3733 StoreIC::GenerateMiss(masm); 3705 StoreIC::GenerateMiss(masm);
3734 } 3706 }
3735 3707
3736 void KeyedStoreICStub::Generate(MacroAssembler* masm) { 3708 void KeyedStoreICStub::Generate(MacroAssembler* masm) {
3737 GenerateImpl(masm, false); 3709 GenerateImpl(masm, false);
3738 } 3710 }
3739 3711
3740 void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { 3712 void KeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) {
3741 GenerateImpl(masm, true); 3713 GenerateImpl(masm, true);
3742 } 3714 }
3743 3715
3744 3716
3745 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, 3717 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
3746 Register receiver, Register key, 3718 Register receiver, Register key,
3747 Register vector, Register slot, 3719 Register vector, Register slot,
3748 Register feedback, Label* miss) { 3720 Register feedback, Label* miss) {
3749 // feedback initially contains the feedback array 3721 // feedback initially contains the feedback array
3750 Label next, next_loop, prepare_next; 3722 Label next, next_loop, prepare_next;
3751 Label load_smi_map, compare_map; 3723 Label load_smi_map, compare_map;
3752 Label transition_call; 3724 Label transition_call;
3753 Label pop_and_miss; 3725 Label pop_and_miss;
3754 ExternalReference virtual_register =
3755 ExternalReference::virtual_handler_register(masm->isolate());
3756 ExternalReference virtual_slot =
3757 ExternalReference::virtual_slot_register(masm->isolate());
3758 3726
3759 __ push(receiver); 3727 __ push(receiver);
3760 __ push(vector); 3728 // Value, vector and slot are passed on the stack, so no need to save/restore
3729 // them.
3761 3730
3762 Register receiver_map = receiver; 3731 Register receiver_map = receiver;
3763 Register cached_map = vector; 3732 Register cached_map = vector;
3764 Register value = StoreDescriptor::ValueRegister();
3765 3733
3766 // Receiver might not be a heap object. 3734 // Receiver might not be a heap object.
3767 __ JumpIfSmi(receiver, &load_smi_map); 3735 __ JumpIfSmi(receiver, &load_smi_map);
3768 __ mov(receiver_map, FieldOperand(receiver, 0)); 3736 __ mov(receiver_map, FieldOperand(receiver, 0));
3769 __ bind(&compare_map); 3737 __ bind(&compare_map);
3770 3738
3771 // Polymorphic, we have to loop from 0 to N - 1 3739 // Polymorphic, we have to loop from 0 to N - 1
3772 __ push(key); 3740 __ push(key);
3773 // Current stack layout: 3741 // Current stack layout:
3774 // - esp[0] -- key 3742 // - esp[0] -- key
3743 // - esp[4] -- receiver
3744 // - esp[8] -- return address
3745 // - esp[12] -- vector
3746 // - esp[16] -- slot
3747 // - esp[20] -- value
3748 //
3749 // Required stack layout for handler call (see StoreWithVectorDescriptor):
3750 // - esp[0] -- return address
3775 // - esp[4] -- vector 3751 // - esp[4] -- vector
3776 // - esp[8] -- receiver 3752 // - esp[8] -- slot
3777 // - esp[12] -- value 3753 // - esp[12] -- value
3778 // - esp[16] -- return address 3754 // - receiver, key, handler in registers.
3779 //
3780 // Required stack layout for handler call:
3781 // - esp[0] -- return address
3782 // - receiver, key, value, vector, slot in registers.
3783 // - handler in virtual register.
3784 Register counter = key; 3755 Register counter = key;
3785 __ mov(counter, Immediate(Smi::FromInt(0))); 3756 __ mov(counter, Immediate(Smi::FromInt(0)));
3786 __ bind(&next_loop); 3757 __ bind(&next_loop);
3787 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 3758 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
3788 FixedArray::kHeaderSize)); 3759 FixedArray::kHeaderSize));
3789 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3760 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3790 __ j(not_equal, &prepare_next); 3761 __ j(not_equal, &prepare_next);
3791 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 3762 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
3792 FixedArray::kHeaderSize + kPointerSize)); 3763 FixedArray::kHeaderSize + kPointerSize));
3793 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); 3764 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex);
3794 __ j(not_equal, &transition_call); 3765 __ j(not_equal, &transition_call);
3795 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, 3766 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
3796 FixedArray::kHeaderSize + 2 * kPointerSize)); 3767 FixedArray::kHeaderSize + 2 * kPointerSize));
3797 __ pop(key); 3768 __ pop(key);
3798 __ pop(vector);
3799 __ pop(receiver); 3769 __ pop(receiver);
3800 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); 3770 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
3801 __ mov(Operand::StaticVariable(virtual_register), feedback); 3771 __ jmp(feedback);
3802 __ pop(value);
3803
3804 // Call store handler using StoreWithVectorDescriptor calling convention.
3805 __ jmp(Operand::StaticVariable(virtual_register));
3806 3772
3807 __ bind(&transition_call); 3773 __ bind(&transition_call);
3808 // Current stack layout: 3774 // Current stack layout:
3809 // - esp[0] -- key 3775 // - esp[0] -- key
3776 // - esp[4] -- receiver
3777 // - esp[8] -- return address
3778 // - esp[12] -- vector
3779 // - esp[16] -- slot
3780 // - esp[20] -- value
3781 //
3782 // Required stack layout for handler call (see StoreTransitionDescriptor):
3783 // - esp[0] -- return address
3810 // - esp[4] -- vector 3784 // - esp[4] -- vector
3811 // - esp[8] -- receiver 3785 // - esp[8] -- slot
3812 // - esp[12] -- value 3786 // - esp[12] -- value
3813 // - esp[16] -- return address 3787 // - receiver, key, map, handler in registers.
3814 //
3815 // Required stack layout for handler call:
3816 // - esp[0] -- return address
3817 // - receiver, key, value, map, vector in registers.
3818 // - handler and slot in virtual registers.
3819 __ mov(Operand::StaticVariable(virtual_slot), slot);
3820 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, 3788 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
3821 FixedArray::kHeaderSize + 2 * kPointerSize)); 3789 FixedArray::kHeaderSize + 2 * kPointerSize));
3822 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); 3790 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
3823 __ mov(Operand::StaticVariable(virtual_register), feedback);
3824 3791
3825 __ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 3792 __ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset));
3826 // The weak cell may have been cleared. 3793 // The weak cell may have been cleared.
3827 __ JumpIfSmi(cached_map, &pop_and_miss); 3794 __ JumpIfSmi(cached_map, &pop_and_miss);
3828 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister())); 3795 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister()));
3829 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map); 3796 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map);
3830 3797
3831 // Call store transition handler using StoreTransitionDescriptor calling 3798 // Call store transition handler using StoreTransitionDescriptor calling
3832 // convention. 3799 // convention.
3833 __ pop(key); 3800 __ pop(key);
3834 __ pop(vector);
3835 __ pop(receiver); 3801 __ pop(receiver);
3836 __ pop(value);
3837 // Ensure that the transition handler we are going to call has the same 3802 // Ensure that the transition handler we are going to call has the same
3838 // number of stack arguments which means that we don't have to adapt them 3803 // number of stack arguments which means that we don't have to adapt them
3839 // before the call. 3804 // before the call.
3840 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); 3805 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3);
3841 STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3); 3806 STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3);
3842 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - 3807 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
3843 StoreWithVectorDescriptor::kValue == 3808 StoreWithVectorDescriptor::kValue ==
3844 StoreTransitionDescriptor::kParameterCount - 3809 StoreTransitionDescriptor::kParameterCount -
3845 StoreTransitionDescriptor::kValue); 3810 StoreTransitionDescriptor::kValue);
3846 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - 3811 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
3847 StoreWithVectorDescriptor::kSlot == 3812 StoreWithVectorDescriptor::kSlot ==
3848 StoreTransitionDescriptor::kParameterCount - 3813 StoreTransitionDescriptor::kParameterCount -
3849 StoreTransitionDescriptor::kSlot); 3814 StoreTransitionDescriptor::kSlot);
3850 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - 3815 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount -
3851 StoreWithVectorDescriptor::kVector == 3816 StoreWithVectorDescriptor::kVector ==
3852 StoreTransitionDescriptor::kParameterCount - 3817 StoreTransitionDescriptor::kParameterCount -
3853 StoreTransitionDescriptor::kVector); 3818 StoreTransitionDescriptor::kVector);
3854 __ jmp(Operand::StaticVariable(virtual_register)); 3819 __ jmp(feedback);
3855 3820
3856 __ bind(&prepare_next); 3821 __ bind(&prepare_next);
3857 __ add(counter, Immediate(Smi::FromInt(3))); 3822 __ add(counter, Immediate(Smi::FromInt(3)));
3858 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 3823 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
3859 __ j(less, &next_loop); 3824 __ j(less, &next_loop);
3860 3825
3861 // We exhausted our array of map handler pairs. 3826 // We exhausted our array of map handler pairs.
3862 __ bind(&pop_and_miss); 3827 __ bind(&pop_and_miss);
3863 __ pop(key); 3828 __ pop(key);
3864 __ pop(vector);
3865 __ pop(receiver); 3829 __ pop(receiver);
3866 __ jmp(miss); 3830 __ jmp(miss);
3867 3831
3868 __ bind(&load_smi_map); 3832 __ bind(&load_smi_map);
3869 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); 3833 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
3870 __ jmp(&compare_map); 3834 __ jmp(&compare_map);
3871 } 3835 }
3872 3836
3873 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 3837 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
3874 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx 3838 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx
(...skipping 15 matching lines...) Expand all
3890 // If the vector is not on the stack, then insert the vector beneath 3854 // If the vector is not on the stack, then insert the vector beneath
3891 // return address in order to prepare for calling handler with 3855 // return address in order to prepare for calling handler with
3892 // StoreWithVector calling convention. 3856 // StoreWithVector calling convention.
3893 __ push(Operand(esp, 0)); 3857 __ push(Operand(esp, 0));
3894 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); 3858 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister());
3895 __ RecordComment("]"); 3859 __ RecordComment("]");
3896 } else { 3860 } else {
3897 __ mov(vector, Operand(esp, 1 * kPointerSize)); 3861 __ mov(vector, Operand(esp, 1 * kPointerSize));
3898 } 3862 }
3899 __ mov(slot, Operand(esp, 2 * kPointerSize)); 3863 __ mov(slot, Operand(esp, 2 * kPointerSize));
3900 __ mov(value, Operand(esp, 3 * kPointerSize));
3901 } 3864 }
3902 3865
3903 __ push(value);
3904
3905 Register scratch = value; 3866 Register scratch = value;
3906 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 3867 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
3907 FixedArray::kHeaderSize)); 3868 FixedArray::kHeaderSize));
3908 3869
3909 // Is it a weak cell? 3870 // Is it a weak cell?
3910 Label try_array; 3871 Label try_array;
3911 Label not_array, smi_key, key_okay; 3872 Label not_array, smi_key, key_okay;
3912 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); 3873 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
3913 __ j(not_equal, &try_array); 3874 __ j(not_equal, &try_array);
3914 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss); 3875 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
3915 3876
3916 // Is it a fixed array? 3877 // Is it a fixed array?
3917 __ bind(&try_array); 3878 __ bind(&try_array);
3918 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex); 3879 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
3919 __ j(not_equal, &not_array); 3880 __ j(not_equal, &not_array);
3920 HandlePolymorphicKeyedStoreCase(masm, receiver, key, vector, slot, scratch, 3881 HandlePolymorphicKeyedStoreCase(masm, receiver, key, vector, slot, scratch,
3921 &miss); 3882 &miss);
3922 3883
3923 __ bind(&not_array); 3884 __ bind(&not_array);
3924 Label try_poly_name; 3885 Label try_poly_name;
3925 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex); 3886 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
3926 __ j(not_equal, &try_poly_name); 3887 __ j(not_equal, &try_poly_name);
3927 3888
3928 __ pop(value);
3929
3930 Handle<Code> megamorphic_stub = 3889 Handle<Code> megamorphic_stub =
3931 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState()); 3890 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
3932 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET); 3891 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
3933 3892
3934 __ bind(&try_poly_name); 3893 __ bind(&try_poly_name);
3935 // We might have a name in feedback, and a fixed array in the next slot. 3894 // We might have a name in feedback, and a fixed array in the next slot.
3936 __ cmp(key, scratch); 3895 __ cmp(key, scratch);
3937 __ j(not_equal, &miss); 3896 __ j(not_equal, &miss);
3938 // If the name comparison succeeded, we know we have a fixed array with 3897 // If the name comparison succeeded, we know we have a fixed array with
3939 // at least one map/handler pair. 3898 // at least one map/handler pair.
3940 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, 3899 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
3941 FixedArray::kHeaderSize + kPointerSize)); 3900 FixedArray::kHeaderSize + kPointerSize));
3942 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false, 3901 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, false,
3943 &miss); 3902 &miss);
3944 3903
3945 __ bind(&miss); 3904 __ bind(&miss);
3946 __ pop(value);
3947 KeyedStoreIC::GenerateMiss(masm); 3905 KeyedStoreIC::GenerateMiss(masm);
3948 } 3906 }
3949 3907
3950 3908
3951 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 3909 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
3952 __ EmitLoadTypeFeedbackVector(ebx); 3910 __ EmitLoadTypeFeedbackVector(ebx);
3953 CallICStub stub(isolate(), state()); 3911 CallICStub stub(isolate(), state());
3954 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 3912 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
3955 } 3913 }
3956 3914
(...skipping 1555 matching lines...) Expand 10 before | Expand all | Expand 10 after
5512 kStackUnwindSpace, nullptr, return_value_operand, 5470 kStackUnwindSpace, nullptr, return_value_operand,
5513 NULL); 5471 NULL);
5514 } 5472 }
5515 5473
5516 #undef __ 5474 #undef __
5517 5475
5518 } // namespace internal 5476 } // namespace internal
5519 } // namespace v8 5477 } // namespace v8
5520 5478
5521 #endif // V8_TARGET_ARCH_IA32 5479 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/external-reference-table.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698