| OLD | NEW | 
|---|
| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 56   UNREACHABLE(); | 56   UNREACHABLE(); | 
| 57   return 0; | 57   return 0; | 
| 58 } | 58 } | 
| 59 | 59 | 
| 60 void IC::TraceIC(const char* type, | 60 void IC::TraceIC(const char* type, | 
| 61                  Handle<String> name, | 61                  Handle<String> name, | 
| 62                  State old_state, | 62                  State old_state, | 
| 63                  Code* new_target, | 63                  Code* new_target, | 
| 64                  const char* extra_info) { | 64                  const char* extra_info) { | 
| 65   if (FLAG_trace_ic) { | 65   if (FLAG_trace_ic) { | 
| 66     State new_state = StateFrom(new_target, Heap::undefined_value()); | 66     State new_state = StateFrom(new_target, | 
|  | 67                                 Heap::undefined_value(), | 
|  | 68                                 Heap::undefined_value()); | 
| 67     PrintF("[%s (%c->%c)%s", type, | 69     PrintF("[%s (%c->%c)%s", type, | 
| 68            TransitionMarkFromState(old_state), | 70            TransitionMarkFromState(old_state), | 
| 69            TransitionMarkFromState(new_state), | 71            TransitionMarkFromState(new_state), | 
| 70            extra_info); | 72            extra_info); | 
| 71     name->Print(); | 73     name->Print(); | 
| 72     PrintF("]\n"); | 74     PrintF("]\n"); | 
| 73   } | 75   } | 
| 74 } | 76 } | 
| 75 #endif | 77 #endif | 
| 76 | 78 | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 125   Address addr = pc() - Assembler::kCallTargetAddressOffset; | 127   Address addr = pc() - Assembler::kCallTargetAddressOffset; | 
| 126   // Return the address in the original code. This is the place where | 128   // Return the address in the original code. This is the place where | 
| 127   // the call which has been overwritten by the DebugBreakXXX resides | 129   // the call which has been overwritten by the DebugBreakXXX resides | 
| 128   // and the place where the inline cache system should look. | 130   // and the place where the inline cache system should look. | 
| 129   intptr_t delta = | 131   intptr_t delta = | 
| 130       original_code->instruction_start() - code->instruction_start(); | 132       original_code->instruction_start() - code->instruction_start(); | 
| 131   return addr + delta; | 133   return addr + delta; | 
| 132 } | 134 } | 
| 133 #endif | 135 #endif | 
| 134 | 136 | 
| 135 IC::State IC::StateFrom(Code* target, Object* receiver) { | 137 IC::State IC::StateFrom(Code* target, Object* receiver, Object* name) { | 
| 136   IC::State state = target->ic_state(); | 138   IC::State state = target->ic_state(); | 
| 137 | 139 | 
| 138   if (state != MONOMORPHIC) return state; | 140   if (state != MONOMORPHIC) return state; | 
| 139   if (receiver->IsUndefined() || receiver->IsNull()) return state; | 141   if (receiver->IsUndefined() || receiver->IsNull()) return state; | 
| 140 | 142 | 
| 141   Map* map = GetCodeCacheMapForObject(receiver); | 143   Map* map = GetCodeCacheMapForObject(receiver); | 
| 142 | 144 | 
| 143   // Decide whether the inline cache failed because of changes to the | 145   // Decide whether the inline cache failed because of changes to the | 
| 144   // receiver itself or changes to one of its prototypes. | 146   // receiver itself or changes to one of its prototypes. | 
| 145   // | 147   // | 
| 146   // If there are changes to the receiver itself, the map of the | 148   // If there are changes to the receiver itself, the map of the | 
| 147   // receiver will have changed and the current target will not be in | 149   // receiver will have changed and the current target will not be in | 
| 148   // the receiver map's code cache.  Therefore, if the current target | 150   // the receiver map's code cache.  Therefore, if the current target | 
| 149   // is in the receiver map's code cache, the inline cache failed due | 151   // is in the receiver map's code cache, the inline cache failed due | 
| 150   // to prototype check failure. | 152   // to prototype check failure. | 
| 151   int index = map->IndexInCodeCache(target); | 153   int index = map->IndexInCodeCache(String::cast(name), target); | 
| 152   if (index >= 0) { | 154   if (index >= 0) { | 
| 153     // For keyed load/store, the most likely cause of cache failure is | 155     // For keyed load/store, the most likely cause of cache failure is | 
| 154     // that the key has changed.  We do not distinguish between | 156     // that the key has changed.  We do not distinguish between | 
| 155     // prototype and non-prototype failures for keyed access. | 157     // prototype and non-prototype failures for keyed access. | 
| 156     Code::Kind kind = target->kind(); | 158     Code::Kind kind = target->kind(); | 
| 157     if (kind == Code::KEYED_LOAD_IC || kind == Code::KEYED_STORE_IC) { | 159     if (kind == Code::KEYED_LOAD_IC || kind == Code::KEYED_STORE_IC) { | 
| 158       return MONOMORPHIC; | 160       return MONOMORPHIC; | 
| 159     } | 161     } | 
| 160 | 162 | 
| 161     // Remove the target from the code cache to avoid hitting the same | 163     // Remove the target from the code cache to avoid hitting the same | 
| 162     // invalid stub again. | 164     // invalid stub again. | 
| 163     map->RemoveFromCodeCache(index); | 165     map->RemoveFromCodeCache(String::cast(name), target, index); | 
| 164 | 166 | 
| 165     return MONOMORPHIC_PROTOTYPE_FAILURE; | 167     return MONOMORPHIC_PROTOTYPE_FAILURE; | 
| 166   } | 168   } | 
| 167 | 169 | 
| 168   // The builtins object is special.  It only changes when JavaScript | 170   // The builtins object is special.  It only changes when JavaScript | 
| 169   // builtins are loaded lazily.  It is important to keep inline | 171   // builtins are loaded lazily.  It is important to keep inline | 
| 170   // caches for the builtins object monomorphic.  Therefore, if we get | 172   // caches for the builtins object monomorphic.  Therefore, if we get | 
| 171   // an inline cache miss for the builtins object after lazily loading | 173   // an inline cache miss for the builtins object after lazily loading | 
| 172   // JavaScript builtins, we return uninitialized as the state to | 174   // JavaScript builtins, we return uninitialized as the state to | 
| 173   // force the inline cache back to monomorphic state. | 175   // force the inline cache back to monomorphic state. | 
| (...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1293 | 1295 | 
| 1294 // ---------------------------------------------------------------------------- | 1296 // ---------------------------------------------------------------------------- | 
| 1295 // Static IC stub generators. | 1297 // Static IC stub generators. | 
| 1296 // | 1298 // | 
| 1297 | 1299 | 
| 1298 // Used from ic_<arch>.cc. | 1300 // Used from ic_<arch>.cc. | 
| 1299 Object* CallIC_Miss(Arguments args) { | 1301 Object* CallIC_Miss(Arguments args) { | 
| 1300   NoHandleAllocation na; | 1302   NoHandleAllocation na; | 
| 1301   ASSERT(args.length() == 2); | 1303   ASSERT(args.length() == 2); | 
| 1302   CallIC ic; | 1304   CallIC ic; | 
| 1303   IC::State state = IC::StateFrom(ic.target(), args[0]); | 1305   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 
| 1304   Object* result = | 1306   Object* result = | 
| 1305       ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1)); | 1307       ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1)); | 
| 1306 | 1308 | 
| 1307   // The first time the inline cache is updated may be the first time the | 1309   // The first time the inline cache is updated may be the first time the | 
| 1308   // function it references gets called.  If the function was lazily compiled | 1310   // function it references gets called.  If the function was lazily compiled | 
| 1309   // then the first call will trigger a compilation.  We check for this case | 1311   // then the first call will trigger a compilation.  We check for this case | 
| 1310   // and we do the compilation immediately, instead of waiting for the stub | 1312   // and we do the compilation immediately, instead of waiting for the stub | 
| 1311   // currently attached to the JSFunction object to trigger compilation.  We | 1313   // currently attached to the JSFunction object to trigger compilation.  We | 
| 1312   // do this in the case where we know that the inline cache is inside a loop, | 1314   // do this in the case where we know that the inline cache is inside a loop, | 
| 1313   // because then we know that we want to optimize the function. | 1315   // because then we know that we want to optimize the function. | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 1326   } | 1328   } | 
| 1327   return *function; | 1329   return *function; | 
| 1328 } | 1330 } | 
| 1329 | 1331 | 
| 1330 | 1332 | 
| 1331 // Used from ic_<arch>.cc. | 1333 // Used from ic_<arch>.cc. | 
| 1332 Object* LoadIC_Miss(Arguments args) { | 1334 Object* LoadIC_Miss(Arguments args) { | 
| 1333   NoHandleAllocation na; | 1335   NoHandleAllocation na; | 
| 1334   ASSERT(args.length() == 2); | 1336   ASSERT(args.length() == 2); | 
| 1335   LoadIC ic; | 1337   LoadIC ic; | 
| 1336   IC::State state = IC::StateFrom(ic.target(), args[0]); | 1338   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 
| 1337   return ic.Load(state, args.at<Object>(0), args.at<String>(1)); | 1339   return ic.Load(state, args.at<Object>(0), args.at<String>(1)); | 
| 1338 } | 1340 } | 
| 1339 | 1341 | 
| 1340 | 1342 | 
| 1341 // Used from ic_<arch>.cc | 1343 // Used from ic_<arch>.cc | 
| 1342 Object* KeyedLoadIC_Miss(Arguments args) { | 1344 Object* KeyedLoadIC_Miss(Arguments args) { | 
| 1343   NoHandleAllocation na; | 1345   NoHandleAllocation na; | 
| 1344   ASSERT(args.length() == 2); | 1346   ASSERT(args.length() == 2); | 
| 1345   KeyedLoadIC ic; | 1347   KeyedLoadIC ic; | 
| 1346   IC::State state = IC::StateFrom(ic.target(), args[0]); | 1348   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 
| 1347   return ic.Load(state, args.at<Object>(0), args.at<Object>(1)); | 1349   return ic.Load(state, args.at<Object>(0), args.at<Object>(1)); | 
| 1348 } | 1350 } | 
| 1349 | 1351 | 
| 1350 | 1352 | 
| 1351 // Used from ic_<arch>.cc. | 1353 // Used from ic_<arch>.cc. | 
| 1352 Object* StoreIC_Miss(Arguments args) { | 1354 Object* StoreIC_Miss(Arguments args) { | 
| 1353   NoHandleAllocation na; | 1355   NoHandleAllocation na; | 
| 1354   ASSERT(args.length() == 3); | 1356   ASSERT(args.length() == 3); | 
| 1355   StoreIC ic; | 1357   StoreIC ic; | 
| 1356   IC::State state = IC::StateFrom(ic.target(), args[0]); | 1358   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 
| 1357   return ic.Store(state, args.at<Object>(0), args.at<String>(1), | 1359   return ic.Store(state, args.at<Object>(0), args.at<String>(1), | 
| 1358                   args.at<Object>(2)); | 1360                   args.at<Object>(2)); | 
| 1359 } | 1361 } | 
| 1360 | 1362 | 
| 1361 | 1363 | 
| 1362 Object* StoreIC_ArrayLength(Arguments args) { | 1364 Object* StoreIC_ArrayLength(Arguments args) { | 
| 1363   NoHandleAllocation nha; | 1365   NoHandleAllocation nha; | 
| 1364 | 1366 | 
| 1365   ASSERT(args.length() == 2); | 1367   ASSERT(args.length() == 2); | 
| 1366   JSObject* receiver = JSObject::cast(args[0]); | 1368   JSObject* receiver = JSObject::cast(args[0]); | 
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1404   // Return the stored value. | 1406   // Return the stored value. | 
| 1405   return value; | 1407   return value; | 
| 1406 } | 1408 } | 
| 1407 | 1409 | 
| 1408 | 1410 | 
| 1409 // Used from ic_<arch>.cc. | 1411 // Used from ic_<arch>.cc. | 
| 1410 Object* KeyedStoreIC_Miss(Arguments args) { | 1412 Object* KeyedStoreIC_Miss(Arguments args) { | 
| 1411   NoHandleAllocation na; | 1413   NoHandleAllocation na; | 
| 1412   ASSERT(args.length() == 3); | 1414   ASSERT(args.length() == 3); | 
| 1413   KeyedStoreIC ic; | 1415   KeyedStoreIC ic; | 
| 1414   IC::State state = IC::StateFrom(ic.target(), args[0]); | 1416   IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 
| 1415   return ic.Store(state, args.at<Object>(0), args.at<Object>(1), | 1417   return ic.Store(state, args.at<Object>(0), args.at<Object>(1), | 
| 1416                   args.at<Object>(2)); | 1418                   args.at<Object>(2)); | 
| 1417 } | 1419 } | 
| 1418 | 1420 | 
| 1419 | 1421 | 
| 1420 void BinaryOpIC::patch(Code* code) { | 1422 void BinaryOpIC::patch(Code* code) { | 
| 1421   set_target(code); | 1423   set_target(code); | 
| 1422 } | 1424 } | 
| 1423 | 1425 | 
| 1424 | 1426 | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1530 #undef ADDR | 1532 #undef ADDR | 
| 1531 }; | 1533 }; | 
| 1532 | 1534 | 
| 1533 | 1535 | 
| 1534 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1536 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 
| 1535   return IC_utilities[id]; | 1537   return IC_utilities[id]; | 
| 1536 } | 1538 } | 
| 1537 | 1539 | 
| 1538 | 1540 | 
| 1539 } }  // namespace v8::internal | 1541 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|