| 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 |