Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: src/ic.cc

Issue 3046006: Inline in-object property stores when in loop and not in top-level (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 State state = target->ic_state(); 270 State state = target->ic_state();
271 if (state == UNINITIALIZED) return; 271 if (state == UNINITIALIZED) return;
272 Code* code = 272 Code* code =
273 StubCache::FindCallInitialize(target->arguments_count(), 273 StubCache::FindCallInitialize(target->arguments_count(),
274 target->ic_in_loop(), 274 target->ic_in_loop(),
275 target->kind()); 275 target->kind());
276 SetTargetAtAddress(address, code); 276 SetTargetAtAddress(address, code);
277 } 277 }
278 278
279 279
280 void KeyedLoadIC::ClearInlinedVersion(Address address) {
281 // Insert null as the map to check for to make sure the map check fails
282 // sending control flow to the IC instead of the inlined version.
283 PatchInlinedLoad(address, Heap::null_value());
284 }
285
286
280 void KeyedLoadIC::Clear(Address address, Code* target) { 287 void KeyedLoadIC::Clear(Address address, Code* target) {
281 if (target->ic_state() == UNINITIALIZED) return; 288 if (target->ic_state() == UNINITIALIZED) return;
282 // Make sure to also clear the map used in inline fast cases. If we 289 // Make sure to also clear the map used in inline fast cases. If we
283 // do not clear these maps, cached code can keep objects alive 290 // do not clear these maps, cached code can keep objects alive
284 // through the embedded maps. 291 // through the embedded maps.
285 ClearInlinedVersion(address); 292 ClearInlinedVersion(address);
286 SetTargetAtAddress(address, initialize_stub()); 293 SetTargetAtAddress(address, initialize_stub());
287 } 294 }
288 295
289 296
297 void LoadIC::ClearInlinedVersion(Address address) {
298 // Reset the map check of the inlined inobject property load (if
299 // present) to guarantee failure by holding an invalid map (the null
300 // value). The offset can be patched to anything.
301 PatchInlinedLoad(address, Heap::null_value(), 0);
302 }
303
304
290 void LoadIC::Clear(Address address, Code* target) { 305 void LoadIC::Clear(Address address, Code* target) {
291 if (target->ic_state() == UNINITIALIZED) return; 306 if (target->ic_state() == UNINITIALIZED) return;
292 ClearInlinedVersion(address); 307 ClearInlinedVersion(address);
293 SetTargetAtAddress(address, initialize_stub()); 308 SetTargetAtAddress(address, initialize_stub());
294 } 309 }
295 310
296 311
312 void StoreIC::ClearInlinedVersion(Address address) {
313 // Reset the map check of the inlined inobject property store (if
314 // present) to guarantee failure by holding an invalid map (the null
315 // value). The offset can be patched to anything.
316 PatchInlinedStore(address, Heap::null_value(), 0);
317 }
318
319
297 void StoreIC::Clear(Address address, Code* target) { 320 void StoreIC::Clear(Address address, Code* target) {
298 if (target->ic_state() == UNINITIALIZED) return; 321 if (target->ic_state() == UNINITIALIZED) return;
322 ClearInlinedVersion(address);
299 SetTargetAtAddress(address, initialize_stub()); 323 SetTargetAtAddress(address, initialize_stub());
300 } 324 }
301 325
302 326
327 void KeyedStoreIC::ClearInlinedVersion(Address address) {
328 // Insert null as the elements map to check for. This will make
329 // sure that the elements fast-case map check fails so that control
330 // flows to the IC instead of the inlined version.
331 PatchInlinedStore(address, Heap::null_value());
332 }
333
334
335 void KeyedStoreIC::RestoreInlinedVersion(Address address) {
336 // Restore the fast-case elements map check so that the inlined
337 // version can be used again.
338 PatchInlinedStore(address, Heap::fixed_array_map());
339 }
340
341
303 void KeyedStoreIC::Clear(Address address, Code* target) { 342 void KeyedStoreIC::Clear(Address address, Code* target) {
304 if (target->ic_state() == UNINITIALIZED) return; 343 if (target->ic_state() == UNINITIALIZED) return;
305 SetTargetAtAddress(address, initialize_stub()); 344 SetTargetAtAddress(address, initialize_stub());
306 } 345 }
307 346
308 347
309 Code* KeyedLoadIC::external_array_stub(JSObject::ElementsKind elements_kind) { 348 Code* KeyedLoadIC::external_array_stub(JSObject::ElementsKind elements_kind) {
310 switch (elements_kind) { 349 switch (elements_kind) {
311 case JSObject::EXTERNAL_BYTE_ELEMENTS: 350 case JSObject::EXTERNAL_BYTE_ELEMENTS:
312 return Builtins::builtin(Builtins::KeyedLoadIC_ExternalByteArray); 351 return Builtins::builtin(Builtins::KeyedLoadIC_ExternalByteArray);
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 if (can_be_inlined) { 809 if (can_be_inlined) {
771 Map* map = lookup.holder()->map(); 810 Map* map = lookup.holder()->map();
772 // Property's index in the properties array. If negative we have 811 // Property's index in the properties array. If negative we have
773 // an inobject property. 812 // an inobject property.
774 int index = lookup.GetFieldIndex() - map->inobject_properties(); 813 int index = lookup.GetFieldIndex() - map->inobject_properties();
775 if (index < 0) { 814 if (index < 0) {
776 // Index is an offset from the end of the object. 815 // Index is an offset from the end of the object.
777 int offset = map->instance_size() + (index * kPointerSize); 816 int offset = map->instance_size() + (index * kPointerSize);
778 if (PatchInlinedLoad(address(), map, offset)) { 817 if (PatchInlinedLoad(address(), map, offset)) {
779 set_target(megamorphic_stub()); 818 set_target(megamorphic_stub());
780 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
781 #ifdef DEBUG 819 #ifdef DEBUG
782 if (FLAG_trace_ic) { 820 if (FLAG_trace_ic) {
783 PrintF("[LoadIC : inline patch %s]\n", *name->ToCString()); 821 PrintF("[LoadIC : inline patch %s]\n", *name->ToCString());
784 } 822 }
823 #endif
824 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex());
825 #ifdef DEBUG
785 } else { 826 } else {
786 if (FLAG_trace_ic) { 827 if (FLAG_trace_ic) {
787 PrintF("[LoadIC : no inline patch %s (patching failed)]\n", 828 PrintF("[LoadIC : no inline patch %s (patching failed)]\n",
788 *name->ToCString()); 829 *name->ToCString());
789 } 830 }
790 } 831 }
791 } else { 832 } else {
792 if (FLAG_trace_ic) { 833 if (FLAG_trace_ic) {
793 PrintF("[LoadIC : no inline patch %s (not inobject)]\n", 834 PrintF("[LoadIC : no inline patch %s (not inobject)]\n",
794 *name->ToCString()); 835 *name->ToCString());
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n"); 1239 if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
1199 #endif 1240 #endif
1200 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength); 1241 Code* target = Builtins::builtin(Builtins::StoreIC_ArrayLength);
1201 set_target(target); 1242 set_target(target);
1202 return receiver->SetProperty(*name, *value, NONE); 1243 return receiver->SetProperty(*name, *value, NONE);
1203 } 1244 }
1204 1245
1205 // Lookup the property locally in the receiver. 1246 // Lookup the property locally in the receiver.
1206 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { 1247 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
1207 LookupResult lookup; 1248 LookupResult lookup;
1249
1208 if (LookupForWrite(*receiver, *name, &lookup)) { 1250 if (LookupForWrite(*receiver, *name, &lookup)) {
1251 bool can_be_inlined =
1252 state == UNINITIALIZED &&
1253 lookup.IsProperty() &&
1254 lookup.holder() == *receiver &&
1255 lookup.type() == FIELD &&
1256 !receiver->IsAccessCheckNeeded();
1257
1258 if (can_be_inlined) {
1259 Map* map = lookup.holder()->map();
1260 // Property's index in the properties array. If negative we have
1261 // an inobject property.
1262 int index = lookup.GetFieldIndex() - map->inobject_properties();
1263 if (index < 0) {
1264 // Index is an offset from the end of the object.
1265 int offset = map->instance_size() + (index * kPointerSize);
1266 if (PatchInlinedStore(address(), map, offset)) {
1267 set_target(megamorphic_stub());
1268 #ifdef DEBUG
1269 if (FLAG_trace_ic) {
1270 PrintF("[StoreIC : inline patch %s]\n", *name->ToCString());
1271 }
1272 #endif
1273 return receiver->SetProperty(*name, *value, NONE);
1274 #ifdef DEBUG
1275
1276 } else {
1277 if (FLAG_trace_ic) {
1278 PrintF("[StoreIC : no inline patch %s (patching failed)]\n",
1279 *name->ToCString());
1280 }
1281 }
1282 } else {
1283 if (FLAG_trace_ic) {
1284 PrintF("[StoreIC : no inline patch %s (not inobject)]\n",
1285 *name->ToCString());
1286 }
1287 }
1288 } else {
1289 if (state == PREMONOMORPHIC) {
1290 if (FLAG_trace_ic) {
1291 PrintF("[StoreIC : no inline patch %s (not inlinable)]\n",
1292 *name->ToCString());
1293 #endif
1294 }
1295 }
1296 }
1297
1298 // If no inlined store ic was patched, generate a stub for this
1299 // store.
1209 UpdateCaches(&lookup, state, receiver, name, value); 1300 UpdateCaches(&lookup, state, receiver, name, value);
1210 } 1301 }
1211 } 1302 }
1212 1303
1213 // Set the property. 1304 // Set the property.
1214 return receiver->SetProperty(*name, *value, NONE); 1305 return receiver->SetProperty(*name, *value, NONE);
1215 } 1306 }
1216 1307
1217 1308
1218 void StoreIC::UpdateCaches(LookupResult* lookup, 1309 void StoreIC::UpdateCaches(LookupResult* lookup,
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 #undef ADDR 1818 #undef ADDR
1728 }; 1819 };
1729 1820
1730 1821
1731 Address IC::AddressFromUtilityId(IC::UtilityId id) { 1822 Address IC::AddressFromUtilityId(IC::UtilityId id) {
1732 return IC_utilities[id]; 1823 return IC_utilities[id];
1733 } 1824 }
1734 1825
1735 1826
1736 } } // namespace v8::internal 1827 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698