OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/bytecode-graph-builder.h" | 5 #include "src/compiler/bytecode-graph-builder.h" |
6 | 6 |
7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/bytecode-branch-analysis.h" | 10 #include "src/compiler/bytecode-branch-analysis.h" |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
779 Node* value = environment()->LookupAccumulator(); | 779 Node* value = environment()->LookupAccumulator(); |
780 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value); | 780 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value); |
781 } | 781 } |
782 | 782 |
783 void BytecodeGraphBuilder::VisitMov() { | 783 void BytecodeGraphBuilder::VisitMov() { |
784 Node* value = | 784 Node* value = |
785 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 785 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
786 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value); | 786 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value); |
787 } | 787 } |
788 | 788 |
789 Node* BytecodeGraphBuilder::BuildLoadGlobal(TypeofMode typeof_mode) { | 789 Node* BytecodeGraphBuilder::BuildLoadGlobal(uint32_t feedback_slot_index, |
790 VectorSlotPair feedback = | 790 TypeofMode typeof_mode) { |
791 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(0)); | 791 VectorSlotPair feedback = CreateVectorSlotPair(feedback_slot_index); |
792 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, | 792 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, |
793 feedback_vector()->GetKind(feedback.slot())); | 793 feedback_vector()->GetKind(feedback.slot())); |
794 Handle<Name> name(feedback_vector()->GetName(feedback.slot())); | 794 Handle<Name> name(feedback_vector()->GetName(feedback.slot())); |
795 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); | 795 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); |
796 return NewNode(op, GetFunctionClosure()); | 796 return NewNode(op, GetFunctionClosure()); |
797 } | 797 } |
798 | 798 |
799 void BytecodeGraphBuilder::VisitLdaGlobal() { | 799 void BytecodeGraphBuilder::VisitLdaGlobal() { |
800 FrameStateBeforeAndAfter states(this); | 800 FrameStateBeforeAndAfter states(this); |
801 Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF); | 801 Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0), |
| 802 TypeofMode::NOT_INSIDE_TYPEOF); |
802 environment()->BindAccumulator(node, &states); | 803 environment()->BindAccumulator(node, &states); |
803 } | 804 } |
804 | 805 |
805 void BytecodeGraphBuilder::VisitLdrGlobal() { | 806 void BytecodeGraphBuilder::VisitLdrGlobal() { |
806 FrameStateBeforeAndAfter states(this); | 807 FrameStateBeforeAndAfter states(this); |
807 Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF); | 808 Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0), |
| 809 TypeofMode::NOT_INSIDE_TYPEOF); |
808 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node, | 810 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node, |
809 &states); | 811 &states); |
810 } | 812 } |
811 | 813 |
812 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() { | 814 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() { |
813 FrameStateBeforeAndAfter states(this); | 815 FrameStateBeforeAndAfter states(this); |
814 Node* node = BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF); | 816 Node* node = BuildLoadGlobal(bytecode_iterator().GetIndexOperand(0), |
| 817 TypeofMode::INSIDE_TYPEOF); |
815 environment()->BindAccumulator(node, &states); | 818 environment()->BindAccumulator(node, &states); |
816 } | 819 } |
817 | 820 |
818 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) { | 821 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) { |
819 FrameStateBeforeAndAfter states(this); | 822 FrameStateBeforeAndAfter states(this); |
820 Handle<Name> name = | 823 Handle<Name> name = |
821 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0)); | 824 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0)); |
822 VectorSlotPair feedback = | 825 VectorSlotPair feedback = |
823 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1)); | 826 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1)); |
824 Node* value = environment()->LookupAccumulator(); | 827 Node* value = environment()->LookupAccumulator(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 } | 884 } |
882 | 885 |
883 void BytecodeGraphBuilder::VisitLdaLookupSlot() { | 886 void BytecodeGraphBuilder::VisitLdaLookupSlot() { |
884 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 887 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
885 } | 888 } |
886 | 889 |
887 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { | 890 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { |
888 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); | 891 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); |
889 } | 892 } |
890 | 893 |
891 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { | 894 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( |
892 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); | 895 uint32_t depth) { |
| 896 // Output environment where the context has an extension |
| 897 Environment* slow_environment = nullptr; |
893 | 898 |
894 // Check if any context in the depth has an extension. | 899 DCHECK_GT(depth, 0u); |
895 Environment* slow_environment = nullptr; | |
896 | 900 |
897 // We only need to check up to the last-but-one depth, because the an eval in | 901 // We only need to check up to the last-but-one depth, because the an eval in |
898 // the same scope as the variable itself has no way of shadowing it. | 902 // the same scope as the variable itself has no way of shadowing it. |
899 for (uint32_t d = 0; d < depth; d++) { | 903 for (uint32_t d = 0; d < depth; d++) { |
900 Node* extension_slot = | 904 Node* extension_slot = |
901 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), | 905 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), |
902 environment()->Context()); | 906 environment()->Context()); |
903 | 907 |
904 Node* check_no_extension = | 908 Node* check_no_extension = |
905 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 909 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
(...skipping 14 matching lines...) Expand all Loading... |
920 } | 924 } |
921 | 925 |
922 { | 926 { |
923 set_environment(true_environment); | 927 set_environment(true_environment); |
924 NewIfTrue(); | 928 NewIfTrue(); |
925 // Do nothing on if there is no extension, eventually falling through to | 929 // Do nothing on if there is no extension, eventually falling through to |
926 // the fast path. | 930 // the fast path. |
927 } | 931 } |
928 } | 932 } |
929 | 933 |
| 934 DCHECK_NOT_NULL(slow_environment); |
| 935 |
| 936 return slow_environment; |
| 937 } |
| 938 |
| 939 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { |
| 940 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
| 941 |
| 942 // Check if any context in the depth has an extension. |
| 943 Environment* slow_environment = CheckContextExtensions(depth); |
| 944 |
930 // Fast path, do a context load. | 945 // Fast path, do a context load. |
931 { | 946 { |
932 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); | 947 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); |
933 | 948 |
934 const Operator* op = javascript()->LoadContext(depth, slot_index, false); | 949 const Operator* op = javascript()->LoadContext(depth, slot_index, false); |
935 Node* context = environment()->Context(); | 950 Node* context = environment()->Context(); |
936 environment()->BindAccumulator(NewNode(op, context)); | 951 environment()->BindAccumulator(NewNode(op, context)); |
937 NewMerge(); | 952 NewMerge(); |
938 } | 953 } |
939 Environment* fast_environment = environment(); | 954 Environment* fast_environment = environment(); |
(...skipping 20 matching lines...) Expand all Loading... |
960 | 975 |
961 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { | 976 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { |
962 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 977 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
963 } | 978 } |
964 | 979 |
965 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { | 980 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { |
966 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); | 981 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); |
967 } | 982 } |
968 | 983 |
969 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { | 984 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { |
970 // TODO(leszeks): Build the fast path here. | 985 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
| 986 |
| 987 // Check if any context in the depth has an extension. |
| 988 Environment* slow_environment = CheckContextExtensions(depth); |
| 989 |
| 990 // Fast path, do a global load. |
| 991 { |
| 992 FrameStateBeforeAndAfter states(this); |
| 993 Node* node = |
| 994 BuildLoadGlobal(bytecode_iterator().GetIndexOperand(1), typeof_mode); |
| 995 environment()->BindAccumulator(node, &states); |
| 996 |
| 997 NewMerge(); |
| 998 } |
| 999 Environment* fast_environment = environment(); |
971 | 1000 |
972 // Slow path, do a runtime load lookup. | 1001 // Slow path, do a runtime load lookup. |
| 1002 set_environment(slow_environment); |
973 { | 1003 { |
974 FrameStateBeforeAndAfter states(this); | 1004 FrameStateBeforeAndAfter states(this); |
975 | 1005 |
976 Node* name = | 1006 Node* name = |
977 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); | 1007 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); |
978 | 1008 |
979 const Operator* op = | 1009 const Operator* op = |
980 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF | 1010 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF |
981 ? Runtime::kLoadLookupSlot | 1011 ? Runtime::kLoadLookupSlot |
982 : Runtime::kLoadLookupSlotInsideTypeof); | 1012 : Runtime::kLoadLookupSlotInsideTypeof); |
983 Node* value = NewNode(op, name); | 1013 Node* value = NewNode(op, name); |
984 environment()->BindAccumulator(value, &states); | 1014 environment()->BindAccumulator(value, &states); |
985 } | 1015 } |
| 1016 |
| 1017 fast_environment->Merge(environment()); |
| 1018 set_environment(fast_environment); |
986 } | 1019 } |
987 | 1020 |
988 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { | 1021 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { |
989 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 1022 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
990 } | 1023 } |
991 | 1024 |
992 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() { | 1025 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() { |
993 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF); | 1026 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF); |
994 } | 1027 } |
995 | 1028 |
(...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2189 // Phi does not exist yet, introduce one. | 2222 // Phi does not exist yet, introduce one. |
2190 value = NewPhi(inputs, value, control); | 2223 value = NewPhi(inputs, value, control); |
2191 value->ReplaceInput(inputs - 1, other); | 2224 value->ReplaceInput(inputs - 1, other); |
2192 } | 2225 } |
2193 return value; | 2226 return value; |
2194 } | 2227 } |
2195 | 2228 |
2196 } // namespace compiler | 2229 } // namespace compiler |
2197 } // namespace internal | 2230 } // namespace internal |
2198 } // namespace v8 | 2231 } // namespace v8 |
OLD | NEW |