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

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

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

Powered by Google App Engine
This is Rietveld 408576698