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

Side by Side Diff: src/ic.cc

Issue 717001: Refactor the code cache to handle large number of properties on the global ob... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 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/objects.h » ('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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698