| 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 |