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

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

Issue 1340123002: Revert of VectorICs: ia32 store ics need a virtual register. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 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/flag-definitions.h ('k') | src/ic/ia32/stub-cache-ia32.cc » ('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/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 4549 matching lines...) Expand 10 before | Expand all | Expand 10 after
4560 4560
4561 // value is on the stack already. 4561 // value is on the stack already.
4562 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver, 4562 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
4563 Register key, Register vector, 4563 Register key, Register vector,
4564 Register slot, Register feedback, 4564 Register slot, Register feedback,
4565 Label* miss) { 4565 Label* miss) {
4566 // feedback initially contains the feedback array 4566 // feedback initially contains the feedback array
4567 Label next, next_loop, prepare_next; 4567 Label next, next_loop, prepare_next;
4568 Label load_smi_map, compare_map; 4568 Label load_smi_map, compare_map;
4569 Label start_polymorphic; 4569 Label start_polymorphic;
4570 ExternalReference virtual_register =
4571 ExternalReference::vector_store_virtual_register(masm->isolate());
4572 4570
4573 __ push(receiver); 4571 __ push(receiver);
4574 __ push(vector); 4572 __ push(vector);
4575 4573
4576 Register receiver_map = receiver; 4574 Register receiver_map = receiver;
4577 Register cached_map = vector; 4575 Register cached_map = vector;
4578 4576
4579 // Receiver might not be a heap object. 4577 // Receiver might not be a heap object.
4580 __ JumpIfSmi(receiver, &load_smi_map); 4578 __ JumpIfSmi(receiver, &load_smi_map);
4581 __ mov(receiver_map, FieldOperand(receiver, 0)); 4579 __ mov(receiver_map, FieldOperand(receiver, 0));
4582 __ bind(&compare_map); 4580 __ bind(&compare_map);
4583 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0))); 4581 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4584 4582
4585 // A named keyed store might have a 2 element array, all other cases can count 4583 // A named keyed store might have a 2 element array, all other cases can count
4586 // on an array with at least 2 {map, handler} pairs, so they can go right 4584 // on an array with at least 2 {map, handler} pairs, so they can go right
4587 // into polymorphic array handling. 4585 // into polymorphic array handling.
4588 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 4586 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4589 __ j(not_equal, &start_polymorphic); 4587 __ j(not_equal, &start_polymorphic);
4590 4588
4591 // found, now call handler. 4589 // found, now call handler.
4592 Register handler = feedback; 4590 Register handler = feedback;
4593 DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister())); 4591 DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister()));
4594 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1))); 4592 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4595 __ pop(vector); 4593 __ pop(vector);
4596 __ pop(receiver); 4594 __ pop(receiver);
4597 __ lea(handler, FieldOperand(handler, Code::kHeaderSize)); 4595 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4598 __ mov(Operand::StaticVariable(virtual_register), handler); 4596 __ xchg(handler, Operand(esp, 0));
4599 __ pop(handler); // Pop "value". 4597 __ ret(0);
4600 __ jmp(Operand::StaticVariable(virtual_register));
4601 4598
4602 // Polymorphic, we have to loop from 2 to N 4599 // Polymorphic, we have to loop from 2 to N
4603 4600
4604 // TODO(mvstanton): I think there is a bug here, we are assuming the 4601 // TODO(mvstanton): I think there is a bug here, we are assuming the
4605 // array has more than one map/handler pair, but we call this function in the 4602 // array has more than one map/handler pair, but we call this function in the
4606 // keyed store with a string key case, where it might be just an array of two 4603 // keyed store with a string key case, where it might be just an array of two
4607 // elements. 4604 // elements.
4608 4605
4609 __ bind(&start_polymorphic); 4606 __ bind(&start_polymorphic);
4610 __ push(key); 4607 __ push(key);
4611 Register counter = key; 4608 Register counter = key;
4612 __ mov(counter, Immediate(Smi::FromInt(2))); 4609 __ mov(counter, Immediate(Smi::FromInt(2)));
4613 __ bind(&next_loop); 4610 __ bind(&next_loop);
4614 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 4611 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4615 FixedArray::kHeaderSize)); 4612 FixedArray::kHeaderSize));
4616 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset)); 4613 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4617 __ j(not_equal, &prepare_next); 4614 __ j(not_equal, &prepare_next);
4618 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size, 4615 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size,
4619 FixedArray::kHeaderSize + kPointerSize)); 4616 FixedArray::kHeaderSize + kPointerSize));
4620 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4621 __ pop(key); 4617 __ pop(key);
4622 __ pop(vector); 4618 __ pop(vector);
4623 __ pop(receiver); 4619 __ pop(receiver);
4624 __ mov(Operand::StaticVariable(virtual_register), handler); 4620 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4625 __ pop(handler); // Pop "value". 4621 __ xchg(handler, Operand(esp, 0));
4626 __ jmp(Operand::StaticVariable(virtual_register)); 4622 __ ret(0);
4627 4623
4628 __ bind(&prepare_next); 4624 __ bind(&prepare_next);
4629 __ add(counter, Immediate(Smi::FromInt(2))); 4625 __ add(counter, Immediate(Smi::FromInt(2)));
4630 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); 4626 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
4631 __ j(less, &next_loop); 4627 __ j(less, &next_loop);
4632 4628
4633 // We exhausted our array of map handler pairs. 4629 // We exhausted our array of map handler pairs.
4634 __ pop(key); 4630 __ pop(key);
4635 __ pop(vector); 4631 __ pop(vector);
4636 __ pop(receiver); 4632 __ pop(receiver);
4637 __ jmp(miss); 4633 __ jmp(miss);
4638 4634
4639 __ bind(&load_smi_map); 4635 __ bind(&load_smi_map);
4640 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); 4636 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4641 __ jmp(&compare_map); 4637 __ jmp(&compare_map);
4642 } 4638 }
4643 4639
4644 4640
4645 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver, 4641 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
4646 Register key, Register vector, 4642 Register key, Register vector,
4647 Register slot, Register weak_cell, 4643 Register slot, Register weak_cell,
4648 Label* miss) { 4644 Label* miss) {
4649 // The store ic value is on the stack. 4645 // The store ic value is on the stack.
4650 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister())); 4646 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister()));
4651 ExternalReference virtual_register =
4652 ExternalReference::vector_store_virtual_register(masm->isolate());
4653 4647
4654 // feedback initially contains the feedback array 4648 // feedback initially contains the feedback array
4655 Label compare_smi_map; 4649 Label compare_smi_map;
4656 4650
4657 // Move the weak map into the weak_cell register. 4651 // Move the weak map into the weak_cell register.
4658 Register ic_map = weak_cell; 4652 Register ic_map = weak_cell;
4659 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset)); 4653 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset));
4660 4654
4661 // Receiver might not be a heap object. 4655 // Receiver might not be a heap object.
4662 __ JumpIfSmi(receiver, &compare_smi_map); 4656 __ JumpIfSmi(receiver, &compare_smi_map);
4663 __ cmp(ic_map, FieldOperand(receiver, 0)); 4657 __ cmp(ic_map, FieldOperand(receiver, 0));
4664 __ j(not_equal, miss); 4658 __ j(not_equal, miss);
4665 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, 4659 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4666 FixedArray::kHeaderSize + kPointerSize)); 4660 FixedArray::kHeaderSize + kPointerSize));
4667 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); 4661 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4668 // Put the store ic value back in it's register. 4662 // Put the store ic value back in it's register.
4669 __ mov(Operand::StaticVariable(virtual_register), weak_cell); 4663 __ xchg(weak_cell, Operand(esp, 0));
4670 __ pop(weak_cell); // Pop "value". 4664 // "return" to the handler.
4671 // jump to the handler. 4665 __ ret(0);
4672 __ jmp(Operand::StaticVariable(virtual_register));
4673 4666
4674 // In microbenchmarks, it made sense to unroll this code so that the call to 4667 // In microbenchmarks, it made sense to unroll this code so that the call to
4675 // the handler is duplicated for a HeapObject receiver and a Smi receiver. 4668 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4676 __ bind(&compare_smi_map); 4669 __ bind(&compare_smi_map);
4677 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex); 4670 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex);
4678 __ j(not_equal, miss); 4671 __ j(not_equal, miss);
4679 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size, 4672 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4680 FixedArray::kHeaderSize + kPointerSize)); 4673 FixedArray::kHeaderSize + kPointerSize));
4681 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize)); 4674 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4682 __ mov(Operand::StaticVariable(virtual_register), weak_cell); 4675 // Put the store ic value back in it's register.
4683 __ pop(weak_cell); // Pop "value". 4676 __ xchg(weak_cell, Operand(esp, 0));
4684 // jump to the handler. 4677 // "return" to the handler.
4685 __ jmp(Operand::StaticVariable(virtual_register)); 4678 __ ret(0);
4686 } 4679 }
4687 4680
4688 4681
4689 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4682 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4690 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx 4683 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx
4691 Register key = VectorStoreICDescriptor::NameRegister(); // ecx 4684 Register key = VectorStoreICDescriptor::NameRegister(); // ecx
4692 Register value = VectorStoreICDescriptor::ValueRegister(); // eax 4685 Register value = VectorStoreICDescriptor::ValueRegister(); // eax
4693 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx 4686 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx
4694 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi 4687 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi
4695 Label miss; 4688 Label miss;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4748 4741
4749 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm, 4742 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
4750 Register receiver, Register key, 4743 Register receiver, Register key,
4751 Register vector, Register slot, 4744 Register vector, Register slot,
4752 Register feedback, Label* miss) { 4745 Register feedback, Label* miss) {
4753 // feedback initially contains the feedback array 4746 // feedback initially contains the feedback array
4754 Label next, next_loop, prepare_next; 4747 Label next, next_loop, prepare_next;
4755 Label load_smi_map, compare_map; 4748 Label load_smi_map, compare_map;
4756 Label transition_call; 4749 Label transition_call;
4757 Label pop_and_miss; 4750 Label pop_and_miss;
4758 ExternalReference virtual_register =
4759 ExternalReference::vector_store_virtual_register(masm->isolate());
4760 4751
4761 __ push(receiver); 4752 __ push(receiver);
4762 __ push(vector); 4753 __ push(vector);
4763 4754
4764 Register receiver_map = receiver; 4755 Register receiver_map = receiver;
4765 Register cached_map = vector; 4756 Register cached_map = vector;
4766 4757
4767 // Receiver might not be a heap object. 4758 // Receiver might not be a heap object.
4768 __ JumpIfSmi(receiver, &load_smi_map); 4759 __ JumpIfSmi(receiver, &load_smi_map);
4769 __ mov(receiver_map, FieldOperand(receiver, 0)); 4760 __ mov(receiver_map, FieldOperand(receiver, 0));
(...skipping 16 matching lines...) Expand all
4786 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size, 4777 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4787 FixedArray::kHeaderSize + kPointerSize)); 4778 FixedArray::kHeaderSize + kPointerSize));
4788 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex); 4779 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex);
4789 __ j(not_equal, &transition_call); 4780 __ j(not_equal, &transition_call);
4790 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size, 4781 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
4791 FixedArray::kHeaderSize + 2 * kPointerSize)); 4782 FixedArray::kHeaderSize + 2 * kPointerSize));
4792 __ pop(key); 4783 __ pop(key);
4793 __ pop(vector); 4784 __ pop(vector);
4794 __ pop(receiver); 4785 __ pop(receiver);
4795 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize)); 4786 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4796 __ mov(Operand::StaticVariable(virtual_register), feedback); 4787 __ xchg(feedback, Operand(esp, 0));
4797 __ pop(feedback); // Pop "value". 4788 __ ret(0);
4798 __ jmp(Operand::StaticVariable(virtual_register));
4799 4789
4800 __ bind(&transition_call); 4790 __ bind(&transition_call);
4801 // Oh holy hell this will be tough. 4791 // Oh holy hell this will be tough.
4802 // The map goes in vector register. 4792 // The map goes in vector register.
4803 __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset)); 4793 __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset));
4804 // The weak cell may have been cleared. 4794 // The weak cell may have been cleared.
4805 __ JumpIfSmi(receiver, &pop_and_miss); 4795 __ JumpIfSmi(receiver, &pop_and_miss);
4806 // slot goes on the stack, and holds return address. 4796 // slot goes on the stack, and holds return address.
4807 __ xchg(slot, Operand(esp, 4 * kPointerSize)); 4797 __ xchg(slot, Operand(esp, 4 * kPointerSize));
4808 // Get the handler in value. 4798 // Get the handler in value.
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after
5816 Operand(ebp, 7 * kPointerSize), NULL); 5806 Operand(ebp, 7 * kPointerSize), NULL);
5817 } 5807 }
5818 5808
5819 5809
5820 #undef __ 5810 #undef __
5821 5811
5822 } // namespace internal 5812 } // namespace internal
5823 } // namespace v8 5813 } // namespace v8
5824 5814
5825 #endif // V8_TARGET_ARCH_IA32 5815 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/flag-definitions.h ('k') | src/ic/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698