OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |