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_ARM | 5 #if V8_TARGET_ARCH_ARM |
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 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 __ Ret(); | 455 __ Ret(); |
456 | 456 |
457 __ bind(&index_name); | 457 __ bind(&index_name); |
458 __ IndexFromHash(r3, key); | 458 __ IndexFromHash(r3, key); |
459 // Now jump to the place where smi keys are handled. | 459 // Now jump to the place where smi keys are handled. |
460 __ jmp(&index_smi); | 460 __ jmp(&index_smi); |
461 } | 461 } |
462 | 462 |
463 | 463 |
464 static void StoreIC_PushArgs(MacroAssembler* masm) { | 464 static void StoreIC_PushArgs(MacroAssembler* masm) { |
465 if (FLAG_vector_stores) { | 465 __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), |
466 __ Push(StoreDescriptor::ReceiverRegister(), | 466 StoreDescriptor::ValueRegister(), |
467 StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister(), | 467 VectorStoreICDescriptor::SlotRegister(), |
468 VectorStoreICDescriptor::SlotRegister(), | 468 VectorStoreICDescriptor::VectorRegister()); |
469 VectorStoreICDescriptor::VectorRegister()); | |
470 } else { | |
471 __ Push(StoreDescriptor::ReceiverRegister(), | |
472 StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister()); | |
473 } | |
474 } | 469 } |
475 | 470 |
476 | 471 |
477 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { | 472 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { |
478 StoreIC_PushArgs(masm); | 473 StoreIC_PushArgs(masm); |
479 | 474 |
480 int args = FLAG_vector_stores ? 5 : 3; | 475 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, 5, 1); |
481 __ TailCallRuntime(Runtime::kKeyedStoreIC_Miss, args, 1); | |
482 } | 476 } |
483 | 477 |
484 | 478 |
485 static void KeyedStoreGenerateMegamorphicHelper( | 479 static void KeyedStoreGenerateMegamorphicHelper( |
486 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 480 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
487 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length, | 481 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length, |
488 Register value, Register key, Register receiver, Register receiver_map, | 482 Register value, Register key, Register receiver, Register receiver_map, |
489 Register elements_map, Register elements) { | 483 Register elements_map, Register elements) { |
490 Label transition_smi_elements; | 484 Label transition_smi_elements; |
491 Label finish_object_store, non_double_value, transition_double_elements; | 485 Label finish_object_store, non_double_value, transition_double_elements; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 // r1: key. | 677 // r1: key. |
684 // r2: receiver. | 678 // r2: receiver. |
685 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode); | 679 PropertyICCompiler::GenerateRuntimeSetProperty(masm, language_mode); |
686 // Never returns to here. | 680 // Never returns to here. |
687 | 681 |
688 __ bind(&maybe_name_key); | 682 __ bind(&maybe_name_key); |
689 __ ldr(r4, FieldMemOperand(key, HeapObject::kMapOffset)); | 683 __ ldr(r4, FieldMemOperand(key, HeapObject::kMapOffset)); |
690 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); | 684 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); |
691 __ JumpIfNotUniqueNameInstanceType(r4, &slow); | 685 __ JumpIfNotUniqueNameInstanceType(r4, &slow); |
692 | 686 |
693 // We use register r8 when FLAG_vector_stores is enabled, because otherwise | 687 // We use register r8, because otherwise probing the megamorphic stub cache |
694 // probing the megamorphic stub cache would require pushing temporaries on | 688 // would require pushing temporaries on the stack. |
695 // the stack. | |
696 // TODO(mvstanton): quit using register r8 when | 689 // TODO(mvstanton): quit using register r8 when |
697 // FLAG_enable_embedded_constant_pool is turned on. | 690 // FLAG_enable_embedded_constant_pool is turned on. |
698 DCHECK(!FLAG_vector_stores || !FLAG_enable_embedded_constant_pool); | 691 DCHECK(!FLAG_enable_embedded_constant_pool); |
699 Register temporary2 = FLAG_vector_stores ? r8 : r4; | 692 Register temporary2 = r8; |
700 if (FLAG_vector_stores) { | 693 // The handlers in the stub cache expect a vector and slot. Since we won't |
701 // The handlers in the stub cache expect a vector and slot. Since we won't | 694 // change the IC from any downstream misses, a dummy vector can be used. |
702 // change the IC from any downstream misses, a dummy vector can be used. | 695 Register vector = VectorStoreICDescriptor::VectorRegister(); |
703 Register vector = VectorStoreICDescriptor::VectorRegister(); | 696 Register slot = VectorStoreICDescriptor::SlotRegister(); |
704 Register slot = VectorStoreICDescriptor::SlotRegister(); | |
705 | 697 |
706 DCHECK(!AreAliased(vector, slot, r5, temporary2, r6, r9)); | 698 DCHECK(!AreAliased(vector, slot, r5, temporary2, r6, r9)); |
707 Handle<TypeFeedbackVector> dummy_vector = | 699 Handle<TypeFeedbackVector> dummy_vector = |
708 TypeFeedbackVector::DummyVector(masm->isolate()); | 700 TypeFeedbackVector::DummyVector(masm->isolate()); |
709 int slot_index = dummy_vector->GetIndex( | 701 int slot_index = dummy_vector->GetIndex( |
710 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)); | 702 FeedbackVectorSlot(TypeFeedbackVector::kDummyKeyedStoreICSlot)); |
711 __ LoadRoot(vector, Heap::kDummyVectorRootIndex); | 703 __ LoadRoot(vector, Heap::kDummyVectorRootIndex); |
712 __ mov(slot, Operand(Smi::FromInt(slot_index))); | 704 __ mov(slot, Operand(Smi::FromInt(slot_index))); |
713 } | |
714 | 705 |
715 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( | 706 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
716 Code::ComputeHandlerFlags(Code::STORE_IC)); | 707 Code::ComputeHandlerFlags(Code::STORE_IC)); |
717 masm->isolate()->stub_cache()->GenerateProbe( | 708 masm->isolate()->stub_cache()->GenerateProbe( |
718 masm, Code::STORE_IC, flags, receiver, key, r5, temporary2, r6, r9); | 709 masm, Code::STORE_IC, flags, receiver, key, r5, temporary2, r6, r9); |
719 // Cache miss. | 710 // Cache miss. |
720 __ b(&miss); | 711 __ b(&miss); |
721 | 712 |
722 // Extra capacity case: Check if there is extra capacity to | 713 // Extra capacity case: Check if there is extra capacity to |
723 // perform the store and update the length. Used for adding one | 714 // perform the store and update the length. Used for adding one |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
781 | 772 |
782 // Cache miss: Jump to runtime. | 773 // Cache miss: Jump to runtime. |
783 GenerateMiss(masm); | 774 GenerateMiss(masm); |
784 } | 775 } |
785 | 776 |
786 | 777 |
787 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 778 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
788 StoreIC_PushArgs(masm); | 779 StoreIC_PushArgs(masm); |
789 | 780 |
790 // Perform tail call to the entry. | 781 // Perform tail call to the entry. |
791 int args = FLAG_vector_stores ? 5 : 3; | 782 __ TailCallRuntime(Runtime::kStoreIC_Miss, 5, 1); |
792 __ TailCallRuntime(Runtime::kStoreIC_Miss, args, 1); | |
793 } | 783 } |
794 | 784 |
795 | 785 |
796 void StoreIC::GenerateNormal(MacroAssembler* masm) { | 786 void StoreIC::GenerateNormal(MacroAssembler* masm) { |
797 Label miss; | 787 Label miss; |
798 Register receiver = StoreDescriptor::ReceiverRegister(); | 788 Register receiver = StoreDescriptor::ReceiverRegister(); |
799 Register name = StoreDescriptor::NameRegister(); | 789 Register name = StoreDescriptor::NameRegister(); |
800 Register value = StoreDescriptor::ValueRegister(); | 790 Register value = StoreDescriptor::ValueRegister(); |
801 Register dictionary = r5; | 791 Register dictionary = r5; |
802 DCHECK(receiver.is(r1)); | 792 DCHECK(receiver.is(r1)); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 patcher.EmitCondition(ne); | 899 patcher.EmitCondition(ne); |
910 } else { | 900 } else { |
911 DCHECK(Assembler::GetCondition(branch_instr) == ne); | 901 DCHECK(Assembler::GetCondition(branch_instr) == ne); |
912 patcher.EmitCondition(eq); | 902 patcher.EmitCondition(eq); |
913 } | 903 } |
914 } | 904 } |
915 } // namespace internal | 905 } // namespace internal |
916 } // namespace v8 | 906 } // namespace v8 |
917 | 907 |
918 #endif // V8_TARGET_ARCH_ARM | 908 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |