OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 // ----------------------------------- | 545 // ----------------------------------- |
546 Label number, non_number, non_string, boolean, probe, miss; | 546 Label number, non_number, non_string, boolean, probe, miss; |
547 | 547 |
548 // Probe the stub cache. | 548 // Probe the stub cache. |
549 Code::Flags flags = Code::ComputeFlags(kind, | 549 Code::Flags flags = Code::ComputeFlags(kind, |
550 NOT_IN_LOOP, | 550 NOT_IN_LOOP, |
551 MONOMORPHIC, | 551 MONOMORPHIC, |
552 Code::kNoExtraICState, | 552 Code::kNoExtraICState, |
553 NORMAL, | 553 NORMAL, |
554 argc); | 554 argc); |
555 StubCache::GenerateProbe(masm, flags, r1, r2, r3, r4, r5); | 555 Isolate::Current()->stub_cache()->GenerateProbe( |
| 556 masm, flags, r1, r2, r3, r4, r5); |
556 | 557 |
557 // If the stub cache probing failed, the receiver might be a value. | 558 // If the stub cache probing failed, the receiver might be a value. |
558 // For value objects, we use the map of the prototype objects for | 559 // For value objects, we use the map of the prototype objects for |
559 // the corresponding JSValue for the cache and that is what we need | 560 // the corresponding JSValue for the cache and that is what we need |
560 // to probe. | 561 // to probe. |
561 // | 562 // |
562 // Check for number. | 563 // Check for number. |
563 __ tst(r1, Operand(kSmiTagMask)); | 564 __ tst(r1, Operand(kSmiTagMask)); |
564 __ b(eq, &number); | 565 __ b(eq, &number); |
565 __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE); | 566 __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE); |
(...skipping 18 matching lines...) Expand all Loading... |
584 __ b(eq, &boolean); | 585 __ b(eq, &boolean); |
585 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 586 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
586 __ cmp(r1, ip); | 587 __ cmp(r1, ip); |
587 __ b(ne, &miss); | 588 __ b(ne, &miss); |
588 __ bind(&boolean); | 589 __ bind(&boolean); |
589 StubCompiler::GenerateLoadGlobalFunctionPrototype( | 590 StubCompiler::GenerateLoadGlobalFunctionPrototype( |
590 masm, Context::BOOLEAN_FUNCTION_INDEX, r1); | 591 masm, Context::BOOLEAN_FUNCTION_INDEX, r1); |
591 | 592 |
592 // Probe the stub cache for the value object. | 593 // Probe the stub cache for the value object. |
593 __ bind(&probe); | 594 __ bind(&probe); |
594 StubCache::GenerateProbe(masm, flags, r1, r2, r3, r4, r5); | 595 Isolate::Current()->stub_cache()->GenerateProbe( |
| 596 masm, flags, r1, r2, r3, r4, r5); |
595 | 597 |
596 __ bind(&miss); | 598 __ bind(&miss); |
597 } | 599 } |
598 | 600 |
599 | 601 |
600 static void GenerateFunctionTailCall(MacroAssembler* masm, | 602 static void GenerateFunctionTailCall(MacroAssembler* masm, |
601 int argc, | 603 int argc, |
602 Label* miss, | 604 Label* miss, |
603 Register scratch) { | 605 Register scratch) { |
604 // r1: function | 606 // r1: function |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 } | 641 } |
640 | 642 |
641 | 643 |
642 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) { | 644 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) { |
643 // ----------- S t a t e ------------- | 645 // ----------- S t a t e ------------- |
644 // -- r2 : name | 646 // -- r2 : name |
645 // -- lr : return address | 647 // -- lr : return address |
646 // ----------------------------------- | 648 // ----------------------------------- |
647 | 649 |
648 if (id == IC::kCallIC_Miss) { | 650 if (id == IC::kCallIC_Miss) { |
649 __ IncrementCounter(&Counters::call_miss, 1, r3, r4); | 651 __ IncrementCounter(COUNTERS->call_miss(), 1, r3, r4); |
650 } else { | 652 } else { |
651 __ IncrementCounter(&Counters::keyed_call_miss, 1, r3, r4); | 653 __ IncrementCounter(COUNTERS->keyed_call_miss(), 1, r3, r4); |
652 } | 654 } |
653 | 655 |
654 // Get the receiver of the function from the stack. | 656 // Get the receiver of the function from the stack. |
655 __ ldr(r3, MemOperand(sp, argc * kPointerSize)); | 657 __ ldr(r3, MemOperand(sp, argc * kPointerSize)); |
656 | 658 |
657 __ EnterInternalFrame(); | 659 __ EnterInternalFrame(); |
658 | 660 |
659 // Push the receiver and the name of the function. | 661 // Push the receiver and the name of the function. |
660 __ Push(r3, r2); | 662 __ Push(r3, r2); |
661 | 663 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 __ JumpIfNotSmi(r2, &check_string); | 758 __ JumpIfNotSmi(r2, &check_string); |
757 __ bind(&index_smi); | 759 __ bind(&index_smi); |
758 // Now the key is known to be a smi. This place is also jumped to from below | 760 // Now the key is known to be a smi. This place is also jumped to from below |
759 // where a numeric string is converted to a smi. | 761 // where a numeric string is converted to a smi. |
760 | 762 |
761 GenerateKeyedLoadReceiverCheck( | 763 GenerateKeyedLoadReceiverCheck( |
762 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call); | 764 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call); |
763 | 765 |
764 GenerateFastArrayLoad( | 766 GenerateFastArrayLoad( |
765 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load); | 767 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load); |
766 __ IncrementCounter(&Counters::keyed_call_generic_smi_fast, 1, r0, r3); | 768 __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1, r0, r3); |
767 | 769 |
768 __ bind(&do_call); | 770 __ bind(&do_call); |
769 // receiver in r1 is not used after this point. | 771 // receiver in r1 is not used after this point. |
770 // r2: key | 772 // r2: key |
771 // r1: function | 773 // r1: function |
772 GenerateFunctionTailCall(masm, argc, &slow_call, r0); | 774 GenerateFunctionTailCall(masm, argc, &slow_call, r0); |
773 | 775 |
774 __ bind(&check_number_dictionary); | 776 __ bind(&check_number_dictionary); |
775 // r2: key | 777 // r2: key |
776 // r3: elements map | 778 // r3: elements map |
777 // r4: elements | 779 // r4: elements |
778 // Check whether the elements is a number dictionary. | 780 // Check whether the elements is a number dictionary. |
779 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 781 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
780 __ cmp(r3, ip); | 782 __ cmp(r3, ip); |
781 __ b(ne, &slow_load); | 783 __ b(ne, &slow_load); |
782 __ mov(r0, Operand(r2, ASR, kSmiTagSize)); | 784 __ mov(r0, Operand(r2, ASR, kSmiTagSize)); |
783 // r0: untagged index | 785 // r0: untagged index |
784 GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5); | 786 GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5); |
785 __ IncrementCounter(&Counters::keyed_call_generic_smi_dict, 1, r0, r3); | 787 __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1, r0, r3); |
786 __ jmp(&do_call); | 788 __ jmp(&do_call); |
787 | 789 |
788 __ bind(&slow_load); | 790 __ bind(&slow_load); |
789 // This branch is taken when calling KeyedCallIC_Miss is neither required | 791 // This branch is taken when calling KeyedCallIC_Miss is neither required |
790 // nor beneficial. | 792 // nor beneficial. |
791 __ IncrementCounter(&Counters::keyed_call_generic_slow_load, 1, r0, r3); | 793 __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1, r0, r3); |
792 __ EnterInternalFrame(); | 794 __ EnterInternalFrame(); |
793 __ push(r2); // save the key | 795 __ push(r2); // save the key |
794 __ Push(r1, r2); // pass the receiver and the key | 796 __ Push(r1, r2); // pass the receiver and the key |
795 __ CallRuntime(Runtime::kKeyedGetProperty, 2); | 797 __ CallRuntime(Runtime::kKeyedGetProperty, 2); |
796 __ pop(r2); // restore the key | 798 __ pop(r2); // restore the key |
797 __ LeaveInternalFrame(); | 799 __ LeaveInternalFrame(); |
798 __ mov(r1, r0); | 800 __ mov(r1, r0); |
799 __ jmp(&do_call); | 801 __ jmp(&do_call); |
800 | 802 |
801 __ bind(&check_string); | 803 __ bind(&check_string); |
802 GenerateKeyStringCheck(masm, r2, r0, r3, &index_string, &slow_call); | 804 GenerateKeyStringCheck(masm, r2, r0, r3, &index_string, &slow_call); |
803 | 805 |
804 // The key is known to be a symbol. | 806 // The key is known to be a symbol. |
805 // If the receiver is a regular JS object with slow properties then do | 807 // If the receiver is a regular JS object with slow properties then do |
806 // a quick inline probe of the receiver's dictionary. | 808 // a quick inline probe of the receiver's dictionary. |
807 // Otherwise do the monomorphic cache probe. | 809 // Otherwise do the monomorphic cache probe. |
808 GenerateKeyedLoadReceiverCheck( | 810 GenerateKeyedLoadReceiverCheck( |
809 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); | 811 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); |
810 | 812 |
811 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset)); | 813 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset)); |
812 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); | 814 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); |
813 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 815 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
814 __ cmp(r3, ip); | 816 __ cmp(r3, ip); |
815 __ b(ne, &lookup_monomorphic_cache); | 817 __ b(ne, &lookup_monomorphic_cache); |
816 | 818 |
817 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); | 819 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); |
818 __ IncrementCounter(&Counters::keyed_call_generic_lookup_dict, 1, r0, r3); | 820 __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1, r0, r3); |
819 __ jmp(&do_call); | 821 __ jmp(&do_call); |
820 | 822 |
821 __ bind(&lookup_monomorphic_cache); | 823 __ bind(&lookup_monomorphic_cache); |
822 __ IncrementCounter(&Counters::keyed_call_generic_lookup_cache, 1, r0, r3); | 824 __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1, r0, r3); |
823 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 825 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); |
824 // Fall through on miss. | 826 // Fall through on miss. |
825 | 827 |
826 __ bind(&slow_call); | 828 __ bind(&slow_call); |
827 // This branch is taken if: | 829 // This branch is taken if: |
828 // - the receiver requires boxing or access check, | 830 // - the receiver requires boxing or access check, |
829 // - the key is neither smi nor symbol, | 831 // - the key is neither smi nor symbol, |
830 // - the value loaded is not a function, | 832 // - the value loaded is not a function, |
831 // - there is hope that the runtime will create a monomorphic call stub | 833 // - there is hope that the runtime will create a monomorphic call stub |
832 // that will get fetched next time. | 834 // that will get fetched next time. |
833 __ IncrementCounter(&Counters::keyed_call_generic_slow, 1, r0, r3); | 835 __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1, r0, r3); |
834 GenerateMiss(masm, argc); | 836 GenerateMiss(masm, argc); |
835 | 837 |
836 __ bind(&index_string); | 838 __ bind(&index_string); |
837 __ IndexFromHash(r3, r2); | 839 __ IndexFromHash(r3, r2); |
838 // Now jump to the place where smi keys are handled. | 840 // Now jump to the place where smi keys are handled. |
839 __ jmp(&index_smi); | 841 __ jmp(&index_smi); |
840 } | 842 } |
841 | 843 |
842 | 844 |
843 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 845 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
(...skipping 22 matching lines...) Expand all Loading... |
866 // -- r2 : name | 868 // -- r2 : name |
867 // -- lr : return address | 869 // -- lr : return address |
868 // -- r0 : receiver | 870 // -- r0 : receiver |
869 // -- sp[0] : receiver | 871 // -- sp[0] : receiver |
870 // ----------------------------------- | 872 // ----------------------------------- |
871 | 873 |
872 // Probe the stub cache. | 874 // Probe the stub cache. |
873 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, | 875 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, |
874 NOT_IN_LOOP, | 876 NOT_IN_LOOP, |
875 MONOMORPHIC); | 877 MONOMORPHIC); |
876 StubCache::GenerateProbe(masm, flags, r0, r2, r3, r4, r5); | 878 Isolate::Current()->stub_cache()->GenerateProbe( |
| 879 masm, flags, r0, r2, r3, r4, r5); |
877 | 880 |
878 // Cache miss: Jump to runtime. | 881 // Cache miss: Jump to runtime. |
879 GenerateMiss(masm); | 882 GenerateMiss(masm); |
880 } | 883 } |
881 | 884 |
882 | 885 |
883 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 886 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
884 // ----------- S t a t e ------------- | 887 // ----------- S t a t e ------------- |
885 // -- r2 : name | 888 // -- r2 : name |
886 // -- lr : return address | 889 // -- lr : return address |
(...skipping 15 matching lines...) Expand all Loading... |
902 | 905 |
903 | 906 |
904 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 907 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
905 // ----------- S t a t e ------------- | 908 // ----------- S t a t e ------------- |
906 // -- r2 : name | 909 // -- r2 : name |
907 // -- lr : return address | 910 // -- lr : return address |
908 // -- r0 : receiver | 911 // -- r0 : receiver |
909 // -- sp[0] : receiver | 912 // -- sp[0] : receiver |
910 // ----------------------------------- | 913 // ----------------------------------- |
911 | 914 |
912 __ IncrementCounter(&Counters::load_miss, 1, r3, r4); | 915 __ IncrementCounter(COUNTERS->load_miss(), 1, r3, r4); |
913 | 916 |
914 __ mov(r3, r0); | 917 __ mov(r3, r0); |
915 __ Push(r3, r2); | 918 __ Push(r3, r2); |
916 | 919 |
917 // Perform tail call to the entry. | 920 // Perform tail call to the entry. |
918 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); | 921 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); |
919 __ TailCallExternalReference(ref, 2, 1); | 922 __ TailCallExternalReference(ref, 2, 1); |
920 } | 923 } |
921 | 924 |
922 // Returns the code marker, or the 0 if the code is not marked. | 925 // Returns the code marker, or the 0 if the code is not marked. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 | 1053 |
1051 // Compute the address of the map load instruction. | 1054 // Compute the address of the map load instruction. |
1052 Address ldr_map_instr_address = | 1055 Address ldr_map_instr_address = |
1053 inline_end_address - | 1056 inline_end_address - |
1054 (CodeGenerator::GetInlinedNamedStoreInstructionsAfterPatch() * | 1057 (CodeGenerator::GetInlinedNamedStoreInstructionsAfterPatch() * |
1055 Assembler::kInstrSize); | 1058 Assembler::kInstrSize); |
1056 | 1059 |
1057 // Update the offsets if initializing the inlined store. No reason | 1060 // Update the offsets if initializing the inlined store. No reason |
1058 // to update the offsets when clearing the inlined version because | 1061 // to update the offsets when clearing the inlined version because |
1059 // it will bail out in the map check. | 1062 // it will bail out in the map check. |
1060 if (map != Heap::null_value()) { | 1063 if (map != HEAP->null_value()) { |
1061 // Patch the offset in the actual store instruction. | 1064 // Patch the offset in the actual store instruction. |
1062 Address str_property_instr_address = | 1065 Address str_property_instr_address = |
1063 ldr_map_instr_address + 3 * Assembler::kInstrSize; | 1066 ldr_map_instr_address + 3 * Assembler::kInstrSize; |
1064 Instr str_property_instr = Assembler::instr_at(str_property_instr_address); | 1067 Instr str_property_instr = Assembler::instr_at(str_property_instr_address); |
1065 ASSERT(Assembler::IsStrRegisterImmediate(str_property_instr)); | 1068 ASSERT(Assembler::IsStrRegisterImmediate(str_property_instr)); |
1066 str_property_instr = Assembler::SetStrRegisterImmediateOffset( | 1069 str_property_instr = Assembler::SetStrRegisterImmediateOffset( |
1067 str_property_instr, offset - kHeapObjectTag); | 1070 str_property_instr, offset - kHeapObjectTag); |
1068 Assembler::instr_at_put(str_property_instr_address, str_property_instr); | 1071 Assembler::instr_at_put(str_property_instr_address, str_property_instr); |
1069 | 1072 |
1070 // Patch the offset in the add instruction that is part of the | 1073 // Patch the offset in the add instruction that is part of the |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 Object* KeyedLoadIC_Miss(Arguments args); | 1137 Object* KeyedLoadIC_Miss(Arguments args); |
1135 | 1138 |
1136 | 1139 |
1137 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 1140 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
1138 // ---------- S t a t e -------------- | 1141 // ---------- S t a t e -------------- |
1139 // -- lr : return address | 1142 // -- lr : return address |
1140 // -- r0 : key | 1143 // -- r0 : key |
1141 // -- r1 : receiver | 1144 // -- r1 : receiver |
1142 // ----------------------------------- | 1145 // ----------------------------------- |
1143 | 1146 |
1144 __ IncrementCounter(&Counters::keyed_load_miss, 1, r3, r4); | 1147 __ IncrementCounter(COUNTERS->keyed_load_miss(), 1, r3, r4); |
1145 | 1148 |
1146 __ Push(r1, r0); | 1149 __ Push(r1, r0); |
1147 | 1150 |
1148 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); | 1151 ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); |
1149 __ TailCallExternalReference(ref, 2, 1); | 1152 __ TailCallExternalReference(ref, 2, 1); |
1150 } | 1153 } |
1151 | 1154 |
1152 | 1155 |
1153 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1156 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1154 // ---------- S t a t e -------------- | 1157 // ---------- S t a t e -------------- |
(...skipping 30 matching lines...) Expand all Loading... |
1185 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); | 1188 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); |
1186 | 1189 |
1187 // Check the "has fast elements" bit in the receiver's map which is | 1190 // Check the "has fast elements" bit in the receiver's map which is |
1188 // now in r2. | 1191 // now in r2. |
1189 __ ldrb(r3, FieldMemOperand(r2, Map::kBitField2Offset)); | 1192 __ ldrb(r3, FieldMemOperand(r2, Map::kBitField2Offset)); |
1190 __ tst(r3, Operand(1 << Map::kHasFastElements)); | 1193 __ tst(r3, Operand(1 << Map::kHasFastElements)); |
1191 __ b(eq, &check_number_dictionary); | 1194 __ b(eq, &check_number_dictionary); |
1192 | 1195 |
1193 GenerateFastArrayLoad( | 1196 GenerateFastArrayLoad( |
1194 masm, receiver, key, r4, r3, r2, r0, NULL, &slow); | 1197 masm, receiver, key, r4, r3, r2, r0, NULL, &slow); |
1195 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1, r2, r3); | 1198 __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1, r2, r3); |
1196 __ Ret(); | 1199 __ Ret(); |
1197 | 1200 |
1198 __ bind(&check_number_dictionary); | 1201 __ bind(&check_number_dictionary); |
1199 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 1202 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
1200 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); | 1203 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); |
1201 | 1204 |
1202 // Check whether the elements is a number dictionary. | 1205 // Check whether the elements is a number dictionary. |
1203 // r0: key | 1206 // r0: key |
1204 // r3: elements map | 1207 // r3: elements map |
1205 // r4: elements | 1208 // r4: elements |
1206 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 1209 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
1207 __ cmp(r3, ip); | 1210 __ cmp(r3, ip); |
1208 __ b(ne, &slow); | 1211 __ b(ne, &slow); |
1209 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); | 1212 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); |
1210 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r0, r2, r3, r5); | 1213 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r0, r2, r3, r5); |
1211 __ Ret(); | 1214 __ Ret(); |
1212 | 1215 |
1213 // Slow case, key and receiver still in r0 and r1. | 1216 // Slow case, key and receiver still in r0 and r1. |
1214 __ bind(&slow); | 1217 __ bind(&slow); |
1215 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r2, r3); | 1218 __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1, r2, r3); |
1216 GenerateRuntimeGetProperty(masm); | 1219 GenerateRuntimeGetProperty(masm); |
1217 | 1220 |
1218 __ bind(&check_string); | 1221 __ bind(&check_string); |
1219 GenerateKeyStringCheck(masm, key, r2, r3, &index_string, &slow); | 1222 GenerateKeyStringCheck(masm, key, r2, r3, &index_string, &slow); |
1220 | 1223 |
1221 GenerateKeyedLoadReceiverCheck( | 1224 GenerateKeyedLoadReceiverCheck( |
1222 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); | 1225 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); |
1223 | 1226 |
1224 // If the receiver is a fast-case object, check the keyed lookup | 1227 // If the receiver is a fast-case object, check the keyed lookup |
1225 // cache. Otherwise probe the dictionary. | 1228 // cache. Otherwise probe the dictionary. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1260 __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); | 1263 __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); |
1261 __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); | 1264 __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); |
1262 __ sub(r5, r5, r6, SetCC); | 1265 __ sub(r5, r5, r6, SetCC); |
1263 __ b(ge, &property_array_property); | 1266 __ b(ge, &property_array_property); |
1264 | 1267 |
1265 // Load in-object property. | 1268 // Load in-object property. |
1266 __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); | 1269 __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); |
1267 __ add(r6, r6, r5); // Index from start of object. | 1270 __ add(r6, r6, r5); // Index from start of object. |
1268 __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. | 1271 __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. |
1269 __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2)); | 1272 __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2)); |
1270 __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1, r2, r3); | 1273 __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3); |
1271 __ Ret(); | 1274 __ Ret(); |
1272 | 1275 |
1273 // Load property array property. | 1276 // Load property array property. |
1274 __ bind(&property_array_property); | 1277 __ bind(&property_array_property); |
1275 __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); | 1278 __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); |
1276 __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1279 __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1277 __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); | 1280 __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); |
1278 __ IncrementCounter(&Counters::keyed_load_generic_lookup_cache, 1, r2, r3); | 1281 __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3); |
1279 __ Ret(); | 1282 __ Ret(); |
1280 | 1283 |
1281 // Do a quick inline probe of the receiver's dictionary, if it | 1284 // Do a quick inline probe of the receiver's dictionary, if it |
1282 // exists. | 1285 // exists. |
1283 __ bind(&probe_dictionary); | 1286 __ bind(&probe_dictionary); |
1284 // r1: receiver | 1287 // r1: receiver |
1285 // r0: key | 1288 // r0: key |
1286 // r3: elements | 1289 // r3: elements |
1287 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1290 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1288 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 1291 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
1289 GenerateGlobalInstanceTypeCheck(masm, r2, &slow); | 1292 GenerateGlobalInstanceTypeCheck(masm, r2, &slow); |
1290 // Load the property to r0. | 1293 // Load the property to r0. |
1291 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); | 1294 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); |
1292 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1, r2, r3); | 1295 __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1, r2, r3); |
1293 __ Ret(); | 1296 __ Ret(); |
1294 | 1297 |
1295 __ bind(&index_string); | 1298 __ bind(&index_string); |
1296 __ IndexFromHash(r3, key); | 1299 __ IndexFromHash(r3, key); |
1297 // Now jump to the place where smi keys are handled. | 1300 // Now jump to the place where smi keys are handled. |
1298 __ jmp(&index_smi); | 1301 __ jmp(&index_smi); |
1299 } | 1302 } |
1300 | 1303 |
1301 | 1304 |
1302 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 1305 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1520 // -- r1 : receiver | 1523 // -- r1 : receiver |
1521 // -- r2 : name | 1524 // -- r2 : name |
1522 // -- lr : return address | 1525 // -- lr : return address |
1523 // ----------------------------------- | 1526 // ----------------------------------- |
1524 | 1527 |
1525 // Get the receiver from the stack and probe the stub cache. | 1528 // Get the receiver from the stack and probe the stub cache. |
1526 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, | 1529 Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, |
1527 NOT_IN_LOOP, | 1530 NOT_IN_LOOP, |
1528 MONOMORPHIC, | 1531 MONOMORPHIC, |
1529 strict_mode); | 1532 strict_mode); |
1530 StubCache::GenerateProbe(masm, flags, r1, r2, r3, r4, r5); | 1533 |
| 1534 Isolate::Current()->stub_cache()->GenerateProbe( |
| 1535 masm, flags, r1, r2, r3, r4, r5); |
1531 | 1536 |
1532 // Cache miss: Jump to runtime. | 1537 // Cache miss: Jump to runtime. |
1533 GenerateMiss(masm); | 1538 GenerateMiss(masm); |
1534 } | 1539 } |
1535 | 1540 |
1536 | 1541 |
1537 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 1542 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
1538 // ----------- S t a t e ------------- | 1543 // ----------- S t a t e ------------- |
1539 // -- r0 : value | 1544 // -- r0 : value |
1540 // -- r1 : receiver | 1545 // -- r1 : receiver |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1604 // -- r0 : value | 1609 // -- r0 : value |
1605 // -- r1 : receiver | 1610 // -- r1 : receiver |
1606 // -- r2 : name | 1611 // -- r2 : name |
1607 // -- lr : return address | 1612 // -- lr : return address |
1608 // ----------------------------------- | 1613 // ----------------------------------- |
1609 Label miss; | 1614 Label miss; |
1610 | 1615 |
1611 GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss); | 1616 GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss); |
1612 | 1617 |
1613 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); | 1618 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); |
1614 __ IncrementCounter(&Counters::store_normal_hit, 1, r4, r5); | 1619 __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5); |
1615 __ Ret(); | 1620 __ Ret(); |
1616 | 1621 |
1617 __ bind(&miss); | 1622 __ bind(&miss); |
1618 __ IncrementCounter(&Counters::store_normal_miss, 1, r4, r5); | 1623 __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5); |
1619 GenerateMiss(masm); | 1624 GenerateMiss(masm); |
1620 } | 1625 } |
1621 | 1626 |
1622 | 1627 |
1623 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, | 1628 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, |
1624 StrictModeFlag strict_mode) { | 1629 StrictModeFlag strict_mode) { |
1625 // ----------- S t a t e ------------- | 1630 // ----------- S t a t e ------------- |
1626 // -- r0 : value | 1631 // -- r0 : value |
1627 // -- r1 : receiver | 1632 // -- r1 : receiver |
1628 // -- r2 : name | 1633 // -- r2 : name |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1758 Register reg = Assembler::GetRn(instr_at_patch); | 1763 Register reg = Assembler::GetRn(instr_at_patch); |
1759 patcher.masm()->tst(reg, Operand(kSmiTagMask)); | 1764 patcher.masm()->tst(reg, Operand(kSmiTagMask)); |
1760 patcher.EmitCondition(eq); | 1765 patcher.EmitCondition(eq); |
1761 } | 1766 } |
1762 } | 1767 } |
1763 | 1768 |
1764 | 1769 |
1765 } } // namespace v8::internal | 1770 } } // namespace v8::internal |
1766 | 1771 |
1767 #endif // V8_TARGET_ARCH_ARM | 1772 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |