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