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

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

Issue 1319123004: Reland Vector ICs: platform support for vector-based stores. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix for arm[64] release build failure. 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/ast.cc ('k') | src/ic/access-compiler.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/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 4571 matching lines...) Expand 10 before | Expand all | Expand 10 after
4582 void VectorStoreICStub::Generate(MacroAssembler* masm) { 4582 void VectorStoreICStub::Generate(MacroAssembler* masm) {
4583 GenerateImpl(masm, false); 4583 GenerateImpl(masm, false);
4584 } 4584 }
4585 4585
4586 4586
4587 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { 4587 void VectorStoreICStub::GenerateForTrampoline(MacroAssembler* masm) {
4588 GenerateImpl(masm, true); 4588 GenerateImpl(masm, true);
4589 } 4589 }
4590 4590
4591 4591
4592 // value is on the stack already.
4593 static void HandlePolymorphicStoreCase(MacroAssembler* masm, Register receiver,
4594 Register key, Register vector,
4595 Register slot, Register feedback,
4596 Label* miss) {
4597 // feedback initially contains the feedback array
4598 Label next, next_loop, prepare_next;
4599 Label load_smi_map, compare_map;
4600 Label start_polymorphic;
4601
4602 __ push(receiver);
4603 __ push(vector);
4604
4605 Register receiver_map = receiver;
4606 Register cached_map = vector;
4607
4608 // Receiver might not be a heap object.
4609 __ JumpIfSmi(receiver, &load_smi_map);
4610 __ mov(receiver_map, FieldOperand(receiver, 0));
4611 __ bind(&compare_map);
4612 __ mov(cached_map, FieldOperand(feedback, FixedArray::OffsetOfElementAt(0)));
4613
4614 // A named keyed store might have a 2 element array, all other cases can count
4615 // on an array with at least 2 {map, handler} pairs, so they can go right
4616 // into polymorphic array handling.
4617 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4618 __ j(not_equal, &start_polymorphic);
4619
4620 // found, now call handler.
4621 Register handler = feedback;
4622 DCHECK(handler.is(VectorStoreICDescriptor::ValueRegister()));
4623 __ mov(handler, FieldOperand(feedback, FixedArray::OffsetOfElementAt(1)));
4624 __ pop(vector);
4625 __ pop(receiver);
4626 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4627 __ xchg(handler, Operand(esp, 0));
4628 __ ret(0);
4629
4630 // Polymorphic, we have to loop from 2 to N
4631
4632 // TODO(mvstanton): I think there is a bug here, we are assuming the
4633 // array has more than one map/handler pair, but we call this function in the
4634 // keyed store with a string key case, where it might be just an array of two
4635 // elements.
4636
4637 __ bind(&start_polymorphic);
4638 __ push(key);
4639 Register counter = key;
4640 __ mov(counter, Immediate(Smi::FromInt(2)));
4641 __ bind(&next_loop);
4642 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4643 FixedArray::kHeaderSize));
4644 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4645 __ j(not_equal, &prepare_next);
4646 __ mov(handler, FieldOperand(feedback, counter, times_half_pointer_size,
4647 FixedArray::kHeaderSize + kPointerSize));
4648 __ pop(key);
4649 __ pop(vector);
4650 __ pop(receiver);
4651 __ lea(handler, FieldOperand(handler, Code::kHeaderSize));
4652 __ xchg(handler, Operand(esp, 0));
4653 __ ret(0);
4654
4655 __ bind(&prepare_next);
4656 __ add(counter, Immediate(Smi::FromInt(2)));
4657 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
4658 __ j(less, &next_loop);
4659
4660 // We exhausted our array of map handler pairs.
4661 __ pop(key);
4662 __ pop(vector);
4663 __ pop(receiver);
4664 __ jmp(miss);
4665
4666 __ bind(&load_smi_map);
4667 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4668 __ jmp(&compare_map);
4669 }
4670
4671
4672 static void HandleMonomorphicStoreCase(MacroAssembler* masm, Register receiver,
4673 Register key, Register vector,
4674 Register slot, Register weak_cell,
4675 Label* miss) {
4676 // The store ic value is on the stack.
4677 DCHECK(weak_cell.is(VectorStoreICDescriptor::ValueRegister()));
4678
4679 // feedback initially contains the feedback array
4680 Label compare_smi_map;
4681
4682 // Move the weak map into the weak_cell register.
4683 Register ic_map = weak_cell;
4684 __ mov(ic_map, FieldOperand(weak_cell, WeakCell::kValueOffset));
4685
4686 // Receiver might not be a heap object.
4687 __ JumpIfSmi(receiver, &compare_smi_map);
4688 __ cmp(ic_map, FieldOperand(receiver, 0));
4689 __ j(not_equal, miss);
4690 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4691 FixedArray::kHeaderSize + kPointerSize));
4692 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4693 // Put the store ic value back in it's register.
4694 __ xchg(weak_cell, Operand(esp, 0));
4695 // "return" to the handler.
4696 __ ret(0);
4697
4698 // In microbenchmarks, it made sense to unroll this code so that the call to
4699 // the handler is duplicated for a HeapObject receiver and a Smi receiver.
4700 __ bind(&compare_smi_map);
4701 __ CompareRoot(ic_map, Heap::kHeapNumberMapRootIndex);
4702 __ j(not_equal, miss);
4703 __ mov(weak_cell, FieldOperand(vector, slot, times_half_pointer_size,
4704 FixedArray::kHeaderSize + kPointerSize));
4705 __ lea(weak_cell, FieldOperand(weak_cell, Code::kHeaderSize));
4706 // Put the store ic value back in it's register.
4707 __ xchg(weak_cell, Operand(esp, 0));
4708 // "return" to the handler.
4709 __ ret(0);
4710 }
4711
4712
4592 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4713 void VectorStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4714 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx
4715 Register key = VectorStoreICDescriptor::NameRegister(); // ecx
4716 Register value = VectorStoreICDescriptor::ValueRegister(); // eax
4717 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx
4718 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi
4593 Label miss; 4719 Label miss;
4594 4720
4595 // TODO(mvstanton): Implement. 4721 __ push(value);
4722
4723 Register scratch = value;
4724 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4725 FixedArray::kHeaderSize));
4726
4727 // Is it a weak cell?
4728 Label try_array;
4729 Label not_array, smi_key, key_okay;
4730 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
4731 __ j(not_equal, &try_array);
4732 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4733
4734 // Is it a fixed array?
4735 __ bind(&try_array);
4736 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
4737 __ j(not_equal, &not_array);
4738 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4739
4740 __ bind(&not_array);
4741 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
4742 __ j(not_equal, &miss);
4743
4744 __ pop(value);
4745 __ push(slot);
4746 __ push(vector);
4747 Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
4748 Code::ComputeHandlerFlags(Code::STORE_IC));
4749 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, code_flags,
4750 receiver, key, slot, no_reg);
4751 __ pop(vector);
4752 __ pop(slot);
4753 Label no_pop_miss;
4754 __ jmp(&no_pop_miss);
4755
4596 __ bind(&miss); 4756 __ bind(&miss);
4757 __ pop(value);
4758 __ bind(&no_pop_miss);
4597 StoreIC::GenerateMiss(masm); 4759 StoreIC::GenerateMiss(masm);
4598 } 4760 }
4599 4761
4600 4762
4601 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) { 4763 void VectorKeyedStoreICStub::Generate(MacroAssembler* masm) {
4602 GenerateImpl(masm, false); 4764 GenerateImpl(masm, false);
4603 } 4765 }
4604 4766
4605 4767
4606 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) { 4768 void VectorKeyedStoreICStub::GenerateForTrampoline(MacroAssembler* masm) {
4607 GenerateImpl(masm, true); 4769 GenerateImpl(masm, true);
4608 } 4770 }
4609 4771
4610 4772
4773 static void HandlePolymorphicKeyedStoreCase(MacroAssembler* masm,
4774 Register receiver, Register key,
4775 Register vector, Register slot,
4776 Register feedback, Label* miss) {
4777 // feedback initially contains the feedback array
4778 Label next, next_loop, prepare_next;
4779 Label load_smi_map, compare_map;
4780 Label transition_call;
4781 Label pop_and_miss;
4782
4783 __ push(receiver);
4784 __ push(vector);
4785
4786 Register receiver_map = receiver;
4787 Register cached_map = vector;
4788
4789 // Receiver might not be a heap object.
4790 __ JumpIfSmi(receiver, &load_smi_map);
4791 __ mov(receiver_map, FieldOperand(receiver, 0));
4792 __ bind(&compare_map);
4793
4794 // Polymorphic, we have to loop from 0 to N - 1
4795 __ push(key);
4796 // On the stack we have:
4797 // key (esp)
4798 // vector
4799 // receiver
4800 // value
4801 Register counter = key;
4802 __ mov(counter, Immediate(Smi::FromInt(0)));
4803 __ bind(&next_loop);
4804 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4805 FixedArray::kHeaderSize));
4806 __ cmp(receiver_map, FieldOperand(cached_map, WeakCell::kValueOffset));
4807 __ j(not_equal, &prepare_next);
4808 __ mov(cached_map, FieldOperand(feedback, counter, times_half_pointer_size,
4809 FixedArray::kHeaderSize + kPointerSize));
4810 __ CompareRoot(cached_map, Heap::kUndefinedValueRootIndex);
4811 __ j(not_equal, &transition_call);
4812 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
4813 FixedArray::kHeaderSize + 2 * kPointerSize));
4814 __ pop(key);
4815 __ pop(vector);
4816 __ pop(receiver);
4817 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4818 __ xchg(feedback, Operand(esp, 0));
4819 __ ret(0);
4820
4821 __ bind(&transition_call);
4822 // Oh holy hell this will be tough.
4823 // The map goes in vector register.
4824 __ mov(receiver, FieldOperand(cached_map, WeakCell::kValueOffset));
4825 // The weak cell may have been cleared.
4826 __ JumpIfSmi(receiver, &pop_and_miss);
4827 // slot goes on the stack, and holds return address.
4828 __ xchg(slot, Operand(esp, 4 * kPointerSize));
4829 // Get the handler in value.
4830 __ mov(feedback, FieldOperand(feedback, counter, times_half_pointer_size,
4831 FixedArray::kHeaderSize + 2 * kPointerSize));
4832 __ lea(feedback, FieldOperand(feedback, Code::kHeaderSize));
4833 // Pop key into place.
4834 __ pop(key);
4835 // Put the return address on top of stack, vector goes in slot.
4836 __ xchg(slot, Operand(esp, 0));
4837 // put the map on the stack, receiver holds receiver.
4838 __ xchg(receiver, Operand(esp, 1 * kPointerSize));
4839 // put the vector on the stack, slot holds value.
4840 __ xchg(slot, Operand(esp, 2 * kPointerSize));
4841 // feedback (value) = value, slot = handler.
4842 __ xchg(feedback, slot);
4843 __ jmp(slot);
4844
4845 __ bind(&prepare_next);
4846 __ add(counter, Immediate(Smi::FromInt(3)));
4847 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset));
4848 __ j(less, &next_loop);
4849
4850 // We exhausted our array of map handler pairs.
4851 __ bind(&pop_and_miss);
4852 __ pop(key);
4853 __ pop(vector);
4854 __ pop(receiver);
4855 __ jmp(miss);
4856
4857 __ bind(&load_smi_map);
4858 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex);
4859 __ jmp(&compare_map);
4860 }
4861
4862
4611 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { 4863 void VectorKeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) {
4864 Register receiver = VectorStoreICDescriptor::ReceiverRegister(); // edx
4865 Register key = VectorStoreICDescriptor::NameRegister(); // ecx
4866 Register value = VectorStoreICDescriptor::ValueRegister(); // eax
4867 Register vector = VectorStoreICDescriptor::VectorRegister(); // ebx
4868 Register slot = VectorStoreICDescriptor::SlotRegister(); // edi
4612 Label miss; 4869 Label miss;
4613 4870
4614 // TODO(mvstanton): Implement. 4871 __ push(value);
4872
4873 Register scratch = value;
4874 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4875 FixedArray::kHeaderSize));
4876
4877 // Is it a weak cell?
4878 Label try_array;
4879 Label not_array, smi_key, key_okay;
4880 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex);
4881 __ j(not_equal, &try_array);
4882 HandleMonomorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4883
4884 // Is it a fixed array?
4885 __ bind(&try_array);
4886 __ CompareRoot(FieldOperand(scratch, 0), Heap::kFixedArrayMapRootIndex);
4887 __ j(not_equal, &not_array);
4888 HandlePolymorphicKeyedStoreCase(masm, receiver, key, vector, slot, scratch,
4889 &miss);
4890
4891 __ bind(&not_array);
4892 Label try_poly_name;
4893 __ CompareRoot(scratch, Heap::kmegamorphic_symbolRootIndex);
4894 __ j(not_equal, &try_poly_name);
4895
4896 __ pop(value);
4897
4898 Handle<Code> megamorphic_stub =
4899 KeyedStoreIC::ChooseMegamorphicStub(masm->isolate(), GetExtraICState());
4900 __ jmp(megamorphic_stub, RelocInfo::CODE_TARGET);
4901
4902 __ bind(&try_poly_name);
4903 // We might have a name in feedback, and a fixed array in the next slot.
4904 __ cmp(key, scratch);
4905 __ j(not_equal, &miss);
4906 // If the name comparison succeeded, we know we have a fixed array with
4907 // at least one map/handler pair.
4908 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size,
4909 FixedArray::kHeaderSize + kPointerSize));
4910 HandlePolymorphicStoreCase(masm, receiver, key, vector, slot, scratch, &miss);
4911
4615 __ bind(&miss); 4912 __ bind(&miss);
4913 __ pop(value);
4616 KeyedStoreIC::GenerateMiss(masm); 4914 KeyedStoreIC::GenerateMiss(masm);
4617 } 4915 }
4618 4916
4619 4917
4620 void CallICTrampolineStub::Generate(MacroAssembler* masm) { 4918 void CallICTrampolineStub::Generate(MacroAssembler* masm) {
4621 EmitLoadTypeFeedbackVector(masm, ebx); 4919 EmitLoadTypeFeedbackVector(masm, ebx);
4622 CallICStub stub(isolate(), state()); 4920 CallICStub stub(isolate(), state());
4623 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET); 4921 __ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
4624 } 4922 }
4625 4923
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after
5546 Operand(ebp, 7 * kPointerSize), NULL); 5844 Operand(ebp, 7 * kPointerSize), NULL);
5547 } 5845 }
5548 5846
5549 5847
5550 #undef __ 5848 #undef __
5551 5849
5552 } // namespace internal 5850 } // namespace internal
5553 } // namespace v8 5851 } // namespace v8
5554 5852
5555 #endif // V8_TARGET_ARCH_IA32 5853 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ast.cc ('k') | src/ic/access-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698