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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 | 639 |
640 __ bind(&miss); | 640 __ bind(&miss); |
641 } | 641 } |
642 | 642 |
643 | 643 |
644 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) { | 644 static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) { |
645 // ----------- S t a t e ------------- | 645 // ----------- S t a t e ------------- |
646 // -- r2 : name | 646 // -- r2 : name |
647 // -- lr : return address | 647 // -- lr : return address |
648 // ----------------------------------- | 648 // ----------------------------------- |
| 649 Isolate* isolate = masm->isolate(); |
649 | 650 |
650 if (id == IC::kCallIC_Miss) { | 651 if (id == IC::kCallIC_Miss) { |
651 __ IncrementCounter(COUNTERS->call_miss(), 1, r3, r4); | 652 __ IncrementCounter(isolate->counters()->call_miss(), 1, r3, r4); |
652 } else { | 653 } else { |
653 __ IncrementCounter(COUNTERS->keyed_call_miss(), 1, r3, r4); | 654 __ IncrementCounter(isolate->counters()->keyed_call_miss(), 1, r3, r4); |
654 } | 655 } |
655 | 656 |
656 // Get the receiver of the function from the stack. | 657 // Get the receiver of the function from the stack. |
657 __ ldr(r3, MemOperand(sp, argc * kPointerSize)); | 658 __ ldr(r3, MemOperand(sp, argc * kPointerSize)); |
658 | 659 |
659 __ EnterInternalFrame(); | 660 __ EnterInternalFrame(); |
660 | 661 |
661 // Push the receiver and the name of the function. | 662 // Push the receiver and the name of the function. |
662 __ Push(r3, r2); | 663 __ Push(r3, r2); |
663 | 664 |
664 // Call the entry. | 665 // Call the entry. |
665 __ mov(r0, Operand(2)); | 666 __ mov(r0, Operand(2)); |
666 __ mov(r1, Operand(ExternalReference(IC_Utility(id), masm->isolate()))); | 667 __ mov(r1, Operand(ExternalReference(IC_Utility(id), isolate))); |
667 | 668 |
668 CEntryStub stub(1); | 669 CEntryStub stub(1); |
669 __ CallStub(&stub); | 670 __ CallStub(&stub); |
670 | 671 |
671 // Move result to r1 and leave the internal frame. | 672 // Move result to r1 and leave the internal frame. |
672 __ mov(r1, Operand(r0)); | 673 __ mov(r1, Operand(r0)); |
673 __ LeaveInternalFrame(); | 674 __ LeaveInternalFrame(); |
674 | 675 |
675 // Check if the receiver is a global object of some sort. | 676 // Check if the receiver is a global object of some sort. |
676 // This can happen only for regular CallIC but not KeyedCallIC. | 677 // This can happen only for regular CallIC but not KeyedCallIC. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 __ JumpIfNotSmi(r2, &check_string); | 759 __ JumpIfNotSmi(r2, &check_string); |
759 __ bind(&index_smi); | 760 __ bind(&index_smi); |
760 // Now the key is known to be a smi. This place is also jumped to from below | 761 // Now the key is known to be a smi. This place is also jumped to from below |
761 // where a numeric string is converted to a smi. | 762 // where a numeric string is converted to a smi. |
762 | 763 |
763 GenerateKeyedLoadReceiverCheck( | 764 GenerateKeyedLoadReceiverCheck( |
764 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call); | 765 masm, r1, r0, r3, Map::kHasIndexedInterceptor, &slow_call); |
765 | 766 |
766 GenerateFastArrayLoad( | 767 GenerateFastArrayLoad( |
767 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load); | 768 masm, r1, r2, r4, r3, r0, r1, &check_number_dictionary, &slow_load); |
768 __ IncrementCounter(COUNTERS->keyed_call_generic_smi_fast(), 1, r0, r3); | 769 Counters* counters = masm->isolate()->counters(); |
| 770 __ IncrementCounter(counters->keyed_call_generic_smi_fast(), 1, r0, r3); |
769 | 771 |
770 __ bind(&do_call); | 772 __ bind(&do_call); |
771 // receiver in r1 is not used after this point. | 773 // receiver in r1 is not used after this point. |
772 // r2: key | 774 // r2: key |
773 // r1: function | 775 // r1: function |
774 GenerateFunctionTailCall(masm, argc, &slow_call, r0); | 776 GenerateFunctionTailCall(masm, argc, &slow_call, r0); |
775 | 777 |
776 __ bind(&check_number_dictionary); | 778 __ bind(&check_number_dictionary); |
777 // r2: key | 779 // r2: key |
778 // r3: elements map | 780 // r3: elements map |
779 // r4: elements | 781 // r4: elements |
780 // Check whether the elements is a number dictionary. | 782 // Check whether the elements is a number dictionary. |
781 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 783 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
782 __ cmp(r3, ip); | 784 __ cmp(r3, ip); |
783 __ b(ne, &slow_load); | 785 __ b(ne, &slow_load); |
784 __ mov(r0, Operand(r2, ASR, kSmiTagSize)); | 786 __ mov(r0, Operand(r2, ASR, kSmiTagSize)); |
785 // r0: untagged index | 787 // r0: untagged index |
786 GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5); | 788 GenerateNumberDictionaryLoad(masm, &slow_load, r4, r2, r1, r0, r3, r5); |
787 __ IncrementCounter(COUNTERS->keyed_call_generic_smi_dict(), 1, r0, r3); | 789 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, r0, r3); |
788 __ jmp(&do_call); | 790 __ jmp(&do_call); |
789 | 791 |
790 __ bind(&slow_load); | 792 __ bind(&slow_load); |
791 // This branch is taken when calling KeyedCallIC_Miss is neither required | 793 // This branch is taken when calling KeyedCallIC_Miss is neither required |
792 // nor beneficial. | 794 // nor beneficial. |
793 __ IncrementCounter(COUNTERS->keyed_call_generic_slow_load(), 1, r0, r3); | 795 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, r0, r3); |
794 __ EnterInternalFrame(); | 796 __ EnterInternalFrame(); |
795 __ push(r2); // save the key | 797 __ push(r2); // save the key |
796 __ Push(r1, r2); // pass the receiver and the key | 798 __ Push(r1, r2); // pass the receiver and the key |
797 __ CallRuntime(Runtime::kKeyedGetProperty, 2); | 799 __ CallRuntime(Runtime::kKeyedGetProperty, 2); |
798 __ pop(r2); // restore the key | 800 __ pop(r2); // restore the key |
799 __ LeaveInternalFrame(); | 801 __ LeaveInternalFrame(); |
800 __ mov(r1, r0); | 802 __ mov(r1, r0); |
801 __ jmp(&do_call); | 803 __ jmp(&do_call); |
802 | 804 |
803 __ bind(&check_string); | 805 __ bind(&check_string); |
804 GenerateKeyStringCheck(masm, r2, r0, r3, &index_string, &slow_call); | 806 GenerateKeyStringCheck(masm, r2, r0, r3, &index_string, &slow_call); |
805 | 807 |
806 // The key is known to be a symbol. | 808 // The key is known to be a symbol. |
807 // If the receiver is a regular JS object with slow properties then do | 809 // If the receiver is a regular JS object with slow properties then do |
808 // a quick inline probe of the receiver's dictionary. | 810 // a quick inline probe of the receiver's dictionary. |
809 // Otherwise do the monomorphic cache probe. | 811 // Otherwise do the monomorphic cache probe. |
810 GenerateKeyedLoadReceiverCheck( | 812 GenerateKeyedLoadReceiverCheck( |
811 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); | 813 masm, r1, r0, r3, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); |
812 | 814 |
813 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset)); | 815 __ ldr(r0, FieldMemOperand(r1, JSObject::kPropertiesOffset)); |
814 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); | 816 __ ldr(r3, FieldMemOperand(r0, HeapObject::kMapOffset)); |
815 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 817 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
816 __ cmp(r3, ip); | 818 __ cmp(r3, ip); |
817 __ b(ne, &lookup_monomorphic_cache); | 819 __ b(ne, &lookup_monomorphic_cache); |
818 | 820 |
819 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); | 821 GenerateDictionaryLoad(masm, &slow_load, r0, r2, r1, r3, r4); |
820 __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_dict(), 1, r0, r3); | 822 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1, r0, r3); |
821 __ jmp(&do_call); | 823 __ jmp(&do_call); |
822 | 824 |
823 __ bind(&lookup_monomorphic_cache); | 825 __ bind(&lookup_monomorphic_cache); |
824 __ IncrementCounter(COUNTERS->keyed_call_generic_lookup_cache(), 1, r0, r3); | 826 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1, r0, r3); |
825 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); | 827 GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); |
826 // Fall through on miss. | 828 // Fall through on miss. |
827 | 829 |
828 __ bind(&slow_call); | 830 __ bind(&slow_call); |
829 // This branch is taken if: | 831 // This branch is taken if: |
830 // - the receiver requires boxing or access check, | 832 // - the receiver requires boxing or access check, |
831 // - the key is neither smi nor symbol, | 833 // - the key is neither smi nor symbol, |
832 // - the value loaded is not a function, | 834 // - the value loaded is not a function, |
833 // - there is hope that the runtime will create a monomorphic call stub | 835 // - there is hope that the runtime will create a monomorphic call stub |
834 // that will get fetched next time. | 836 // that will get fetched next time. |
835 __ IncrementCounter(COUNTERS->keyed_call_generic_slow(), 1, r0, r3); | 837 __ IncrementCounter(counters->keyed_call_generic_slow(), 1, r0, r3); |
836 GenerateMiss(masm, argc); | 838 GenerateMiss(masm, argc); |
837 | 839 |
838 __ bind(&index_string); | 840 __ bind(&index_string); |
839 __ IndexFromHash(r3, r2); | 841 __ IndexFromHash(r3, r2); |
840 // Now jump to the place where smi keys are handled. | 842 // Now jump to the place where smi keys are handled. |
841 __ jmp(&index_smi); | 843 __ jmp(&index_smi); |
842 } | 844 } |
843 | 845 |
844 | 846 |
845 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 847 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 } | 906 } |
905 | 907 |
906 | 908 |
907 void LoadIC::GenerateMiss(MacroAssembler* masm) { | 909 void LoadIC::GenerateMiss(MacroAssembler* masm) { |
908 // ----------- S t a t e ------------- | 910 // ----------- S t a t e ------------- |
909 // -- r2 : name | 911 // -- r2 : name |
910 // -- lr : return address | 912 // -- lr : return address |
911 // -- r0 : receiver | 913 // -- r0 : receiver |
912 // -- sp[0] : receiver | 914 // -- sp[0] : receiver |
913 // ----------------------------------- | 915 // ----------------------------------- |
| 916 Isolate* isolate = masm->isolate(); |
914 | 917 |
915 __ IncrementCounter(COUNTERS->load_miss(), 1, r3, r4); | 918 __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4); |
916 | 919 |
917 __ mov(r3, r0); | 920 __ mov(r3, r0); |
918 __ Push(r3, r2); | 921 __ Push(r3, r2); |
919 | 922 |
920 // Perform tail call to the entry. | 923 // Perform tail call to the entry. |
921 ExternalReference ref = | 924 ExternalReference ref = |
922 ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate()); | 925 ExternalReference(IC_Utility(kLoadIC_Miss), isolate); |
923 __ TailCallExternalReference(ref, 2, 1); | 926 __ TailCallExternalReference(ref, 2, 1); |
924 } | 927 } |
925 | 928 |
926 // Returns the code marker, or the 0 if the code is not marked. | 929 // Returns the code marker, or the 0 if the code is not marked. |
927 static inline int InlinedICSiteMarker(Address address, | 930 static inline int InlinedICSiteMarker(Address address, |
928 Address* inline_end_address) { | 931 Address* inline_end_address) { |
929 if (V8::UseCrankshaft()) return false; | 932 if (V8::UseCrankshaft()) return false; |
930 | 933 |
931 // If the instruction after the call site is not the pseudo instruction nop1 | 934 // If the instruction after the call site is not the pseudo instruction nop1 |
932 // then this is not related to an inlined in-object property load. The nop1 | 935 // then this is not related to an inlined in-object property load. The nop1 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 | 1140 |
1138 Object* KeyedLoadIC_Miss(Arguments args); | 1141 Object* KeyedLoadIC_Miss(Arguments args); |
1139 | 1142 |
1140 | 1143 |
1141 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { | 1144 void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { |
1142 // ---------- S t a t e -------------- | 1145 // ---------- S t a t e -------------- |
1143 // -- lr : return address | 1146 // -- lr : return address |
1144 // -- r0 : key | 1147 // -- r0 : key |
1145 // -- r1 : receiver | 1148 // -- r1 : receiver |
1146 // ----------------------------------- | 1149 // ----------------------------------- |
| 1150 Isolate* isolate = masm->isolate(); |
1147 | 1151 |
1148 __ IncrementCounter(COUNTERS->keyed_load_miss(), 1, r3, r4); | 1152 __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); |
1149 | 1153 |
1150 __ Push(r1, r0); | 1154 __ Push(r1, r0); |
1151 | 1155 |
1152 ExternalReference ref = | 1156 ExternalReference ref = |
1153 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 1157 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate); |
1154 __ TailCallExternalReference(ref, 2, 1); | 1158 __ TailCallExternalReference(ref, 2, 1); |
1155 } | 1159 } |
1156 | 1160 |
1157 | 1161 |
1158 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 1162 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |
1159 // ---------- S t a t e -------------- | 1163 // ---------- S t a t e -------------- |
1160 // -- lr : return address | 1164 // -- lr : return address |
1161 // -- r0 : key | 1165 // -- r0 : key |
1162 // -- r1 : receiver | 1166 // -- r1 : receiver |
1163 // ----------------------------------- | 1167 // ----------------------------------- |
1164 | 1168 |
1165 __ Push(r1, r0); | 1169 __ Push(r1, r0); |
1166 | 1170 |
1167 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); | 1171 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); |
1168 } | 1172 } |
1169 | 1173 |
1170 | 1174 |
1171 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { | 1175 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { |
1172 // ---------- S t a t e -------------- | 1176 // ---------- S t a t e -------------- |
1173 // -- lr : return address | 1177 // -- lr : return address |
1174 // -- r0 : key | 1178 // -- r0 : key |
1175 // -- r1 : receiver | 1179 // -- r1 : receiver |
1176 // ----------------------------------- | 1180 // ----------------------------------- |
1177 Label slow, check_string, index_smi, index_string, property_array_property; | 1181 Label slow, check_string, index_smi, index_string, property_array_property; |
1178 Label probe_dictionary, check_number_dictionary; | 1182 Label probe_dictionary, check_number_dictionary; |
1179 | 1183 |
1180 Register key = r0; | 1184 Register key = r0; |
1181 Register receiver = r1; | 1185 Register receiver = r1; |
1182 | 1186 |
| 1187 Isolate* isolate = masm->isolate(); |
| 1188 |
1183 // Check that the key is a smi. | 1189 // Check that the key is a smi. |
1184 __ JumpIfNotSmi(key, &check_string); | 1190 __ JumpIfNotSmi(key, &check_string); |
1185 __ bind(&index_smi); | 1191 __ bind(&index_smi); |
1186 // Now the key is known to be a smi. This place is also jumped to from below | 1192 // Now the key is known to be a smi. This place is also jumped to from below |
1187 // where a numeric string is converted to a smi. | 1193 // where a numeric string is converted to a smi. |
1188 | 1194 |
1189 GenerateKeyedLoadReceiverCheck( | 1195 GenerateKeyedLoadReceiverCheck( |
1190 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); | 1196 masm, receiver, r2, r3, Map::kHasIndexedInterceptor, &slow); |
1191 | 1197 |
1192 // Check the "has fast elements" bit in the receiver's map which is | 1198 // Check the "has fast elements" bit in the receiver's map which is |
1193 // now in r2. | 1199 // now in r2. |
1194 __ ldrb(r3, FieldMemOperand(r2, Map::kBitField2Offset)); | 1200 __ ldrb(r3, FieldMemOperand(r2, Map::kBitField2Offset)); |
1195 __ tst(r3, Operand(1 << Map::kHasFastElements)); | 1201 __ tst(r3, Operand(1 << Map::kHasFastElements)); |
1196 __ b(eq, &check_number_dictionary); | 1202 __ b(eq, &check_number_dictionary); |
1197 | 1203 |
1198 GenerateFastArrayLoad( | 1204 GenerateFastArrayLoad( |
1199 masm, receiver, key, r4, r3, r2, r0, NULL, &slow); | 1205 masm, receiver, key, r4, r3, r2, r0, NULL, &slow); |
1200 __ IncrementCounter(COUNTERS->keyed_load_generic_smi(), 1, r2, r3); | 1206 __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r2, r3); |
1201 __ Ret(); | 1207 __ Ret(); |
1202 | 1208 |
1203 __ bind(&check_number_dictionary); | 1209 __ bind(&check_number_dictionary); |
1204 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 1210 __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
1205 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); | 1211 __ ldr(r3, FieldMemOperand(r4, JSObject::kMapOffset)); |
1206 | 1212 |
1207 // Check whether the elements is a number dictionary. | 1213 // Check whether the elements is a number dictionary. |
1208 // r0: key | 1214 // r0: key |
1209 // r3: elements map | 1215 // r3: elements map |
1210 // r4: elements | 1216 // r4: elements |
1211 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 1217 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
1212 __ cmp(r3, ip); | 1218 __ cmp(r3, ip); |
1213 __ b(ne, &slow); | 1219 __ b(ne, &slow); |
1214 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); | 1220 __ mov(r2, Operand(r0, ASR, kSmiTagSize)); |
1215 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r0, r2, r3, r5); | 1221 GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r0, r2, r3, r5); |
1216 __ Ret(); | 1222 __ Ret(); |
1217 | 1223 |
1218 // Slow case, key and receiver still in r0 and r1. | 1224 // Slow case, key and receiver still in r0 and r1. |
1219 __ bind(&slow); | 1225 __ bind(&slow); |
1220 __ IncrementCounter(COUNTERS->keyed_load_generic_slow(), 1, r2, r3); | 1226 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), |
| 1227 1, r2, r3); |
1221 GenerateRuntimeGetProperty(masm); | 1228 GenerateRuntimeGetProperty(masm); |
1222 | 1229 |
1223 __ bind(&check_string); | 1230 __ bind(&check_string); |
1224 GenerateKeyStringCheck(masm, key, r2, r3, &index_string, &slow); | 1231 GenerateKeyStringCheck(masm, key, r2, r3, &index_string, &slow); |
1225 | 1232 |
1226 GenerateKeyedLoadReceiverCheck( | 1233 GenerateKeyedLoadReceiverCheck( |
1227 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); | 1234 masm, receiver, r2, r3, Map::kHasNamedInterceptor, &slow); |
1228 | 1235 |
1229 // If the receiver is a fast-case object, check the keyed lookup | 1236 // If the receiver is a fast-case object, check the keyed lookup |
1230 // cache. Otherwise probe the dictionary. | 1237 // cache. Otherwise probe the dictionary. |
1231 __ ldr(r3, FieldMemOperand(r1, JSObject::kPropertiesOffset)); | 1238 __ ldr(r3, FieldMemOperand(r1, JSObject::kPropertiesOffset)); |
1232 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); | 1239 __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset)); |
1233 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); | 1240 __ LoadRoot(ip, Heap::kHashTableMapRootIndex); |
1234 __ cmp(r4, ip); | 1241 __ cmp(r4, ip); |
1235 __ b(eq, &probe_dictionary); | 1242 __ b(eq, &probe_dictionary); |
1236 | 1243 |
1237 // Load the map of the receiver, compute the keyed lookup cache hash | 1244 // Load the map of the receiver, compute the keyed lookup cache hash |
1238 // based on 32 bits of the map pointer and the string hash. | 1245 // based on 32 bits of the map pointer and the string hash. |
1239 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1246 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1240 __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift)); | 1247 __ mov(r3, Operand(r2, ASR, KeyedLookupCache::kMapHashShift)); |
1241 __ ldr(r4, FieldMemOperand(r0, String::kHashFieldOffset)); | 1248 __ ldr(r4, FieldMemOperand(r0, String::kHashFieldOffset)); |
1242 __ eor(r3, r3, Operand(r4, ASR, String::kHashShift)); | 1249 __ eor(r3, r3, Operand(r4, ASR, String::kHashShift)); |
1243 __ And(r3, r3, Operand(KeyedLookupCache::kCapacityMask)); | 1250 __ And(r3, r3, Operand(KeyedLookupCache::kCapacityMask)); |
1244 | 1251 |
1245 // Load the key (consisting of map and symbol) from the cache and | 1252 // Load the key (consisting of map and symbol) from the cache and |
1246 // check for match. | 1253 // check for match. |
1247 ExternalReference cache_keys = | 1254 ExternalReference cache_keys = |
1248 ExternalReference::keyed_lookup_cache_keys(masm->isolate()); | 1255 ExternalReference::keyed_lookup_cache_keys(isolate); |
1249 __ mov(r4, Operand(cache_keys)); | 1256 __ mov(r4, Operand(cache_keys)); |
1250 __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1)); | 1257 __ add(r4, r4, Operand(r3, LSL, kPointerSizeLog2 + 1)); |
1251 __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); // Move r4 to symbol. | 1258 __ ldr(r5, MemOperand(r4, kPointerSize, PostIndex)); // Move r4 to symbol. |
1252 __ cmp(r2, r5); | 1259 __ cmp(r2, r5); |
1253 __ b(ne, &slow); | 1260 __ b(ne, &slow); |
1254 __ ldr(r5, MemOperand(r4)); | 1261 __ ldr(r5, MemOperand(r4)); |
1255 __ cmp(r0, r5); | 1262 __ cmp(r0, r5); |
1256 __ b(ne, &slow); | 1263 __ b(ne, &slow); |
1257 | 1264 |
1258 // Get field offset. | 1265 // Get field offset. |
1259 // r0 : key | 1266 // r0 : key |
1260 // r1 : receiver | 1267 // r1 : receiver |
1261 // r2 : receiver's map | 1268 // r2 : receiver's map |
1262 // r3 : lookup cache index | 1269 // r3 : lookup cache index |
1263 ExternalReference cache_field_offsets = | 1270 ExternalReference cache_field_offsets = |
1264 ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); | 1271 ExternalReference::keyed_lookup_cache_field_offsets(isolate); |
1265 __ mov(r4, Operand(cache_field_offsets)); | 1272 __ mov(r4, Operand(cache_field_offsets)); |
1266 __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); | 1273 __ ldr(r5, MemOperand(r4, r3, LSL, kPointerSizeLog2)); |
1267 __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); | 1274 __ ldrb(r6, FieldMemOperand(r2, Map::kInObjectPropertiesOffset)); |
1268 __ sub(r5, r5, r6, SetCC); | 1275 __ sub(r5, r5, r6, SetCC); |
1269 __ b(ge, &property_array_property); | 1276 __ b(ge, &property_array_property); |
1270 | 1277 |
1271 // Load in-object property. | 1278 // Load in-object property. |
1272 __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); | 1279 __ ldrb(r6, FieldMemOperand(r2, Map::kInstanceSizeOffset)); |
1273 __ add(r6, r6, r5); // Index from start of object. | 1280 __ add(r6, r6, r5); // Index from start of object. |
1274 __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. | 1281 __ sub(r1, r1, Operand(kHeapObjectTag)); // Remove the heap tag. |
1275 __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2)); | 1282 __ ldr(r0, MemOperand(r1, r6, LSL, kPointerSizeLog2)); |
1276 __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3); | 1283 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), |
| 1284 1, r2, r3); |
1277 __ Ret(); | 1285 __ Ret(); |
1278 | 1286 |
1279 // Load property array property. | 1287 // Load property array property. |
1280 __ bind(&property_array_property); | 1288 __ bind(&property_array_property); |
1281 __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); | 1289 __ ldr(r1, FieldMemOperand(r1, JSObject::kPropertiesOffset)); |
1282 __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); | 1290 __ add(r1, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
1283 __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); | 1291 __ ldr(r0, MemOperand(r1, r5, LSL, kPointerSizeLog2)); |
1284 __ IncrementCounter(COUNTERS->keyed_load_generic_lookup_cache(), 1, r2, r3); | 1292 __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), |
| 1293 1, r2, r3); |
1285 __ Ret(); | 1294 __ Ret(); |
1286 | 1295 |
1287 // Do a quick inline probe of the receiver's dictionary, if it | 1296 // Do a quick inline probe of the receiver's dictionary, if it |
1288 // exists. | 1297 // exists. |
1289 __ bind(&probe_dictionary); | 1298 __ bind(&probe_dictionary); |
1290 // r1: receiver | 1299 // r1: receiver |
1291 // r0: key | 1300 // r0: key |
1292 // r3: elements | 1301 // r3: elements |
1293 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); | 1302 __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
1294 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); | 1303 __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
1295 GenerateGlobalInstanceTypeCheck(masm, r2, &slow); | 1304 GenerateGlobalInstanceTypeCheck(masm, r2, &slow); |
1296 // Load the property to r0. | 1305 // Load the property to r0. |
1297 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); | 1306 GenerateDictionaryLoad(masm, &slow, r3, r0, r0, r2, r4); |
1298 __ IncrementCounter(COUNTERS->keyed_load_generic_symbol(), 1, r2, r3); | 1307 __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), |
| 1308 1, r2, r3); |
1299 __ Ret(); | 1309 __ Ret(); |
1300 | 1310 |
1301 __ bind(&index_string); | 1311 __ bind(&index_string); |
1302 __ IndexFromHash(r3, key); | 1312 __ IndexFromHash(r3, key); |
1303 // Now jump to the place where smi keys are handled. | 1313 // Now jump to the place where smi keys are handled. |
1304 __ jmp(&index_smi); | 1314 __ jmp(&index_smi); |
1305 } | 1315 } |
1306 | 1316 |
1307 | 1317 |
1308 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 1318 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1618 // -- r0 : value | 1628 // -- r0 : value |
1619 // -- r1 : receiver | 1629 // -- r1 : receiver |
1620 // -- r2 : name | 1630 // -- r2 : name |
1621 // -- lr : return address | 1631 // -- lr : return address |
1622 // ----------------------------------- | 1632 // ----------------------------------- |
1623 Label miss; | 1633 Label miss; |
1624 | 1634 |
1625 GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss); | 1635 GenerateStringDictionaryReceiverCheck(masm, r1, r3, r4, r5, &miss); |
1626 | 1636 |
1627 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); | 1637 GenerateDictionaryStore(masm, &miss, r3, r2, r0, r4, r5); |
1628 __ IncrementCounter(COUNTERS->store_normal_hit(), 1, r4, r5); | 1638 Counters* counters = masm->isolate()->counters(); |
| 1639 __ IncrementCounter(counters->store_normal_hit(), |
| 1640 1, r4, r5); |
1629 __ Ret(); | 1641 __ Ret(); |
1630 | 1642 |
1631 __ bind(&miss); | 1643 __ bind(&miss); |
1632 __ IncrementCounter(COUNTERS->store_normal_miss(), 1, r4, r5); | 1644 __ IncrementCounter(counters->store_normal_miss(), 1, r4, r5); |
1633 GenerateMiss(masm); | 1645 GenerateMiss(masm); |
1634 } | 1646 } |
1635 | 1647 |
1636 | 1648 |
1637 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, | 1649 void StoreIC::GenerateGlobalProxy(MacroAssembler* masm, |
1638 StrictModeFlag strict_mode) { | 1650 StrictModeFlag strict_mode) { |
1639 // ----------- S t a t e ------------- | 1651 // ----------- S t a t e ------------- |
1640 // -- r0 : value | 1652 // -- r0 : value |
1641 // -- r1 : receiver | 1653 // -- r1 : receiver |
1642 // -- r2 : name | 1654 // -- r2 : name |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 Register reg = Assembler::GetRn(instr_at_patch); | 1784 Register reg = Assembler::GetRn(instr_at_patch); |
1773 patcher.masm()->tst(reg, Operand(kSmiTagMask)); | 1785 patcher.masm()->tst(reg, Operand(kSmiTagMask)); |
1774 patcher.EmitCondition(eq); | 1786 patcher.EmitCondition(eq); |
1775 } | 1787 } |
1776 } | 1788 } |
1777 | 1789 |
1778 | 1790 |
1779 } } // namespace v8::internal | 1791 } } // namespace v8::internal |
1780 | 1792 |
1781 #endif // V8_TARGET_ARCH_ARM | 1793 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |