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

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

Issue 2280007: Extend CallIC to support non-constant names.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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/x64/codegen-x64.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 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 code = compiler.CompileStoreField(receiver, field_index, transition, name); 434 code = compiler.CompileStoreField(receiver, field_index, transition, name);
435 if (code->IsFailure()) return code; 435 if (code->IsFailure()) return code;
436 PROFILE(CodeCreateEvent( 436 PROFILE(CodeCreateEvent(
437 Logger::KEYED_STORE_IC_TAG, Code::cast(code), name)); 437 Logger::KEYED_STORE_IC_TAG, Code::cast(code), name));
438 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 438 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
439 if (result->IsFailure()) return result; 439 if (result->IsFailure()) return result;
440 } 440 }
441 return code; 441 return code;
442 } 442 }
443 443
444 #define CALL_LOGGER_TAG(kind, type) \
445 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
444 446
445 Object* StubCache::ComputeCallConstant(int argc, 447 Object* StubCache::ComputeCallConstant(int argc,
446 InLoopFlag in_loop, 448 InLoopFlag in_loop,
449 Code::Kind kind,
447 String* name, 450 String* name,
448 Object* object, 451 Object* object,
449 JSObject* holder, 452 JSObject* holder,
450 JSFunction* function) { 453 JSFunction* function) {
451 // Compute the check type and the map. 454 // Compute the check type and the map.
452 Map* map = IC::GetCodeCacheMapForObject(object); 455 Map* map = IC::GetCodeCacheMapForObject(object);
453 456
454 // Compute check type based on receiver/holder. 457 // Compute check type based on receiver/holder.
455 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK; 458 StubCompiler::CheckType check = StubCompiler::RECEIVER_MAP_CHECK;
456 if (object->IsString()) { 459 if (object->IsString()) {
457 check = StubCompiler::STRING_CHECK; 460 check = StubCompiler::STRING_CHECK;
458 } else if (object->IsNumber()) { 461 } else if (object->IsNumber()) {
459 check = StubCompiler::NUMBER_CHECK; 462 check = StubCompiler::NUMBER_CHECK;
460 } else if (object->IsBoolean()) { 463 } else if (object->IsBoolean()) {
461 check = StubCompiler::BOOLEAN_CHECK; 464 check = StubCompiler::BOOLEAN_CHECK;
462 } 465 }
463 466
464 Code::Flags flags = 467 Code::Flags flags =
465 Code::ComputeMonomorphicFlags(Code::CALL_IC, 468 Code::ComputeMonomorphicFlags(kind,
466 CONSTANT_FUNCTION, 469 CONSTANT_FUNCTION,
467 in_loop, 470 in_loop,
468 argc); 471 argc);
469 Object* code = map->FindInCodeCache(name, flags); 472 Object* code = map->FindInCodeCache(name, flags);
470 if (code->IsUndefined()) { 473 if (code->IsUndefined()) {
471 // If the function hasn't been compiled yet, we cannot do it now 474 // If the function hasn't been compiled yet, we cannot do it now
472 // because it may cause GC. To avoid this issue, we return an 475 // because it may cause GC. To avoid this issue, we return an
473 // internal error which will make sure we do not update any 476 // internal error which will make sure we do not update any
474 // caches. 477 // caches.
475 if (!function->is_compiled()) return Failure::InternalError(); 478 if (!function->is_compiled()) return Failure::InternalError();
476 // Compile the stub - only create stubs for fully compiled functions. 479 // Compile the stub - only create stubs for fully compiled functions.
477 CallStubCompiler compiler(argc, in_loop); 480 CallStubCompiler compiler(argc, in_loop, kind);
478 code = compiler.CompileCallConstant(object, holder, function, name, check); 481 code = compiler.CompileCallConstant(object, holder, function, name, check);
479 if (code->IsFailure()) return code; 482 if (code->IsFailure()) return code;
480 ASSERT_EQ(flags, Code::cast(code)->flags()); 483 ASSERT_EQ(flags, Code::cast(code)->flags());
481 PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); 484 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
485 Code::cast(code), name));
482 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 486 Object* result = map->UpdateCodeCache(name, Code::cast(code));
483 if (result->IsFailure()) return result; 487 if (result->IsFailure()) return result;
484 } 488 }
485 return Set(name, map, Code::cast(code)); 489 return Set(name, map, Code::cast(code));
486 } 490 }
487 491
488 492
489 Object* StubCache::ComputeCallField(int argc, 493 Object* StubCache::ComputeCallField(int argc,
490 InLoopFlag in_loop, 494 InLoopFlag in_loop,
495 Code::Kind kind,
491 String* name, 496 String* name,
492 Object* object, 497 Object* object,
493 JSObject* holder, 498 JSObject* holder,
494 int index) { 499 int index) {
495 // Compute the check type and the map. 500 // Compute the check type and the map.
496 Map* map = IC::GetCodeCacheMapForObject(object); 501 Map* map = IC::GetCodeCacheMapForObject(object);
497 502
498 // TODO(1233596): We cannot do receiver map check for non-JS objects 503 // TODO(1233596): We cannot do receiver map check for non-JS objects
499 // because they may be represented as immediates without a 504 // because they may be represented as immediates without a
500 // map. Instead, we check against the map in the holder. 505 // map. Instead, we check against the map in the holder.
501 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 506 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
502 object = holder; 507 object = holder;
503 } 508 }
504 509
505 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, 510 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
506 FIELD, 511 FIELD,
507 in_loop, 512 in_loop,
508 argc); 513 argc);
509 Object* code = map->FindInCodeCache(name, flags); 514 Object* code = map->FindInCodeCache(name, flags);
510 if (code->IsUndefined()) { 515 if (code->IsUndefined()) {
511 CallStubCompiler compiler(argc, in_loop); 516 CallStubCompiler compiler(argc, in_loop, kind);
512 code = compiler.CompileCallField(JSObject::cast(object), 517 code = compiler.CompileCallField(JSObject::cast(object),
513 holder, 518 holder,
514 index, 519 index,
515 name); 520 name);
516 if (code->IsFailure()) return code; 521 if (code->IsFailure()) return code;
517 ASSERT_EQ(flags, Code::cast(code)->flags()); 522 ASSERT_EQ(flags, Code::cast(code)->flags());
518 PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); 523 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
524 Code::cast(code), name));
519 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 525 Object* result = map->UpdateCodeCache(name, Code::cast(code));
520 if (result->IsFailure()) return result; 526 if (result->IsFailure()) return result;
521 } 527 }
522 return Set(name, map, Code::cast(code)); 528 return Set(name, map, Code::cast(code));
523 } 529 }
524 530
525 531
526 Object* StubCache::ComputeCallInterceptor(int argc, 532 Object* StubCache::ComputeCallInterceptor(int argc,
533 Code::Kind kind,
527 String* name, 534 String* name,
528 Object* object, 535 Object* object,
529 JSObject* holder) { 536 JSObject* holder) {
530 // Compute the check type and the map. 537 // Compute the check type and the map.
531 // If the object is a value, we use the prototype map for the cache. 538 // If the object is a value, we use the prototype map for the cache.
532 Map* map = IC::GetCodeCacheMapForObject(object); 539 Map* map = IC::GetCodeCacheMapForObject(object);
533 540
534 // TODO(1233596): We cannot do receiver map check for non-JS objects 541 // TODO(1233596): We cannot do receiver map check for non-JS objects
535 // because they may be represented as immediates without a 542 // because they may be represented as immediates without a
536 // map. Instead, we check against the map in the holder. 543 // map. Instead, we check against the map in the holder.
537 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 544 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
538 object = holder; 545 object = holder;
539 } 546 }
540 547
541 Code::Flags flags = 548 Code::Flags flags =
542 Code::ComputeMonomorphicFlags(Code::CALL_IC, 549 Code::ComputeMonomorphicFlags(kind,
543 INTERCEPTOR, 550 INTERCEPTOR,
544 NOT_IN_LOOP, 551 NOT_IN_LOOP,
545 argc); 552 argc);
546 Object* code = map->FindInCodeCache(name, flags); 553 Object* code = map->FindInCodeCache(name, flags);
547 if (code->IsUndefined()) { 554 if (code->IsUndefined()) {
548 CallStubCompiler compiler(argc, NOT_IN_LOOP); 555 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind);
549 code = compiler.CompileCallInterceptor(JSObject::cast(object), 556 code = compiler.CompileCallInterceptor(JSObject::cast(object),
550 holder, 557 holder,
551 name); 558 name);
552 if (code->IsFailure()) return code; 559 if (code->IsFailure()) return code;
553 ASSERT_EQ(flags, Code::cast(code)->flags()); 560 ASSERT_EQ(flags, Code::cast(code)->flags());
554 PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); 561 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
562 Code::cast(code), name));
555 Object* result = map->UpdateCodeCache(name, Code::cast(code)); 563 Object* result = map->UpdateCodeCache(name, Code::cast(code));
556 if (result->IsFailure()) return result; 564 if (result->IsFailure()) return result;
557 } 565 }
558 return Set(name, map, Code::cast(code)); 566 return Set(name, map, Code::cast(code));
559 } 567 }
560 568
561 569
562 Object* StubCache::ComputeCallNormal(int argc, 570 Object* StubCache::ComputeCallNormal(int argc,
563 InLoopFlag in_loop, 571 InLoopFlag in_loop,
572 Code::Kind kind,
564 String* name, 573 String* name,
565 JSObject* receiver) { 574 JSObject* receiver) {
566 Object* code = ComputeCallNormal(argc, in_loop); 575 Object* code = ComputeCallNormal(argc, in_loop, kind);
567 if (code->IsFailure()) return code; 576 if (code->IsFailure()) return code;
568 return Set(name, receiver->map(), Code::cast(code)); 577 return Set(name, receiver->map(), Code::cast(code));
569 } 578 }
570 579
571 580
572 Object* StubCache::ComputeCallGlobal(int argc, 581 Object* StubCache::ComputeCallGlobal(int argc,
573 InLoopFlag in_loop, 582 InLoopFlag in_loop,
583 Code::Kind kind,
574 String* name, 584 String* name,
575 JSObject* receiver, 585 JSObject* receiver,
576 GlobalObject* holder, 586 GlobalObject* holder,
577 JSGlobalPropertyCell* cell, 587 JSGlobalPropertyCell* cell,
578 JSFunction* function) { 588 JSFunction* function) {
579 Code::Flags flags = 589 Code::Flags flags =
580 Code::ComputeMonomorphicFlags(Code::CALL_IC, NORMAL, in_loop, argc); 590 Code::ComputeMonomorphicFlags(kind,
591 NORMAL,
592 in_loop,
593 argc);
581 Object* code = receiver->map()->FindInCodeCache(name, flags); 594 Object* code = receiver->map()->FindInCodeCache(name, flags);
582 if (code->IsUndefined()) { 595 if (code->IsUndefined()) {
583 // If the function hasn't been compiled yet, we cannot do it now 596 // If the function hasn't been compiled yet, we cannot do it now
584 // because it may cause GC. To avoid this issue, we return an 597 // because it may cause GC. To avoid this issue, we return an
585 // internal error which will make sure we do not update any 598 // internal error which will make sure we do not update any
586 // caches. 599 // caches.
587 if (!function->is_compiled()) return Failure::InternalError(); 600 if (!function->is_compiled()) return Failure::InternalError();
588 CallStubCompiler compiler(argc, in_loop); 601 CallStubCompiler compiler(argc, in_loop, kind);
589 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name); 602 code = compiler.CompileCallGlobal(receiver, holder, cell, function, name);
590 if (code->IsFailure()) return code; 603 if (code->IsFailure()) return code;
591 ASSERT_EQ(flags, Code::cast(code)->flags()); 604 ASSERT_EQ(flags, Code::cast(code)->flags());
592 PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name)); 605 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
606 Code::cast(code), name));
593 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code)); 607 Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
594 if (result->IsFailure()) return result; 608 if (result->IsFailure()) return result;
595 } 609 }
596 return Set(name, receiver->map(), Code::cast(code)); 610 return Set(name, receiver->map(), Code::cast(code));
597 } 611 }
598 612
599 613
600 static Object* GetProbeValue(Code::Flags flags) { 614 static Object* GetProbeValue(Code::Flags flags) {
601 // Use raw_unchecked... so we don't get assert failures during GC. 615 // Use raw_unchecked... so we don't get assert failures during GC.
602 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache(); 616 NumberDictionary* dictionary = Heap::raw_unchecked_non_monomorphic_cache();
(...skipping 27 matching lines...) Expand all
630 ASSERT(entry != -1); 644 ASSERT(entry != -1);
631 ASSERT(Heap::non_monomorphic_cache()->ValueAt(entry) == 645 ASSERT(Heap::non_monomorphic_cache()->ValueAt(entry) ==
632 Heap::undefined_value()); 646 Heap::undefined_value());
633 Heap::non_monomorphic_cache()->ValueAtPut(entry, code); 647 Heap::non_monomorphic_cache()->ValueAtPut(entry, code);
634 CHECK(GetProbeValue(Code::cast(code)->flags()) == code); 648 CHECK(GetProbeValue(Code::cast(code)->flags()) == code);
635 } 649 }
636 return code; 650 return code;
637 } 651 }
638 652
639 653
640 Code* StubCache::FindCallInitialize(int argc, InLoopFlag in_loop) { 654 Code* StubCache::FindCallInitialize(int argc,
655 InLoopFlag in_loop,
656 Code::Kind kind) {
641 Code::Flags flags = 657 Code::Flags flags =
642 Code::ComputeFlags(Code::CALL_IC, in_loop, UNINITIALIZED, NORMAL, argc); 658 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc);
643 Object* result = ProbeCache(flags); 659 Object* result = ProbeCache(flags);
644 ASSERT(!result->IsUndefined()); 660 ASSERT(!result->IsUndefined());
645 // This might be called during the marking phase of the collector 661 // This might be called during the marking phase of the collector
646 // hence the unchecked cast. 662 // hence the unchecked cast.
647 return reinterpret_cast<Code*>(result); 663 return reinterpret_cast<Code*>(result);
648 } 664 }
649 665
650 666
651 Object* StubCache::ComputeCallInitialize(int argc, InLoopFlag in_loop) { 667 Object* StubCache::ComputeCallInitialize(int argc,
668 InLoopFlag in_loop,
669 Code::Kind kind) {
652 Code::Flags flags = 670 Code::Flags flags =
653 Code::ComputeFlags(Code::CALL_IC, in_loop, UNINITIALIZED, NORMAL, argc); 671 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc);
654 Object* probe = ProbeCache(flags); 672 Object* probe = ProbeCache(flags);
655 if (!probe->IsUndefined()) return probe; 673 if (!probe->IsUndefined()) return probe;
656 StubCompiler compiler; 674 StubCompiler compiler;
657 return FillCache(compiler.CompileCallInitialize(flags)); 675 return FillCache(compiler.CompileCallInitialize(flags));
658 } 676 }
659 677
660 678
661 Object* StubCache::ComputeCallPreMonomorphic(int argc, InLoopFlag in_loop) { 679 Object* StubCache::ComputeCallPreMonomorphic(int argc,
680 InLoopFlag in_loop,
681 Code::Kind kind) {
662 Code::Flags flags = 682 Code::Flags flags =
663 Code::ComputeFlags(Code::CALL_IC, in_loop, PREMONOMORPHIC, NORMAL, argc); 683 Code::ComputeFlags(kind, in_loop, PREMONOMORPHIC, NORMAL, argc);
664 Object* probe = ProbeCache(flags); 684 Object* probe = ProbeCache(flags);
665 if (!probe->IsUndefined()) return probe; 685 if (!probe->IsUndefined()) return probe;
666 StubCompiler compiler; 686 StubCompiler compiler;
667 return FillCache(compiler.CompileCallPreMonomorphic(flags)); 687 return FillCache(compiler.CompileCallPreMonomorphic(flags));
668 } 688 }
669 689
670 690
671 Object* StubCache::ComputeCallNormal(int argc, InLoopFlag in_loop) { 691 Object* StubCache::ComputeCallNormal(int argc,
692 InLoopFlag in_loop,
693 Code::Kind kind) {
672 Code::Flags flags = 694 Code::Flags flags =
673 Code::ComputeFlags(Code::CALL_IC, in_loop, MONOMORPHIC, NORMAL, argc); 695 Code::ComputeFlags(kind, in_loop, MONOMORPHIC, NORMAL, argc);
674 Object* probe = ProbeCache(flags); 696 Object* probe = ProbeCache(flags);
675 if (!probe->IsUndefined()) return probe; 697 if (!probe->IsUndefined()) return probe;
676 StubCompiler compiler; 698 StubCompiler compiler;
677 return FillCache(compiler.CompileCallNormal(flags)); 699 return FillCache(compiler.CompileCallNormal(flags));
678 } 700 }
679 701
680 702
681 Object* StubCache::ComputeCallMegamorphic(int argc, InLoopFlag in_loop) { 703 Object* StubCache::ComputeCallMegamorphic(int argc,
704 InLoopFlag in_loop,
705 Code::Kind kind) {
682 Code::Flags flags = 706 Code::Flags flags =
683 Code::ComputeFlags(Code::CALL_IC, in_loop, MEGAMORPHIC, NORMAL, argc); 707 Code::ComputeFlags(kind, in_loop, MEGAMORPHIC, NORMAL, argc);
684 Object* probe = ProbeCache(flags); 708 Object* probe = ProbeCache(flags);
685 if (!probe->IsUndefined()) return probe; 709 if (!probe->IsUndefined()) return probe;
686 StubCompiler compiler; 710 StubCompiler compiler;
687 return FillCache(compiler.CompileCallMegamorphic(flags)); 711 return FillCache(compiler.CompileCallMegamorphic(flags));
688 } 712 }
689 713
690 714
691 Object* StubCache::ComputeCallMiss(int argc) { 715 Object* StubCache::ComputeCallMiss(int argc, Code::Kind kind) {
692 Code::Flags flags = 716 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
693 Code::ComputeFlags(Code::STUB, NOT_IN_LOOP, MEGAMORPHIC, NORMAL, argc); 717 // and monomorphic stubs are not mixed up together in the stub cache.
718 Code::Flags flags = Code::ComputeFlags(
719 kind, NOT_IN_LOOP, MONOMORPHIC_PROTOTYPE_FAILURE, NORMAL, argc);
694 Object* probe = ProbeCache(flags); 720 Object* probe = ProbeCache(flags);
695 if (!probe->IsUndefined()) return probe; 721 if (!probe->IsUndefined()) return probe;
696 StubCompiler compiler; 722 StubCompiler compiler;
697 return FillCache(compiler.CompileCallMiss(flags)); 723 return FillCache(compiler.CompileCallMiss(flags));
698 } 724 }
699 725
700 726
701 #ifdef ENABLE_DEBUGGER_SUPPORT 727 #ifdef ENABLE_DEBUGGER_SUPPORT
702 Object* StubCache::ComputeCallDebugBreak(int argc) { 728 Object* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) {
703 Code::Flags flags = 729 Code::Flags flags =
704 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc); 730 Code::ComputeFlags(kind, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc);
705 Object* probe = ProbeCache(flags); 731 Object* probe = ProbeCache(flags);
706 if (!probe->IsUndefined()) return probe; 732 if (!probe->IsUndefined()) return probe;
707 StubCompiler compiler; 733 StubCompiler compiler;
708 return FillCache(compiler.CompileCallDebugBreak(flags)); 734 return FillCache(compiler.CompileCallDebugBreak(flags));
709 } 735 }
710 736
711 737
712 Object* StubCache::ComputeCallDebugPrepareStepIn(int argc) { 738 Object* StubCache::ComputeCallDebugPrepareStepIn(int argc, Code::Kind kind) {
713 Code::Flags flags = 739 Code::Flags flags =
714 Code::ComputeFlags(Code::CALL_IC, 740 Code::ComputeFlags(kind,
715 NOT_IN_LOOP, 741 NOT_IN_LOOP,
716 DEBUG_PREPARE_STEP_IN, 742 DEBUG_PREPARE_STEP_IN,
717 NORMAL, 743 NORMAL,
718 argc); 744 argc);
719 Object* probe = ProbeCache(flags); 745 Object* probe = ProbeCache(flags);
720 if (!probe->IsUndefined()) return probe; 746 if (!probe->IsUndefined()) return probe;
721 StubCompiler compiler; 747 StubCompiler compiler;
722 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags)); 748 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags));
723 } 749 }
724 #endif 750 #endif
(...skipping 26 matching lines...) Expand all
751 secondary_[j].value = Builtins::builtin(Builtins::Illegal); 777 secondary_[j].value = Builtins::builtin(Builtins::Illegal);
752 } 778 }
753 } 779 }
754 780
755 781
756 // ------------------------------------------------------------------------ 782 // ------------------------------------------------------------------------
757 // StubCompiler implementation. 783 // StubCompiler implementation.
758 784
759 785
760 // Support function for computing call IC miss stubs. 786 // Support function for computing call IC miss stubs.
761 Handle<Code> ComputeCallMiss(int argc) { 787 Handle<Code> ComputeCallMiss(int argc, Code::Kind kind) {
762 CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc), Code); 788 CALL_HEAP_FUNCTION(StubCache::ComputeCallMiss(argc, kind), Code);
763 } 789 }
764 790
765 791
766 792
767 Object* LoadCallbackProperty(Arguments args) { 793 Object* LoadCallbackProperty(Arguments args) {
768 ASSERT(args[0]->IsJSObject()); 794 ASSERT(args[0]->IsJSObject());
769 ASSERT(args[1]->IsJSObject()); 795 ASSERT(args[1]->IsJSObject());
770 AccessorInfo* callback = AccessorInfo::cast(args[2]); 796 AccessorInfo* callback = AccessorInfo::cast(args[2]);
771 Address getter_address = v8::ToCData<Address>(callback->getter()); 797 Address getter_address = v8::ToCData<Address>(callback->getter());
772 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); 798 v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
959 Object* KeyedLoadPropertyWithInterceptor(Arguments args) { 985 Object* KeyedLoadPropertyWithInterceptor(Arguments args) {
960 JSObject* receiver = JSObject::cast(args[0]); 986 JSObject* receiver = JSObject::cast(args[0]);
961 uint32_t index = Smi::cast(args[1])->value(); 987 uint32_t index = Smi::cast(args[1])->value();
962 return receiver->GetElementWithInterceptor(receiver, index); 988 return receiver->GetElementWithInterceptor(receiver, index);
963 } 989 }
964 990
965 991
966 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) { 992 Object* StubCompiler::CompileCallInitialize(Code::Flags flags) {
967 HandleScope scope; 993 HandleScope scope;
968 int argc = Code::ExtractArgumentsCountFromFlags(flags); 994 int argc = Code::ExtractArgumentsCountFromFlags(flags);
969 CallIC::GenerateInitialize(masm(), argc); 995 Code::Kind kind = Code::ExtractKindFromFlags(flags);
996 if (kind == Code::CALL_IC) {
997 CallIC::GenerateInitialize(masm(), argc);
998 } else {
999 KeyedCallIC::GenerateInitialize(masm(), argc);
1000 }
970 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize"); 1001 Object* result = GetCodeWithFlags(flags, "CompileCallInitialize");
971 if (!result->IsFailure()) { 1002 if (!result->IsFailure()) {
972 Counters::call_initialize_stubs.Increment(); 1003 Counters::call_initialize_stubs.Increment();
973 Code* code = Code::cast(result); 1004 Code* code = Code::cast(result);
974 USE(code); 1005 USE(code);
975 PROFILE(CodeCreateEvent(Logger::CALL_INITIALIZE_TAG, 1006 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG),
976 code, code->arguments_count())); 1007 code, code->arguments_count()));
977 } 1008 }
978 return result; 1009 return result;
979 } 1010 }
980 1011
981 1012
982 Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { 1013 Object* StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) {
983 HandleScope scope; 1014 HandleScope scope;
984 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1015 int argc = Code::ExtractArgumentsCountFromFlags(flags);
985 // The code of the PreMonomorphic stub is the same as the code 1016 // The code of the PreMonomorphic stub is the same as the code
986 // of the Initialized stub. They just differ on the code object flags. 1017 // of the Initialized stub. They just differ on the code object flags.
987 CallIC::GenerateInitialize(masm(), argc); 1018 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1019 if (kind == Code::CALL_IC) {
1020 CallIC::GenerateInitialize(masm(), argc);
1021 } else {
1022 KeyedCallIC::GenerateInitialize(masm(), argc);
1023 }
988 Object* result = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); 1024 Object* result = GetCodeWithFlags(flags, "CompileCallPreMonomorphic");
989 if (!result->IsFailure()) { 1025 if (!result->IsFailure()) {
990 Counters::call_premonomorphic_stubs.Increment(); 1026 Counters::call_premonomorphic_stubs.Increment();
991 Code* code = Code::cast(result); 1027 Code* code = Code::cast(result);
992 USE(code); 1028 USE(code);
993 PROFILE(CodeCreateEvent(Logger::CALL_PRE_MONOMORPHIC_TAG, 1029 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG),
994 code, code->arguments_count())); 1030 code, code->arguments_count()));
995 } 1031 }
996 return result; 1032 return result;
997 } 1033 }
998 1034
999 1035
1000 Object* StubCompiler::CompileCallNormal(Code::Flags flags) { 1036 Object* StubCompiler::CompileCallNormal(Code::Flags flags) {
1001 HandleScope scope; 1037 HandleScope scope;
1002 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1038 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1003 CallIC::GenerateNormal(masm(), argc); 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 }
1004 Object* result = GetCodeWithFlags(flags, "CompileCallNormal"); 1045 Object* result = GetCodeWithFlags(flags, "CompileCallNormal");
1005 if (!result->IsFailure()) { 1046 if (!result->IsFailure()) {
1006 Counters::call_normal_stubs.Increment(); 1047 Counters::call_normal_stubs.Increment();
1007 Code* code = Code::cast(result); 1048 Code* code = Code::cast(result);
1008 USE(code); 1049 USE(code);
1009 PROFILE(CodeCreateEvent(Logger::CALL_NORMAL_TAG, 1050 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG),
1010 code, code->arguments_count())); 1051 code, code->arguments_count()));
1011 } 1052 }
1012 return result; 1053 return result;
1013 } 1054 }
1014 1055
1015 1056
1016 Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) { 1057 Object* StubCompiler::CompileCallMegamorphic(Code::Flags flags) {
1017 HandleScope scope; 1058 HandleScope scope;
1018 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1059 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1019 CallIC::GenerateMegamorphic(masm(), argc); 1060 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1061 if (kind == Code::CALL_IC) {
1062 CallIC::GenerateMegamorphic(masm(), argc);
1063 } else {
1064 KeyedCallIC::GenerateMegamorphic(masm(), argc);
1065 }
1066
1020 Object* result = GetCodeWithFlags(flags, "CompileCallMegamorphic"); 1067 Object* result = GetCodeWithFlags(flags, "CompileCallMegamorphic");
1021 if (!result->IsFailure()) { 1068 if (!result->IsFailure()) {
1022 Counters::call_megamorphic_stubs.Increment(); 1069 Counters::call_megamorphic_stubs.Increment();
1023 Code* code = Code::cast(result); 1070 Code* code = Code::cast(result);
1024 USE(code); 1071 USE(code);
1025 PROFILE(CodeCreateEvent(Logger::CALL_MEGAMORPHIC_TAG, 1072 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG),
1026 code, code->arguments_count())); 1073 code, code->arguments_count()));
1027 } 1074 }
1028 return result; 1075 return result;
1029 } 1076 }
1030 1077
1031 1078
1032 Object* StubCompiler::CompileCallMiss(Code::Flags flags) { 1079 Object* StubCompiler::CompileCallMiss(Code::Flags flags) {
1033 HandleScope scope; 1080 HandleScope scope;
1034 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1081 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1035 CallIC::GenerateMiss(masm(), argc); 1082 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1083 if (kind == Code::CALL_IC) {
1084 CallIC::GenerateMiss(masm(), argc);
1085 } else {
1086 KeyedCallIC::GenerateMiss(masm(), argc);
1087 }
1036 Object* result = GetCodeWithFlags(flags, "CompileCallMiss"); 1088 Object* result = GetCodeWithFlags(flags, "CompileCallMiss");
1037 if (!result->IsFailure()) { 1089 if (!result->IsFailure()) {
1038 Counters::call_megamorphic_stubs.Increment(); 1090 Counters::call_megamorphic_stubs.Increment();
1039 Code* code = Code::cast(result); 1091 Code* code = Code::cast(result);
1040 USE(code); 1092 USE(code);
1041 PROFILE(CodeCreateEvent(Logger::CALL_MISS_TAG, 1093 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG),
1042 code, code->arguments_count())); 1094 code, code->arguments_count()));
1043 } 1095 }
1044 return result; 1096 return result;
1045 } 1097 }
1046 1098
1047 1099
1048 #ifdef ENABLE_DEBUGGER_SUPPORT 1100 #ifdef ENABLE_DEBUGGER_SUPPORT
1049 Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) { 1101 Object* StubCompiler::CompileCallDebugBreak(Code::Flags flags) {
1050 HandleScope scope; 1102 HandleScope scope;
1051 Debug::GenerateCallICDebugBreak(masm()); 1103 Debug::GenerateCallICDebugBreak(masm());
1052 Object* result = GetCodeWithFlags(flags, "CompileCallDebugBreak"); 1104 Object* result = GetCodeWithFlags(flags, "CompileCallDebugBreak");
1053 if (!result->IsFailure()) { 1105 if (!result->IsFailure()) {
1054 Code* code = Code::cast(result); 1106 Code* code = Code::cast(result);
1055 USE(code); 1107 USE(code);
1056 PROFILE(CodeCreateEvent(Logger::CALL_DEBUG_BREAK_TAG, 1108 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1109 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_DEBUG_BREAK_TAG),
1057 code, code->arguments_count())); 1110 code, code->arguments_count()));
1058 } 1111 }
1059 return result; 1112 return result;
1060 } 1113 }
1061 1114
1062 1115
1063 Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { 1116 Object* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) {
1064 HandleScope scope; 1117 HandleScope scope;
1065 // Use the same code for the the step in preparations as we do for 1118 // Use the same code for the the step in preparations as we do for
1066 // the miss case. 1119 // the miss case.
1067 int argc = Code::ExtractArgumentsCountFromFlags(flags); 1120 int argc = Code::ExtractArgumentsCountFromFlags(flags);
1068 CallIC::GenerateMiss(masm(), argc); 1121 Code::Kind kind = Code::ExtractKindFromFlags(flags);
1122 if (kind == Code::CALL_IC) {
1123 CallIC::GenerateMiss(masm(), argc);
1124 } else {
1125 KeyedCallIC::GenerateMiss(masm(), argc);
1126 }
1069 Object* result = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); 1127 Object* result = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn");
1070 if (!result->IsFailure()) { 1128 if (!result->IsFailure()) {
1071 Code* code = Code::cast(result); 1129 Code* code = Code::cast(result);
1072 USE(code); 1130 USE(code);
1073 PROFILE(CodeCreateEvent(Logger::CALL_DEBUG_PREPARE_STEP_IN_TAG, 1131 PROFILE(CodeCreateEvent(
1074 code, code->arguments_count())); 1132 CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG),
1133 code,
1134 code->arguments_count()));
1075 } 1135 }
1076 return result; 1136 return result;
1077 } 1137 }
1078 #endif 1138 #endif
1079 1139
1140 #undef CALL_LOGGER_TAG
1080 1141
1081 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags, const char* name) { 1142 Object* StubCompiler::GetCodeWithFlags(Code::Flags flags, const char* name) {
1082 // Check for allocation failures during stub compilation. 1143 // Check for allocation failures during stub compilation.
1083 if (failure_->IsFailure()) return failure_; 1144 if (failure_->IsFailure()) return failure_;
1084 1145
1085 // Create code object in the heap. 1146 // Create code object in the heap.
1086 CodeDesc desc; 1147 CodeDesc desc;
1087 masm_.GetCode(&desc); 1148 masm_.GetCode(&desc);
1088 Object* result = Heap::CreateCode(desc, NULL, flags, masm_.CodeObject()); 1149 Object* result = Heap::CreateCode(desc, NULL, flags, masm_.CodeObject());
1089 #ifdef ENABLE_DISASSEMBLER 1150 #ifdef ENABLE_DISASSEMBLER
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 1221 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE)
1161 #undef CALL_GENERATOR_CASE 1222 #undef CALL_GENERATOR_CASE
1162 } 1223 }
1163 UNREACHABLE(); 1224 UNREACHABLE();
1164 return Heap::undefined_value(); 1225 return Heap::undefined_value();
1165 } 1226 }
1166 1227
1167 1228
1168 Object* CallStubCompiler::GetCode(PropertyType type, String* name) { 1229 Object* CallStubCompiler::GetCode(PropertyType type, String* name) {
1169 int argc = arguments_.immediate(); 1230 int argc = arguments_.immediate();
1170 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, 1231 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1171 type, 1232 type,
1172 in_loop_, 1233 in_loop_,
1173 argc); 1234 argc);
1174 return GetCodeWithFlags(flags, name); 1235 return GetCodeWithFlags(flags, name);
1175 } 1236 }
1176 1237
1177 1238
1178 Object* CallStubCompiler::GetCode(JSFunction* function) { 1239 Object* CallStubCompiler::GetCode(JSFunction* function) {
1179 String* function_name = NULL; 1240 String* function_name = NULL;
1180 if (function->shared()->name()->IsString()) { 1241 if (function->shared()->name()->IsString()) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 expected_receiver_type_ = 1318 expected_receiver_type_ =
1258 FunctionTemplateInfo::cast(signature->receiver()); 1319 FunctionTemplateInfo::cast(signature->receiver());
1259 } 1320 }
1260 } 1321 }
1261 1322
1262 is_simple_api_call_ = true; 1323 is_simple_api_call_ = true;
1263 } 1324 }
1264 1325
1265 1326
1266 } } // namespace v8::internal 1327 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/x64/codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698