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

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

Issue 7869009: Remove in-loop tracking for call ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 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.cc » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 634 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 if (!maybe_result->ToObject(&result)) return maybe_result; 645 if (!maybe_result->ToObject(&result)) return maybe_result;
646 } 646 }
647 } 647 }
648 return code; 648 return code;
649 } 649 }
650 650
651 #define CALL_LOGGER_TAG(kind, type) \ 651 #define CALL_LOGGER_TAG(kind, type) \
652 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 652 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type)
653 653
654 MaybeObject* StubCache::ComputeCallConstant(int argc, 654 MaybeObject* StubCache::ComputeCallConstant(int argc,
655 InLoopFlag in_loop,
656 Code::Kind kind, 655 Code::Kind kind,
657 Code::ExtraICState extra_ic_state, 656 Code::ExtraICState extra_ic_state,
658 String* name, 657 String* name,
659 Object* object, 658 Object* object,
660 JSObject* holder, 659 JSObject* holder,
661 JSFunction* function) { 660 JSFunction* function) {
662 // Compute the check type and the map. 661 // Compute the check type and the map.
663 InlineCacheHolderFlag cache_holder = 662 InlineCacheHolderFlag cache_holder =
664 IC::GetCodeCacheForObject(object, holder); 663 IC::GetCodeCacheForObject(object, holder);
665 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 664 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
666 665
667 // Compute check type based on receiver/holder. 666 // Compute check type based on receiver/holder.
668 CheckType check = RECEIVER_MAP_CHECK; 667 CheckType check = RECEIVER_MAP_CHECK;
669 if (object->IsString()) { 668 if (object->IsString()) {
670 check = STRING_CHECK; 669 check = STRING_CHECK;
671 } else if (object->IsNumber()) { 670 } else if (object->IsNumber()) {
672 check = NUMBER_CHECK; 671 check = NUMBER_CHECK;
673 } else if (object->IsBoolean()) { 672 } else if (object->IsBoolean()) {
674 check = BOOLEAN_CHECK; 673 check = BOOLEAN_CHECK;
675 } 674 }
676 675
677 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 676 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
678 CONSTANT_FUNCTION, 677 CONSTANT_FUNCTION,
679 extra_ic_state, 678 extra_ic_state,
680 cache_holder, 679 cache_holder,
681 in_loop,
682 argc); 680 argc);
683 Object* code = map_holder->map()->FindInCodeCache(name, flags); 681 Object* code = map_holder->map()->FindInCodeCache(name, flags);
684 if (code->IsUndefined()) { 682 if (code->IsUndefined()) {
685 // If the function hasn't been compiled yet, we cannot do it now 683 // If the function hasn't been compiled yet, we cannot do it now
686 // because it may cause GC. To avoid this issue, we return an 684 // because it may cause GC. To avoid this issue, we return an
687 // internal error which will make sure we do not update any 685 // internal error which will make sure we do not update any
688 // caches. 686 // caches.
689 if (!function->is_compiled()) return Failure::InternalError(); 687 if (!function->is_compiled()) return Failure::InternalError();
690 // Compile the stub - only create stubs for fully compiled functions. 688 // Compile the stub - only create stubs for fully compiled functions.
691 CallStubCompiler compiler( 689 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
692 argc, in_loop, kind, extra_ic_state, cache_holder);
693 { MaybeObject* maybe_code = 690 { MaybeObject* maybe_code =
694 compiler.CompileCallConstant(object, holder, function, name, check); 691 compiler.CompileCallConstant(object, holder, function, name, check);
695 if (!maybe_code->ToObject(&code)) return maybe_code; 692 if (!maybe_code->ToObject(&code)) return maybe_code;
696 } 693 }
697 Code::cast(code)->set_check_type(check); 694 Code::cast(code)->set_check_type(check);
698 ASSERT_EQ(flags, Code::cast(code)->flags()); 695 ASSERT_EQ(flags, Code::cast(code)->flags());
699 PROFILE(isolate_, 696 PROFILE(isolate_,
700 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 697 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
701 Code::cast(code), name)); 698 Code::cast(code), name));
702 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); 699 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
703 Object* result; 700 Object* result;
704 { MaybeObject* maybe_result = 701 { MaybeObject* maybe_result =
705 map_holder->UpdateMapCodeCache(name, Code::cast(code)); 702 map_holder->UpdateMapCodeCache(name, Code::cast(code));
706 if (!maybe_result->ToObject(&result)) return maybe_result; 703 if (!maybe_result->ToObject(&result)) return maybe_result;
707 } 704 }
708 } 705 }
709 return code; 706 return code;
710 } 707 }
711 708
712 709
713 MaybeObject* StubCache::ComputeCallField(int argc, 710 MaybeObject* StubCache::ComputeCallField(int argc,
714 InLoopFlag in_loop,
715 Code::Kind kind, 711 Code::Kind kind,
716 Code::ExtraICState extra_ic_state, 712 Code::ExtraICState extra_ic_state,
717 String* name, 713 String* name,
718 Object* object, 714 Object* object,
719 JSObject* holder, 715 JSObject* holder,
720 int index) { 716 int index) {
721 // Compute the check type and the map. 717 // Compute the check type and the map.
722 InlineCacheHolderFlag cache_holder = 718 InlineCacheHolderFlag cache_holder =
723 IC::GetCodeCacheForObject(object, holder); 719 IC::GetCodeCacheForObject(object, holder);
724 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); 720 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder);
725 721
726 // TODO(1233596): We cannot do receiver map check for non-JS objects 722 // TODO(1233596): We cannot do receiver map check for non-JS objects
727 // because they may be represented as immediates without a 723 // because they may be represented as immediates without a
728 // map. Instead, we check against the map in the holder. 724 // map. Instead, we check against the map in the holder.
729 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 725 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
730 object = holder; 726 object = holder;
731 } 727 }
732 728
733 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 729 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
734 FIELD, 730 FIELD,
735 extra_ic_state, 731 extra_ic_state,
736 cache_holder, 732 cache_holder,
737 in_loop,
738 argc); 733 argc);
739 Object* code = map_holder->map()->FindInCodeCache(name, flags); 734 Object* code = map_holder->map()->FindInCodeCache(name, flags);
740 if (code->IsUndefined()) { 735 if (code->IsUndefined()) {
741 CallStubCompiler compiler( 736 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
742 argc, in_loop, kind, extra_ic_state, cache_holder);
743 { MaybeObject* maybe_code = 737 { MaybeObject* maybe_code =
744 compiler.CompileCallField(JSObject::cast(object), 738 compiler.CompileCallField(JSObject::cast(object),
745 holder, 739 holder,
746 index, 740 index,
747 name); 741 name);
748 if (!maybe_code->ToObject(&code)) return maybe_code; 742 if (!maybe_code->ToObject(&code)) return maybe_code;
749 } 743 }
750 ASSERT_EQ(flags, Code::cast(code)->flags()); 744 ASSERT_EQ(flags, Code::cast(code)->flags());
751 PROFILE(isolate_, 745 PROFILE(isolate_,
752 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 746 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
(...skipping 25 matching lines...) Expand all
778 // because they may be represented as immediates without a 772 // because they may be represented as immediates without a
779 // map. Instead, we check against the map in the holder. 773 // map. Instead, we check against the map in the holder.
780 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 774 if (object->IsNumber() || object->IsBoolean() || object->IsString()) {
781 object = holder; 775 object = holder;
782 } 776 }
783 777
784 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 778 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
785 INTERCEPTOR, 779 INTERCEPTOR,
786 extra_ic_state, 780 extra_ic_state,
787 cache_holder, 781 cache_holder,
788 NOT_IN_LOOP,
789 argc); 782 argc);
790 Object* code = map_holder->map()->FindInCodeCache(name, flags); 783 Object* code = map_holder->map()->FindInCodeCache(name, flags);
791 if (code->IsUndefined()) { 784 if (code->IsUndefined()) {
792 CallStubCompiler compiler( 785 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
793 argc, NOT_IN_LOOP, kind, extra_ic_state, cache_holder);
794 { MaybeObject* maybe_code = 786 { MaybeObject* maybe_code =
795 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); 787 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name);
796 if (!maybe_code->ToObject(&code)) return maybe_code; 788 if (!maybe_code->ToObject(&code)) return maybe_code;
797 } 789 }
798 ASSERT_EQ(flags, Code::cast(code)->flags()); 790 ASSERT_EQ(flags, Code::cast(code)->flags());
799 PROFILE(isolate(), 791 PROFILE(isolate(),
800 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 792 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
801 Code::cast(code), name)); 793 Code::cast(code), name));
802 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); 794 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
803 Object* result; 795 Object* result;
804 { MaybeObject* maybe_result = 796 { MaybeObject* maybe_result =
805 map_holder->UpdateMapCodeCache(name, Code::cast(code)); 797 map_holder->UpdateMapCodeCache(name, Code::cast(code));
806 if (!maybe_result->ToObject(&result)) return maybe_result; 798 if (!maybe_result->ToObject(&result)) return maybe_result;
807 } 799 }
808 } 800 }
809 return code; 801 return code;
810 } 802 }
811 803
812 804
813 MaybeObject* StubCache::ComputeCallNormal(int argc, 805 MaybeObject* StubCache::ComputeCallNormal(int argc,
814 InLoopFlag in_loop,
815 Code::Kind kind, 806 Code::Kind kind,
816 Code::ExtraICState extra_ic_state, 807 Code::ExtraICState extra_ic_state,
817 String* name, 808 String* name,
818 JSObject* receiver) { 809 JSObject* receiver) {
819 Object* code; 810 Object* code;
820 { MaybeObject* maybe_code = 811 { MaybeObject* maybe_code = ComputeCallNormal(argc, kind, extra_ic_state);
821 ComputeCallNormal(argc, in_loop, kind, extra_ic_state);
822 if (!maybe_code->ToObject(&code)) return maybe_code; 812 if (!maybe_code->ToObject(&code)) return maybe_code;
823 } 813 }
824 return code; 814 return code;
825 } 815 }
826 816
827 817
828 MaybeObject* StubCache::ComputeCallGlobal(int argc, 818 MaybeObject* StubCache::ComputeCallGlobal(int argc,
829 InLoopFlag in_loop,
830 Code::Kind kind, 819 Code::Kind kind,
831 Code::ExtraICState extra_ic_state, 820 Code::ExtraICState extra_ic_state,
832 String* name, 821 String* name,
833 JSObject* receiver, 822 JSObject* receiver,
834 GlobalObject* holder, 823 GlobalObject* holder,
835 JSGlobalPropertyCell* cell, 824 JSGlobalPropertyCell* cell,
836 JSFunction* function) { 825 JSFunction* function) {
837 InlineCacheHolderFlag cache_holder = 826 InlineCacheHolderFlag cache_holder =
838 IC::GetCodeCacheForObject(receiver, holder); 827 IC::GetCodeCacheForObject(receiver, holder);
839 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); 828 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder);
840 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, 829 Code::Flags flags = Code::ComputeMonomorphicFlags(kind,
841 NORMAL, 830 NORMAL,
842 extra_ic_state, 831 extra_ic_state,
843 cache_holder, 832 cache_holder,
844 in_loop,
845 argc); 833 argc);
846 Object* code = map_holder->map()->FindInCodeCache(name, flags); 834 Object* code = map_holder->map()->FindInCodeCache(name, flags);
847 if (code->IsUndefined()) { 835 if (code->IsUndefined()) {
848 // If the function hasn't been compiled yet, we cannot do it now 836 // If the function hasn't been compiled yet, we cannot do it now
849 // because it may cause GC. To avoid this issue, we return an 837 // because it may cause GC. To avoid this issue, we return an
850 // internal error which will make sure we do not update any 838 // internal error which will make sure we do not update any
851 // caches. 839 // caches.
852 if (!function->is_compiled()) return Failure::InternalError(); 840 if (!function->is_compiled()) return Failure::InternalError();
853 CallStubCompiler compiler( 841 CallStubCompiler compiler(argc, kind, extra_ic_state, cache_holder);
854 argc, in_loop, kind, extra_ic_state, cache_holder);
855 { MaybeObject* maybe_code = 842 { MaybeObject* maybe_code =
856 compiler.CompileCallGlobal(receiver, holder, cell, function, name); 843 compiler.CompileCallGlobal(receiver, holder, cell, function, name);
857 if (!maybe_code->ToObject(&code)) return maybe_code; 844 if (!maybe_code->ToObject(&code)) return maybe_code;
858 } 845 }
859 ASSERT_EQ(flags, Code::cast(code)->flags()); 846 ASSERT_EQ(flags, Code::cast(code)->flags());
860 PROFILE(isolate(), 847 PROFILE(isolate(),
861 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), 848 CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG),
862 Code::cast(code), name)); 849 Code::cast(code), name));
863 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code))); 850 GDBJIT(AddCode(GDBJITInterface::CALL_IC, name, Code::cast(code)));
864 Object* result; 851 Object* result;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 heap->undefined_value()); 900 heap->undefined_value());
914 heap->non_monomorphic_cache()->ValueAtPut(entry, code); 901 heap->non_monomorphic_cache()->ValueAtPut(entry, code);
915 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code); 902 CHECK(GetProbeValue(isolate, Code::cast(code)->flags()) == code);
916 } 903 }
917 } 904 }
918 return maybe_code; 905 return maybe_code;
919 } 906 }
920 907
921 908
922 Code* StubCache::FindCallInitialize(int argc, 909 Code* StubCache::FindCallInitialize(int argc,
923 InLoopFlag in_loop,
924 RelocInfo::Mode mode, 910 RelocInfo::Mode mode,
925 Code::Kind kind) { 911 Code::Kind kind) {
926 Code::ExtraICState extra_state = 912 Code::ExtraICState extra_state =
927 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | 913 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
928 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); 914 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
929 Code::Flags flags = Code::ComputeFlags(kind, 915 Code::Flags flags = Code::ComputeFlags(kind,
930 in_loop,
931 UNINITIALIZED, 916 UNINITIALIZED,
932 extra_state, 917 extra_state,
933 NORMAL, 918 NORMAL,
934 argc); 919 argc);
935 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked(); 920 Object* result = ProbeCache(isolate(), flags)->ToObjectUnchecked();
936 ASSERT(result != heap()->undefined_value()); 921 ASSERT(result != heap()->undefined_value());
937 // This might be called during the marking phase of the collector 922 // This might be called during the marking phase of the collector
938 // hence the unchecked cast. 923 // hence the unchecked cast.
939 return reinterpret_cast<Code*>(result); 924 return reinterpret_cast<Code*>(result);
940 } 925 }
941 926
942 927
943 MaybeObject* StubCache::ComputeCallInitialize(int argc, 928 MaybeObject* StubCache::ComputeCallInitialize(int argc,
944 InLoopFlag in_loop,
945 RelocInfo::Mode mode, 929 RelocInfo::Mode mode,
946 Code::Kind kind) { 930 Code::Kind kind) {
947 Code::ExtraICState extra_state = 931 Code::ExtraICState extra_state =
948 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | 932 CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) |
949 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); 933 CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT);
950 Code::Flags flags = Code::ComputeFlags(kind, 934 Code::Flags flags = Code::ComputeFlags(kind,
951 in_loop,
952 UNINITIALIZED, 935 UNINITIALIZED,
953 extra_state, 936 extra_state,
954 NORMAL, 937 NORMAL,
955 argc); 938 argc);
956 Object* probe; 939 Object* probe;
957 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 940 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
958 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 941 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
959 } 942 }
960 if (!probe->IsUndefined()) return probe; 943 if (!probe->IsUndefined()) return probe;
961 StubCompiler compiler; 944 StubCompiler compiler;
962 return FillCache(isolate_, compiler.CompileCallInitialize(flags)); 945 return FillCache(isolate_, compiler.CompileCallInitialize(flags));
963 } 946 }
964 947
965 948
966 Handle<Code> StubCache::ComputeCallInitialize(int argc, 949 Handle<Code> StubCache::ComputeCallInitialize(int argc,
967 InLoopFlag in_loop,
968 RelocInfo::Mode mode) { 950 RelocInfo::Mode mode) {
969 if (in_loop == IN_LOOP) {
970 // Force the creation of the corresponding stub outside loops,
971 // because it may be used when clearing the ICs later - it is
972 // possible for a series of IC transitions to lose the in-loop
973 // information, and the IC clearing code can't generate a stub
974 // that it needs so we need to ensure it is generated already.
975 ComputeCallInitialize(argc, NOT_IN_LOOP, mode);
976 }
977 CALL_HEAP_FUNCTION(isolate_, 951 CALL_HEAP_FUNCTION(isolate_,
978 ComputeCallInitialize(argc, in_loop, mode, Code::CALL_IC), 952 ComputeCallInitialize(argc, mode, Code::CALL_IC),
979 Code); 953 Code);
980 } 954 }
981 955
982 956
983 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc, 957 Handle<Code> StubCache::ComputeKeyedCallInitialize(int argc) {
984 InLoopFlag in_loop) {
985 if (in_loop == IN_LOOP) {
986 // Force the creation of the corresponding stub outside loops,
987 // because it may be used when clearing the ICs later - it is
988 // possible for a series of IC transitions to lose the in-loop
989 // information, and the IC clearing code can't generate a stub
990 // that it needs so we need to ensure it is generated already.
991 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP);
992 }
993 CALL_HEAP_FUNCTION( 958 CALL_HEAP_FUNCTION(
994 isolate_, 959 isolate_,
995 ComputeCallInitialize(argc, 960 ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, Code::KEYED_CALL_IC),
996 in_loop,
997 RelocInfo::CODE_TARGET,
998 Code::KEYED_CALL_IC),
999 Code); 961 Code);
1000 } 962 }
1001 963
1002 964
1003 MaybeObject* StubCache::ComputeCallPreMonomorphic( 965 MaybeObject* StubCache::ComputeCallPreMonomorphic(
1004 int argc, 966 int argc,
1005 InLoopFlag in_loop,
1006 Code::Kind kind, 967 Code::Kind kind,
1007 Code::ExtraICState extra_ic_state) { 968 Code::ExtraICState extra_ic_state) {
1008 Code::Flags flags = Code::ComputeFlags(kind, 969 Code::Flags flags = Code::ComputeFlags(kind,
1009 in_loop,
1010 PREMONOMORPHIC, 970 PREMONOMORPHIC,
1011 extra_ic_state, 971 extra_ic_state,
1012 NORMAL, 972 NORMAL,
1013 argc); 973 argc);
1014 Object* probe; 974 Object* probe;
1015 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 975 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1016 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 976 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1017 } 977 }
1018 if (!probe->IsUndefined()) return probe; 978 if (!probe->IsUndefined()) return probe;
1019 StubCompiler compiler; 979 StubCompiler compiler;
1020 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags)); 980 return FillCache(isolate_, compiler.CompileCallPreMonomorphic(flags));
1021 } 981 }
1022 982
1023 983
1024 MaybeObject* StubCache::ComputeCallNormal(int argc, 984 MaybeObject* StubCache::ComputeCallNormal(int argc,
1025 InLoopFlag in_loop,
1026 Code::Kind kind, 985 Code::Kind kind,
1027 Code::ExtraICState extra_ic_state) { 986 Code::ExtraICState extra_ic_state) {
1028 Code::Flags flags = Code::ComputeFlags(kind, 987 Code::Flags flags = Code::ComputeFlags(kind,
1029 in_loop,
1030 MONOMORPHIC, 988 MONOMORPHIC,
1031 extra_ic_state, 989 extra_ic_state,
1032 NORMAL, 990 NORMAL,
1033 argc); 991 argc);
1034 Object* probe; 992 Object* probe;
1035 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 993 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1036 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 994 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1037 } 995 }
1038 if (!probe->IsUndefined()) return probe; 996 if (!probe->IsUndefined()) return probe;
1039 StubCompiler compiler; 997 StubCompiler compiler;
1040 return FillCache(isolate_, compiler.CompileCallNormal(flags)); 998 return FillCache(isolate_, compiler.CompileCallNormal(flags));
1041 } 999 }
1042 1000
1043 1001
1044 MaybeObject* StubCache::ComputeCallArguments(int argc, 1002 MaybeObject* StubCache::ComputeCallArguments(int argc, Code::Kind kind) {
1045 InLoopFlag in_loop,
1046 Code::Kind kind) {
1047 ASSERT(kind == Code::KEYED_CALL_IC); 1003 ASSERT(kind == Code::KEYED_CALL_IC);
1048 Code::Flags flags = Code::ComputeFlags(kind, 1004 Code::Flags flags = Code::ComputeFlags(kind,
1049 in_loop,
1050 MEGAMORPHIC, 1005 MEGAMORPHIC,
1051 Code::kNoExtraICState, 1006 Code::kNoExtraICState,
1052 NORMAL, 1007 NORMAL,
1053 argc); 1008 argc);
1054 Object* probe; 1009 Object* probe;
1055 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1010 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1056 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 1011 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1057 } 1012 }
1058 if (!probe->IsUndefined()) return probe; 1013 if (!probe->IsUndefined()) return probe;
1059 StubCompiler compiler; 1014 StubCompiler compiler;
1060 return FillCache(isolate_, compiler.CompileCallArguments(flags)); 1015 return FillCache(isolate_, compiler.CompileCallArguments(flags));
1061 } 1016 }
1062 1017
1063 1018
1064 MaybeObject* StubCache::ComputeCallMegamorphic( 1019 MaybeObject* StubCache::ComputeCallMegamorphic(
1065 int argc, 1020 int argc,
1066 InLoopFlag in_loop,
1067 Code::Kind kind, 1021 Code::Kind kind,
1068 Code::ExtraICState extra_ic_state) { 1022 Code::ExtraICState extra_ic_state) {
1069 Code::Flags flags = Code::ComputeFlags(kind, 1023 Code::Flags flags = Code::ComputeFlags(kind,
1070 in_loop,
1071 MEGAMORPHIC, 1024 MEGAMORPHIC,
1072 extra_ic_state, 1025 extra_ic_state,
1073 NORMAL, 1026 NORMAL,
1074 argc); 1027 argc);
1075 Object* probe; 1028 Object* probe;
1076 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1029 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1077 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 1030 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1078 } 1031 }
1079 if (!probe->IsUndefined()) return probe; 1032 if (!probe->IsUndefined()) return probe;
1080 StubCompiler compiler; 1033 StubCompiler compiler;
1081 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags)); 1034 return FillCache(isolate_, compiler.CompileCallMegamorphic(flags));
1082 } 1035 }
1083 1036
1084 1037
1085 MaybeObject* StubCache::ComputeCallMiss(int argc, 1038 MaybeObject* StubCache::ComputeCallMiss(int argc,
1086 Code::Kind kind, 1039 Code::Kind kind,
1087 Code::ExtraICState extra_ic_state) { 1040 Code::ExtraICState extra_ic_state) {
1088 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs 1041 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs
1089 // and monomorphic stubs are not mixed up together in the stub cache. 1042 // and monomorphic stubs are not mixed up together in the stub cache.
1090 Code::Flags flags = Code::ComputeFlags(kind, 1043 Code::Flags flags = Code::ComputeFlags(kind,
1091 NOT_IN_LOOP,
1092 MONOMORPHIC_PROTOTYPE_FAILURE, 1044 MONOMORPHIC_PROTOTYPE_FAILURE,
1093 extra_ic_state, 1045 extra_ic_state,
1094 NORMAL, 1046 NORMAL,
1095 argc, 1047 argc,
1096 OWN_MAP); 1048 OWN_MAP);
1097 Object* probe; 1049 Object* probe;
1098 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1050 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1099 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 1051 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1100 } 1052 }
1101 if (!probe->IsUndefined()) return probe; 1053 if (!probe->IsUndefined()) return probe;
1102 StubCompiler compiler; 1054 StubCompiler compiler;
1103 return FillCache(isolate_, compiler.CompileCallMiss(flags)); 1055 return FillCache(isolate_, compiler.CompileCallMiss(flags));
1104 } 1056 }
1105 1057
1106 1058
1107 #ifdef ENABLE_DEBUGGER_SUPPORT 1059 #ifdef ENABLE_DEBUGGER_SUPPORT
1108 MaybeObject* StubCache::ComputeCallDebugBreak( 1060 MaybeObject* StubCache::ComputeCallDebugBreak(
1109 int argc, 1061 int argc,
1110 Code::Kind kind) { 1062 Code::Kind kind) {
1111 // Extra IC state is irrelevant for debug break ICs. They jump to 1063 // Extra IC state is irrelevant for debug break ICs. They jump to
1112 // the actual call ic to carry out the work. 1064 // the actual call ic to carry out the work.
1113 Code::Flags flags = Code::ComputeFlags(kind, 1065 Code::Flags flags = Code::ComputeFlags(kind,
1114 NOT_IN_LOOP,
1115 DEBUG_BREAK, 1066 DEBUG_BREAK,
1116 Code::kNoExtraICState, 1067 Code::kNoExtraICState,
1117 NORMAL, 1068 NORMAL,
1118 argc); 1069 argc);
1119 Object* probe; 1070 Object* probe;
1120 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1071 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1121 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 1072 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1122 } 1073 }
1123 if (!probe->IsUndefined()) return probe; 1074 if (!probe->IsUndefined()) return probe;
1124 StubCompiler compiler; 1075 StubCompiler compiler;
1125 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags)); 1076 return FillCache(isolate_, compiler.CompileCallDebugBreak(flags));
1126 } 1077 }
1127 1078
1128 1079
1129 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn( 1080 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(
1130 int argc, 1081 int argc,
1131 Code::Kind kind) { 1082 Code::Kind kind) {
1132 // Extra IC state is irrelevant for debug break ICs. They jump to 1083 // Extra IC state is irrelevant for debug break ICs. They jump to
1133 // the actual call ic to carry out the work. 1084 // the actual call ic to carry out the work.
1134 Code::Flags flags = Code::ComputeFlags(kind, 1085 Code::Flags flags = Code::ComputeFlags(kind,
1135 NOT_IN_LOOP,
1136 DEBUG_PREPARE_STEP_IN, 1086 DEBUG_PREPARE_STEP_IN,
1137 Code::kNoExtraICState, 1087 Code::kNoExtraICState,
1138 NORMAL, 1088 NORMAL,
1139 argc); 1089 argc);
1140 Object* probe; 1090 Object* probe;
1141 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags); 1091 { MaybeObject* maybe_probe = ProbeCache(isolate_, flags);
1142 if (!maybe_probe->ToObject(&probe)) return maybe_probe; 1092 if (!maybe_probe->ToObject(&probe)) return maybe_probe;
1143 } 1093 }
1144 if (!probe->IsUndefined()) return probe; 1094 if (!probe->IsUndefined()) return probe;
1145 StubCompiler compiler; 1095 StubCompiler compiler;
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 Code::cast(result->ToObjectUnchecked()))); 1615 Code::cast(result->ToObjectUnchecked())));
1666 } 1616 }
1667 return result; 1617 return result;
1668 } 1618 }
1669 1619
1670 1620
1671 MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type, 1621 MaybeObject* KeyedLoadStubCompiler::GetCode(PropertyType type,
1672 String* name, 1622 String* name,
1673 InlineCacheState state) { 1623 InlineCacheState state) {
1674 Code::Flags flags = Code::ComputeFlags( 1624 Code::Flags flags = Code::ComputeFlags(
1675 Code::KEYED_LOAD_IC, NOT_IN_LOOP, state, Code::kNoExtraICState, type); 1625 Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type);
1676 MaybeObject* result = GetCodeWithFlags(flags, name); 1626 MaybeObject* result = GetCodeWithFlags(flags, name);
1677 if (!result->IsFailure()) { 1627 if (!result->IsFailure()) {
1678 PROFILE(isolate(), 1628 PROFILE(isolate(),
1679 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, 1629 CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG,
1680 Code::cast(result->ToObjectUnchecked()), 1630 Code::cast(result->ToObjectUnchecked()),
1681 name)); 1631 name));
1682 GDBJIT(AddCode(GDBJITInterface::LOAD_IC, 1632 GDBJIT(AddCode(GDBJITInterface::LOAD_IC,
1683 name, 1633 name,
1684 Code::cast(result->ToObjectUnchecked()))); 1634 Code::cast(result->ToObjectUnchecked())));
1685 } 1635 }
1686 return result; 1636 return result;
1687 } 1637 }
1688 1638
1689 1639
1690 MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) { 1640 MaybeObject* StoreStubCompiler::GetCode(PropertyType type, String* name) {
1691 Code::Flags flags = Code::ComputeMonomorphicFlags( 1641 Code::Flags flags =
1692 Code::STORE_IC, type, strict_mode_); 1642 Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_);
1693 MaybeObject* result = GetCodeWithFlags(flags, name); 1643 MaybeObject* result = GetCodeWithFlags(flags, name);
1694 if (!result->IsFailure()) { 1644 if (!result->IsFailure()) {
1695 PROFILE(isolate(), 1645 PROFILE(isolate(),
1696 CodeCreateEvent(Logger::STORE_IC_TAG, 1646 CodeCreateEvent(Logger::STORE_IC_TAG,
1697 Code::cast(result->ToObjectUnchecked()), 1647 Code::cast(result->ToObjectUnchecked()),
1698 name)); 1648 name));
1699 GDBJIT(AddCode(GDBJITInterface::STORE_IC, 1649 GDBJIT(AddCode(GDBJITInterface::STORE_IC,
1700 name, 1650 name,
1701 Code::cast(result->ToObjectUnchecked()))); 1651 Code::cast(result->ToObjectUnchecked())));
1702 } 1652 }
1703 return result; 1653 return result;
1704 } 1654 }
1705 1655
1706 1656
1707 MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type, 1657 MaybeObject* KeyedStoreStubCompiler::GetCode(PropertyType type,
1708 String* name, 1658 String* name,
1709 InlineCacheState state) { 1659 InlineCacheState state) {
1710 Code::Flags flags = Code::ComputeFlags( 1660 Code::Flags flags =
1711 Code::KEYED_STORE_IC, NOT_IN_LOOP, state, strict_mode_, type); 1661 Code::ComputeFlags(Code::KEYED_STORE_IC, state, strict_mode_, type);
1712 MaybeObject* result = GetCodeWithFlags(flags, name); 1662 MaybeObject* result = GetCodeWithFlags(flags, name);
1713 if (!result->IsFailure()) { 1663 if (!result->IsFailure()) {
1714 PROFILE(isolate(), 1664 PROFILE(isolate(),
1715 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, 1665 CodeCreateEvent(Logger::KEYED_STORE_IC_TAG,
1716 Code::cast(result->ToObjectUnchecked()), 1666 Code::cast(result->ToObjectUnchecked()),
1717 name)); 1667 name));
1718 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, 1668 GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC,
1719 name, 1669 name,
1720 Code::cast(result->ToObjectUnchecked()))); 1670 Code::cast(result->ToObjectUnchecked())));
1721 } 1671 }
1722 return result; 1672 return result;
1723 } 1673 }
1724 1674
1725 1675
1726 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 1676 void KeyedStoreStubCompiler::GenerateStoreDictionaryElement(
1727 MacroAssembler* masm) { 1677 MacroAssembler* masm) {
1728 KeyedStoreIC::GenerateSlow(masm); 1678 KeyedStoreIC::GenerateSlow(masm);
1729 } 1679 }
1730 1680
1731 1681
1732 CallStubCompiler::CallStubCompiler(int argc, 1682 CallStubCompiler::CallStubCompiler(int argc,
1733 InLoopFlag in_loop,
1734 Code::Kind kind, 1683 Code::Kind kind,
1735 Code::ExtraICState extra_ic_state, 1684 Code::ExtraICState extra_ic_state,
1736 InlineCacheHolderFlag cache_holder) 1685 InlineCacheHolderFlag cache_holder)
1737 : arguments_(argc), 1686 : arguments_(argc),
1738 in_loop_(in_loop),
1739 kind_(kind), 1687 kind_(kind),
1740 extra_ic_state_(extra_ic_state), 1688 extra_ic_state_(extra_ic_state),
1741 cache_holder_(cache_holder) { 1689 cache_holder_(cache_holder) {
1742 } 1690 }
1743 1691
1744 1692
1745 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) { 1693 bool CallStubCompiler::HasCustomCallGenerator(JSFunction* function) {
1746 SharedFunctionInfo* info = function->shared(); 1694 SharedFunctionInfo* info = function->shared();
1747 if (info->HasBuiltinFunctionId()) { 1695 if (info->HasBuiltinFunctionId()) {
1748 BuiltinFunctionId id = info->builtin_function_id(); 1696 BuiltinFunctionId id = info->builtin_function_id();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1789 fname); 1737 fname);
1790 } 1738 }
1791 1739
1792 1740
1793 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) { 1741 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) {
1794 int argc = arguments_.immediate(); 1742 int argc = arguments_.immediate();
1795 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1743 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_,
1796 type, 1744 type,
1797 extra_ic_state_, 1745 extra_ic_state_,
1798 cache_holder_, 1746 cache_holder_,
1799 in_loop_,
1800 argc); 1747 argc);
1801 return GetCodeWithFlags(flags, name); 1748 return GetCodeWithFlags(flags, name);
1802 } 1749 }
1803 1750
1804 1751
1805 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) { 1752 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) {
1806 String* function_name = NULL; 1753 String* function_name = NULL;
1807 if (function->shared()->name()->IsString()) { 1754 if (function->shared()->name()->IsString()) {
1808 function_name = String::cast(function->shared()->name()); 1755 function_name = String::cast(function->shared()->name());
1809 } 1756 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 expected_receiver_type_ = 1833 expected_receiver_type_ =
1887 FunctionTemplateInfo::cast(signature->receiver()); 1834 FunctionTemplateInfo::cast(signature->receiver());
1888 } 1835 }
1889 } 1836 }
1890 1837
1891 is_simple_api_call_ = true; 1838 is_simple_api_call_ = true;
1892 } 1839 }
1893 1840
1894 1841
1895 } } // namespace v8::internal 1842 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/stub-cache.h ('k') | src/type-info.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698