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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 | 114 |
115 // Miss: fall through. | 115 // Miss: fall through. |
116 __ bind(&miss); | 116 __ bind(&miss); |
117 } | 117 } |
118 | 118 |
119 | 119 |
120 // Helper function used to check that the dictionary doesn't contain | 120 // Helper function used to check that the dictionary doesn't contain |
121 // the property. This function may return false negatives, so miss_label | 121 // the property. This function may return false negatives, so miss_label |
122 // must always call a backup property check that is complete. | 122 // must always call a backup property check that is complete. |
123 // This function is safe to call if the receiver has fast properties. | 123 // This function is safe to call if the receiver has fast properties. |
124 // Name must be internalized and receiver must be a heap object. | 124 // Name must be unique and receiver must be a heap object. |
125 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, | 125 static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, |
126 Label* miss_label, | 126 Label* miss_label, |
127 Register receiver, | 127 Register receiver, |
128 Handle<String> name, | 128 Handle<Name> name, |
129 Register scratch0, | 129 Register scratch0, |
130 Register scratch1) { | 130 Register scratch1) { |
131 ASSERT(name->IsInternalizedString()); | 131 ASSERT(name->IsUniqueName()); |
132 Counters* counters = masm->isolate()->counters(); | 132 Counters* counters = masm->isolate()->counters(); |
133 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 133 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
134 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 134 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
135 | 135 |
136 Label done; | 136 Label done; |
137 | 137 |
138 const int kInterceptorOrAccessCheckNeededMask = | 138 const int kInterceptorOrAccessCheckNeededMask = |
139 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); | 139 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); |
140 | 140 |
141 // Bail out if the receiver has a named interceptor or requires access checks. | 141 // Bail out if the receiver has a named interceptor or requires access checks. |
(...skipping 13 matching lines...) Expand all Loading... |
155 // Check that the properties array is a dictionary. | 155 // Check that the properties array is a dictionary. |
156 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); | 156 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); |
157 Register tmp = properties; | 157 Register tmp = properties; |
158 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); | 158 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); |
159 __ Branch(miss_label, ne, map, Operand(tmp)); | 159 __ Branch(miss_label, ne, map, Operand(tmp)); |
160 | 160 |
161 // Restore the temporarily used register. | 161 // Restore the temporarily used register. |
162 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); | 162 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); |
163 | 163 |
164 | 164 |
165 StringDictionaryLookupStub::GenerateNegativeLookup(masm, | 165 NameDictionaryLookupStub::GenerateNegativeLookup(masm, |
166 miss_label, | 166 miss_label, |
167 &done, | 167 &done, |
168 receiver, | 168 receiver, |
169 properties, | 169 properties, |
170 name, | 170 name, |
171 scratch1); | 171 scratch1); |
172 __ bind(&done); | 172 __ bind(&done); |
173 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 173 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 void StubCache::GenerateProbe(MacroAssembler* masm, | 177 void StubCache::GenerateProbe(MacroAssembler* masm, |
178 Code::Flags flags, | 178 Code::Flags flags, |
179 Register receiver, | 179 Register receiver, |
180 Register name, | 180 Register name, |
181 Register scratch, | 181 Register scratch, |
(...skipping 28 matching lines...) Expand all Loading... |
210 ASSERT(!extra3.is(no_reg)); | 210 ASSERT(!extra3.is(no_reg)); |
211 | 211 |
212 Counters* counters = masm->isolate()->counters(); | 212 Counters* counters = masm->isolate()->counters(); |
213 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, | 213 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, |
214 extra2, extra3); | 214 extra2, extra3); |
215 | 215 |
216 // Check that the receiver isn't a smi. | 216 // Check that the receiver isn't a smi. |
217 __ JumpIfSmi(receiver, &miss); | 217 __ JumpIfSmi(receiver, &miss); |
218 | 218 |
219 // Get the map of the receiver and compute the hash. | 219 // Get the map of the receiver and compute the hash. |
220 __ lw(scratch, FieldMemOperand(name, String::kHashFieldOffset)); | 220 __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); |
221 __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 221 __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
222 __ Addu(scratch, scratch, at); | 222 __ Addu(scratch, scratch, at); |
223 uint32_t mask = kPrimaryTableSize - 1; | 223 uint32_t mask = kPrimaryTableSize - 1; |
224 // We shift out the last two bits because they are not part of the hash and | 224 // We shift out the last two bits because they are not part of the hash and |
225 // they are always 01 for maps. | 225 // they are always 01 for maps. |
226 __ srl(scratch, scratch, kHeapObjectTagSize); | 226 __ srl(scratch, scratch, kHeapObjectTagSize); |
227 __ Xor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); | 227 __ Xor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); |
228 __ And(scratch, scratch, Operand(mask)); | 228 __ And(scratch, scratch, Operand(mask)); |
229 | 229 |
230 // Probe the primary table. | 230 // Probe the primary table. |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 } | 423 } |
424 | 424 |
425 | 425 |
426 // Generate StoreField code, value is passed in a0 register. | 426 // Generate StoreField code, value is passed in a0 register. |
427 // After executing generated code, the receiver_reg and name_reg | 427 // After executing generated code, the receiver_reg and name_reg |
428 // may be clobbered. | 428 // may be clobbered. |
429 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 429 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
430 Handle<JSObject> object, | 430 Handle<JSObject> object, |
431 int index, | 431 int index, |
432 Handle<Map> transition, | 432 Handle<Map> transition, |
433 Handle<String> name, | 433 Handle<Name> name, |
434 Register receiver_reg, | 434 Register receiver_reg, |
435 Register name_reg, | 435 Register name_reg, |
436 Register scratch1, | 436 Register scratch1, |
437 Register scratch2, | 437 Register scratch2, |
438 Label* miss_label) { | 438 Label* miss_label) { |
439 // a0 : value. | 439 // a0 : value. |
440 Label exit; | 440 Label exit; |
441 | 441 |
442 LookupResult lookup(masm->isolate()); | 442 LookupResult lookup(masm->isolate()); |
443 object->Lookup(*name, &lookup); | 443 object->Lookup(*name, &lookup); |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
759 Register name, | 759 Register name, |
760 Code::ExtraICState extra_ic_state) | 760 Code::ExtraICState extra_ic_state) |
761 : stub_compiler_(stub_compiler), | 761 : stub_compiler_(stub_compiler), |
762 arguments_(arguments), | 762 arguments_(arguments), |
763 name_(name), | 763 name_(name), |
764 extra_ic_state_(extra_ic_state) {} | 764 extra_ic_state_(extra_ic_state) {} |
765 | 765 |
766 void Compile(MacroAssembler* masm, | 766 void Compile(MacroAssembler* masm, |
767 Handle<JSObject> object, | 767 Handle<JSObject> object, |
768 Handle<JSObject> holder, | 768 Handle<JSObject> holder, |
769 Handle<String> name, | 769 Handle<Name> name, |
770 LookupResult* lookup, | 770 LookupResult* lookup, |
771 Register receiver, | 771 Register receiver, |
772 Register scratch1, | 772 Register scratch1, |
773 Register scratch2, | 773 Register scratch2, |
774 Register scratch3, | 774 Register scratch3, |
775 Label* miss) { | 775 Label* miss) { |
776 ASSERT(holder->HasNamedInterceptor()); | 776 ASSERT(holder->HasNamedInterceptor()); |
777 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 777 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |
778 | 778 |
779 // Check that the receiver isn't a smi. | 779 // Check that the receiver isn't a smi. |
(...skipping 10 matching lines...) Expand all Loading... |
790 | 790 |
791 private: | 791 private: |
792 void CompileCacheable(MacroAssembler* masm, | 792 void CompileCacheable(MacroAssembler* masm, |
793 Handle<JSObject> object, | 793 Handle<JSObject> object, |
794 Register receiver, | 794 Register receiver, |
795 Register scratch1, | 795 Register scratch1, |
796 Register scratch2, | 796 Register scratch2, |
797 Register scratch3, | 797 Register scratch3, |
798 Handle<JSObject> interceptor_holder, | 798 Handle<JSObject> interceptor_holder, |
799 LookupResult* lookup, | 799 LookupResult* lookup, |
800 Handle<String> name, | 800 Handle<Name> name, |
801 const CallOptimization& optimization, | 801 const CallOptimization& optimization, |
802 Label* miss_label) { | 802 Label* miss_label) { |
803 ASSERT(optimization.is_constant_call()); | 803 ASSERT(optimization.is_constant_call()); |
804 ASSERT(!lookup->holder()->IsGlobalObject()); | 804 ASSERT(!lookup->holder()->IsGlobalObject()); |
805 Counters* counters = masm->isolate()->counters(); | 805 Counters* counters = masm->isolate()->counters(); |
806 int depth1 = kInvalidProtoDepth; | 806 int depth1 = kInvalidProtoDepth; |
807 int depth2 = kInvalidProtoDepth; | 807 int depth2 = kInvalidProtoDepth; |
808 bool can_do_fast_api_call = false; | 808 bool can_do_fast_api_call = false; |
809 if (optimization.is_simple_api_call() && | 809 if (optimization.is_simple_api_call() && |
810 !lookup->holder()->IsGlobalObject()) { | 810 !lookup->holder()->IsGlobalObject()) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 Code::ExtraICState extra_ic_state_; | 945 Code::ExtraICState extra_ic_state_; |
946 }; | 946 }; |
947 | 947 |
948 | 948 |
949 | 949 |
950 // Generate code to check that a global property cell is empty. Create | 950 // Generate code to check that a global property cell is empty. Create |
951 // the property cell at compilation time if no cell exists for the | 951 // the property cell at compilation time if no cell exists for the |
952 // property. | 952 // property. |
953 static void GenerateCheckPropertyCell(MacroAssembler* masm, | 953 static void GenerateCheckPropertyCell(MacroAssembler* masm, |
954 Handle<GlobalObject> global, | 954 Handle<GlobalObject> global, |
955 Handle<String> name, | 955 Handle<Name> name, |
956 Register scratch, | 956 Register scratch, |
957 Label* miss) { | 957 Label* miss) { |
958 Handle<JSGlobalPropertyCell> cell = | 958 Handle<JSGlobalPropertyCell> cell = |
959 GlobalObject::EnsurePropertyCell(global, name); | 959 GlobalObject::EnsurePropertyCell(global, name); |
960 ASSERT(cell->value()->IsTheHole()); | 960 ASSERT(cell->value()->IsTheHole()); |
961 __ li(scratch, Operand(cell)); | 961 __ li(scratch, Operand(cell)); |
962 __ lw(scratch, | 962 __ lw(scratch, |
963 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); | 963 FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); |
964 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 964 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
965 __ Branch(miss, ne, scratch, Operand(at)); | 965 __ Branch(miss, ne, scratch, Operand(at)); |
966 } | 966 } |
967 | 967 |
968 | 968 |
969 // Calls GenerateCheckPropertyCell for each global object in the prototype chain | 969 // Calls GenerateCheckPropertyCell for each global object in the prototype chain |
970 // from object to (but not including) holder. | 970 // from object to (but not including) holder. |
971 static void GenerateCheckPropertyCells(MacroAssembler* masm, | 971 static void GenerateCheckPropertyCells(MacroAssembler* masm, |
972 Handle<JSObject> object, | 972 Handle<JSObject> object, |
973 Handle<JSObject> holder, | 973 Handle<JSObject> holder, |
974 Handle<String> name, | 974 Handle<Name> name, |
975 Register scratch, | 975 Register scratch, |
976 Label* miss) { | 976 Label* miss) { |
977 Handle<JSObject> current = object; | 977 Handle<JSObject> current = object; |
978 while (!current.is_identical_to(holder)) { | 978 while (!current.is_identical_to(holder)) { |
979 if (current->IsGlobalObject()) { | 979 if (current->IsGlobalObject()) { |
980 GenerateCheckPropertyCell(masm, | 980 GenerateCheckPropertyCell(masm, |
981 Handle<GlobalObject>::cast(current), | 981 Handle<GlobalObject>::cast(current), |
982 name, | 982 name, |
983 scratch, | 983 scratch, |
984 miss); | 984 miss); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 __ Jump(code, RelocInfo::CODE_TARGET); | 1072 __ Jump(code, RelocInfo::CODE_TARGET); |
1073 } | 1073 } |
1074 | 1074 |
1075 | 1075 |
1076 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, | 1076 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, |
1077 Register object_reg, | 1077 Register object_reg, |
1078 Handle<JSObject> holder, | 1078 Handle<JSObject> holder, |
1079 Register holder_reg, | 1079 Register holder_reg, |
1080 Register scratch1, | 1080 Register scratch1, |
1081 Register scratch2, | 1081 Register scratch2, |
1082 Handle<String> name, | 1082 Handle<Name> name, |
1083 int save_at_depth, | 1083 int save_at_depth, |
1084 Label* miss, | 1084 Label* miss, |
1085 PrototypeCheckType check) { | 1085 PrototypeCheckType check) { |
1086 Handle<JSObject> first = object; | 1086 Handle<JSObject> first = object; |
1087 // Make sure there's no overlap between holder and object registers. | 1087 // Make sure there's no overlap between holder and object registers. |
1088 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); | 1088 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); |
1089 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) | 1089 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) |
1090 && !scratch2.is(scratch1)); | 1090 && !scratch2.is(scratch1)); |
1091 | 1091 |
1092 // Keep track of the current object in register reg. | 1092 // Keep track of the current object in register reg. |
(...skipping 11 matching lines...) Expand all Loading... |
1104 ++depth; | 1104 ++depth; |
1105 | 1105 |
1106 // Only global objects and objects that do not require access | 1106 // Only global objects and objects that do not require access |
1107 // checks are allowed in stubs. | 1107 // checks are allowed in stubs. |
1108 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); | 1108 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); |
1109 | 1109 |
1110 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); | 1110 Handle<JSObject> prototype(JSObject::cast(current->GetPrototype())); |
1111 if (!current->HasFastProperties() && | 1111 if (!current->HasFastProperties() && |
1112 !current->IsJSGlobalObject() && | 1112 !current->IsJSGlobalObject() && |
1113 !current->IsJSGlobalProxy()) { | 1113 !current->IsJSGlobalProxy()) { |
1114 if (!name->IsInternalizedString()) { | 1114 if (!name->IsUniqueName()) { |
1115 name = factory()->InternalizeString(name); | 1115 ASSERT(name->IsString()); |
| 1116 name = factory()->InternalizeString(Handle<String>::cast(name)); |
1116 } | 1117 } |
1117 ASSERT(current->property_dictionary()->FindEntry(*name) == | 1118 ASSERT(current->property_dictionary()->FindEntry(*name) == |
1118 StringDictionary::kNotFound); | 1119 NameDictionary::kNotFound); |
1119 | 1120 |
1120 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, | 1121 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, |
1121 scratch1, scratch2); | 1122 scratch1, scratch2); |
1122 | 1123 |
1123 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1124 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1124 reg = holder_reg; // From now on the object will be in holder_reg. | 1125 reg = holder_reg; // From now on the object will be in holder_reg. |
1125 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); | 1126 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); |
1126 } else { | 1127 } else { |
1127 Register map_reg = scratch1; | 1128 Register map_reg = scratch1; |
1128 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { | 1129 if (!current.is_identical_to(first) || check == CHECK_ALL_MAPS) { |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 __ bind(miss); | 1192 __ bind(miss); |
1192 GenerateLoadMiss(masm(), kind()); | 1193 GenerateLoadMiss(masm(), kind()); |
1193 } | 1194 } |
1194 } | 1195 } |
1195 | 1196 |
1196 | 1197 |
1197 Register BaseLoadStubCompiler::CallbackHandlerFrontend( | 1198 Register BaseLoadStubCompiler::CallbackHandlerFrontend( |
1198 Handle<JSObject> object, | 1199 Handle<JSObject> object, |
1199 Register object_reg, | 1200 Register object_reg, |
1200 Handle<JSObject> holder, | 1201 Handle<JSObject> holder, |
1201 Handle<String> name, | 1202 Handle<Name> name, |
1202 Label* success, | 1203 Label* success, |
1203 Handle<ExecutableAccessorInfo> callback) { | 1204 Handle<ExecutableAccessorInfo> callback) { |
1204 Label miss; | 1205 Label miss; |
1205 | 1206 |
1206 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); | 1207 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); |
1207 | 1208 |
1208 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { | 1209 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { |
1209 ASSERT(!reg.is(scratch2())); | 1210 ASSERT(!reg.is(scratch2())); |
1210 ASSERT(!reg.is(scratch3())); | 1211 ASSERT(!reg.is(scratch3())); |
1211 ASSERT(!reg.is(scratch4())); | 1212 ASSERT(!reg.is(scratch4())); |
1212 | 1213 |
1213 // Load the properties dictionary. | 1214 // Load the properties dictionary. |
1214 Register dictionary = scratch4(); | 1215 Register dictionary = scratch4(); |
1215 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); | 1216 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); |
1216 | 1217 |
1217 // Probe the dictionary. | 1218 // Probe the dictionary. |
1218 Label probe_done; | 1219 Label probe_done; |
1219 StringDictionaryLookupStub::GeneratePositiveLookup(masm(), | 1220 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), |
1220 &miss, | 1221 &miss, |
1221 &probe_done, | 1222 &probe_done, |
1222 dictionary, | 1223 dictionary, |
1223 this->name(), | 1224 this->name(), |
1224 scratch2(), | 1225 scratch2(), |
1225 scratch3()); | 1226 scratch3()); |
1226 __ bind(&probe_done); | 1227 __ bind(&probe_done); |
1227 | 1228 |
1228 // If probing finds an entry in the dictionary, scratch3 contains the | 1229 // If probing finds an entry in the dictionary, scratch3 contains the |
1229 // pointer into the dictionary. Check that the value is the callback. | 1230 // pointer into the dictionary. Check that the value is the callback. |
1230 Register pointer = scratch3(); | 1231 Register pointer = scratch3(); |
1231 const int kElementsStartOffset = StringDictionary::kHeaderSize + | 1232 const int kElementsStartOffset = NameDictionary::kHeaderSize + |
1232 StringDictionary::kElementsStartIndex * kPointerSize; | 1233 NameDictionary::kElementsStartIndex * kPointerSize; |
1233 const int kValueOffset = kElementsStartOffset + kPointerSize; | 1234 const int kValueOffset = kElementsStartOffset + kPointerSize; |
1234 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); | 1235 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); |
1235 __ Branch(&miss, ne, scratch2(), Operand(callback)); | 1236 __ Branch(&miss, ne, scratch2(), Operand(callback)); |
1236 } | 1237 } |
1237 | 1238 |
1238 HandlerFrontendFooter(success, &miss); | 1239 HandlerFrontendFooter(success, &miss); |
1239 return reg; | 1240 return reg; |
1240 } | 1241 } |
1241 | 1242 |
1242 | 1243 |
1243 void BaseLoadStubCompiler::NonexistentHandlerFrontend( | 1244 void BaseLoadStubCompiler::NonexistentHandlerFrontend( |
1244 Handle<JSObject> object, | 1245 Handle<JSObject> object, |
1245 Handle<JSObject> last, | 1246 Handle<JSObject> last, |
1246 Handle<String> name, | 1247 Handle<Name> name, |
1247 Label* success, | 1248 Label* success, |
1248 Handle<GlobalObject> global) { | 1249 Handle<GlobalObject> global) { |
1249 Label miss; | 1250 Label miss; |
1250 | 1251 |
1251 Register reg = HandlerFrontendHeader(object, receiver(), last, name, &miss); | 1252 Register reg = HandlerFrontendHeader(object, receiver(), last, name, &miss); |
1252 | 1253 |
1253 // If the last object in the prototype chain is a global object, | 1254 // If the last object in the prototype chain is a global object, |
1254 // check that the global property cell is empty. | 1255 // check that the global property cell is empty. |
1255 if (!global.is_null()) { | 1256 if (!global.is_null()) { |
1256 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); | 1257 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1298 callback->GetIsolate())); | 1299 callback->GetIsolate())); |
1299 } | 1300 } |
1300 __ Subu(sp, sp, 4 * kPointerSize); | 1301 __ Subu(sp, sp, 4 * kPointerSize); |
1301 __ sw(reg, MemOperand(sp, 3 * kPointerSize)); | 1302 __ sw(reg, MemOperand(sp, 3 * kPointerSize)); |
1302 __ sw(scratch3(), MemOperand(sp, 2 * kPointerSize)); | 1303 __ sw(scratch3(), MemOperand(sp, 2 * kPointerSize)); |
1303 __ li(scratch3(), Operand(ExternalReference::isolate_address())); | 1304 __ li(scratch3(), Operand(ExternalReference::isolate_address())); |
1304 __ sw(scratch3(), MemOperand(sp, 1 * kPointerSize)); | 1305 __ sw(scratch3(), MemOperand(sp, 1 * kPointerSize)); |
1305 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); | 1306 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); |
1306 | 1307 |
1307 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. | 1308 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. |
1308 __ mov(a1, sp); // a1 (first argument - see note below) = Handle<String> | 1309 __ mov(a1, sp); // a1 (first argument - see note below) = Handle<Name> |
1309 | 1310 |
1310 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a | 1311 // NOTE: the O32 abi requires a0 to hold a special pointer when returning a |
1311 // struct from the function (which is currently the case). This means we pass | 1312 // struct from the function (which is currently the case). This means we pass |
1312 // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn | 1313 // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn |
1313 // will handle setting up a0. | 1314 // will handle setting up a0. |
1314 | 1315 |
1315 const int kApiStackSpace = 1; | 1316 const int kApiStackSpace = 1; |
1316 FrameScope frame_scope(masm(), StackFrame::MANUAL); | 1317 FrameScope frame_scope(masm(), StackFrame::MANUAL); |
1317 __ EnterExitFrame(false, kApiStackSpace); | 1318 __ EnterExitFrame(false, kApiStackSpace); |
1318 | 1319 |
(...skipping 12 matching lines...) Expand all Loading... |
1331 masm()->isolate()); | 1332 masm()->isolate()); |
1332 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); | 1333 __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); |
1333 } | 1334 } |
1334 | 1335 |
1335 | 1336 |
1336 void BaseLoadStubCompiler::GenerateLoadInterceptor( | 1337 void BaseLoadStubCompiler::GenerateLoadInterceptor( |
1337 Register holder_reg, | 1338 Register holder_reg, |
1338 Handle<JSObject> object, | 1339 Handle<JSObject> object, |
1339 Handle<JSObject> interceptor_holder, | 1340 Handle<JSObject> interceptor_holder, |
1340 LookupResult* lookup, | 1341 LookupResult* lookup, |
1341 Handle<String> name) { | 1342 Handle<Name> name) { |
1342 ASSERT(interceptor_holder->HasNamedInterceptor()); | 1343 ASSERT(interceptor_holder->HasNamedInterceptor()); |
1343 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); | 1344 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); |
1344 | 1345 |
1345 // So far the most popular follow ups for interceptor loads are FIELD | 1346 // So far the most popular follow ups for interceptor loads are FIELD |
1346 // and CALLBACKS, so inline only them, other cases may be added | 1347 // and CALLBACKS, so inline only them, other cases may be added |
1347 // later. | 1348 // later. |
1348 bool compile_followup_inline = false; | 1349 bool compile_followup_inline = false; |
1349 if (lookup->IsFound() && lookup->IsCacheable()) { | 1350 if (lookup->IsFound() && lookup->IsCacheable()) { |
1350 if (lookup->IsField()) { | 1351 if (lookup->IsField()) { |
1351 compile_followup_inline = true; | 1352 compile_followup_inline = true; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 PushInterceptorArguments(masm(), receiver(), holder_reg, | 1413 PushInterceptorArguments(masm(), receiver(), holder_reg, |
1413 this->name(), interceptor_holder); | 1414 this->name(), interceptor_holder); |
1414 | 1415 |
1415 ExternalReference ref = ExternalReference( | 1416 ExternalReference ref = ExternalReference( |
1416 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); | 1417 IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), masm()->isolate()); |
1417 __ TailCallExternalReference(ref, 6, 1); | 1418 __ TailCallExternalReference(ref, 6, 1); |
1418 } | 1419 } |
1419 } | 1420 } |
1420 | 1421 |
1421 | 1422 |
1422 void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) { | 1423 void CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { |
1423 if (kind_ == Code::KEYED_CALL_IC) { | 1424 if (kind_ == Code::KEYED_CALL_IC) { |
1424 __ Branch(miss, ne, a2, Operand(name)); | 1425 __ Branch(miss, ne, a2, Operand(name)); |
1425 } | 1426 } |
1426 } | 1427 } |
1427 | 1428 |
1428 | 1429 |
1429 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, | 1430 void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object, |
1430 Handle<JSObject> holder, | 1431 Handle<JSObject> holder, |
1431 Handle<String> name, | 1432 Handle<Name> name, |
1432 Label* miss) { | 1433 Label* miss) { |
1433 ASSERT(holder->IsGlobalObject()); | 1434 ASSERT(holder->IsGlobalObject()); |
1434 | 1435 |
1435 // Get the number of arguments. | 1436 // Get the number of arguments. |
1436 const int argc = arguments().immediate(); | 1437 const int argc = arguments().immediate(); |
1437 | 1438 |
1438 // Get the receiver from the stack. | 1439 // Get the receiver from the stack. |
1439 __ lw(a0, MemOperand(sp, argc * kPointerSize)); | 1440 __ lw(a0, MemOperand(sp, argc * kPointerSize)); |
1440 | 1441 |
1441 // Check that the maps haven't changed. | 1442 // Check that the maps haven't changed. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), | 1479 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), |
1479 kind_, | 1480 kind_, |
1480 extra_state_); | 1481 extra_state_); |
1481 __ Jump(code, RelocInfo::CODE_TARGET); | 1482 __ Jump(code, RelocInfo::CODE_TARGET); |
1482 } | 1483 } |
1483 | 1484 |
1484 | 1485 |
1485 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, | 1486 Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
1486 Handle<JSObject> holder, | 1487 Handle<JSObject> holder, |
1487 PropertyIndex index, | 1488 PropertyIndex index, |
1488 Handle<String> name) { | 1489 Handle<Name> name) { |
1489 // ----------- S t a t e ------------- | 1490 // ----------- S t a t e ------------- |
1490 // -- a2 : name | 1491 // -- a2 : name |
1491 // -- ra : return address | 1492 // -- ra : return address |
1492 // ----------------------------------- | 1493 // ----------------------------------- |
1493 Label miss; | 1494 Label miss; |
1494 | 1495 |
1495 GenerateNameCheck(name, &miss); | 1496 GenerateNameCheck(name, &miss); |
1496 | 1497 |
1497 const int argc = arguments().immediate(); | 1498 const int argc = arguments().immediate(); |
1498 | 1499 |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2388 __ bind(&miss_before_stack_reserved); | 2389 __ bind(&miss_before_stack_reserved); |
2389 GenerateMissBranch(); | 2390 GenerateMissBranch(); |
2390 | 2391 |
2391 // Return the generated code. | 2392 // Return the generated code. |
2392 return GetCode(function); | 2393 return GetCode(function); |
2393 } | 2394 } |
2394 | 2395 |
2395 | 2396 |
2396 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, | 2397 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, |
2397 Handle<JSObject> holder, | 2398 Handle<JSObject> holder, |
2398 Handle<String> name, | 2399 Handle<Name> name, |
2399 CheckType check, | 2400 CheckType check, |
2400 Label* success) { | 2401 Label* success) { |
2401 // ----------- S t a t e ------------- | 2402 // ----------- S t a t e ------------- |
2402 // -- a2 : name | 2403 // -- a2 : name |
2403 // -- ra : return address | 2404 // -- ra : return address |
2404 // ----------------------------------- | 2405 // ----------------------------------- |
2405 Label miss; | 2406 Label miss; |
2406 GenerateNameCheck(name, &miss); | 2407 GenerateNameCheck(name, &miss); |
2407 | 2408 |
2408 // Get the receiver from the stack. | 2409 // Get the receiver from the stack. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2493 ? CALL_AS_FUNCTION | 2494 ? CALL_AS_FUNCTION |
2494 : CALL_AS_METHOD; | 2495 : CALL_AS_METHOD; |
2495 __ InvokeFunction( | 2496 __ InvokeFunction( |
2496 function, arguments(), JUMP_FUNCTION, NullCallWrapper(), call_kind); | 2497 function, arguments(), JUMP_FUNCTION, NullCallWrapper(), call_kind); |
2497 } | 2498 } |
2498 | 2499 |
2499 | 2500 |
2500 Handle<Code> CallStubCompiler::CompileCallConstant( | 2501 Handle<Code> CallStubCompiler::CompileCallConstant( |
2501 Handle<Object> object, | 2502 Handle<Object> object, |
2502 Handle<JSObject> holder, | 2503 Handle<JSObject> holder, |
2503 Handle<String> name, | 2504 Handle<Name> name, |
2504 CheckType check, | 2505 CheckType check, |
2505 Handle<JSFunction> function) { | 2506 Handle<JSFunction> function) { |
2506 if (HasCustomCallGenerator(function)) { | 2507 if (HasCustomCallGenerator(function)) { |
2507 Handle<Code> code = CompileCustomCall(object, holder, | 2508 Handle<Code> code = CompileCustomCall(object, holder, |
2508 Handle<JSGlobalPropertyCell>::null(), | 2509 Handle<JSGlobalPropertyCell>::null(), |
2509 function, name); | 2510 function, Handle<String>::cast(name)); |
2510 // A null handle means bail out to the regular compiler code below. | 2511 // A null handle means bail out to the regular compiler code below. |
2511 if (!code.is_null()) return code; | 2512 if (!code.is_null()) return code; |
2512 } | 2513 } |
2513 | 2514 |
2514 Label success; | 2515 Label success; |
2515 | 2516 |
2516 CompileHandlerFrontend(object, holder, name, check, &success); | 2517 CompileHandlerFrontend(object, holder, name, check, &success); |
2517 __ bind(&success); | 2518 __ bind(&success); |
2518 CompileHandlerBackend(function); | 2519 CompileHandlerBackend(function); |
2519 | 2520 |
2520 // Return the generated code. | 2521 // Return the generated code. |
2521 return GetCode(function); | 2522 return GetCode(function); |
2522 } | 2523 } |
2523 | 2524 |
2524 | 2525 |
2525 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, | 2526 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, |
2526 Handle<JSObject> holder, | 2527 Handle<JSObject> holder, |
2527 Handle<String> name) { | 2528 Handle<Name> name) { |
2528 // ----------- S t a t e ------------- | 2529 // ----------- S t a t e ------------- |
2529 // -- a2 : name | 2530 // -- a2 : name |
2530 // -- ra : return address | 2531 // -- ra : return address |
2531 // ----------------------------------- | 2532 // ----------------------------------- |
2532 | 2533 |
2533 Label miss; | 2534 Label miss; |
2534 | 2535 |
2535 GenerateNameCheck(name, &miss); | 2536 GenerateNameCheck(name, &miss); |
2536 | 2537 |
2537 // Get the number of arguments. | 2538 // Get the number of arguments. |
(...skipping 22 matching lines...) Expand all Loading... |
2560 // Return the generated code. | 2561 // Return the generated code. |
2561 return GetCode(Code::INTERCEPTOR, name); | 2562 return GetCode(Code::INTERCEPTOR, name); |
2562 } | 2563 } |
2563 | 2564 |
2564 | 2565 |
2565 Handle<Code> CallStubCompiler::CompileCallGlobal( | 2566 Handle<Code> CallStubCompiler::CompileCallGlobal( |
2566 Handle<JSObject> object, | 2567 Handle<JSObject> object, |
2567 Handle<GlobalObject> holder, | 2568 Handle<GlobalObject> holder, |
2568 Handle<JSGlobalPropertyCell> cell, | 2569 Handle<JSGlobalPropertyCell> cell, |
2569 Handle<JSFunction> function, | 2570 Handle<JSFunction> function, |
2570 Handle<String> name) { | 2571 Handle<Name> name) { |
2571 // ----------- S t a t e ------------- | 2572 // ----------- S t a t e ------------- |
2572 // -- a2 : name | 2573 // -- a2 : name |
2573 // -- ra : return address | 2574 // -- ra : return address |
2574 // ----------------------------------- | 2575 // ----------------------------------- |
2575 | 2576 |
2576 if (HasCustomCallGenerator(function)) { | 2577 if (HasCustomCallGenerator(function)) { |
2577 Handle<Code> code = CompileCustomCall(object, holder, cell, function, name); | 2578 Handle<Code> code = CompileCustomCall( |
| 2579 object, holder, cell, function, Handle<String>::cast(name)); |
2578 // A null handle means bail out to the regular compiler code below. | 2580 // A null handle means bail out to the regular compiler code below. |
2579 if (!code.is_null()) return code; | 2581 if (!code.is_null()) return code; |
2580 } | 2582 } |
2581 | 2583 |
2582 Label miss; | 2584 Label miss; |
2583 GenerateNameCheck(name, &miss); | 2585 GenerateNameCheck(name, &miss); |
2584 | 2586 |
2585 // Get the number of arguments. | 2587 // Get the number of arguments. |
2586 const int argc = arguments().immediate(); | 2588 const int argc = arguments().immediate(); |
2587 GenerateGlobalReceiverCheck(object, holder, name, &miss); | 2589 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
(...skipping 29 matching lines...) Expand all Loading... |
2617 GenerateMissBranch(); | 2619 GenerateMissBranch(); |
2618 | 2620 |
2619 // Return the generated code. | 2621 // Return the generated code. |
2620 return GetCode(Code::NORMAL, name); | 2622 return GetCode(Code::NORMAL, name); |
2621 } | 2623 } |
2622 | 2624 |
2623 | 2625 |
2624 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 2626 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
2625 int index, | 2627 int index, |
2626 Handle<Map> transition, | 2628 Handle<Map> transition, |
2627 Handle<String> name) { | 2629 Handle<Name> name) { |
2628 // ----------- S t a t e ------------- | 2630 // ----------- S t a t e ------------- |
2629 // -- a0 : value | 2631 // -- a0 : value |
2630 // -- a1 : receiver | 2632 // -- a1 : receiver |
2631 // -- a2 : name | 2633 // -- a2 : name |
2632 // -- ra : return address | 2634 // -- ra : return address |
2633 // ----------------------------------- | 2635 // ----------------------------------- |
2634 Label miss; | 2636 Label miss; |
2635 | 2637 |
2636 // Name register might be clobbered. | 2638 // Name register might be clobbered. |
2637 GenerateStoreField(masm(), | 2639 GenerateStoreField(masm(), |
2638 object, | 2640 object, |
2639 index, | 2641 index, |
2640 transition, | 2642 transition, |
2641 name, | 2643 name, |
2642 a1, a2, a3, t0, | 2644 a1, a2, a3, t0, |
2643 &miss); | 2645 &miss); |
2644 __ bind(&miss); | 2646 __ bind(&miss); |
2645 __ li(a2, Operand(Handle<String>(name))); // Restore name. | 2647 __ li(a2, Operand(Handle<String>(name))); // Restore name. |
2646 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); | 2648 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); |
2647 __ Jump(ic, RelocInfo::CODE_TARGET); | 2649 __ Jump(ic, RelocInfo::CODE_TARGET); |
2648 | 2650 |
2649 // Return the generated code. | 2651 // Return the generated code. |
2650 return GetCode(transition.is_null() | 2652 return GetCode(transition.is_null() |
2651 ? Code::FIELD | 2653 ? Code::FIELD |
2652 : Code::MAP_TRANSITION, name); | 2654 : Code::MAP_TRANSITION, name); |
2653 } | 2655 } |
2654 | 2656 |
2655 | 2657 |
2656 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 2658 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
2657 Handle<String> name, | 2659 Handle<Name> name, |
2658 Handle<JSObject> receiver, | 2660 Handle<JSObject> receiver, |
2659 Handle<JSObject> holder, | 2661 Handle<JSObject> holder, |
2660 Handle<ExecutableAccessorInfo> callback) { | 2662 Handle<ExecutableAccessorInfo> callback) { |
2661 // ----------- S t a t e ------------- | 2663 // ----------- S t a t e ------------- |
2662 // -- a0 : value | 2664 // -- a0 : value |
2663 // -- a1 : receiver | 2665 // -- a1 : receiver |
2664 // -- a2 : name | 2666 // -- a2 : name |
2665 // -- ra : return address | 2667 // -- ra : return address |
2666 // ----------------------------------- | 2668 // ----------------------------------- |
2667 Label miss; | 2669 Label miss; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2733 } | 2735 } |
2734 __ Ret(); | 2736 __ Ret(); |
2735 } | 2737 } |
2736 | 2738 |
2737 | 2739 |
2738 #undef __ | 2740 #undef __ |
2739 #define __ ACCESS_MASM(masm()) | 2741 #define __ ACCESS_MASM(masm()) |
2740 | 2742 |
2741 | 2743 |
2742 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( | 2744 Handle<Code> StoreStubCompiler::CompileStoreViaSetter( |
2743 Handle<String> name, | 2745 Handle<Name> name, |
2744 Handle<JSObject> receiver, | 2746 Handle<JSObject> receiver, |
2745 Handle<JSObject> holder, | 2747 Handle<JSObject> holder, |
2746 Handle<JSFunction> setter) { | 2748 Handle<JSFunction> setter) { |
2747 // ----------- S t a t e ------------- | 2749 // ----------- S t a t e ------------- |
2748 // -- a0 : value | 2750 // -- a0 : value |
2749 // -- a1 : receiver | 2751 // -- a1 : receiver |
2750 // -- a2 : name | 2752 // -- a2 : name |
2751 // -- ra : return address | 2753 // -- ra : return address |
2752 // ----------------------------------- | 2754 // ----------------------------------- |
2753 Label miss; | 2755 Label miss; |
2754 | 2756 |
2755 // Check that the maps haven't changed. | 2757 // Check that the maps haven't changed. |
2756 __ JumpIfSmi(a1, &miss); | 2758 __ JumpIfSmi(a1, &miss); |
2757 CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); | 2759 CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); |
2758 | 2760 |
2759 GenerateStoreViaSetter(masm(), setter); | 2761 GenerateStoreViaSetter(masm(), setter); |
2760 | 2762 |
2761 __ bind(&miss); | 2763 __ bind(&miss); |
2762 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); | 2764 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); |
2763 __ Jump(ic, RelocInfo::CODE_TARGET); | 2765 __ Jump(ic, RelocInfo::CODE_TARGET); |
2764 | 2766 |
2765 // Return the generated code. | 2767 // Return the generated code. |
2766 return GetCode(Code::CALLBACKS, name); | 2768 return GetCode(Code::CALLBACKS, name); |
2767 } | 2769 } |
2768 | 2770 |
2769 | 2771 |
2770 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( | 2772 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( |
2771 Handle<JSObject> receiver, | 2773 Handle<JSObject> receiver, |
2772 Handle<String> name) { | 2774 Handle<Name> name) { |
2773 // ----------- S t a t e ------------- | 2775 // ----------- S t a t e ------------- |
2774 // -- a0 : value | 2776 // -- a0 : value |
2775 // -- a1 : receiver | 2777 // -- a1 : receiver |
2776 // -- a2 : name | 2778 // -- a2 : name |
2777 // -- ra : return address | 2779 // -- ra : return address |
2778 // ----------------------------------- | 2780 // ----------------------------------- |
2779 Label miss; | 2781 Label miss; |
2780 | 2782 |
2781 // Check that the map of the object hasn't changed. | 2783 // Check that the map of the object hasn't changed. |
2782 __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss, | 2784 __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss, |
(...skipping 25 matching lines...) Expand all Loading... |
2808 __ Jump(ic, RelocInfo::CODE_TARGET); | 2810 __ Jump(ic, RelocInfo::CODE_TARGET); |
2809 | 2811 |
2810 // Return the generated code. | 2812 // Return the generated code. |
2811 return GetCode(Code::INTERCEPTOR, name); | 2813 return GetCode(Code::INTERCEPTOR, name); |
2812 } | 2814 } |
2813 | 2815 |
2814 | 2816 |
2815 Handle<Code> StoreStubCompiler::CompileStoreGlobal( | 2817 Handle<Code> StoreStubCompiler::CompileStoreGlobal( |
2816 Handle<GlobalObject> object, | 2818 Handle<GlobalObject> object, |
2817 Handle<JSGlobalPropertyCell> cell, | 2819 Handle<JSGlobalPropertyCell> cell, |
2818 Handle<String> name) { | 2820 Handle<Name> name) { |
2819 // ----------- S t a t e ------------- | 2821 // ----------- S t a t e ------------- |
2820 // -- a0 : value | 2822 // -- a0 : value |
2821 // -- a1 : receiver | 2823 // -- a1 : receiver |
2822 // -- a2 : name | 2824 // -- a2 : name |
2823 // -- ra : return address | 2825 // -- ra : return address |
2824 // ----------------------------------- | 2826 // ----------------------------------- |
2825 Label miss; | 2827 Label miss; |
2826 | 2828 |
2827 // Check that the map of the global has not changed. | 2829 // Check that the map of the global has not changed. |
2828 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); | 2830 __ lw(a3, FieldMemOperand(a1, HeapObject::kMapOffset)); |
(...skipping 24 matching lines...) Expand all Loading... |
2853 __ Jump(ic, RelocInfo::CODE_TARGET); | 2855 __ Jump(ic, RelocInfo::CODE_TARGET); |
2854 | 2856 |
2855 // Return the generated code. | 2857 // Return the generated code. |
2856 return GetCode(Code::NORMAL, name); | 2858 return GetCode(Code::NORMAL, name); |
2857 } | 2859 } |
2858 | 2860 |
2859 | 2861 |
2860 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( | 2862 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( |
2861 Handle<JSObject> object, | 2863 Handle<JSObject> object, |
2862 Handle<JSObject> last, | 2864 Handle<JSObject> last, |
2863 Handle<String> name, | 2865 Handle<Name> name, |
2864 Handle<GlobalObject> global) { | 2866 Handle<GlobalObject> global) { |
2865 Label success; | 2867 Label success; |
2866 | 2868 |
2867 NonexistentHandlerFrontend(object, last, name, &success, global); | 2869 NonexistentHandlerFrontend(object, last, name, &success, global); |
2868 | 2870 |
2869 __ bind(&success); | 2871 __ bind(&success); |
2870 // Return undefined if maps of the full prototype chain is still the same. | 2872 // Return undefined if maps of the full prototype chain is still the same. |
2871 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); | 2873 __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); |
2872 __ Ret(); | 2874 __ Ret(); |
2873 | 2875 |
2874 // Return the generated code. | 2876 // Return the generated code. |
2875 return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name); | 2877 return GetCode(Code::HANDLER_FRAGMENT, Code::NONEXISTENT, name); |
2876 } | 2878 } |
2877 | 2879 |
2878 | 2880 |
2879 Register* LoadStubCompiler::registers() { | 2881 Register* LoadStubCompiler::registers() { |
2880 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2882 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
2881 static Register registers[] = { a0, a2, a3, a1, t0, t1 }; | 2883 static Register registers[] = { a0, a2, a3, a1, t0, t1 }; |
2882 return registers; | 2884 return registers; |
2883 } | 2885 } |
2884 | 2886 |
2885 | 2887 |
2886 Register* KeyedLoadStubCompiler::registers() { | 2888 Register* KeyedLoadStubCompiler::registers() { |
2887 // receiver, name, scratch1, scratch2, scratch3, scratch4. | 2889 // receiver, name, scratch1, scratch2, scratch3, scratch4. |
2888 static Register registers[] = { a1, a0, a2, a3, t0, t1 }; | 2890 static Register registers[] = { a1, a0, a2, a3, t0, t1 }; |
2889 return registers; | 2891 return registers; |
2890 } | 2892 } |
2891 | 2893 |
2892 | 2894 |
2893 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<String> name, | 2895 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, |
2894 Register name_reg, | 2896 Register name_reg, |
2895 Label* miss) { | 2897 Label* miss) { |
2896 __ Branch(miss, ne, name_reg, Operand(name)); | 2898 __ Branch(miss, ne, name_reg, Operand(name)); |
2897 } | 2899 } |
2898 | 2900 |
2899 | 2901 |
2900 #undef __ | 2902 #undef __ |
2901 #define __ ACCESS_MASM(masm) | 2903 #define __ ACCESS_MASM(masm) |
2902 | 2904 |
2903 | 2905 |
(...skipping 27 matching lines...) Expand all Loading... |
2931 | 2933 |
2932 | 2934 |
2933 #undef __ | 2935 #undef __ |
2934 #define __ ACCESS_MASM(masm()) | 2936 #define __ ACCESS_MASM(masm()) |
2935 | 2937 |
2936 | 2938 |
2937 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 2939 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
2938 Handle<JSObject> object, | 2940 Handle<JSObject> object, |
2939 Handle<GlobalObject> global, | 2941 Handle<GlobalObject> global, |
2940 Handle<JSGlobalPropertyCell> cell, | 2942 Handle<JSGlobalPropertyCell> cell, |
2941 Handle<String> name, | 2943 Handle<Name> name, |
2942 bool is_dont_delete) { | 2944 bool is_dont_delete) { |
2943 Label success, miss; | 2945 Label success, miss; |
2944 | 2946 |
2945 __ CheckMap( | 2947 __ CheckMap( |
2946 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); | 2948 receiver(), scratch1(), Handle<Map>(object->map()), &miss, DO_SMI_CHECK); |
2947 HandlerFrontendHeader( | 2949 HandlerFrontendHeader( |
2948 object, receiver(), Handle<JSObject>::cast(global), name, &miss); | 2950 object, receiver(), Handle<JSObject>::cast(global), name, &miss); |
2949 | 2951 |
2950 // Get the value from the cell. | 2952 // Get the value from the cell. |
2951 __ li(a3, Operand(cell)); | 2953 __ li(a3, Operand(cell)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2994 __ Jump(ic, RelocInfo::CODE_TARGET); | 2996 __ Jump(ic, RelocInfo::CODE_TARGET); |
2995 | 2997 |
2996 // Return the generated code. | 2998 // Return the generated code. |
2997 return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string()); | 2999 return GetCode(Code::IC_FRAGMENT, Code::NORMAL, factory()->empty_string()); |
2998 } | 3000 } |
2999 | 3001 |
3000 | 3002 |
3001 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( | 3003 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( |
3002 MapHandleList* receiver_maps, | 3004 MapHandleList* receiver_maps, |
3003 CodeHandleList* handlers, | 3005 CodeHandleList* handlers, |
3004 Handle<String> name, | 3006 Handle<Name> name, |
3005 Code::StubType type, | 3007 Code::StubType type, |
3006 IcCheckType check) { | 3008 IcCheckType check) { |
3007 Label miss; | 3009 Label miss; |
3008 | 3010 |
3009 if (check == PROPERTY) { | 3011 if (check == PROPERTY) { |
3010 GenerateNameCheck(name, this->name(), &miss); | 3012 GenerateNameCheck(name, this->name(), &miss); |
3011 } | 3013 } |
3012 | 3014 |
3013 __ JumpIfSmi(receiver(), &miss); | 3015 __ JumpIfSmi(receiver(), &miss); |
3014 Register map_reg = scratch1(); | 3016 Register map_reg = scratch1(); |
(...skipping 11 matching lines...) Expand all Loading... |
3026 // Return the generated code. | 3028 // Return the generated code. |
3027 InlineCacheState state = | 3029 InlineCacheState state = |
3028 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; | 3030 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; |
3029 return GetCode(Code::IC_FRAGMENT, type, name, state); | 3031 return GetCode(Code::IC_FRAGMENT, type, name, state); |
3030 } | 3032 } |
3031 | 3033 |
3032 | 3034 |
3033 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, | 3035 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object, |
3034 int index, | 3036 int index, |
3035 Handle<Map> transition, | 3037 Handle<Map> transition, |
3036 Handle<String> name) { | 3038 Handle<Name> name) { |
3037 // ----------- S t a t e ------------- | 3039 // ----------- S t a t e ------------- |
3038 // -- a0 : value | 3040 // -- a0 : value |
3039 // -- a1 : key | 3041 // -- a1 : key |
3040 // -- a2 : receiver | 3042 // -- a2 : receiver |
3041 // -- ra : return address | 3043 // -- ra : return address |
3042 // ----------------------------------- | 3044 // ----------------------------------- |
3043 | 3045 |
3044 Label miss; | 3046 Label miss; |
3045 | 3047 |
3046 Counters* counters = masm()->isolate()->counters(); | 3048 Counters* counters = masm()->isolate()->counters(); |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4134 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4136 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4135 } | 4137 } |
4136 } | 4138 } |
4137 | 4139 |
4138 | 4140 |
4139 #undef __ | 4141 #undef __ |
4140 | 4142 |
4141 } } // namespace v8::internal | 4143 } } // namespace v8::internal |
4142 | 4144 |
4143 #endif // V8_TARGET_ARCH_MIPS | 4145 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |