OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 | 123 |
124 // Miss: fall through. | 124 // Miss: fall through. |
125 __ bind(&miss); | 125 __ bind(&miss); |
126 } | 126 } |
127 | 127 |
128 | 128 |
129 // Helper function used to check that the dictionary doesn't contain | 129 // Helper function used to check that the dictionary doesn't contain |
130 // the property. This function may return false negatives, so miss_label | 130 // the property. This function may return false negatives, so miss_label |
131 // must always call a backup property check that is complete. | 131 // must always call a backup property check that is complete. |
132 // This function is safe to call if the receiver has fast properties. | 132 // This function is safe to call if the receiver has fast properties. |
133 // Name must be internalized and receiver must be a heap object. | 133 // Name must be unique and receiver must be a heap object. |
134 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 134 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
135 Label* miss_label, | 135 Label* miss_label, |
136 Register receiver, | 136 Register receiver, |
137 Handle<String> name, | 137 Handle<Name> name, |
138 Register scratch0, | 138 Register scratch0, |
139 Register scratch1) { | 139 Register scratch1) { |
140 ASSERT(name->IsInternalizedString()); | 140 ASSERT(name->IsUniqueName()); |
141 Counters* counters = masm->isolate()->counters(); | 141 Counters* counters = masm->isolate()->counters(); |
142 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 142 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
143 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 143 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
144 | 144 |
145 Label done; | 145 Label done; |
146 | 146 |
147 const int kInterceptorOrAccessCheckNeededMask = | 147 const int kInterceptorOrAccessCheckNeededMask = |
148 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 148 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
149 | 149 |
150 // Bail out if the receiver has a named interceptor or requires access checks. | 150 // Bail out if the receiver has a named interceptor or requires access checks. |
(...skipping 15 matching lines...) Expand all Loading... |
166 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 166 __ ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
167 Register tmp = properties; | 167 Register tmp = properties; |
168 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 168 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
169 __ cmp(map, tmp); | 169 __ cmp(map, tmp); |
170 __ b(ne, miss_label); | 170 __ b(ne, miss_label); |
171 | 171 |
172 // Restore the temporarily used register. | 172 // Restore the temporarily used register. |
173 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 173 __ ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
174 | 174 |
175 | 175 |
176 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 176 NameDictionaryLookupStub::GenerateNegativeLookup(masm, |
177 miss_label, | 177 miss_label, |
178 &done, | 178 &done, |
179 receiver, | 179 receiver, |
180 properties, | 180 properties, |
181 name, | 181 name, |
182 scratch1); | 182 scratch1); |
183 __ bind(&done); | 183 __ bind(&done); |
184 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 184 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
185 } | 185 } |
186 | 186 |
187 | 187 |
188 void StubCache::GenerateProbe(MacroAssembler* masm, | 188 void StubCache::GenerateProbe(MacroAssembler* masm, |
189 Code::Flags flags, | 189 Code::Flags flags, |
190 Register receiver, | 190 Register receiver, |
191 Register name, | 191 Register name, |
192 Register scratch, | 192 Register scratch, |
(...skipping 28 matching lines...) Expand all Loading... |
221 ASSERT(!extra3.is(no_reg)); | 221 ASSERT(!extra3.is(no_reg)); |
222 | 222 |
223 Counters* counters = masm->isolate()->counters(); | 223 Counters* counters = masm->isolate()->counters(); |
224 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, | 224 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, |
225 extra2, extra3); | 225 extra2, extra3); |
226 | 226 |
227 // Check that the receiver isn't a smi. | 227 // Check that the receiver isn't a smi. |
228 __ JumpIfSmi(receiver, &miss); | 228 __ JumpIfSmi(receiver, &miss); |
229 | 229 |
230 // Get the map of the receiver and compute the hash. | 230 // Get the map of the receiver and compute the hash. |
231 __ ldr(scratch, FieldMemOperand(name, String::kHashFieldOffset)); | 231 __ ldr(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); |
232 __ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 232 __ ldr(ip, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
233 __ add(scratch, scratch, Operand(ip)); | 233 __ add(scratch, scratch, Operand(ip)); |
234 uint32_t mask = kPrimaryTableSize - 1; | 234 uint32_t mask = kPrimaryTableSize - 1; |
235 // We shift out the last two bits because they are not part of the hash and | 235 // We shift out the last two bits because they are not part of the hash and |
236 // they are always 01 for maps. | 236 // they are always 01 for maps. |
237 __ mov(scratch, Operand(scratch, LSR, kHeapObjectTagSize)); | 237 __ mov(scratch, Operand(scratch, LSR, kHeapObjectTagSize)); |
238 // Mask down the eor argument to the minimum to keep the immediate | 238 // Mask down the eor argument to the minimum to keep the immediate |
239 // ARM-encodable. | 239 // ARM-encodable. |
240 __ eor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); | 240 __ eor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); |
241 // Prefer and_ to ubfx here because ubfx takes 2 cycles. | 241 // Prefer and_ to ubfx here because ubfx takes 2 cycles. |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 435 |
436 | 436 |
437 // Generate StoreField code, value is passed in r0 register. | 437 // Generate StoreField code, value is passed in r0 register. |
438 // When leaving generated code after success, the receiver_reg and name_reg | 438 // When leaving generated code after success, the receiver_reg and name_reg |
439 // may be clobbered. Upon branch to miss_label, the receiver and name | 439 // may be clobbered. Upon branch to miss_label, the receiver and name |
440 // registers have their original values. | 440 // registers have their original values. |
441 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 441 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
442 Handle<JSObject> object, | 442 Handle<JSObject> object, |
443 int index, | 443 int index, |
444 Handle<Map> transition, | 444 Handle<Map> transition, |
445 Handle<String> name, | 445 Handle<Name> name, |
446 Register receiver_reg, | 446 Register receiver_reg, |
447 Register name_reg, | 447 Register name_reg, |
448 Register scratch1, | 448 Register scratch1, |
449 Register scratch2, | 449 Register scratch2, |
450 Label* miss_label) { | 450 Label* miss_label) { |
451 // r0 : value | 451 // r0 : value |
452 Label exit; | 452 Label exit; |
453 | 453 |
454 LookupResult lookup(masm->isolate()); | 454 LookupResult lookup(masm->isolate()); |
455 object->Lookup(*name, &lookup); | 455 object->Lookup(*name, &lookup); |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 Register name, | 766 Register name, |
767 Code::ExtraICState extra_ic_state) | 767 Code::ExtraICState extra_ic_state) |
768 : stub_compiler_(stub_compiler), | 768 : stub_compiler_(stub_compiler), |
769 arguments_(arguments), | 769 arguments_(arguments), |
770 name_(name), | 770 name_(name), |
771 extra_ic_state_(extra_ic_state) {} | 771 extra_ic_state_(extra_ic_state) {} |
772 | 772 |
773 void Compile(MacroAssembler* masm, | 773 void Compile(MacroAssembler* masm, |
774 Handle<JSObject> object, | 774 Handle<JSObject> object, |
775 Handle<JSObject> holder, | 775 Handle<JSObject> holder, |
776 Handle<String> name, | 776 Handle<Name> name, |
777 LookupResult* lookup, | 777 LookupResult* lookup, |
778 Register receiver, | 778 Register receiver, |
779 Register scratch1, | 779 Register scratch1, |
780 Register scratch2, | 780 Register scratch2, |
781 Register scratch3, | 781 Register scratch3, |
782 Label* miss) { | 782 Label* miss) { |
783 ASSERT(holder->HasNamedInterceptor()); | 783 ASSERT(holder->HasNamedInterceptor()); |
784 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 784 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
785 | 785 |
786 // Check that the receiver isn't a smi. | 786 // Check that the receiver isn't a smi. |
(...skipping 10 matching lines...) Expand all Loading... |
797 | 797 |
798 private: | 798 private: |
799 void CompileCacheable(MacroAssembler* masm, | 799 void CompileCacheable(MacroAssembler* masm, |
800 Handle<JSObject> object, | 800 Handle<JSObject> object, |
801 Register receiver, | 801 Register receiver, |
802 Register scratch1, | 802 Register scratch1, |
803 Register scratch2, | 803 Register scratch2, |
804 Register scratch3, | 804 Register scratch3, |
805 Handle<JSObject> interceptor_holder, | 805 Handle<JSObject> interceptor_holder, |
806 LookupResult* lookup, | 806 LookupResult* lookup, |
807 Handle<String> name, | 807 Handle<Name> name, |
808 const CallOptimization& optimization, | 808 const CallOptimization& optimization, |
809 Label* miss_label) { | 809 Label* miss_label) { |
810 ASSERT(optimization.is_constant_call()); | 810 ASSERT(optimization.is_constant_call()); |
811 ASSERT(!lookup->holder()->IsGlobalObject()); | 811 ASSERT(!lookup->holder()->IsGlobalObject()); |
812 Counters* counters = masm->isolate()->counters(); | 812 Counters* counters = masm->isolate()->counters(); |
813 int depth1 = kInvalidProtoDepth; | 813 int depth1 = kInvalidProtoDepth; |
814 int depth2 = kInvalidProtoDepth; | 814 int depth2 = kInvalidProtoDepth; |
815 bool can_do_fast_api_call = false; | 815 bool can_do_fast_api_call = false; |
816 if (optimization.is_simple_api_call() && | 816 if (optimization.is_simple_api_call() && |
817 !lookup->holder()->IsGlobalObject()) { | 817 !lookup->holder()->IsGlobalObject()) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 FreeSpaceForFastApiCall(masm); | 891 FreeSpaceForFastApiCall(masm); |
892 } | 892 } |
893 } | 893 } |
894 | 894 |
895 void CompileRegular(MacroAssembler* masm, | 895 void CompileRegular(MacroAssembler* masm, |
896 Handle<JSObject> object, | 896 Handle<JSObject> object, |
897 Register receiver, | 897 Register receiver, |
898 Register scratch1, | 898 Register scratch1, |
899 Register scratch2, | 899 Register scratch2, |
900 Register scratch3, | 900 Register scratch3, |
901 Handle<String> name, | 901 Handle<Name> name, |
902 Handle<JSObject> interceptor_holder, | 902 Handle<JSObject> interceptor_holder, |
903 Label* miss_label) { | 903 Label* miss_label) { |
904 Register holder = | 904 Register holder = |
905 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, | 905 stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, |
906 scratch1, scratch2, scratch3, | 906 scratch1, scratch2, scratch3, |
907 name, miss_label); | 907 name, miss_label); |
908 | 908 |
909 // Call a runtime function to load the interceptor property. | 909 // Call a runtime function to load the interceptor property. |
910 FrameScope scope(masm, StackFrame::INTERNAL); | 910 FrameScope scope(masm, StackFrame::INTERNAL); |
911 // Save the name_ register across the call. | 911 // Save the name_ register across the call. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
948 Register name_; | 948 Register name_; |
949 Code::ExtraICState extra_ic_state_; | 949 Code::ExtraICState extra_ic_state_; |
950 }; | 950 }; |
951 | 951 |
952 | 952 |
953 // Generate code to check that a global property cell is empty. Create | 953 // Generate code to check that a global property cell is empty. Create |
954 // the property cell at compilation time if no cell exists for the | 954 // the property cell at compilation time if no cell exists for the |
955 // property. | 955 // property. |
956 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 956 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
957 Handle<GlobalObject> global, | 957 Handle<GlobalObject> global, |
958 Handle<String> name, | 958 Handle<Name> name, |
959 Register scratch, | 959 Register scratch, |
960 Label* miss) { | 960 Label* miss) { |
961 Handle<JSGlobalPropertyCell> cell = | 961 Handle<JSGlobalPropertyCell> cell = |
962 GlobalObject::EnsurePropertyCell(global, name); | 962 GlobalObject::EnsurePropertyCell(global, name); |
963 ASSERT(cell->value()->IsTheHole()); | 963 ASSERT(cell->value()->IsTheHole()); |
964 __ mov(scratch, Operand(cell)); | 964 __ mov(scratch, Operand(cell)); |
965 __ ldr(scratch, | 965 __ ldr(scratch, |
966 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 966 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
967 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 967 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
968 __ cmp(scratch, ip); | 968 __ cmp(scratch, ip); |
969 __ b(ne, miss); | 969 __ b(ne, miss); |
970 } | 970 } |
971 | 971 |
972 | 972 |
973 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 973 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
974 // from object to (but not including) holder. | 974 // from object to (but not including) holder. |
975 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 975 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
976 Handle<JSObject> object, | 976 Handle<JSObject> object, |
977 Handle<JSObject> holder, | 977 Handle<JSObject> holder, |
978 Handle<String> name, | 978 Handle<Name> name, |
979 Register scratch, | 979 Register scratch, |
980 Label* miss) { | 980 Label* miss) { |
981 Handle<JSObject> current = object; | 981 Handle<JSObject> current = object; |
982 while (!current.is_identical_to(holder)) { | 982 while (!current.is_identical_to(holder)) { |
983 if (current->IsGlobalObject()) { | 983 if (current->IsGlobalObject()) { |
984 GenerateCheckPropertyCell(masm, | 984 GenerateCheckPropertyCell(masm, |
985 Handle<GlobalObject>::cast(current), | 985 Handle<GlobalObject>::cast(current), |
986 name, | 986 name, |
987 scratch, | 987 scratch, |
988 miss); | 988 miss); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 #undef __ | 1065 #undef __ |
1066 #define __ ACCESS_MASM(masm()) | 1066 #define __ ACCESS_MASM(masm()) |
1067 | 1067 |
1068 | 1068 |
1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1069 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
1070 Register object_reg, | 1070 Register object_reg, |
1071 Handle<JSObject> holder, | 1071 Handle<JSObject> holder, |
1072 Register holder_reg, | 1072 Register holder_reg, |
1073 Register scratch1, | 1073 Register scratch1, |
1074 Register scratch2, | 1074 Register scratch2, |
1075 Handle<String> name, | 1075 Handle<Name> name, |
1076 int save_at_depth, | 1076 int save_at_depth, |
1077 Label* miss) { | 1077 Label* miss) { |
1078 // Make sure there's no overlap between holder and object registers. | 1078 // Make sure there's no overlap between holder and object registers. |
1079 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1079 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1080 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1080 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1081 && !scratch2.is(scratch1)); | 1081 && !scratch2.is(scratch1)); |
1082 | 1082 |
1083 // Keep track of the current object in register reg. | 1083 // Keep track of the current object in register reg. |
1084 Register reg = object_reg; | 1084 Register reg = object_reg; |
1085 int depth = 0; | 1085 int depth = 0; |
1086 | 1086 |
1087 if (save_at_depth == depth) { | 1087 if (save_at_depth == depth) { |
1088 __ str(reg, MemOperand(sp)); | 1088 __ str(reg, MemOperand(sp)); |
1089 } | 1089 } |
1090 | 1090 |
1091 // Check the maps in the prototype chain. | 1091 // Check the maps in the prototype chain. |
1092 // Traverse the prototype chain from the object and do map checks. | 1092 // Traverse the prototype chain from the object and do map checks. |
1093 Handle<JSObject> current = object; | 1093 Handle<JSObject> current = object; |
1094 while (!current.is_identical_to(holder)) { | 1094 while (!current.is_identical_to(holder)) { |
1095 ++depth; | 1095 ++depth; |
1096 | 1096 |
1097 // Only global objects and objects that do not require access | 1097 // Only global objects and objects that do not require access |
1098 // checks are allowed in stubs. | 1098 // checks are allowed in stubs. |
1099 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1099 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
1100 | 1100 |
1101 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1101 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
1102 if (!current->HasFastProperties() && | 1102 if (!current->HasFastProperties() && |
1103 !current->IsJSGlobalObject() && | 1103 !current->IsJSGlobalObject() && |
1104 !current->IsJSGlobalProxy()) { | 1104 !current->IsJSGlobalProxy()) { |
1105 if (!name->IsInternalizedString()) { | 1105 if (!name->IsUniqueName()) { |
1106 name = factory()->InternalizeString(name); | 1106 ASSERT(name->IsString()); |
| 1107 name = factory()->InternalizeString(Handle<String>::cast(name)); |
1107 } | 1108 } |
1108 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1109 ASSERT(current->property_dictionary()->FindEntry(*name) == |
1109 StringDictionary::kNotFound); | 1110 NameDictionary::kNotFound); |
1110 | 1111 |
1111 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1112 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
1112 scratch1, scratch2); | 1113 scratch1, scratch2); |
1113 | 1114 |
1114 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1115 __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1115 reg = holder_reg; // From now on the object will be in holder_reg. | 1116 reg = holder_reg; // From now on the object will be in holder_reg. |
1116 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1117 __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1117 } else { | 1118 } else { |
1118 Handle<Map> current_map(current->map()); | 1119 Handle<Map> current_map(current->map()); |
1119 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, | 1120 __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK, |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 } | 1169 } |
1169 | 1170 |
1170 | 1171 |
1171 void StubCompiler::GenerateLoadField(Handle<JSObject> object, | 1172 void StubCompiler::GenerateLoadField(Handle<JSObject> object, |
1172 Handle<JSObject> holder, | 1173 Handle<JSObject> holder, |
1173 Register receiver, | 1174 Register receiver, |
1174 Register scratch1, | 1175 Register scratch1, |
1175 Register scratch2, | 1176 Register scratch2, |
1176 Register scratch3, | 1177 Register scratch3, |
1177 PropertyIndex index, | 1178 PropertyIndex index, |
1178 Handle<String> name, | 1179 Handle<Name> name, |
1179 Label* miss) { | 1180 Label* miss) { |
1180 // Check that the receiver isn't a smi. | 1181 // Check that the receiver isn't a smi. |
1181 __ JumpIfSmi(receiver, miss); | 1182 __ JumpIfSmi(receiver, miss); |
1182 | 1183 |
1183 // Check that the maps haven't changed. | 1184 // Check that the maps haven't changed. |
1184 Register reg = CheckPrototypes( | 1185 Register reg = CheckPrototypes( |
1185 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1186 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1186 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); | 1187 GenerateFastPropertyLoad(masm(), r0, reg, holder, index); |
1187 __ Ret(); | 1188 __ Ret(); |
1188 } | 1189 } |
1189 | 1190 |
1190 | 1191 |
1191 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, | 1192 void StubCompiler::GenerateLoadConstant(Handle<JSObject> object, |
1192 Handle<JSObject> holder, | 1193 Handle<JSObject> holder, |
1193 Register receiver, | 1194 Register receiver, |
1194 Register scratch1, | 1195 Register scratch1, |
1195 Register scratch2, | 1196 Register scratch2, |
1196 Register scratch3, | 1197 Register scratch3, |
1197 Handle<JSFunction> value, | 1198 Handle<JSFunction> value, |
1198 Handle<String> name, | 1199 Handle<Name> name, |
1199 Label* miss) { | 1200 Label* miss) { |
1200 // Check that the receiver isn't a smi. | 1201 // Check that the receiver isn't a smi. |
1201 __ JumpIfSmi(receiver, miss); | 1202 __ JumpIfSmi(receiver, miss); |
1202 | 1203 |
1203 // Check that the maps haven't changed. | 1204 // Check that the maps haven't changed. |
1204 CheckPrototypes( | 1205 CheckPrototypes( |
1205 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); | 1206 object, receiver, holder, scratch1, scratch2, scratch3, name, miss); |
1206 | 1207 |
1207 // Return the constant value. | 1208 // Return the constant value. |
1208 __ LoadHeapObject(r0, value); | 1209 __ LoadHeapObject(r0, value); |
1209 __ Ret(); | 1210 __ Ret(); |
1210 } | 1211 } |
1211 | 1212 |
1212 | 1213 |
1213 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, | 1214 void StubCompiler::GenerateDictionaryLoadCallback(Register receiver, |
1214 Register name_reg, | 1215 Register name_reg, |
1215 Register scratch1, | 1216 Register scratch1, |
1216 Register scratch2, | 1217 Register scratch2, |
1217 Register scratch3, | 1218 Register scratch3, |
1218 Handle<AccessorInfo> callback, | 1219 Handle<AccessorInfo> callback, |
1219 Handle<String> name, | 1220 Handle<Name> name, |
1220 Label* miss) { | 1221 Label* miss) { |
1221 ASSERT(!receiver.is(scratch1)); | 1222 ASSERT(!receiver.is(scratch1)); |
1222 ASSERT(!receiver.is(scratch2)); | 1223 ASSERT(!receiver.is(scratch2)); |
1223 ASSERT(!receiver.is(scratch3)); | 1224 ASSERT(!receiver.is(scratch3)); |
1224 | 1225 |
1225 // Load the properties dictionary. | 1226 // Load the properties dictionary. |
1226 Register dictionary = scratch1; | 1227 Register dictionary = scratch1; |
1227 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 1228 __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
1228 | 1229 |
1229 // Probe the dictionary. | 1230 // Probe the dictionary. |
1230 Label probe_done; | 1231 Label probe_done; |
1231 StringDictionaryLookupStub::GeneratePositiveLookup(masm(), | 1232 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
1232 miss, | 1233 miss, |
1233 &probe_done, | 1234 &probe_done, |
1234 dictionary, | 1235 dictionary, |
1235 name_reg, | 1236 name_reg, |
1236 scratch2, | 1237 scratch2, |
1237 scratch3); | 1238 scratch3); |
1238 __ bind(&probe_done); | 1239 __ bind(&probe_done); |
1239 | 1240 |
1240 // If probing finds an entry in the dictionary, scratch3 contains the | 1241 // If probing finds an entry in the dictionary, scratch3 contains the |
1241 // pointer into the dictionary. Check that the value is the callback. | 1242 // pointer into the dictionary. Check that the value is the callback. |
1242 Register pointer = scratch3; | 1243 Register pointer = scratch3; |
1243 const int kElementsStartOffset = StringDictionary::kHeaderSize + | 1244 const int kElementsStartOffset = NameDictionary::kHeaderSize + |
1244 StringDictionary::kElementsStartIndex * kPointerSize; | 1245 NameDictionary::kElementsStartIndex * kPointerSize; |
1245 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1246 const int kValueOffset = kElementsStartOffset + kPointerSize; |
1246 __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); | 1247 __ ldr(scratch2, FieldMemOperand(pointer, kValueOffset)); |
1247 __ cmp(scratch2, Operand(callback)); | 1248 __ cmp(scratch2, Operand(callback)); |
1248 __ b(ne, miss); | 1249 __ b(ne, miss); |
1249 } | 1250 } |
1250 | 1251 |
1251 | 1252 |
1252 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, | 1253 void StubCompiler::GenerateLoadCallback(Handle<JSObject> object, |
1253 Handle<JSObject> holder, | 1254 Handle<JSObject> holder, |
1254 Register receiver, | 1255 Register receiver, |
1255 Register name_reg, | 1256 Register name_reg, |
1256 Register scratch1, | 1257 Register scratch1, |
1257 Register scratch2, | 1258 Register scratch2, |
1258 Register scratch3, | 1259 Register scratch3, |
1259 Register scratch4, | 1260 Register scratch4, |
1260 Handle<AccessorInfo> callback, | 1261 Handle<AccessorInfo> callback, |
1261 Handle<String> name, | 1262 Handle<Name> name, |
1262 Label* miss) { | 1263 Label* miss) { |
1263 // Check that the receiver isn't a smi. | 1264 // Check that the receiver isn't a smi. |
1264 __ JumpIfSmi(receiver, miss); | 1265 __ JumpIfSmi(receiver, miss); |
1265 | 1266 |
1266 // Check that the maps haven't changed. | 1267 // Check that the maps haven't changed. |
1267 Register reg = CheckPrototypes(object, receiver, holder, scratch1, | 1268 Register reg = CheckPrototypes(object, receiver, holder, scratch1, |
1268 scratch2, scratch3, name, miss); | 1269 scratch2, scratch3, name, miss); |
1269 | 1270 |
1270 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1271 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
1271 GenerateDictionaryLoadCallback( | 1272 GenerateDictionaryLoadCallback( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 | 1309 |
1309 | 1310 |
1310 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, | 1311 void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object, |
1311 Handle<JSObject> interceptor_holder, | 1312 Handle<JSObject> interceptor_holder, |
1312 LookupResult* lookup, | 1313 LookupResult* lookup, |
1313 Register receiver, | 1314 Register receiver, |
1314 Register name_reg, | 1315 Register name_reg, |
1315 Register scratch1, | 1316 Register scratch1, |
1316 Register scratch2, | 1317 Register scratch2, |
1317 Register scratch3, | 1318 Register scratch3, |
1318 Handle<String> name, | 1319 Handle<Name> name, |
1319 Label* miss) { | 1320 Label* miss) { |
1320 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1321 ASSERT(interceptor_holder->HasNamedInterceptor()); |
1321 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1322 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
1322 | 1323 |
1323 // Check that the receiver isn't a smi. | 1324 // Check that the receiver isn't a smi. |
1324 __ JumpIfSmi(receiver, miss); | 1325 __ JumpIfSmi(receiver, miss); |
1325 | 1326 |
1326 // So far the most popular follow ups for interceptor loads are FIELD | 1327 // So far the most popular follow ups for interceptor loads are FIELD |
1327 // and CALLBACKS, so inline only them, other cases may be added | 1328 // and CALLBACKS, so inline only them, other cases may be added |
1328 // later. | 1329 // later. |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1449 name_reg, interceptor_holder); | 1450 name_reg, interceptor_holder); |
1450 | 1451 |
1451 ExternalReference ref = | 1452 ExternalReference ref = |
1452 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), | 1453 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), |
1453 masm()->isolate()); | 1454 masm()->isolate()); |
1454 __ TailCallExternalReference(ref, 6, 1); | 1455 __ TailCallExternalReference(ref, 6, 1); |
1455 } | 1456 } |
1456 } | 1457 } |
1457 | 1458 |
1458 | 1459 |
1459 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1460 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
1460 if (kind_ == Code::KEYED_CALL_IC) { | 1461 if (kind_ == Code::KEYED_CALL_IC) { |
1461 __ cmp(r2, Operand(name)); | 1462 __ cmp(r2, Operand(name)); |
1462 __ b(ne, miss); | 1463 __ b(ne, miss); |
1463 } | 1464 } |
1464 } | 1465 } |
1465 | 1466 |
1466 | 1467 |
1467 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | 1468 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, |
1468 Handle<JSObject> holder, | 1469 Handle<JSObject> holder, |
1469 Handle<String> name, | 1470 Handle<Name> name, |
1470 Label* miss) { | 1471 Label* miss) { |
1471 ASSERT(holder->IsGlobalObject()); | 1472 ASSERT(holder->IsGlobalObject()); |
1472 | 1473 |
1473 // Get the number of arguments. | 1474 // Get the number of arguments. |
1474 const int argc = arguments().immediate(); | 1475 const int argc = arguments().immediate(); |
1475 | 1476 |
1476 // Get the receiver from the stack. | 1477 // Get the receiver from the stack. |
1477 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); | 1478 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
1478 | 1479 |
1479 // Check that the maps haven't changed. | 1480 // Check that the maps haven't changed. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1518 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1518 kind_, | 1519 kind_, |
1519 extra_state_); | 1520 extra_state_); |
1520 __ Jump(code, RelocInfo::CODE_TARGET); | 1521 __ Jump(code, RelocInfo::CODE_TARGET); |
1521 } | 1522 } |
1522 | 1523 |
1523 | 1524 |
1524 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1525 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1525 Handle<JSObject> holder, | 1526 Handle<JSObject> holder, |
1526 PropertyIndex index, | 1527 PropertyIndex index, |
1527 Handle<String> name) { | 1528 Handle<Name> name) { |
1528 // ----------- S t a t e ------------- | 1529 // ----------- S t a t e ------------- |
1529 // -- r2 : name | 1530 // -- r2 : name |
1530 // -- lr : return address | 1531 // -- lr : return address |
1531 // ----------------------------------- | 1532 // ----------------------------------- |
1532 Label miss; | 1533 Label miss; |
1533 | 1534 |
1534 GenerateNameCheck(name, &miss); | 1535 GenerateNameCheck(name, &miss); |
1535 | 1536 |
1536 const int argc = arguments().immediate(); | 1537 const int argc = arguments().immediate(); |
1537 | 1538 |
(...skipping 895 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2433 GenerateMissBranch(); | 2434 GenerateMissBranch(); |
2434 | 2435 |
2435 // Return the generated code. | 2436 // Return the generated code. |
2436 return GetCode(function); | 2437 return GetCode(function); |
2437 } | 2438 } |
2438 | 2439 |
2439 | 2440 |
2440 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, | 2441 Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object, |
2441 Handle<JSObject> holder, | 2442 Handle<JSObject> holder, |
2442 Handle<JSFunction> function, | 2443 Handle<JSFunction> function, |
2443 Handle<String> name, | 2444 Handle<Name> name, |
2444 CheckType check) { | 2445 CheckType check) { |
2445 // ----------- S t a t e ------------- | 2446 // ----------- S t a t e ------------- |
2446 // -- r2 : name | 2447 // -- r2 : name |
2447 // -- lr : return address | 2448 // -- lr : return address |
2448 // ----------------------------------- | 2449 // ----------------------------------- |
2449 if (HasCustomCallGenerator(function)) { | 2450 if (HasCustomCallGenerator(function)) { |
2450 Handle<Code> code = CompileCustomCall(object, holder, | 2451 Handle<Code> code = CompileCustomCall(object, holder, |
2451 Handle<JSGlobalPropertyCell>::null(), | 2452 Handle<JSGlobalPropertyCell>::null(), |
2452 function, name); | 2453 function, Handle<String>::cast(name)); |
2453 // A null handle means bail out to the regular compiler code below. | 2454 // A null handle means bail out to the regular compiler code below. |
2454 if (!code.is_null()) return code; | 2455 if (!code.is_null()) return code; |
2455 } | 2456 } |
2456 | 2457 |
2457 Label miss; | 2458 Label miss; |
2458 GenerateNameCheck(name, &miss); | 2459 GenerateNameCheck(name, &miss); |
2459 | 2460 |
2460 // Get the receiver from the stack | 2461 // Get the receiver from the stack |
2461 const int argc = arguments().immediate(); | 2462 const int argc = arguments().immediate(); |
2462 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 2463 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2566 __ bind(&miss); | 2567 __ bind(&miss); |
2567 GenerateMissBranch(); | 2568 GenerateMissBranch(); |
2568 | 2569 |
2569 // Return the generated code. | 2570 // Return the generated code. |
2570 return GetCode(function); | 2571 return GetCode(function); |
2571 } | 2572 } |
2572 | 2573 |
2573 | 2574 |
2574 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2575 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
2575 Handle<JSObject> holder, | 2576 Handle<JSObject> holder, |
2576 Handle<String> name) { | 2577 Handle<Name> name) { |
2577 // ----------- S t a t e ------------- | 2578 // ----------- S t a t e ------------- |
2578 // -- r2 : name | 2579 // -- r2 : name |
2579 // -- lr : return address | 2580 // -- lr : return address |
2580 // ----------------------------------- | 2581 // ----------------------------------- |
2581 Label miss; | 2582 Label miss; |
2582 GenerateNameCheck(name, &miss); | 2583 GenerateNameCheck(name, &miss); |
2583 | 2584 |
2584 // Get the number of arguments. | 2585 // Get the number of arguments. |
2585 const int argc = arguments().immediate(); | 2586 const int argc = arguments().immediate(); |
2586 LookupResult lookup(isolate()); | 2587 LookupResult lookup(isolate()); |
(...skipping 20 matching lines...) Expand all Loading... |
2607 // Return the generated code. | 2608 // Return the generated code. |
2608 return GetCode(Code::INTERCEPTOR, name); | 2609 return GetCode(Code::INTERCEPTOR, name); |
2609 } | 2610 } |
2610 | 2611 |
2611 | 2612 |
2612 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2613 Handle<Code> CallStubCompiler::CompileCallGlobal( |
2613 Handle<JSObject> object, | 2614 Handle<JSObject> object, |
2614 Handle<GlobalObject> holder, | 2615 Handle<GlobalObject> holder, |
2615 Handle<JSGlobalPropertyCell> cell, | 2616 Handle<JSGlobalPropertyCell> cell, |
2616 Handle<JSFunction> function, | 2617 Handle<JSFunction> function, |
2617 Handle<String> name) { | 2618 Handle<Name> name) { |
2618 // ----------- S t a t e ------------- | 2619 // ----------- S t a t e ------------- |
2619 // -- r2 : name | 2620 // -- r2 : name |
2620 // -- lr : return address | 2621 // -- lr : return address |
2621 // ----------------------------------- | 2622 // ----------------------------------- |
2622 if (HasCustomCallGenerator(function)) { | 2623 if (HasCustomCallGenerator(function)) { |
2623 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name); | 2624 Handle<Code> code = CompileCustomCall( |
| 2625 object, holder, cell, function, Handle<String>::cast(name)); |
2624 // A null handle means bail out to the regular compiler code below. | 2626 // A null handle means bail out to the regular compiler code below. |
2625 if (!code.is_null()) return code; | 2627 if (!code.is_null()) return code; |
2626 } | 2628 } |
2627 | 2629 |
2628 Label miss; | 2630 Label miss; |
2629 GenerateNameCheck(name, &miss); | 2631 GenerateNameCheck(name, &miss); |
2630 | 2632 |
2631 // Get the number of arguments. | 2633 // Get the number of arguments. |
2632 const int argc = arguments().immediate(); | 2634 const int argc = arguments().immediate(); |
2633 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2635 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
(...skipping 29 matching lines...) Expand all Loading... |
2663 GenerateMissBranch(); | 2665 GenerateMissBranch(); |
2664 | 2666 |
2665 // Return the generated code. | 2667 // Return the generated code. |
2666 return GetCode(Code::NORMAL, name); | 2668 return GetCode(Code::NORMAL, name); |
2667 } | 2669 } |
2668 | 2670 |
2669 | 2671 |
2670 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2672 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2671 int index, | 2673 int index, |
2672 Handle<Map> transition, | 2674 Handle<Map> transition, |
2673 Handle<String> name) { | 2675 Handle<Name> name) { |
2674 // ----------- S t a t e ------------- | 2676 // ----------- S t a t e ------------- |
2675 // -- r0 : value | 2677 // -- r0 : value |
2676 // -- r1 : receiver | 2678 // -- r1 : receiver |
2677 // -- r2 : name | 2679 // -- r2 : name |
2678 // -- lr : return address | 2680 // -- lr : return address |
2679 // ----------------------------------- | 2681 // ----------------------------------- |
2680 Label miss; | 2682 Label miss; |
2681 | 2683 |
2682 GenerateStoreField(masm(), | 2684 GenerateStoreField(masm(), |
2683 object, | 2685 object, |
2684 index, | 2686 index, |
2685 transition, | 2687 transition, |
2686 name, | 2688 name, |
2687 r1, r2, r3, r4, | 2689 r1, r2, r3, r4, |
2688 &miss); | 2690 &miss); |
2689 __ bind(&miss); | 2691 __ bind(&miss); |
2690 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2692 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2691 __ Jump(ic, RelocInfo::CODE_TARGET); | 2693 __ Jump(ic, RelocInfo::CODE_TARGET); |
2692 | 2694 |
2693 // Return the generated code. | 2695 // Return the generated code. |
2694 return GetCode(transition.is_null() | 2696 return GetCode(transition.is_null() |
2695 ? Code::FIELD | 2697 ? Code::FIELD |
2696 : Code::MAP_TRANSITION, name); | 2698 : Code::MAP_TRANSITION, name); |
2697 } | 2699 } |
2698 | 2700 |
2699 | 2701 |
2700 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2702 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2701 Handle<String> name, | 2703 Handle<Name> name, |
2702 Handle<JSObject> receiver, | 2704 Handle<JSObject> receiver, |
2703 Handle<JSObject> holder, | 2705 Handle<JSObject> holder, |
2704 Handle<AccessorInfo> callback) { | 2706 Handle<AccessorInfo> callback) { |
2705 // ----------- S t a t e ------------- | 2707 // ----------- S t a t e ------------- |
2706 // -- r0 : value | 2708 // -- r0 : value |
2707 // -- r1 : receiver | 2709 // -- r1 : receiver |
2708 // -- r2 : name | 2710 // -- r2 : name |
2709 // -- lr : return address | 2711 // -- lr : return address |
2710 // ----------------------------------- | 2712 // ----------------------------------- |
2711 Label miss; | 2713 Label miss; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2775 } | 2777 } |
2776 __ Ret(); | 2778 __ Ret(); |
2777 } | 2779 } |
2778 | 2780 |
2779 | 2781 |
2780 #undef __ | 2782 #undef __ |
2781 #define __ ACCESS_MASM(masm()) | 2783 #define __ ACCESS_MASM(masm()) |
2782 | 2784 |
2783 | 2785 |
2784 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 2786 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
2785 Handle<String> name, | 2787 Handle<Name> name, |
2786 Handle<JSObject> receiver, | 2788 Handle<JSObject> receiver, |
2787 Handle<JSObject> holder, | 2789 Handle<JSObject> holder, |
2788 Handle<JSFunction> setter) { | 2790 Handle<JSFunction> setter) { |
2789 // ----------- S t a t e ------------- | 2791 // ----------- S t a t e ------------- |
2790 // -- r0 : value | 2792 // -- r0 : value |
2791 // -- r1 : receiver | 2793 // -- r1 : receiver |
2792 // -- r2 : name | 2794 // -- r2 : name |
2793 // -- lr : return address | 2795 // -- lr : return address |
2794 // ----------------------------------- | 2796 // ----------------------------------- |
2795 Label miss; | 2797 Label miss; |
2796 | 2798 |
2797 // Check that the maps haven't changed. | 2799 // Check that the maps haven't changed. |
2798 __ JumpIfSmi(r1, &miss); | 2800 __ JumpIfSmi(r1, &miss); |
2799 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); | 2801 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); |
2800 | 2802 |
2801 GenerateStoreViaSetter(masm(), setter); | 2803 GenerateStoreViaSetter(masm(), setter); |
2802 | 2804 |
2803 __ bind(&miss); | 2805 __ bind(&miss); |
2804 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2806 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2805 __ Jump(ic, RelocInfo::CODE_TARGET); | 2807 __ Jump(ic, RelocInfo::CODE_TARGET); |
2806 | 2808 |
2807 // Return the generated code. | 2809 // Return the generated code. |
2808 return GetCode(Code::CALLBACKS, name); | 2810 return GetCode(Code::CALLBACKS, name); |
2809 } | 2811 } |
2810 | 2812 |
2811 | 2813 |
2812 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2814 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2813 Handle<JSObject> receiver, | 2815 Handle<JSObject> receiver, |
2814 Handle<String> name) { | 2816 Handle<Name> name) { |
2815 // ----------- S t a t e ------------- | 2817 // ----------- S t a t e ------------- |
2816 // -- r0 : value | 2818 // -- r0 : value |
2817 // -- r1 : receiver | 2819 // -- r1 : receiver |
2818 // -- r2 : name | 2820 // -- r2 : name |
2819 // -- lr : return address | 2821 // -- lr : return address |
2820 // ----------------------------------- | 2822 // ----------------------------------- |
2821 Label miss; | 2823 Label miss; |
2822 | 2824 |
2823 // Check that the map of the object hasn't changed. | 2825 // Check that the map of the object hasn't changed. |
2824 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, | 2826 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, |
(...skipping 25 matching lines...) Expand all Loading... |
2850 __ Jump(ic, RelocInfo::CODE_TARGET); | 2852 __ Jump(ic, RelocInfo::CODE_TARGET); |
2851 | 2853 |
2852 // Return the generated code. | 2854 // Return the generated code. |
2853 return GetCode(Code::INTERCEPTOR, name); | 2855 return GetCode(Code::INTERCEPTOR, name); |
2854 } | 2856 } |
2855 | 2857 |
2856 | 2858 |
2857 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2859 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2858 Handle<GlobalObject> object, | 2860 Handle<GlobalObject> object, |
2859 Handle<JSGlobalPropertyCell> cell, | 2861 Handle<JSGlobalPropertyCell> cell, |
2860 Handle<String> name) { | 2862 Handle<Name> name) { |
2861 // ----------- S t a t e ------------- | 2863 // ----------- S t a t e ------------- |
2862 // -- r0 : value | 2864 // -- r0 : value |
2863 // -- r1 : receiver | 2865 // -- r1 : receiver |
2864 // -- r2 : name | 2866 // -- r2 : name |
2865 // -- lr : return address | 2867 // -- lr : return address |
2866 // ----------------------------------- | 2868 // ----------------------------------- |
2867 Label miss; | 2869 Label miss; |
2868 | 2870 |
2869 // Check that the map of the global has not changed. | 2871 // Check that the map of the global has not changed. |
2870 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); | 2872 __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); |
(...skipping 25 matching lines...) Expand all Loading... |
2896 __ Jump(ic, RelocInfo::CODE_TARGET); | 2898 __ Jump(ic, RelocInfo::CODE_TARGET); |
2897 | 2899 |
2898 // Return the generated code. | 2900 // Return the generated code. |
2899 return GetCode(Code::NORMAL, name); | 2901 return GetCode(Code::NORMAL, name); |
2900 } | 2902 } |
2901 | 2903 |
2902 | 2904 |
2903 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2905 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
2904 Handle<JSObject> object, | 2906 Handle<JSObject> object, |
2905 Handle<JSObject> last, | 2907 Handle<JSObject> last, |
2906 Handle<String> name, | 2908 Handle<Name> name, |
2907 Handle<GlobalObject> global) { | 2909 Handle<GlobalObject> global) { |
2908 // ----------- S t a t e ------------- | 2910 // ----------- S t a t e ------------- |
2909 // -- r0 : receiver | 2911 // -- r0 : receiver |
2910 // -- lr : return address | 2912 // -- lr : return address |
2911 // ----------------------------------- | 2913 // ----------------------------------- |
2912 Label miss; | 2914 Label miss; |
2913 | 2915 |
2914 // Check that receiver is not a smi. | 2916 // Check that receiver is not a smi. |
2915 __ JumpIfSmi(r0, &miss); | 2917 __ JumpIfSmi(r0, &miss); |
2916 | 2918 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2954 } | 2956 } |
2955 | 2957 |
2956 | 2958 |
2957 Register* KeyedLoadStubCompiler::registers() { | 2959 Register* KeyedLoadStubCompiler::registers() { |
2958 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2960 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
2959 static Register registers[] = { r1, r0, r2, r3, r4, r5 }; | 2961 static Register registers[] = { r1, r0, r2, r3, r4, r5 }; |
2960 return registers; | 2962 return registers; |
2961 } | 2963 } |
2962 | 2964 |
2963 | 2965 |
2964 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name, | 2966 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, |
2965 Register name_reg, | 2967 Register name_reg, |
2966 Label* miss) { | 2968 Label* miss) { |
2967 __ cmp(name_reg, Operand(name)); | 2969 __ cmp(name_reg, Operand(name)); |
2968 __ b(ne, miss); | 2970 __ b(ne, miss); |
2969 } | 2971 } |
2970 | 2972 |
2971 | 2973 |
2972 #undef __ | 2974 #undef __ |
2973 #define __ ACCESS_MASM(masm) | 2975 #define __ ACCESS_MASM(masm) |
2974 | 2976 |
(...skipping 27 matching lines...) Expand all Loading... |
3002 } | 3004 } |
3003 | 3005 |
3004 | 3006 |
3005 #undef __ | 3007 #undef __ |
3006 #define __ ACCESS_MASM(masm()) | 3008 #define __ ACCESS_MASM(masm()) |
3007 | 3009 |
3008 | 3010 |
3009 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( | 3011 Handle<Code> LoadStubCompiler::CompileLoadViaGetter( |
3010 Handle<JSObject> receiver, | 3012 Handle<JSObject> receiver, |
3011 Handle<JSObject> holder, | 3013 Handle<JSObject> holder, |
3012 Handle<String> name, | 3014 Handle<Name> name, |
3013 Handle<JSFunction> getter) { | 3015 Handle<JSFunction> getter) { |
3014 // ----------- S t a t e ------------- | 3016 // ----------- S t a t e ------------- |
3015 // -- r0 : receiver | 3017 // -- r0 : receiver |
3016 // -- r2 : name | 3018 // -- r2 : name |
3017 // -- lr : return address | 3019 // -- lr : return address |
3018 // ----------------------------------- | 3020 // ----------------------------------- |
3019 Label miss; | 3021 Label miss; |
3020 | 3022 |
3021 // Check that the maps haven't changed. | 3023 // Check that the maps haven't changed. |
3022 __ JumpIfSmi(r0, &miss); | 3024 __ JumpIfSmi(r0, &miss); |
3023 CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss); | 3025 CheckPrototypes(receiver, r0, holder, r3, r4, r1, name, &miss); |
3024 | 3026 |
3025 GenerateLoadViaGetter(masm(), getter); | 3027 GenerateLoadViaGetter(masm(), getter); |
3026 | 3028 |
3027 __ bind(&miss); | 3029 __ bind(&miss); |
3028 GenerateLoadMiss(masm(), Code::LOAD_IC); | 3030 GenerateLoadMiss(masm(), Code::LOAD_IC); |
3029 | 3031 |
3030 // Return the generated code. | 3032 // Return the generated code. |
3031 return GetCode(Code::CALLBACKS, name); | 3033 return GetCode(Code::CALLBACKS, name); |
3032 } | 3034 } |
3033 | 3035 |
3034 | 3036 |
3035 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 3037 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
3036 Handle<JSObject> object, | 3038 Handle<JSObject> object, |
3037 Handle<GlobalObject> holder, | 3039 Handle<GlobalObject> holder, |
3038 Handle<JSGlobalPropertyCell> cell, | 3040 Handle<JSGlobalPropertyCell> cell, |
3039 Handle<String> name, | 3041 Handle<Name> name, |
3040 bool is_dont_delete) { | 3042 bool is_dont_delete) { |
3041 // ----------- S t a t e ------------- | 3043 // ----------- S t a t e ------------- |
3042 // -- r0 : receiver | 3044 // -- r0 : receiver |
3043 // -- r2 : name | 3045 // -- r2 : name |
3044 // -- lr : return address | 3046 // -- lr : return address |
3045 // ----------------------------------- | 3047 // ----------------------------------- |
3046 Label miss; | 3048 Label miss; |
3047 | 3049 |
3048 // Check that the map of the global has not changed. | 3050 // Check that the map of the global has not changed. |
3049 __ JumpIfSmi(r0, &miss); | 3051 __ JumpIfSmi(r0, &miss); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3126 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); | 3128 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al); |
3127 | 3129 |
3128 // Return the generated code. | 3130 // Return the generated code. |
3129 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); | 3131 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); |
3130 } | 3132 } |
3131 | 3133 |
3132 | 3134 |
3133 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 3135 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
3134 int index, | 3136 int index, |
3135 Handle<Map> transition, | 3137 Handle<Map> transition, |
3136 Handle<String> name) { | 3138 Handle<Name> name) { |
3137 // ----------- S t a t e ------------- | 3139 // ----------- S t a t e ------------- |
3138 // -- r0 : value | 3140 // -- r0 : value |
3139 // -- r1 : name | 3141 // -- r1 : name |
3140 // -- r2 : receiver | 3142 // -- r2 : receiver |
3141 // -- lr : return address | 3143 // -- lr : return address |
3142 // ----------------------------------- | 3144 // ----------------------------------- |
3143 Label miss; | 3145 Label miss; |
3144 | 3146 |
3145 Counters* counters = masm()->isolate()->counters(); | 3147 Counters* counters = masm()->isolate()->counters(); |
3146 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); | 3148 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4); |
(...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4171 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4173 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4172 } | 4174 } |
4173 } | 4175 } |
4174 | 4176 |
4175 | 4177 |
4176 #undef __ | 4178 #undef __ |
4177 | 4179 |
4178 } } // namespace v8::internal | 4180 } } // namespace v8::internal |
4179 | 4181 |
4180 #endif // V8_TARGET_ARCH_ARM | 4182 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |