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

Side by Side Diff: src/stub-cache.cc

Issue 148223002: Remove CallICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update test262 status file Created 6 years, 10 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/stub-cache.h ('k') | src/type-info.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 current_map = handle(Handle<HeapObject>::cast(next)->map()); 188 current_map = handle(Handle<HeapObject>::cast(next)->map());
189 if (current_map->is_dictionary_map()) cache_name = name; 189 if (current_map->is_dictionary_map()) cache_name = name;
190 } 190 }
191 191
192 // Compile the stub that is either shared for all names or 192 // Compile the stub that is either shared for all names or
193 // name specific if there are global objects involved. 193 // name specific if there are global objects involved.
194 Handle<Code> handler = FindHandler( 194 Handle<Code> handler = FindHandler(
195 cache_name, stub_holder, Code::LOAD_IC, flag); 195 cache_name, stub_holder, Code::LOAD_IC, flag);
196 if (!handler.is_null()) return handler; 196 if (!handler.is_null()) return handler;
197 197
198 LoadStubCompiler compiler(isolate_, flag); 198 LoadStubCompiler compiler(isolate_, kNoExtraICState, flag);
199 handler = compiler.CompileLoadNonexistent(type, last, cache_name); 199 handler = compiler.CompileLoadNonexistent(type, last, cache_name);
200 Map::UpdateCodeCache(stub_holder, cache_name, handler); 200 Map::UpdateCodeCache(stub_holder, cache_name, handler);
201 return handler; 201 return handler;
202 } 202 }
203 203
204 204
205 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) { 205 Handle<Code> StubCache::ComputeKeyedLoadElement(Handle<Map> receiver_map) {
206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); 206 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
207 Handle<Name> name = 207 Handle<Name> name =
208 isolate()->factory()->KeyedLoadElementMonomorphic_string(); 208 isolate()->factory()->KeyedLoadElementMonomorphic_string();
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 KeyedStoreStubCompiler compiler(isolate(), extra_state); 240 KeyedStoreStubCompiler compiler(isolate(), extra_state);
241 Handle<Code> code = compiler.CompileStoreElement(receiver_map); 241 Handle<Code> code = compiler.CompileStoreElement(receiver_map);
242 242
243 Map::UpdateCodeCache(receiver_map, name, code); 243 Map::UpdateCodeCache(receiver_map, name, code);
244 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state()) 244 ASSERT(KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state())
245 == store_mode); 245 == store_mode);
246 return code; 246 return code;
247 } 247 }
248 248
249 249
250 #define CALL_LOGGER_TAG(kind, type) \ 250 #define CALL_LOGGER_TAG(kind, type) (Logger::KEYED_##type)
251 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
252
253 Handle<Code> StubCache::ComputeCallConstant(int argc,
254 Code::Kind kind,
255 ExtraICState extra_state,
256 Handle<Name> name,
257 Handle<Object> object,
258 Handle<JSObject> holder,
259 Handle<JSFunction> function) {
260 // Compute the check type and the map.
261 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
262 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
263 isolate_, *object, cache_holder));
264
265 // Compute check type based on receiver/holder.
266 CheckType check = RECEIVER_MAP_CHECK;
267 if (object->IsString()) {
268 check = STRING_CHECK;
269 } else if (object->IsSymbol()) {
270 check = SYMBOL_CHECK;
271 } else if (object->IsNumber()) {
272 check = NUMBER_CHECK;
273 } else if (object->IsBoolean()) {
274 check = BOOLEAN_CHECK;
275 }
276
277 if (check != RECEIVER_MAP_CHECK &&
278 !function->IsBuiltin() &&
279 function->shared()->is_classic_mode()) {
280 // Calling non-strict non-builtins with a value as the receiver
281 // requires boxing.
282 return Handle<Code>::null();
283 }
284
285 Code::Flags flags = Code::ComputeMonomorphicFlags(
286 kind, extra_state, cache_holder, Code::FAST, argc);
287 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
288 isolate_);
289 if (probe->IsCode()) return Handle<Code>::cast(probe);
290
291 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
292 Handle<Code> code =
293 compiler.CompileCallConstant(object, holder, name, check, function);
294 code->set_check_type(check);
295 ASSERT(flags == code->flags());
296 PROFILE(isolate_,
297 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
298 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
299
300 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
301 return code;
302 }
303
304
305 Handle<Code> StubCache::ComputeCallField(int argc,
306 Code::Kind kind,
307 ExtraICState extra_state,
308 Handle<Name> name,
309 Handle<Object> object,
310 Handle<JSObject> holder,
311 PropertyIndex index) {
312 // Compute the check type and the map.
313 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
314 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
315 isolate_, *object, cache_holder));
316
317 // TODO(1233596): We cannot do receiver map check for non-JS objects
318 // because they may be represented as immediates without a
319 // map. Instead, we check against the map in the holder.
320 if (object->IsNumber() || object->IsSymbol() ||
321 object->IsBoolean() || object->IsString()) {
322 object = holder;
323 }
324
325 Code::Flags flags = Code::ComputeMonomorphicFlags(
326 kind, extra_state, cache_holder, Code::FAST, argc);
327 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
328 isolate_);
329 if (probe->IsCode()) return Handle<Code>::cast(probe);
330
331 CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder);
332 Handle<Code> code =
333 compiler.CompileCallField(Handle<JSObject>::cast(object),
334 holder, index, name);
335 ASSERT(flags == code->flags());
336 PROFILE(isolate_,
337 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
338 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
339 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
340 return code;
341 }
342
343
344 Handle<Code> StubCache::ComputeCallInterceptor(int argc,
345 Code::Kind kind,
346 ExtraICState extra_state,
347 Handle<Name> name,
348 Handle<Object> object,
349 Handle<JSObject> holder) {
350 // Compute the check type and the map.
351 InlineCacheHolderFlag cache_holder = IC::GetCodeCacheForObject(*object);
352 Handle<HeapObject> stub_holder(IC::GetCodeCacheHolder(
353 isolate_, *object, cache_holder));
354
355 // TODO(1233596): We cannot do receiver map check for non-JS objects
356 // because they may be represented as immediates without a
357 // map. Instead, we check against the map in the holder.
358 if (object->IsNumber() || object->IsSymbol() ||
359 object->IsBoolean() || object->IsString()) {
360 object = holder;
361 }
362
363 Code::Flags flags = Code::ComputeMonomorphicFlags(
364 kind, extra_state, cache_holder, Code::FAST, argc);
365 Handle<Object> probe(stub_holder->map()->FindInCodeCache(*name, flags),
366 isolate_);
367 if (probe->IsCode()) return Handle<Code>::cast(probe);
368
369 CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder);
370 Handle<Code> code =
371 compiler.CompileCallInterceptor(Handle<JSObject>::cast(object),
372 holder, name);
373 ASSERT(flags == code->flags());
374 PROFILE(isolate(),
375 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
376 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
377 HeapObject::UpdateMapCodeCache(stub_holder, name, code);
378 return code;
379 }
380
381
382 Handle<Code> StubCache::ComputeCallGlobal(int argc,
383 Code::Kind kind,
384 ExtraICState extra_state,
385 Handle<Name> name,
386 Handle<JSObject> receiver,
387 Handle<GlobalObject> holder,
388 Handle<PropertyCell> cell,
389 Handle<JSFunction> function) {
390 Code::Flags flags = Code::ComputeMonomorphicFlags(
391 kind, extra_state, OWN_MAP, Code::NORMAL, argc);
392 Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags),
393 isolate_);
394 if (probe->IsCode()) return Handle<Code>::cast(probe);
395
396 CallStubCompiler compiler(isolate(), argc, kind, extra_state);
397 Handle<Code> code =
398 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
399 ASSERT(flags == code->flags());
400 PROFILE(isolate(),
401 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name));
402 GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code));
403 HeapObject::UpdateMapCodeCache(receiver, name, code);
404 return code;
405 }
406
407 251
408 static void FillCache(Isolate* isolate, Handle<Code> code) { 252 static void FillCache(Isolate* isolate, Handle<Code> code) {
409 Handle<UnseededNumberDictionary> dictionary = 253 Handle<UnseededNumberDictionary> dictionary =
410 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 254 UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(),
411 code->flags(), 255 code->flags(),
412 code); 256 code);
413 isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 257 isolate->heap()->public_set_non_monomorphic_cache(*dictionary);
414 } 258 }
415 259
416 260
417 Code* StubCache::FindCallInitialize(int argc, Code::Kind kind) {
418 Code::Flags flags = Code::ComputeFlags(
419 kind, UNINITIALIZED, kNoExtraICState, Code::NORMAL, argc);
420 UnseededNumberDictionary* dictionary =
421 isolate()->heap()->non_monomorphic_cache();
422 int entry = dictionary->FindEntry(isolate(), flags);
423 ASSERT(entry != -1);
424 Object* code = dictionary->ValueAt(entry);
425 // This might be called during the marking phase of the collector
426 // hence the unchecked cast.
427 return reinterpret_cast<Code*>(code);
428 }
429
430
431 Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) { 261 Code* StubCache::FindPreMonomorphicIC(Code::Kind kind, ExtraICState state) {
432 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state); 262 Code::Flags flags = Code::ComputeFlags(kind, PREMONOMORPHIC, state);
433 UnseededNumberDictionary* dictionary = 263 UnseededNumberDictionary* dictionary =
434 isolate()->heap()->non_monomorphic_cache(); 264 isolate()->heap()->non_monomorphic_cache();
435 int entry = dictionary->FindEntry(isolate(), flags); 265 int entry = dictionary->FindEntry(isolate(), flags);
436 ASSERT(entry != -1); 266 ASSERT(entry != -1);
437 Object* code = dictionary->ValueAt(entry); 267 Object* code = dictionary->ValueAt(entry);
438 // This might be called during the marking phase of the collector 268 // This might be called during the marking phase of the collector
439 // hence the unchecked cast. 269 // hence the unchecked cast.
440 return reinterpret_cast<Code*>(code); 270 return reinterpret_cast<Code*>(code);
441 } 271 }
442 272
443 273
444 Handle<Code> StubCache::ComputeCallInitialize(int argc, Code::Kind kind) {
445 Code::Flags flags = Code::ComputeFlags(
446 kind, UNINITIALIZED, kNoExtraICState, Code::NORMAL, argc);
447 Handle<UnseededNumberDictionary> cache =
448 isolate_->factory()->non_monomorphic_cache();
449 int entry = cache->FindEntry(isolate_, flags);
450 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
451
452 StubCompiler compiler(isolate_);
453 Handle<Code> code = compiler.CompileCallInitialize(flags);
454 FillCache(isolate_, code);
455 return code;
456 }
457
458
459 Handle<Code> StubCache::ComputeCallInitialize(int argc) {
460 return ComputeCallInitialize(argc, Code::CALL_IC);
461 }
462
463
464 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
465 return ComputeCallInitialize(argc, Code::KEYED_CALL_IC);
466 }
467
468
469 Handle<Code> StubCache::ComputeCallPreMonomorphic(
470 int argc,
471 Code::Kind kind,
472 ExtraICState extra_state) {
473 Code::Flags flags =
474 Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, Code::NORMAL, argc);
475 Handle<UnseededNumberDictionary> cache =
476 isolate_->factory()->non_monomorphic_cache();
477 int entry = cache->FindEntry(isolate_, flags);
478 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
479
480 StubCompiler compiler(isolate_);
481 Handle<Code> code = compiler.CompileCallPreMonomorphic(flags);
482 FillCache(isolate_, code);
483 return code;
484 }
485
486
487 Handle<Code> StubCache::ComputeCallNormal(int argc,
488 Code::Kind kind,
489 ExtraICState extra_state) {
490 Code::Flags flags =
491 Code::ComputeFlags(kind, MONOMORPHIC, extra_state, Code::NORMAL, argc);
492 Handle<UnseededNumberDictionary> cache =
493 isolate_->factory()->non_monomorphic_cache();
494 int entry = cache->FindEntry(isolate_, flags);
495 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
496
497 StubCompiler compiler(isolate_);
498 Handle<Code> code = compiler.CompileCallNormal(flags);
499 FillCache(isolate_, code);
500 return code;
501 }
502
503
504 Handle<Code> StubCache::ComputeCallArguments(int argc) {
505 Code::Flags flags =
506 Code::ComputeFlags(Code::KEYED_CALL_IC, MEGAMORPHIC,
507 kNoExtraICState, Code::NORMAL, argc);
508 Handle<UnseededNumberDictionary> cache =
509 isolate_->factory()->non_monomorphic_cache();
510 int entry = cache->FindEntry(isolate_, flags);
511 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
512
513 StubCompiler compiler(isolate_);
514 Handle<Code> code = compiler.CompileCallArguments(flags);
515 FillCache(isolate_, code);
516 return code;
517 }
518
519
520 Handle<Code> StubCache::ComputeCallMegamorphic(
521 int argc,
522 Code::Kind kind,
523 ExtraICState extra_state) {
524 Code::Flags flags =
525 Code::ComputeFlags(kind, MEGAMORPHIC, extra_state,
526 Code::NORMAL, argc);
527 Handle<UnseededNumberDictionary> cache =
528 isolate_->factory()->non_monomorphic_cache();
529 int entry = cache->FindEntry(isolate_, flags);
530 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
531
532 StubCompiler compiler(isolate_);
533 Handle<Code> code = compiler.CompileCallMegamorphic(flags);
534 FillCache(isolate_, code);
535 return code;
536 }
537
538
539 Handle<Code> StubCache::ComputeLoad(InlineCacheState ic_state, 274 Handle<Code> StubCache::ComputeLoad(InlineCacheState ic_state,
540 ExtraICState extra_state) { 275 ExtraICState extra_state) {
541 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state); 276 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, ic_state, extra_state);
542 Handle<UnseededNumberDictionary> cache = 277 Handle<UnseededNumberDictionary> cache =
543 isolate_->factory()->non_monomorphic_cache(); 278 isolate_->factory()->non_monomorphic_cache();
544 int entry = cache->FindEntry(isolate_, flags); 279 int entry = cache->FindEntry(isolate_, flags);
545 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 280 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
546 281
547 StubCompiler compiler(isolate_); 282 StubCompiler compiler(isolate_);
548 Handle<Code> code; 283 Handle<Code> code;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 code = compiler.CompileStoreMegamorphic(flags); 315 code = compiler.CompileStoreMegamorphic(flags);
581 } else { 316 } else {
582 UNREACHABLE(); 317 UNREACHABLE();
583 } 318 }
584 319
585 FillCache(isolate_, code); 320 FillCache(isolate_, code);
586 return code; 321 return code;
587 } 322 }
588 323
589 324
590 Handle<Code> StubCache::ComputeCallMiss(int argc,
591 Code::Kind kind,
592 ExtraICState extra_state) {
593 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
594 // and monomorphic stubs are not mixed up together in the stub cache.
595 Code::Flags flags =
596 Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state,
597 Code::NORMAL, argc, OWN_MAP);
598 Handle<UnseededNumberDictionary> cache =
599 isolate_->factory()->non_monomorphic_cache();
600 int entry = cache->FindEntry(isolate_, flags);
601 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
602
603 StubCompiler compiler(isolate_);
604 Handle<Code> code = compiler.CompileCallMiss(flags);
605 FillCache(isolate_, code);
606 return code;
607 }
608
609
610 Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map, 325 Handle<Code> StubCache::ComputeCompareNil(Handle<Map> receiver_map,
611 CompareNilICStub& stub) { 326 CompareNilICStub& stub) {
612 Handle<String> name(isolate_->heap()->empty_string()); 327 Handle<String> name(isolate_->heap()->empty_string());
613 if (!receiver_map->is_shared()) { 328 if (!receiver_map->is_shared()) {
614 Handle<Code> cached_ic = FindIC(name, receiver_map, Code::COMPARE_NIL_IC, 329 Handle<Code> cached_ic = FindIC(name, receiver_map, Code::COMPARE_NIL_IC,
615 stub.GetExtraICState()); 330 stub.GetExtraICState());
616 if (!cached_ic.is_null()) return cached_ic; 331 if (!cached_ic.is_null()) return cached_ic;
617 } 332 }
618 333
619 Handle<Code> ic = stub.GetCodeCopyFromTemplate(isolate_); 334 Handle<Code> ic = stub.GetCodeCopyFromTemplate(isolate_);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 Handle<Object> probe = cache->Lookup(receiver_maps, flags); 409 Handle<Object> probe = cache->Lookup(receiver_maps, flags);
695 if (probe->IsCode()) return Handle<Code>::cast(probe); 410 if (probe->IsCode()) return Handle<Code>::cast(probe);
696 411
697 KeyedStoreStubCompiler compiler(isolate_, extra_state); 412 KeyedStoreStubCompiler compiler(isolate_, extra_state);
698 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps); 413 Handle<Code> code = compiler.CompileStoreElementPolymorphic(receiver_maps);
699 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code); 414 PolymorphicCodeCache::Update(cache, receiver_maps, flags, code);
700 return code; 415 return code;
701 } 416 }
702 417
703 418
704 #ifdef ENABLE_DEBUGGER_SUPPORT
705 Handle<Code> StubCache::ComputeCallDebugBreak(int argc,
706 Code::Kind kind) {
707 // Extra IC state is irrelevant for debug break ICs. They jump to
708 // the actual call ic to carry out the work.
709 Code::Flags flags =
710 Code::ComputeFlags(kind, DEBUG_STUB, DEBUG_BREAK,
711 Code::NORMAL, argc);
712 Handle<UnseededNumberDictionary> cache =
713 isolate_->factory()->non_monomorphic_cache();
714 int entry = cache->FindEntry(isolate_, flags);
715 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
716
717 StubCompiler compiler(isolate_);
718 Handle<Code> code = compiler.CompileCallDebugBreak(flags);
719 FillCache(isolate_, code);
720 return code;
721 }
722
723
724 Handle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc,
725 Code::Kind kind) {
726 // Extra IC state is irrelevant for debug break ICs. They jump to
727 // the actual call ic to carry out the work.
728 Code::Flags flags =
729 Code::ComputeFlags(kind, DEBUG_STUB, DEBUG_PREPARE_STEP_IN,
730 Code::NORMAL, argc);
731 Handle<UnseededNumberDictionary> cache =
732 isolate_->factory()->non_monomorphic_cache();
733 int entry = cache->FindEntry(isolate_, flags);
734 if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry)));
735
736 StubCompiler compiler(isolate_);
737 Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags);
738 FillCache(isolate_, code);
739 return code;
740 }
741 #endif
742
743
744 void StubCache::Clear() { 419 void StubCache::Clear() {
745 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); 420 Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal);
746 for (int i = 0; i < kPrimaryTableSize; i++) { 421 for (int i = 0; i < kPrimaryTableSize; i++) {
747 primary_[i].key = heap()->empty_string(); 422 primary_[i].key = heap()->empty_string();
748 primary_[i].map = NULL; 423 primary_[i].map = NULL;
749 primary_[i].value = empty; 424 primary_[i].value = empty;
750 } 425 }
751 for (int j = 0; j < kSecondaryTableSize; j++) { 426 for (int j = 0; j < kSecondaryTableSize; j++) {
752 secondary_[j].key = heap()->empty_string(); 427 secondary_[j].key = heap()->empty_string();
753 secondary_[j].map = NULL; 428 secondary_[j].map = NULL;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 662
988 663
989 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { 664 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) {
990 JSObject* receiver = JSObject::cast(args[0]); 665 JSObject* receiver = JSObject::cast(args[0]);
991 ASSERT(args.smi_at(1) >= 0); 666 ASSERT(args.smi_at(1) >= 0);
992 uint32_t index = args.smi_at(1); 667 uint32_t index = args.smi_at(1);
993 return receiver->GetElementWithInterceptor(receiver, index); 668 return receiver->GetElementWithInterceptor(receiver, index);
994 } 669 }
995 670
996 671
997 Handle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) {
998 int argc = Code::ExtractArgumentsCountFromFlags(flags);
999 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1000 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1001 if (kind == Code::CALL_IC) {
1002 CallIC::GenerateInitialize(masm(), argc, extra_state);
1003 } else {
1004 KeyedCallIC::GenerateInitialize(masm(), argc);
1005 }
1006 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize");
1007 isolate()->counters()->call_initialize_stubs()->Increment();
1008 PROFILE(isolate(),
1009 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
1010 *code, code->arguments_count()));
1011 GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code));
1012 return code;
1013 }
1014
1015
1016 Handle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
1017 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1018 // The code of the PreMonomorphic stub is the same as the code
1019 // of the Initialized stub. They just differ on the code object flags.
1020 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1021 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1022 if (kind == Code::CALL_IC) {
1023 CallIC::GenerateInitialize(masm(), argc, extra_state);
1024 } else {
1025 KeyedCallIC::GenerateInitialize(masm(), argc);
1026 }
1027 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
1028 isolate()->counters()->call_premonomorphic_stubs()->Increment();
1029 PROFILE(isolate(),
1030 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
1031 *code, code->arguments_count()));
1032 GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code));
1033 return code;
1034 }
1035
1036
1037 Handle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) {
1038 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1039 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1040 if (kind == Code::CALL_IC) {
1041 CallIC::GenerateNormal(masm(), argc);
1042 } else {
1043 KeyedCallIC::GenerateNormal(masm(), argc);
1044 }
1045 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal");
1046 isolate()->counters()->call_normal_stubs()->Increment();
1047 PROFILE(isolate(),
1048 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1049 *code, code->arguments_count()));
1050 GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code));
1051 return code;
1052 }
1053
1054
1055 Handle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1056 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1057 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1058 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1059 if (kind == Code::CALL_IC) {
1060 CallIC::GenerateMegamorphic(masm(), argc, extra_state);
1061 } else {
1062 KeyedCallIC::GenerateMegamorphic(masm(), argc);
1063 }
1064 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic");
1065 isolate()->counters()->call_megamorphic_stubs()->Increment();
1066 PROFILE(isolate(),
1067 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1068 *code, code->arguments_count()));
1069 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1070 return code;
1071 }
1072
1073
1074 Handle<Code> StubCompiler::CompileLoadInitialize(Code::Flags flags) { 672 Handle<Code> StubCompiler::CompileLoadInitialize(Code::Flags flags) {
1075 LoadIC::GenerateInitialize(masm()); 673 LoadIC::GenerateInitialize(masm());
1076 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize"); 674 Handle<Code> code = GetCodeWithFlags(flags, "CompileLoadInitialize");
1077 PROFILE(isolate(), 675 PROFILE(isolate(),
1078 CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0)); 676 CodeCreateEvent(Logger::LOAD_INITIALIZE_TAG, *code, 0));
1079 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code)); 677 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *code));
1080 return code; 678 return code;
1081 } 679 }
1082 680
1083 681
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 737 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1140 StoreIC::GenerateMegamorphic(masm(), extra_state); 738 StoreIC::GenerateMegamorphic(masm(), extra_state);
1141 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic"); 739 Handle<Code> code = GetCodeWithFlags(flags, "CompileStoreMegamorphic");
1142 PROFILE(isolate(), 740 PROFILE(isolate(),
1143 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0)); 741 CodeCreateEvent(Logger::STORE_MEGAMORPHIC_TAG, *code, 0));
1144 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *code)); 742 GDBJIT(AddCode(GDBJITInterface::STORE_IC, *code));
1145 return code; 743 return code;
1146 } 744 }
1147 745
1148 746
1149 Handle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) {
1150 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1151 KeyedCallIC::GenerateNonStrictArguments(masm(), argc);
1152 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments");
1153 PROFILE(isolate(),
1154 CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
1155 CALL_MEGAMORPHIC_TAG),
1156 *code, code->arguments_count()));
1157 GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code));
1158 return code;
1159 }
1160
1161
1162 Handle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) {
1163 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1164 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1165 ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags);
1166 if (kind == Code::CALL_IC) {
1167 CallIC::GenerateMiss(masm(), argc, extra_state);
1168 } else {
1169 KeyedCallIC::GenerateMiss(masm(), argc);
1170 }
1171 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss");
1172 isolate()->counters()->call_megamorphic_stubs()->Increment();
1173 PROFILE(isolate(),
1174 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1175 *code, code->arguments_count()));
1176 GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code));
1177 return code;
1178 }
1179
1180
1181 #ifdef ENABLE_DEBUGGER_SUPPORT
1182 Handle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1183 Debug::GenerateCallICDebugBreak(masm());
1184 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak");
1185 PROFILE(isolate(),
1186 CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags),
1187 CALL_DEBUG_BREAK_TAG),
1188 *code, code->arguments_count()));
1189 return code;
1190 }
1191
1192
1193 Handle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1194 // Use the same code for the the step in preparations as we do for the
1195 // miss case.
1196 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1197 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1198 if (kind == Code::CALL_IC) {
1199 // For the debugger extra ic state is irrelevant.
1200 CallIC::GenerateMiss(masm(), argc, kNoExtraICState);
1201 } else {
1202 KeyedCallIC::GenerateMiss(masm(), argc);
1203 }
1204 Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
1205 PROFILE(isolate(),
1206 CodeCreateEvent(
1207 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1208 *code,
1209 code->arguments_count()));
1210 return code;
1211 }
1212 #endif // ENABLE_DEBUGGER_SUPPORT
1213
1214 #undef CALL_LOGGER_TAG 747 #undef CALL_LOGGER_TAG
1215 748
1216 749
1217 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 750 Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
1218 const char* name) { 751 const char* name) {
1219 // Create code object in the heap. 752 // Create code object in the heap.
1220 CodeDesc desc; 753 CodeDesc desc;
1221 masm_.GetCode(&desc); 754 masm_.GetCode(&desc);
1222 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); 755 Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
1223 if (code->has_major_key()) { 756 if (code->has_major_key()) {
(...skipping 20 matching lines...) Expand all
1244 holder->LocalLookupRealNamedProperty(*name, lookup); 777 holder->LocalLookupRealNamedProperty(*name, lookup);
1245 if (lookup->IsFound()) return; 778 if (lookup->IsFound()) return;
1246 if (holder->GetPrototype()->IsNull()) return; 779 if (holder->GetPrototype()->IsNull()) return;
1247 holder->GetPrototype()->Lookup(*name, lookup); 780 holder->GetPrototype()->Lookup(*name, lookup);
1248 } 781 }
1249 782
1250 783
1251 #define __ ACCESS_MASM(masm()) 784 #define __ ACCESS_MASM(masm())
1252 785
1253 786
1254 void CallStubCompiler::HandlerFrontendFooter(Label* miss) {
1255 __ bind(miss);
1256 GenerateMissBranch();
1257 }
1258
1259
1260 void CallStubCompiler::GenerateJumpFunctionIgnoreReceiver(
1261 Handle<JSFunction> function) {
1262 ParameterCount expected(function);
1263 __ InvokeFunction(function, expected, arguments(),
1264 JUMP_FUNCTION, NullCallWrapper());
1265 }
1266
1267
1268 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
1269 Handle<JSFunction> function) {
1270 PatchImplicitReceiver(object);
1271 GenerateJumpFunctionIgnoreReceiver(function);
1272 }
1273
1274
1275 void CallStubCompiler::GenerateJumpFunction(Handle<Object> object,
1276 Register actual_closure,
1277 Handle<JSFunction> function) {
1278 PatchImplicitReceiver(object);
1279 ParameterCount expected(function);
1280 __ InvokeFunction(actual_closure, expected, arguments(),
1281 JUMP_FUNCTION, NullCallWrapper());
1282 }
1283
1284
1285 Handle<Code> CallStubCompiler::CompileCallConstant(
1286 Handle<Object> object,
1287 Handle<JSObject> holder,
1288 Handle<Name> name,
1289 CheckType check,
1290 Handle<JSFunction> function) {
1291 Label miss;
1292 HandlerFrontendHeader(object, holder, name, check, &miss);
1293 GenerateJumpFunction(object, function);
1294 HandlerFrontendFooter(&miss);
1295
1296 // Return the generated code.
1297 return GetCode(function);
1298 }
1299
1300
1301 Register LoadStubCompiler::HandlerFrontendHeader( 787 Register LoadStubCompiler::HandlerFrontendHeader(
1302 Handle<HeapType> type, 788 Handle<HeapType> type,
1303 Register object_reg, 789 Register object_reg,
1304 Handle<JSObject> holder, 790 Handle<JSObject> holder,
1305 Handle<Name> name, 791 Handle<Name> name,
1306 Label* miss) { 792 Label* miss) {
1307 PrototypeCheckType check_type = CHECK_ALL_MAPS; 793 PrototypeCheckType check_type = CHECK_ALL_MAPS;
1308 int function_index = -1; 794 int function_index = -1;
1309 if (type->Is(HeapType::String())) { 795 if (type->Is(HeapType::String())) {
1310 function_index = Context::STRING_FUNCTION_INDEX; 796 function_index = Context::STRING_FUNCTION_INDEX;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1415 HandlerFrontendFooter(name, &miss); 901 HandlerFrontendFooter(name, &miss);
1416 } 902 }
1417 903
1418 904
1419 Handle<Code> LoadStubCompiler::CompileLoadField( 905 Handle<Code> LoadStubCompiler::CompileLoadField(
1420 Handle<HeapType> type, 906 Handle<HeapType> type,
1421 Handle<JSObject> holder, 907 Handle<JSObject> holder,
1422 Handle<Name> name, 908 Handle<Name> name,
1423 PropertyIndex field, 909 PropertyIndex field,
1424 Representation representation) { 910 Representation representation) {
1425 Label miss; 911 Register reg = HandlerFrontend(type, receiver(), holder, name);
1426
1427 Register reg = HandlerFrontendHeader(type, receiver(), holder, name, &miss);
1428
1429 GenerateLoadField(reg, holder, field, representation); 912 GenerateLoadField(reg, holder, field, representation);
1430 913
1431 __ bind(&miss);
1432 TailCallBuiltin(masm(), MissBuiltin(kind()));
1433
1434 // Return the generated code. 914 // Return the generated code.
1435 return GetCode(kind(), Code::FAST, name); 915 return GetCode(kind(), Code::FAST, name);
1436 } 916 }
1437 917
1438 918
1439 Handle<Code> LoadStubCompiler::CompileLoadConstant( 919 Handle<Code> LoadStubCompiler::CompileLoadConstant(
1440 Handle<HeapType> type, 920 Handle<HeapType> type,
1441 Handle<JSObject> holder, 921 Handle<JSObject> holder,
1442 Handle<Name> name, 922 Handle<Name> name,
1443 Handle<Object> value) { 923 Handle<Object> value) {
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1849 return code; 1329 return code;
1850 } 1330 }
1851 1331
1852 1332
1853 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 1333 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1854 MacroAssembler* masm) { 1334 MacroAssembler* masm) {
1855 KeyedStoreIC::GenerateSlow(masm); 1335 KeyedStoreIC::GenerateSlow(masm);
1856 } 1336 }
1857 1337
1858 1338
1859 CallStubCompiler::CallStubCompiler(Isolate* isolate,
1860 int argc,
1861 Code::Kind kind,
1862 ExtraICState extra_state,
1863 InlineCacheHolderFlag cache_holder)
1864 : StubCompiler(isolate, extra_state),
1865 arguments_(argc),
1866 kind_(kind),
1867 cache_holder_(cache_holder) {
1868 }
1869
1870
1871 Handle<Code> CallStubCompiler::GetCode(Code::StubType type,
1872 Handle<Name> name) {
1873 int argc = arguments_.immediate();
1874 Code::Flags flags = Code::ComputeMonomorphicFlags(
1875 kind_, extra_state(), cache_holder_, type, argc);
1876 return GetCodeWithFlags(flags, name);
1877 }
1878
1879
1880 Handle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) {
1881 Handle<String> function_name;
1882 if (function->shared()->name()->IsString()) {
1883 function_name = Handle<String>(String::cast(function->shared()->name()));
1884 }
1885 return GetCode(Code::FAST, function_name);
1886 }
1887
1888
1889 CallOptimization::CallOptimization(LookupResult* lookup) { 1339 CallOptimization::CallOptimization(LookupResult* lookup) {
1890 if (lookup->IsFound() && 1340 if (lookup->IsFound() &&
1891 lookup->IsCacheable() && 1341 lookup->IsCacheable() &&
1892 lookup->IsConstantFunction()) { 1342 lookup->IsConstantFunction()) {
1893 // We only optimize constant function calls. 1343 // We only optimize constant function calls.
1894 Initialize(Handle<JSFunction>(lookup->GetConstantFunction())); 1344 Initialize(Handle<JSFunction>(lookup->GetConstantFunction()));
1895 } else { 1345 } else {
1896 Initialize(Handle<JSFunction>::null()); 1346 Initialize(Handle<JSFunction>::null());
1897 } 1347 }
1898 } 1348 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1965 Handle<FunctionTemplateInfo>( 1415 Handle<FunctionTemplateInfo>(
1966 FunctionTemplateInfo::cast(signature->receiver())); 1416 FunctionTemplateInfo::cast(signature->receiver()));
1967 } 1417 }
1968 } 1418 }
1969 1419
1970 is_simple_api_call_ = true; 1420 is_simple_api_call_ = true;
1971 } 1421 }
1972 1422
1973 1423
1974 } } // namespace v8::internal 1424 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698