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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 4561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4572 // value is on the stack already. | 4572 // value is on the stack already. |
4573 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, | 4573 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, |
4574 Register key, Register vector, | 4574 Register key, Register vector, |
4575 Register slot, Register feedback, | 4575 Register slot, Register feedback, |
4576 Label* miss) { | 4576 Label* miss) { |
4577 // feedback initially contains the feedback array | 4577 // feedback initially contains the feedback array |
4578 Label next, next_loop, prepare_next; | 4578 Label next, next_loop, prepare_next; |
4579 Label load_smi_map, compare_map; | 4579 Label load_smi_map, compare_map; |
4580 Label start_polymorphic; | 4580 Label start_polymorphic; |
4581 ExternalReference virtual_register = | 4581 ExternalReference virtual_register = |
4582 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4582 ExternalReference::virtual_handler_register(masm->isolate()); |
4583 | 4583 |
4584 __ push(receiver); | 4584 __ push(receiver); |
4585 __ push(vector); | 4585 __ push(vector); |
4586 | 4586 |
4587 Register receiver_map = receiver; | 4587 Register receiver_map = receiver; |
4588 Register cached_map = vector; | 4588 Register cached_map = vector; |
4589 | 4589 |
4590 // Receiver might not be a heap object. | 4590 // Receiver might not be a heap object. |
4591 __ JumpIfSmi(receiver, &load_smi_map); | 4591 __ JumpIfSmi(receiver, &load_smi_map); |
4592 __ mov(receiver_map, FieldOperand(receiver, 0)); | 4592 __ mov(receiver_map, FieldOperand(receiver, 0)); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4653 } | 4653 } |
4654 | 4654 |
4655 | 4655 |
4656 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, | 4656 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, |
4657 Register key, Register vector, | 4657 Register key, Register vector, |
4658 Register slot, Register weak_cell, | 4658 Register slot, Register weak_cell, |
4659 Label* miss) { | 4659 Label* miss) { |
4660 // The store ic value is on the stack. | 4660 // The store ic value is on the stack. |
4661 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); | 4661 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); |
4662 ExternalReference virtual_register = | 4662 ExternalReference virtual_register = |
4663 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4663 ExternalReference::virtual_handler_register(masm->isolate()); |
4664 | 4664 |
4665 // feedback initially contains the feedback array | 4665 // feedback initially contains the feedback array |
4666 Label compare_smi_map; | 4666 Label compare_smi_map; |
4667 | 4667 |
4668 // Move the weak map into the weak_cell register. | 4668 // Move the weak map into the weak_cell register. |
4669 Register ic_map = weak_cell; | 4669 Register ic_map = weak_cell; |
4670 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); | 4670 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); |
4671 | 4671 |
4672 // Receiver might not be a heap object. | 4672 // Receiver might not be a heap object. |
4673 __ JumpIfSmi(receiver, &compare_smi_map); | 4673 __ JumpIfSmi(receiver, &compare_smi_map); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4760 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, | 4760 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, |
4761 Register receiver, Register key, | 4761 Register receiver, Register key, |
4762 Register vector, Register slot, | 4762 Register vector, Register slot, |
4763 Register feedback, Label* miss) { | 4763 Register feedback, Label* miss) { |
4764 // feedback initially contains the feedback array | 4764 // feedback initially contains the feedback array |
4765 Label next, next_loop, prepare_next; | 4765 Label next, next_loop, prepare_next; |
4766 Label load_smi_map, compare_map; | 4766 Label load_smi_map, compare_map; |
4767 Label transition_call; | 4767 Label transition_call; |
4768 Label pop_and_miss; | 4768 Label pop_and_miss; |
4769 ExternalReference virtual_register = | 4769 ExternalReference virtual_register = |
4770 ExternalReference::vector_store_virtual_register(masm->isolate()); | 4770 ExternalReference::virtual_handler_register(masm->isolate()); |
| 4771 ExternalReference virtual_slot = |
| 4772 ExternalReference::virtual_slot_register(masm->isolate()); |
4771 | 4773 |
4772 __ push(receiver); | 4774 __ push(receiver); |
4773 __ push(vector); | 4775 __ push(vector); |
4774 | 4776 |
4775 Register receiver_map = receiver; | 4777 Register receiver_map = receiver; |
4776 Register cached_map = vector; | 4778 Register cached_map = vector; |
| 4779 Register value = StoreDescriptor::ValueRegister(); |
4777 | 4780 |
4778 // Receiver might not be a heap object. | 4781 // Receiver might not be a heap object. |
4779 __ JumpIfSmi(receiver, &load_smi_map); | 4782 __ JumpIfSmi(receiver, &load_smi_map); |
4780 __ mov(receiver_map, FieldOperand(receiver, 0)); | 4783 __ mov(receiver_map, FieldOperand(receiver, 0)); |
4781 __ bind(&compare_map); | 4784 __ bind(&compare_map); |
4782 | 4785 |
4783 // Polymorphic, we have to loop from 0 to N - 1 | 4786 // Polymorphic, we have to loop from 0 to N - 1 |
4784 __ push(key); | 4787 __ push(key); |
4785 // On the stack we have: | 4788 // Current stack layout: |
4786 // key (esp) | 4789 // - esp[0] -- key |
4787 // vector | 4790 // - esp[4] -- vector |
4788 // receiver | 4791 // - esp[8] -- receiver |
4789 // value | 4792 // - esp[12] -- value |
| 4793 // - esp[16] -- return address |
| 4794 // |
| 4795 // Required stack layout for handler call: |
| 4796 // - esp[0] -- return address |
| 4797 // - receiver, key, value, vector, slot in registers. |
| 4798 // - handler in virtual register. |
4790 Register counter = key; | 4799 Register counter = key; |
4791 __ mov(counter, Immediate(Smi::FromInt(0))); | 4800 __ mov(counter, Immediate(Smi::FromInt(0))); |
4792 __ bind(&next_loop); | 4801 __ bind(&next_loop); |
4793 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4802 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
4794 FixedArray::kHeaderSize)); | 4803 FixedArray::kHeaderSize)); |
4795 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4804 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
4796 __ j(not_equal, &prepare_next); | 4805 __ j(not_equal, &prepare_next); |
4797 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, | 4806 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, |
4798 FixedArray::kHeaderSize + kPointerSize)); | 4807 FixedArray::kHeaderSize + kPointerSize)); |
4799 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); | 4808 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); |
4800 __ j(not_equal, &transition_call); | 4809 __ j(not_equal, &transition_call); |
4801 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 4810 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, |
4802 FixedArray::kHeaderSize + 2 * kPointerSize)); | 4811 FixedArray::kHeaderSize + 2 * kPointerSize)); |
4803 __ pop(key); | 4812 __ pop(key); |
4804 __ pop(vector); | 4813 __ pop(vector); |
4805 __ pop(receiver); | 4814 __ pop(receiver); |
4806 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); | 4815 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
4807 __ mov(Operand::StaticVariable(virtual_register), feedback); | 4816 __ mov(Operand::StaticVariable(virtual_register), feedback); |
4808 __ pop(feedback); // Pop "value". | 4817 __ pop(value); |
4809 __ jmp(Operand::StaticVariable(virtual_register)); | 4818 __ jmp(Operand::StaticVariable(virtual_register)); |
4810 | 4819 |
4811 __ bind(&transition_call); | 4820 __ bind(&transition_call); |
4812 // Oh holy hell this will be tough. | 4821 // Current stack layout: |
4813 // The map goes in vector register. | 4822 // - esp[0] -- key |
4814 __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset)); | 4823 // - esp[4] -- vector |
4815 // The weak cell may have been cleared. | 4824 // - esp[8] -- receiver |
4816 __ JumpIfSmi(receiver, &pop_and_miss); | 4825 // - esp[12] -- value |
4817 // slot goes on the stack, and holds return address. | 4826 // - esp[16] -- return address |
4818 __ xchg(slot, Operand(esp, 4 * kPointerSize)); | 4827 // |
4819 // Get the handler in value. | 4828 // Required stack layout for handler call: |
| 4829 // - esp[0] -- return address |
| 4830 // - receiver, key, value, map, vector in registers. |
| 4831 // - handler and slot in virtual registers. |
| 4832 __ mov(Operand::StaticVariable(virtual_slot), slot); |
4820 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, | 4833 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, |
4821 FixedArray::kHeaderSize + 2 * kPointerSize)); | 4834 FixedArray::kHeaderSize + 2 * kPointerSize)); |
4822 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); | 4835 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); |
| 4836 __ mov(Operand::StaticVariable(virtual_register), feedback); |
| 4837 |
| 4838 __ mov(cached_map, FieldOperand(cached_map, WeakCell::kValueOffset)); |
| 4839 // The weak cell may have been cleared. |
| 4840 __ JumpIfSmi(cached_map, &pop_and_miss); |
| 4841 DCHECK(!cached_map.is(VectorStoreTransitionDescriptor::MapRegister())); |
| 4842 __ mov(VectorStoreTransitionDescriptor::MapRegister(), cached_map); |
| 4843 |
4823 // Pop key into place. | 4844 // Pop key into place. |
4824 __ pop(key); | 4845 __ pop(key); |
4825 // Put the return address on top of stack, vector goes in slot. | 4846 __ pop(vector); |
4826 __ xchg(slot, Operand(esp, 0)); | 4847 __ pop(receiver); |
4827 // put the map on the stack, receiver holds receiver. | 4848 __ pop(value); |
4828 __ xchg(receiver, Operand(esp, 1 * kPointerSize)); | 4849 __ jmp(Operand::StaticVariable(virtual_register)); |
4829 // put the vector on the stack, slot holds value. | |
4830 __ xchg(slot, Operand(esp, 2 * kPointerSize)); | |
4831 // feedback (value) = value, slot = handler. | |
4832 __ xchg(feedback, slot); | |
4833 __ jmp(slot); | |
4834 | 4850 |
4835 __ bind(&prepare_next); | 4851 __ bind(&prepare_next); |
4836 __ add(counter, Immediate(Smi::FromInt(3))); | 4852 __ add(counter, Immediate(Smi::FromInt(3))); |
4837 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 4853 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); |
4838 __ j(less, &next_loop); | 4854 __ j(less, &next_loop); |
4839 | 4855 |
4840 // We exhausted our array of map handler pairs. | 4856 // We exhausted our array of map handler pairs. |
4841 __ bind(&pop_and_miss); | 4857 __ bind(&pop_and_miss); |
4842 __ pop(key); | 4858 __ pop(key); |
4843 __ pop(vector); | 4859 __ pop(vector); |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5827 Operand(ebp, 7 * kPointerSize), NULL); | 5843 Operand(ebp, 7 * kPointerSize), NULL); |
5828 } | 5844 } |
5829 | 5845 |
5830 | 5846 |
5831 #undef __ | 5847 #undef __ |
5832 | 5848 |
5833 } // namespace internal | 5849 } // namespace internal |
5834 } // namespace v8 | 5850 } // namespace v8 |
5835 | 5851 |
5836 #endif // V8_TARGET_ARCH_IA32 | 5852 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |