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