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_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
9 #include "src/ic/ic-compiler.h" | 9 #include "src/ic/ic-compiler.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 __ Integer32ToSmi(key, key); | 557 __ Integer32ToSmi(key, key); |
558 __ bind(&slow_with_tagged_index); | 558 __ bind(&slow_with_tagged_index); |
559 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode); | 559 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode); |
560 // Never returns to here. | 560 // Never returns to here. |
561 | 561 |
562 __ bind(&maybe_name_key); | 562 __ bind(&maybe_name_key); |
563 __ movp(r9, FieldOperand(key, HeapObject::kMapOffset)); | 563 __ movp(r9, FieldOperand(key, HeapObject::kMapOffset)); |
564 __ movzxbp(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); | 564 __ movzxbp(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); |
565 __ JumpIfNotUniqueNameInstanceType(r9, &slow_with_tagged_index); | 565 __ JumpIfNotUniqueNameInstanceType(r9, &slow_with_tagged_index); |
566 | 566 |
567 if (FLAG_vector_stores) { | 567 Register vector = VectorStoreICDescriptor::VectorRegister(); |
568 Register vector = VectorStoreICDescriptor::VectorRegister(); | 568 Register slot = VectorStoreICDescriptor::SlotRegister(); |
569 Register slot = VectorStoreICDescriptor::SlotRegister(); | 569 // The handlers in the stub cache expect a vector and slot. Since we won't |
570 // The handlers in the stub cache expect a vector and slot. Since we won't | 570 // change the IC from any downstream misses, a dummy vector can be used. |
571 // change the IC from any downstream misses, a dummy vector can be used. | 571 Handle<TypeFeedbackVector> dummy_vector = |
572 Handle<TypeFeedbackVector> dummy_vector = | 572 TypeFeedbackVector::DummyVector(masm->isolate()); |
573 TypeFeedbackVector::DummyVector(masm->isolate()); | 573 int slot_index = dummy_vector->GetIndex( |
574 int slot_index = dummy_vector->GetIndex( | 574 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)); |
575 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)); | 575 __ Move(vector, dummy_vector); |
576 __ Move(vector, dummy_vector); | 576 __ Move(slot, Smi::FromInt(slot_index)); |
577 __ Move(slot, Smi::FromInt(slot_index)); | |
578 } | |
579 | 577 |
580 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 578 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
581 Code::ComputeHandlerFlags(Code::STORE_IC)); | 579 Code::ComputeHandlerFlags(Code::STORE_IC)); |
582 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, flags, | 580 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, flags, |
583 receiver, key, r9, no_reg); | 581 receiver, key, r9, no_reg); |
584 // Cache miss. | 582 // Cache miss. |
585 __ jmp(&miss); | 583 __ jmp(&miss); |
586 | 584 |
587 // Extra capacity case: Check if there is extra capacity to | 585 // Extra capacity case: Check if there is extra capacity to |
588 // perform the store and update the length. Used for adding one | 586 // perform the store and update the length. Used for adding one |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 __ PushReturnAddressFrom(rbx); | 724 __ PushReturnAddressFrom(rbx); |
727 | 725 |
728 // Do tail-call to runtime routine. | 726 // Do tail-call to runtime routine. |
729 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kKeyedGetPropertyStrong | 727 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kKeyedGetPropertyStrong |
730 : Runtime::kKeyedGetProperty, | 728 : Runtime::kKeyedGetProperty, |
731 2, 1); | 729 2, 1); |
732 } | 730 } |
733 | 731 |
734 | 732 |
735 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 733 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
736 if (FLAG_vector_stores) { | 734 // This shouldn't be called. |
737 // This shouldn't be called. | 735 __ int3(); |
738 __ int3(); | |
739 return; | |
740 } | |
741 | |
742 // The return address is on the stack. | |
743 // Get the receiver from the stack and probe the stub cache. | |
744 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | |
745 Code::ComputeHandlerFlags(Code::STORE_IC)); | |
746 masm->isolate()->stub_cache()->GenerateProbe( | |
747 masm, Code::STORE_IC, flags, StoreDescriptor::ReceiverRegister(), | |
748 StoreDescriptor::NameRegister(), rbx, no_reg); | |
749 | |
750 // Cache miss: Jump to runtime. | |
751 GenerateMiss(masm); | |
752 } | 736 } |
753 | 737 |
754 | 738 |
755 static void StoreIC_PushArgs(MacroAssembler* masm) { | 739 static void StoreIC_PushArgs(MacroAssembler* masm) { |
756 Register receiver = StoreDescriptor::ReceiverRegister(); | 740 Register receiver = StoreDescriptor::ReceiverRegister(); |
757 Register name = StoreDescriptor::NameRegister(); | 741 Register name = StoreDescriptor::NameRegister(); |
758 Register value = StoreDescriptor::ValueRegister(); | 742 Register value = StoreDescriptor::ValueRegister(); |
759 Register temp = r11; | 743 Register temp = r11; |
760 DCHECK(!temp.is(receiver) && !temp.is(name) && !temp.is(value)); | 744 DCHECK(!temp.is(receiver) && !temp.is(name) && !temp.is(value)); |
761 | 745 |
762 __ PopReturnAddressTo(temp); | 746 __ PopReturnAddressTo(temp); |
763 __ Push(receiver); | 747 __ Push(receiver); |
764 __ Push(name); | 748 __ Push(name); |
765 __ Push(value); | 749 __ Push(value); |
766 if (FLAG_vector_stores) { | 750 Register slot = VectorStoreICDescriptor::SlotRegister(); |
767 Register slot = VectorStoreICDescriptor::SlotRegister(); | 751 Register vector = VectorStoreICDescriptor::VectorRegister(); |
768 Register vector = VectorStoreICDescriptor::VectorRegister(); | 752 DCHECK(!temp.is(slot) && !temp.is(vector)); |
769 DCHECK(!temp.is(slot) && !temp.is(vector)); | 753 __ Push(slot); |
770 __ Push(slot); | 754 __ Push(vector); |
771 __ Push(vector); | |
772 } | |
773 __ PushReturnAddressFrom(temp); | 755 __ PushReturnAddressFrom(temp); |
774 } | 756 } |
775 | 757 |
776 | 758 |
777 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 759 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
778 // Return address is on the stack. | 760 // Return address is on the stack. |
779 StoreIC_PushArgs(masm); | 761 StoreIC_PushArgs(masm); |
780 | 762 |
781 // Perform tail call to the entry. | 763 // Perform tail call to the entry. |
782 int args = FLAG_vector_stores ? 5 : 3; | 764 __ TailCallRuntime(Runtime::kStoreIC_Miss, 5, 1); |
783 __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1); | |
784 } | 765 } |
785 | 766 |
786 | 767 |
787 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 768 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
788 Register receiver = StoreDescriptor::ReceiverRegister(); | 769 Register receiver = StoreDescriptor::ReceiverRegister(); |
789 Register name = StoreDescriptor::NameRegister(); | 770 Register name = StoreDescriptor::NameRegister(); |
790 Register value = StoreDescriptor::ValueRegister(); | 771 Register value = StoreDescriptor::ValueRegister(); |
791 Register dictionary = r11; | 772 Register dictionary = r11; |
792 DCHECK(!FLAG_vector_stores || | 773 DCHECK(!AreAliased(dictionary, VectorStoreICDescriptor::VectorRegister(), |
793 !AreAliased(dictionary, VectorStoreICDescriptor::VectorRegister(), | |
794 VectorStoreICDescriptor::SlotRegister())); | 774 VectorStoreICDescriptor::SlotRegister())); |
795 | 775 |
796 Label miss; | 776 Label miss; |
797 | 777 |
798 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 778 __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
799 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); | 779 GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); |
800 Counters* counters = masm->isolate()->counters(); | 780 Counters* counters = masm->isolate()->counters(); |
801 __ IncrementCounter(counters->store_normal_hit(), 1); | 781 __ IncrementCounter(counters->store_normal_hit(), 1); |
802 __ ret(0); | 782 __ ret(0); |
803 | 783 |
804 __ bind(&miss); | 784 __ bind(&miss); |
805 __ IncrementCounter(counters->store_normal_miss(), 1); | 785 __ IncrementCounter(counters->store_normal_miss(), 1); |
806 GenerateMiss(masm); | 786 GenerateMiss(masm); |
807 } | 787 } |
808 | 788 |
809 | 789 |
810 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 790 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
811 // Return address is on the stack. | 791 // Return address is on the stack. |
812 StoreIC_PushArgs(masm); | 792 StoreIC_PushArgs(masm); |
813 | 793 |
814 // Do tail-call to runtime routine. | 794 // Do tail-call to runtime routine. |
815 int args = FLAG_vector_stores ? 5 : 3; | 795 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 5, 1); |
816 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1); | |
817 } | 796 } |
818 | 797 |
819 | 798 |
820 #undef __ | 799 #undef __ |
821 | 800 |
822 | 801 |
823 Condition CompareIC::ComputeCondition(Token::Value op) { | 802 Condition CompareIC::ComputeCondition(Token::Value op) { |
824 switch (op) { | 803 switch (op) { |
825 case Token::EQ_STRICT: | 804 case Token::EQ_STRICT: |
826 case Token::EQ: | 805 case Token::EQ: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 Condition cc = | 863 Condition cc = |
885 (check == ENABLE_INLINED_SMI_CHECK) | 864 (check == ENABLE_INLINED_SMI_CHECK) |
886 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 865 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
887 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 866 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
888 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 867 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
889 } | 868 } |
890 } // namespace internal | 869 } // namespace internal |
891 } // namespace v8 | 870 } // namespace v8 |
892 | 871 |
893 #endif // V8_TARGET_ARCH_X64 | 872 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |