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