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

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

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

Powered by Google App Engine
This is Rietveld 408576698