OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "runtime.h" | 35 #include "runtime.h" |
36 #include "stub-cache.h" | 36 #include "stub-cache.h" |
37 | 37 |
38 namespace v8 { namespace internal { | 38 namespace v8 { namespace internal { |
39 | 39 |
40 #ifdef DEBUG | 40 #ifdef DEBUG |
41 static char TransitionMarkFromState(IC::State state) { | 41 static char TransitionMarkFromState(IC::State state) { |
42 switch (state) { | 42 switch (state) { |
43 case UNINITIALIZED: return '0'; | 43 case UNINITIALIZED: return '0'; |
44 case UNINITIALIZED_IN_LOOP: return 'L'; | 44 case UNINITIALIZED_IN_LOOP: return 'L'; |
45 case PREMONOMORPHIC: return '0'; | 45 case PREMONOMORPHIC: return 'P'; |
46 case MONOMORPHIC: return '1'; | 46 case MONOMORPHIC: return '1'; |
47 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; | 47 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; |
48 case MEGAMORPHIC: return 'N'; | 48 case MEGAMORPHIC: return 'N'; |
49 | 49 |
50 // We never see the debugger states here, because the state is | 50 // We never see the debugger states here, because the state is |
51 // computed from the original code - not the patched code. Let | 51 // computed from the original code - not the patched code. Let |
52 // these cases fall through to the unreachable code below. | 52 // these cases fall through to the unreachable code below. |
53 case DEBUG_BREAK: break; | 53 case DEBUG_BREAK: break; |
54 case DEBUG_PREPARE_STEP_IN: break; | 54 case DEBUG_PREPARE_STEP_IN: break; |
55 } | 55 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 // Make sure to also clear the map used in inline fast cases. If we | 237 // Make sure to also clear the map used in inline fast cases. If we |
238 // do not clear these maps, cached code can keep objects alive | 238 // do not clear these maps, cached code can keep objects alive |
239 // through the embedded maps. | 239 // through the embedded maps. |
240 ClearInlinedVersion(address); | 240 ClearInlinedVersion(address); |
241 SetTargetAtAddress(address, initialize_stub()); | 241 SetTargetAtAddress(address, initialize_stub()); |
242 } | 242 } |
243 | 243 |
244 | 244 |
245 void LoadIC::Clear(Address address, Code* target) { | 245 void LoadIC::Clear(Address address, Code* target) { |
246 if (target->ic_state() == UNINITIALIZED) return; | 246 if (target->ic_state() == UNINITIALIZED) return; |
| 247 ClearInlinedVersion(address); |
247 SetTargetAtAddress(address, initialize_stub()); | 248 SetTargetAtAddress(address, initialize_stub()); |
248 } | 249 } |
249 | 250 |
250 | 251 |
251 void StoreIC::Clear(Address address, Code* target) { | 252 void StoreIC::Clear(Address address, Code* target) { |
252 if (target->ic_state() == UNINITIALIZED) return; | 253 if (target->ic_state() == UNINITIALIZED) return; |
253 SetTargetAtAddress(address, initialize_stub()); | 254 SetTargetAtAddress(address, initialize_stub()); |
254 } | 255 } |
255 | 256 |
256 | 257 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 object->Lookup(*name, &lookup); | 517 object->Lookup(*name, &lookup); |
517 | 518 |
518 // If lookup is invalid, check if we need to throw an exception. | 519 // If lookup is invalid, check if we need to throw an exception. |
519 if (!lookup.IsValid()) { | 520 if (!lookup.IsValid()) { |
520 if (FLAG_strict || is_contextual()) { | 521 if (FLAG_strict || is_contextual()) { |
521 return ReferenceError("not_defined", name); | 522 return ReferenceError("not_defined", name); |
522 } | 523 } |
523 LOG(SuspectReadEvent(*name, *object)); | 524 LOG(SuspectReadEvent(*name, *object)); |
524 } | 525 } |
525 | 526 |
| 527 bool can_be_inlined = |
| 528 FLAG_use_ic && |
| 529 state == PREMONOMORPHIC && |
| 530 lookup.IsValid() && |
| 531 lookup.IsLoaded() && |
| 532 lookup.IsCacheable() && |
| 533 lookup.holder() == *object && |
| 534 lookup.type() == FIELD && |
| 535 !object->IsAccessCheckNeeded(); |
| 536 |
| 537 if (can_be_inlined) { |
| 538 Map* map = lookup.holder()->map(); |
| 539 // Property's index in the properties array. If negative we have |
| 540 // an inobject property. |
| 541 int index = lookup.GetFieldIndex() - map->inobject_properties(); |
| 542 if (index < 0) { |
| 543 // Index is an offset from the end of the object. |
| 544 int offset = map->instance_size() + (index * kPointerSize); |
| 545 if (PatchInlinedLoad(address(), map, offset)) { |
| 546 set_target(megamorphic_stub()); |
| 547 return lookup.holder()->FastPropertyAt(lookup.GetFieldIndex()); |
| 548 } |
| 549 } |
| 550 } |
| 551 |
526 // Update inline cache and stub cache. | 552 // Update inline cache and stub cache. |
527 if (FLAG_use_ic && lookup.IsLoaded()) { | 553 if (FLAG_use_ic && lookup.IsLoaded()) { |
528 UpdateCaches(&lookup, state, object, name); | 554 UpdateCaches(&lookup, state, object, name); |
529 } | 555 } |
530 | 556 |
531 PropertyAttributes attr; | 557 PropertyAttributes attr; |
532 if (lookup.IsValid() && lookup.type() == INTERCEPTOR) { | 558 if (lookup.IsValid() && lookup.type() == INTERCEPTOR) { |
533 // Get the property. | 559 // Get the property. |
534 Object* result = object->GetProperty(*object, &lookup, *name, &attr); | 560 Object* result = object->GetProperty(*object, &lookup, *name, &attr); |
535 if (result->IsFailure()) return result; | 561 if (result->IsFailure()) return result; |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 | 753 |
728 if (use_ic) { | 754 if (use_ic) { |
729 set_target(generic_stub()); | 755 set_target(generic_stub()); |
730 // For JSObjects that are not value wrappers and that do not have | 756 // For JSObjects that are not value wrappers and that do not have |
731 // indexed interceptors, we initialize the inlined fast case (if | 757 // indexed interceptors, we initialize the inlined fast case (if |
732 // present) by patching the inlined map check. | 758 // present) by patching the inlined map check. |
733 if (object->IsJSObject() && | 759 if (object->IsJSObject() && |
734 !object->IsJSValue() && | 760 !object->IsJSValue() && |
735 !JSObject::cast(*object)->HasIndexedInterceptor()) { | 761 !JSObject::cast(*object)->HasIndexedInterceptor()) { |
736 Map* map = JSObject::cast(*object)->map(); | 762 Map* map = JSObject::cast(*object)->map(); |
737 PatchInlinedMapCheck(address(), map); | 763 PatchInlinedLoad(address(), map); |
738 } | 764 } |
739 } | 765 } |
740 | 766 |
741 // Get the property. | 767 // Get the property. |
742 return Runtime::GetObjectProperty(object, key); | 768 return Runtime::GetObjectProperty(object, key); |
743 } | 769 } |
744 | 770 |
745 | 771 |
746 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, | 772 void KeyedLoadIC::UpdateCaches(LookupResult* lookup, State state, |
747 Handle<Object> object, Handle<String> name) { | 773 Handle<Object> object, Handle<String> name) { |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1212 #undef ADDR | 1238 #undef ADDR |
1213 }; | 1239 }; |
1214 | 1240 |
1215 | 1241 |
1216 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1242 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
1217 return IC_utilities[id]; | 1243 return IC_utilities[id]; |
1218 } | 1244 } |
1219 | 1245 |
1220 | 1246 |
1221 } } // namespace v8::internal | 1247 } } // namespace v8::internal |
OLD | NEW |