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

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

Issue 115744: This patch much improves our tracking of whether function is... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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
« src/objects-inl.h ('K') | « src/stub-cache.h ('k') | no next file » | 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-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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 if (code->IsFailure()) return code; 362 if (code->IsFailure()) return code;
363 LOG(CodeCreateEvent("KeyedStoreIC", Code::cast(code), name)); 363 LOG(CodeCreateEvent("KeyedStoreIC", Code::cast(code), name));
364 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 364 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
365 if (result->IsFailure()) return result; 365 if (result->IsFailure()) return result;
366 } 366 }
367 return code; 367 return code;
368 } 368 }
369 369
370 370
371 Object* StubCache::ComputeCallConstant(int argc, 371 Object* StubCache::ComputeCallConstant(int argc,
372 InlineCacheInLoop in_loop,
372 String* name, 373 String* name,
373 Object* object, 374 Object* object,
374 JSObject* holder, 375 JSObject* holder,
375 JSFunction* function) { 376 JSFunction* function) {
376 // Compute the check type and the map. 377 // Compute the check type and the map.
377 Map* map = IC::GetCodeCacheMapForObject(object); 378 Map* map = IC::GetCodeCacheMapForObject(object);
378 379
379 // Compute check type based on receiver/holder. 380 // Compute check type based on receiver/holder.
380 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; 381 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK;
381 if (object->IsString()) { 382 if (object->IsString()) {
382 check = StubCompiler::STRING_CHECK; 383 check = StubCompiler::STRING_CHECK;
383 } else if (object->IsNumber()) { 384 } else if (object->IsNumber()) {
384 check = StubCompiler::NUMBER_CHECK; 385 check = StubCompiler::NUMBER_CHECK;
385 } else if (object->IsBoolean()) { 386 } else if (object->IsBoolean()) {
386 check = StubCompiler::BOOLEAN_CHECK; 387 check = StubCompiler::BOOLEAN_CHECK;
387 } 388 }
388 389
389 Code::Flags flags = 390 Code::Flags flags =
390 Code::ComputeMonomorphicFlags(Code::CALL_IC, CONSTANT_FUNCTION, argc); 391 Code::ComputeMonomorphicFlags(Code::CALL_IC,
392 CONSTANT_FUNCTION,
393 in_loop,
394 argc);
391 Object* code = map->FindInCodeCache(name, flags); 395 Object* code = map->FindInCodeCache(name, flags);
392 if (code->IsUndefined()) { 396 if (code->IsUndefined()) {
393 if (object->IsJSObject()) { 397 if (object->IsJSObject()) {
394 Object* opt = 398 Object* opt =
395 Top::LookupSpecialFunction(JSObject::cast(object), holder, function); 399 Top::LookupSpecialFunction(JSObject::cast(object), holder, function);
396 if (opt->IsJSFunction()) { 400 if (opt->IsJSFunction()) {
397 check = StubCompiler::JSARRAY_HAS_FAST_ELEMENTS_CHECK; 401 check = StubCompiler::JSARRAY_HAS_FAST_ELEMENTS_CHECK;
398 function = JSFunction::cast(opt); 402 function = JSFunction::cast(opt);
399 } 403 }
400 } 404 }
401 // If the function hasn't been compiled yet, we cannot do it now 405 // If the function hasn't been compiled yet, we cannot do it now
402 // because it may cause GC. To avoid this issue, we return an 406 // because it may cause GC. To avoid this issue, we return an
403 // internal error which will make sure we do not update any 407 // internal error which will make sure we do not update any
404 // caches. 408 // caches.
405 if (!function->is_compiled()) return Failure::InternalError(); 409 if (!function->is_compiled()) return Failure::InternalError();
406 // Compile the stub - only create stubs for fully compiled functions. 410 // Compile the stub - only create stubs for fully compiled functions.
407 CallStubCompiler compiler(argc); 411 CallStubCompiler compiler(argc);
408 code = compiler.CompileCallConstant(object, holder, function, check); 412 code = compiler.CompileCallConstant(object, holder, function, check, flags);
409 if (code->IsFailure()) return code; 413 if (code->IsFailure()) return code;
410 LOG(CodeCreateEvent("CallIC", Code::cast(code), name)); 414 LOG(CodeCreateEvent("CallIC", Code::cast(code), name));
411 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 415 Object* result = map->UpdateCodeCache(name, Code::cast(code));
412 if (result->IsFailure()) return result; 416 if (result->IsFailure()) return result;
413 } 417 }
414 return Set(name, map, Code::cast(code)); 418 return Set(name, map, Code::cast(code));
415 } 419 }
416 420
417 421
418 Object* StubCache::ComputeCallField(int argc, 422 Object* StubCache::ComputeCallField(int argc,
423 InlineCacheInLoop in_loop,
419 String* name, 424 String* name,
420 Object* object, 425 Object* object,
421 JSObject* holder, 426 JSObject* holder,
422 int index) { 427 int index) {
423 // Compute the check type and the map. 428 // Compute the check type and the map.
424 Map* map = IC::GetCodeCacheMapForObject(object); 429 Map* map = IC::GetCodeCacheMapForObject(object);
425 430
426 // TODO(1233596): We cannot do receiver map check for non-JS objects 431 // TODO(1233596): We cannot do receiver map check for non-JS objects
427 // because they may be represented as immediates without a 432 // because they may be represented as immediates without a
428 // map. Instead, we check against the map in the holder. 433 // map. Instead, we check against the map in the holder.
429 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 434 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
430 object = holder; 435 object = holder;
431 } 436 }
432 437
433 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, FIELD, argc); 438 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
439 FIELD,
440 in_loop,
441 argc);
434 Object* code = map->FindInCodeCache(name, flags); 442 Object* code = map->FindInCodeCache(name, flags);
435 if (code->IsUndefined()) { 443 if (code->IsUndefined()) {
436 CallStubCompiler compiler(argc); 444 CallStubCompiler compiler(argc);
437 code = compiler.CompileCallField(object, holder, index, name); 445 code = compiler.CompileCallField(object, holder, index, name, flags);
438 if (code->IsFailure()) return code; 446 if (code->IsFailure()) return code;
439 LOG(CodeCreateEvent("CallIC", Code::cast(code), name)); 447 LOG(CodeCreateEvent("CallIC", Code::cast(code), name));
440 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 448 Object* result = map->UpdateCodeCache(name, Code::cast(code));
441 if (result->IsFailure()) return result; 449 if (result->IsFailure()) return result;
442 } 450 }
443 return Set(name, map, Code::cast(code)); 451 return Set(name, map, Code::cast(code));
444 } 452 }
445 453
446 454
447 Object* StubCache::ComputeCallInterceptor(int argc, 455 Object* StubCache::ComputeCallInterceptor(int argc,
448 String* name, 456 String* name,
449 Object* object, 457 Object* object,
450 JSObject* holder) { 458 JSObject* holder) {
451 // Compute the check type and the map. 459 // Compute the check type and the map.
452 // If the object is a value, we use the prototype map for the cache. 460 // If the object is a value, we use the prototype map for the cache.
453 Map* map = IC::GetCodeCacheMapForObject(object); 461 Map* map = IC::GetCodeCacheMapForObject(object);
454 462
455 // TODO(1233596): We cannot do receiver map check for non-JS objects 463 // TODO(1233596): We cannot do receiver map check for non-JS objects
456 // because they may be represented as immediates without a 464 // because they may be represented as immediates without a
457 // map. Instead, we check against the map in the holder. 465 // map. Instead, we check against the map in the holder.
458 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 466 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
459 object = holder; 467 object = holder;
460 } 468 }
461 469
462 Code::Flags flags = 470 Code::Flags flags =
463 Code::ComputeMonomorphicFlags(Code::CALL_IC, INTERCEPTOR, argc); 471 Code::ComputeMonomorphicFlags(Code::CALL_IC,
472 INTERCEPTOR,
473 NOT_IN_LOOP,
474 argc);
464 Object* code = map->FindInCodeCache(name, flags); 475 Object* code = map->FindInCodeCache(name, flags);
465 if (code->IsUndefined()) { 476 if (code->IsUndefined()) {
466 CallStubCompiler compiler(argc); 477 CallStubCompiler compiler(argc);
467 code = compiler.CompileCallInterceptor(object, holder, name); 478 code = compiler.CompileCallInterceptor(object, holder, name);
468 if (code->IsFailure()) return code; 479 if (code->IsFailure()) return code;
469 LOG(CodeCreateEvent("CallIC", Code::cast(code), name)); 480 LOG(CodeCreateEvent("CallIC", Code::cast(code), name));
470 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 481 Object* result = map->UpdateCodeCache(name, Code::cast(code));
471 if (result->IsFailure()) return result; 482 if (result->IsFailure()) return result;
472 } 483 }
473 return Set(name, map, Code::cast(code)); 484 return Set(name, map, Code::cast(code));
474 } 485 }
475 486
476 487
477 Object* StubCache::ComputeCallNormal(int argc, 488 Object* StubCache::ComputeCallNormal(int argc,
489 InlineCacheInLoop in_loop,
478 String* name, 490 String* name,
479 JSObject* receiver) { 491 JSObject* receiver) {
480 Object* code = ComputeCallNormal(argc); 492 Object* code = ComputeCallNormal(argc, in_loop);
481 if (code->IsFailure()) return code; 493 if (code->IsFailure()) return code;
482 return Set(name, receiver->map(), Code::cast(code)); 494 return Set(name, receiver->map(), Code::cast(code));
483 } 495 }
484 496
485 497
486 static Object* GetProbeValue(Code::Flags flags) { 498 static Object* GetProbeValue(Code::Flags flags) {
487 Dictionary* dictionary = Heap::non_monomorphic_cache(); 499 Dictionary* dictionary = Heap::non_monomorphic_cache();
488 int entry = dictionary->FindNumberEntry(flags); 500 int entry = dictionary->FindNumberEntry(flags);
489 if (entry != -1) return dictionary->ValueAt(entry); 501 if (entry != -1) return dictionary->ValueAt(entry);
490 return Heap::undefined_value(); 502 return Heap::undefined_value();
(...skipping 24 matching lines...) Expand all
515 ASSERT(entry != -1); 527 ASSERT(entry != -1);
516 ASSERT(Heap::non_monomorphic_cache()->ValueAt(entry) == 528 ASSERT(Heap::non_monomorphic_cache()->ValueAt(entry) ==
517 Heap::undefined_value()); 529 Heap::undefined_value());
518 Heap::non_monomorphic_cache()->ValueAtPut(entry, code); 530 Heap::non_monomorphic_cache()->ValueAtPut(entry, code);
519 CHECK(GetProbeValue(Code::cast(code)->flags()) == code); 531 CHECK(GetProbeValue(Code::cast(code)->flags()) == code);
520 } 532 }
521 return code; 533 return code;
522 } 534 }
523 535
524 536
525 Code* StubCache::FindCallInitialize(int argc) { 537 Code* StubCache::FindCallInitialize(int argc, InlineCacheInLoop in_loop) {
526 Code::Flags flags = 538 Code::Flags flags =
527 Code::ComputeFlags(Code::CALL_IC, UNINITIALIZED, NORMAL, argc); 539 Code::ComputeFlags(Code::CALL_IC, in_loop, UNINITIALIZED, NORMAL, argc);
528 Object* result = ProbeCache(flags); 540 Object* result = ProbeCache(flags);
529 ASSERT(!result->IsUndefined()); 541 ASSERT(!result->IsUndefined());
530 // This might be called during the marking phase of the collector 542 // This might be called during the marking phase of the collector
531 // hence the unchecked cast. 543 // hence the unchecked cast.
532 return reinterpret_cast<Code*>(result); 544 return reinterpret_cast<Code*>(result);
533 } 545 }
534 546
535 547
536 Object* StubCache::ComputeCallInitialize(int argc) { 548 Object* StubCache::ComputeCallInitialize(int argc, InlineCacheInLoop in_loop) {
537 Code::Flags flags = 549 Code::Flags flags =
538 Code::ComputeFlags(Code::CALL_IC, UNINITIALIZED, NORMAL, argc); 550 Code::ComputeFlags(Code::CALL_IC, in_loop, UNINITIALIZED, NORMAL, argc);
539 Object* probe = ProbeCache(flags); 551 Object* probe = ProbeCache(flags);
540 if (!probe->IsUndefined()) return probe; 552 if (!probe->IsUndefined()) return probe;
541 StubCompiler compiler; 553 StubCompiler compiler;
542 return FillCache(compiler.CompileCallInitialize(flags)); 554 return FillCache(compiler.CompileCallInitialize(flags));
543 } 555 }
544 556
545 557
546 Object* StubCache::ComputeCallInitializeInLoop(int argc) { 558 Object* StubCache::ComputeCallPreMonomorphic(int argc,
559 InlineCacheInLoop in_loop) {
547 Code::Flags flags = 560 Code::Flags flags =
548 Code::ComputeFlags(Code::CALL_IC, UNINITIALIZED_IN_LOOP, NORMAL, argc); 561 Code::ComputeFlags(Code::CALL_IC, in_loop, PREMONOMORPHIC, NORMAL, argc);
549 Object* probe = ProbeCache(flags);
550 if (!probe->IsUndefined()) return probe;
551 StubCompiler compiler;
552 return FillCache(compiler.CompileCallInitialize(flags));
553 }
554
555
556
557 Object* StubCache::ComputeCallPreMonomorphic(int argc) {
558 Code::Flags flags =
559 Code::ComputeFlags(Code::CALL_IC, PREMONOMORPHIC, NORMAL, argc);
560 Object* probe = ProbeCache(flags); 562 Object* probe = ProbeCache(flags);
561 if (!probe->IsUndefined()) return probe; 563 if (!probe->IsUndefined()) return probe;
562 StubCompiler compiler; 564 StubCompiler compiler;
563 return FillCache(compiler.CompileCallPreMonomorphic(flags)); 565 return FillCache(compiler.CompileCallPreMonomorphic(flags));
564 } 566 }
565 567
566 568
567 Object* StubCache::ComputeCallNormal(int argc) { 569 Object* StubCache::ComputeCallNormal(int argc, InlineCacheInLoop in_loop) {
568 Code::Flags flags = 570 Code::Flags flags =
569 Code::ComputeFlags(Code::CALL_IC, MONOMORPHIC, NORMAL, argc); 571 Code::ComputeFlags(Code::CALL_IC, in_loop, MONOMORPHIC, NORMAL, argc);
570 Object* probe = ProbeCache(flags); 572 Object* probe = ProbeCache(flags);
571 if (!probe->IsUndefined()) return probe; 573 if (!probe->IsUndefined()) return probe;
572 StubCompiler compiler; 574 StubCompiler compiler;
573 return FillCache(compiler.CompileCallNormal(flags)); 575 return FillCache(compiler.CompileCallNormal(flags));
574 } 576 }
575 577
576 578
577 Object* StubCache::ComputeCallMegamorphic(int argc) { 579 Object* StubCache::ComputeCallMegamorphic(int argc, InlineCacheInLoop in_loop) {
578 Code::Flags flags = 580 Code::Flags flags =
579 Code::ComputeFlags(Code::CALL_IC, MEGAMORPHIC, NORMAL, argc); 581 Code::ComputeFlags(Code::CALL_IC, in_loop, MEGAMORPHIC, NORMAL, argc);
580 Object* probe = ProbeCache(flags); 582 Object* probe = ProbeCache(flags);
581 if (!probe->IsUndefined()) return probe; 583 if (!probe->IsUndefined()) return probe;
582 StubCompiler compiler; 584 StubCompiler compiler;
583 return FillCache(compiler.CompileCallMegamorphic(flags)); 585 return FillCache(compiler.CompileCallMegamorphic(flags));
584 } 586 }
585 587
586 588
587 Object* StubCache::ComputeCallMiss(int argc) { 589 Object* StubCache::ComputeCallMiss(int argc) {
588 Code::Flags flags = 590 Code::Flags flags =
589 Code::ComputeFlags(Code::STUB, MEGAMORPHIC, NORMAL, argc); 591 Code::ComputeFlags(Code::STUB, NOT_IN_LOOP, MEGAMORPHIC, NORMAL, argc);
590 Object* probe = ProbeCache(flags); 592 Object* probe = ProbeCache(flags);
591 if (!probe->IsUndefined()) return probe; 593 if (!probe->IsUndefined()) return probe;
592 StubCompiler compiler; 594 StubCompiler compiler;
593 return FillCache(compiler.CompileCallMiss(flags)); 595 return FillCache(compiler.CompileCallMiss(flags));
594 } 596 }
595 597
596 598
597 #ifdef ENABLE_DEBUGGER_SUPPORT 599 #ifdef ENABLE_DEBUGGER_SUPPORT
598 Object* StubCache::ComputeCallDebugBreak(int argc) { 600 Object* StubCache::ComputeCallDebugBreak(int argc) {
599 Code::Flags flags = 601 Code::Flags flags =
600 Code::ComputeFlags(Code::CALL_IC, DEBUG_BREAK, NORMAL, argc); 602 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc);
601 Object* probe = ProbeCache(flags); 603 Object* probe = ProbeCache(flags);
602 if (!probe->IsUndefined()) return probe; 604 if (!probe->IsUndefined()) return probe;
603 StubCompiler compiler; 605 StubCompiler compiler;
604 return FillCache(compiler.CompileCallDebugBreak(flags)); 606 return FillCache(compiler.CompileCallDebugBreak(flags));
605 } 607 }
606 608
607 609
608 Object* StubCache::ComputeCallDebugPrepareStepIn(int argc) { 610 Object* StubCache::ComputeCallDebugPrepareStepIn(int argc) {
609 Code::Flags flags = 611 Code::Flags flags =
610 Code::ComputeFlags(Code::CALL_IC, DEBUG_PREPARE_STEP_IN, NORMAL, argc); 612 Code::ComputeFlags(Code::CALL_IC,
613 NOT_IN_LOOP,
614 DEBUG_PREPARE_STEP_IN,
615 NORMAL,
616 argc);
611 Object* probe = ProbeCache(flags); 617 Object* probe = ProbeCache(flags);
612 if (!probe->IsUndefined()) return probe; 618 if (!probe->IsUndefined()) return probe;
613 StubCompiler compiler; 619 StubCompiler compiler;
614 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags)); 620 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags));
615 } 621 }
616 #endif 622 #endif
617 623
618 624
619 Object* StubCache::ComputeLazyCompile(int argc) { 625 Object* StubCache::ComputeLazyCompile(int argc) {
620 Code::Flags flags = 626 Code::Flags flags =
621 Code::ComputeFlags(Code::STUB, UNINITIALIZED, NORMAL, argc); 627 Code::ComputeFlags(Code::STUB, NOT_IN_LOOP, UNINITIALIZED, NORMAL, argc);
622 Object* probe = ProbeCache(flags); 628 Object* probe = ProbeCache(flags);
623 if (!probe->IsUndefined()) return probe; 629 if (!probe->IsUndefined()) return probe;
624 StubCompiler compiler; 630 StubCompiler compiler;
625 Object* result = FillCache(compiler.CompileLazyCompile(flags)); 631 Object* result = FillCache(compiler.CompileLazyCompile(flags));
626 if (result->IsCode()) { 632 if (result->IsCode()) {
627 Code* code = Code::cast(result); 633 Code* code = Code::cast(result);
628 USE(code); 634 USE(code);
629 LOG(CodeCreateEvent("LazyCompile", code, code->arguments_count())); 635 LOG(CodeCreateEvent("LazyCompile", code, code->arguments_count()));
630 } 636 }
631 return result; 637 return result;
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 916
911 917
912 Object* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) { 918 Object* KeyedStoreStubCompiler::GetCode(PropertyType type, String* name) {
913 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type); 919 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_STORE_IC, type);
914 return GetCodeWithFlags(flags, name); 920 return GetCodeWithFlags(flags, name);
915 } 921 }
916 922
917 923
918 Object* CallStubCompiler::GetCode(PropertyType type, String* name) { 924 Object* CallStubCompiler::GetCode(PropertyType type, String* name) {
919 int argc = arguments_.immediate(); 925 int argc = arguments_.immediate();
920 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, type, argc); 926 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC,
927 type,
928 NOT_IN_LOOP,
929 argc);
921 return GetCodeWithFlags(flags, name); 930 return GetCodeWithFlags(flags, name);
922 } 931 }
923 932
924 933
925 } } // namespace v8::internal 934 } } // namespace v8::internal
OLDNEW
« src/objects-inl.h ('K') | « src/stub-cache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698