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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 __ bind(&slow); | 554 __ bind(&slow); |
555 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode); | 555 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode); |
556 // Never returns to here. | 556 // Never returns to here. |
557 | 557 |
558 __ bind(&maybe_name_key); | 558 __ bind(&maybe_name_key); |
559 __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset)); | 559 __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset)); |
560 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 560 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
561 __ JumpIfNotUniqueNameInstanceType(ebx, &slow); | 561 __ JumpIfNotUniqueNameInstanceType(ebx, &slow); |
562 | 562 |
563 | 563 |
564 if (FLAG_vector_stores) { | 564 // The handlers in the stub cache expect a vector and slot. Since we won't |
565 // The handlers in the stub cache expect a vector and slot. Since we won't | 565 // change the IC from any downstream misses, a dummy vector can be used. |
566 // change the IC from any downstream misses, a dummy vector can be used. | 566 Handle<TypeFeedbackVector> dummy_vector = |
567 Handle<TypeFeedbackVector> dummy_vector = | 567 TypeFeedbackVector::DummyVector(masm->isolate()); |
568 TypeFeedbackVector::DummyVector(masm->isolate()); | 568 int slot = dummy_vector->GetIndex( |
569 int slot = dummy_vector->GetIndex( | 569 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)); |
570 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)); | 570 __ push(Immediate(Smi::FromInt(slot))); |
571 __ push(Immediate(Smi::FromInt(slot))); | 571 __ push(Immediate(dummy_vector)); |
572 __ push(Immediate(dummy_vector)); | |
573 } | |
574 | 572 |
575 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 573 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
576 Code::ComputeHandlerFlags(Code::STORE_IC)); | 574 Code::ComputeHandlerFlags(Code::STORE_IC)); |
577 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, flags, | 575 masm->isolate()->stub_cache()->GenerateProbe(masm, Code::STORE_IC, flags, |
578 receiver, key, edi, no_reg); | 576 receiver, key, edi, no_reg); |
579 | 577 |
580 if (FLAG_vector_stores) { | 578 __ pop(VectorStoreICDescriptor::VectorRegister()); |
581 __ pop(VectorStoreICDescriptor::VectorRegister()); | 579 __ pop(VectorStoreICDescriptor::SlotRegister()); |
582 __ pop(VectorStoreICDescriptor::SlotRegister()); | |
583 } | |
584 | 580 |
585 // Cache miss. | 581 // Cache miss. |
586 __ jmp(&miss); | 582 __ jmp(&miss); |
587 | 583 |
588 // Extra capacity case: Check if there is extra capacity to | 584 // Extra capacity case: Check if there is extra capacity to |
589 // perform the store and update the length. Used for adding one | 585 // perform the store and update the length. Used for adding one |
590 // element to the array by writing to array[array.length]. | 586 // element to the array by writing to array[array.length]. |
591 __ bind(&extra); | 587 __ bind(&extra); |
592 // receiver is a JSArray. | 588 // receiver is a JSArray. |
593 // key is a smi. | 589 // key is a smi. |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 __ push(ebx); | 721 __ push(ebx); |
726 | 722 |
727 // Do tail-call to runtime routine. | 723 // Do tail-call to runtime routine. |
728 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kKeyedGetPropertyStrong | 724 __ TailCallRuntime(is_strong(language_mode) ? Runtime::kKeyedGetPropertyStrong |
729 : Runtime::kKeyedGetProperty, | 725 : Runtime::kKeyedGetProperty, |
730 2, 1); | 726 2, 1); |
731 } | 727 } |
732 | 728 |
733 | 729 |
734 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { | 730 void StoreIC::GenerateMegamorphic(MacroAssembler* masm) { |
735 if (FLAG_vector_stores) { | 731 // This shouldn't be called. |
736 // This shouldn't be called. | 732 // TODO(mvstanton): remove this method. |
737 __ int3(); | 733 __ int3(); |
738 return; | 734 return; |
739 } | |
740 | |
741 // Return address is on the stack. | |
742 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | |
743 Code::ComputeHandlerFlags(Code::STORE_IC)); | |
744 masm->isolate()->stub_cache()->GenerateProbe( | |
745 masm, Code::STORE_IC, flags, StoreDescriptor::ReceiverRegister(), | |
746 StoreDescriptor::NameRegister(), ebx, no_reg); | |
747 | |
748 // Cache miss: Jump to runtime. | |
749 GenerateMiss(masm); | |
750 } | 735 } |
751 | 736 |
752 | 737 |
753 static void StoreIC_PushArgs(MacroAssembler* masm) { | 738 static void StoreIC_PushArgs(MacroAssembler* masm) { |
754 Register receiver = StoreDescriptor::ReceiverRegister(); | 739 Register receiver = StoreDescriptor::ReceiverRegister(); |
755 Register name = StoreDescriptor::NameRegister(); | 740 Register name = StoreDescriptor::NameRegister(); |
756 Register value = StoreDescriptor::ValueRegister(); | 741 Register value = StoreDescriptor::ValueRegister(); |
| 742 Register slot = VectorStoreICDescriptor::SlotRegister(); |
| 743 Register vector = VectorStoreICDescriptor::VectorRegister(); |
757 | 744 |
758 if (FLAG_vector_stores) { | 745 __ xchg(receiver, Operand(esp, 0)); |
759 Register slot = VectorStoreICDescriptor::SlotRegister(); | 746 __ push(name); |
760 Register vector = VectorStoreICDescriptor::VectorRegister(); | 747 __ push(value); |
761 | 748 __ push(slot); |
762 __ xchg(receiver, Operand(esp, 0)); | 749 __ push(vector); |
763 __ push(name); | 750 __ push(receiver); // Contains the return address. |
764 __ push(value); | |
765 __ push(slot); | |
766 __ push(vector); | |
767 __ push(receiver); // Contains the return address. | |
768 } else { | |
769 DCHECK(!ebx.is(receiver) && !ebx.is(name) && !ebx.is(value)); | |
770 __ pop(ebx); | |
771 __ push(receiver); | |
772 __ push(name); | |
773 __ push(value); | |
774 __ push(ebx); | |
775 } | |
776 } | 751 } |
777 | 752 |
778 | 753 |
779 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 754 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
780 // Return address is on the stack. | 755 // Return address is on the stack. |
781 StoreIC_PushArgs(masm); | 756 StoreIC_PushArgs(masm); |
782 | 757 |
783 // Perform tail call to the entry. | 758 // Perform tail call to the entry. |
784 int args = FLAG_vector_stores ? 5 : 3; | 759 __ TailCallRuntime(Runtime::kStoreIC_Miss, 5, 1); |
785 __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1); | |
786 } | 760 } |
787 | 761 |
788 | 762 |
789 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 763 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
790 Label restore_miss; | 764 Label restore_miss; |
791 Register receiver = StoreDescriptor::ReceiverRegister(); | 765 Register receiver = StoreDescriptor::ReceiverRegister(); |
792 Register name = StoreDescriptor::NameRegister(); | 766 Register name = StoreDescriptor::NameRegister(); |
793 Register value = StoreDescriptor::ValueRegister(); | 767 Register value = StoreDescriptor::ValueRegister(); |
794 Register vector = VectorStoreICDescriptor::VectorRegister(); | 768 Register vector = VectorStoreICDescriptor::VectorRegister(); |
795 Register slot = VectorStoreICDescriptor::SlotRegister(); | 769 Register slot = VectorStoreICDescriptor::SlotRegister(); |
796 | 770 |
797 // A lot of registers are needed for storing to slow case | 771 // A lot of registers are needed for storing to slow case |
798 // objects. Push and restore receiver but rely on | 772 // objects. Push and restore receiver but rely on |
799 // GenerateDictionaryStore preserving the value and name. | 773 // GenerateDictionaryStore preserving the value and name. |
800 __ push(receiver); | 774 __ push(receiver); |
801 if (FLAG_vector_stores) { | 775 __ push(vector); |
802 __ push(vector); | 776 __ push(slot); |
803 __ push(slot); | |
804 } | |
805 | 777 |
806 Register dictionary = ebx; | 778 Register dictionary = ebx; |
807 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 779 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
808 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, | 780 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, |
809 receiver, edi); | 781 receiver, edi); |
810 __ Drop(FLAG_vector_stores ? 3 : 1); | 782 __ Drop(3); |
811 Counters* counters = masm->isolate()->counters(); | 783 Counters* counters = masm->isolate()->counters(); |
812 __ IncrementCounter(counters->store_normal_hit(), 1); | 784 __ IncrementCounter(counters->store_normal_hit(), 1); |
813 __ ret(0); | 785 __ ret(0); |
814 | 786 |
815 __ bind(&restore_miss); | 787 __ bind(&restore_miss); |
816 if (FLAG_vector_stores) { | 788 __ pop(slot); |
817 __ pop(slot); | 789 __ pop(vector); |
818 __ pop(vector); | |
819 } | |
820 __ pop(receiver); | 790 __ pop(receiver); |
821 __ IncrementCounter(counters->store_normal_miss(), 1); | 791 __ IncrementCounter(counters->store_normal_miss(), 1); |
822 GenerateMiss(masm); | 792 GenerateMiss(masm); |
823 } | 793 } |
824 | 794 |
825 | 795 |
826 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 796 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
827 // Return address is on the stack. | 797 // Return address is on the stack. |
828 StoreIC_PushArgs(masm); | 798 StoreIC_PushArgs(masm); |
829 | 799 |
830 // Do tail-call to runtime routine. | 800 // Do tail-call to runtime routine. |
831 int args = FLAG_vector_stores ? 5 : 3; | 801 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 5, 1); |
832 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1); | |
833 } | 802 } |
834 | 803 |
835 | 804 |
836 #undef __ | 805 #undef __ |
837 | 806 |
838 | 807 |
839 Condition CompareIC::ComputeCondition(Token::Value op) { | 808 Condition CompareIC::ComputeCondition(Token::Value op) { |
840 switch (op) { | 809 switch (op) { |
841 case Token::EQ_STRICT: | 810 case Token::EQ_STRICT: |
842 case Token::EQ: | 811 case Token::EQ: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 Condition cc = | 869 Condition cc = |
901 (check == ENABLE_INLINED_SMI_CHECK) | 870 (check == ENABLE_INLINED_SMI_CHECK) |
902 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 871 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
903 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 872 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
904 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 873 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
905 } | 874 } |
906 } // namespace internal | 875 } // namespace internal |
907 } // namespace v8 | 876 } // namespace v8 |
908 | 877 |
909 #endif // V8_TARGET_ARCH_X87 | 878 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |