Chromium Code Reviews| 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(int feedback_slot_operand, |
|
Michael Starzinger
2016/09/29 14:52:25
nit: Could we instead of passing the operand index
Leszek Swirski
2016/09/29 15:40:18
Done. I was on the fence about this too, thanks!
| |
| 790 VectorSlotPair feedback = | 790 TypeofMode typeof_mode) { |
| 791 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(0)); | 791 VectorSlotPair feedback = CreateVectorSlotPair( |
| 792 bytecode_iterator().GetIndexOperand(feedback_slot_operand)); | |
| 792 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, | 793 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC, |
| 793 feedback_vector()->GetKind(feedback.slot())); | 794 feedback_vector()->GetKind(feedback.slot())); |
| 794 Handle<Name> name(feedback_vector()->GetName(feedback.slot())); | 795 Handle<Name> name(feedback_vector()->GetName(feedback.slot())); |
| 795 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); | 796 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode); |
| 796 return NewNode(op, GetFunctionClosure()); | 797 return NewNode(op, GetFunctionClosure()); |
| 797 } | 798 } |
| 798 | 799 |
| 799 void BytecodeGraphBuilder::VisitLdaGlobal() { | 800 void BytecodeGraphBuilder::VisitLdaGlobal() { |
| 800 FrameStateBeforeAndAfter states(this); | 801 FrameStateBeforeAndAfter states(this); |
| 801 Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF); | 802 Node* node = BuildLoadGlobal(0, 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(0, TypeofMode::NOT_INSIDE_TYPEOF); |
| 808 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node, | 809 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node, |
| 809 &states); | 810 &states); |
| 810 } | 811 } |
| 811 | 812 |
| 812 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() { | 813 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() { |
| 813 FrameStateBeforeAndAfter states(this); | 814 FrameStateBeforeAndAfter states(this); |
| 814 Node* node = BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF); | 815 Node* node = BuildLoadGlobal(0, TypeofMode::INSIDE_TYPEOF); |
| 815 environment()->BindAccumulator(node, &states); | 816 environment()->BindAccumulator(node, &states); |
| 816 } | 817 } |
| 817 | 818 |
| 818 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) { | 819 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) { |
| 819 FrameStateBeforeAndAfter states(this); | 820 FrameStateBeforeAndAfter states(this); |
| 820 Handle<Name> name = | 821 Handle<Name> name = |
| 821 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0)); | 822 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0)); |
| 822 VectorSlotPair feedback = | 823 VectorSlotPair feedback = |
| 823 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1)); | 824 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1)); |
| 824 Node* value = environment()->LookupAccumulator(); | 825 Node* value = environment()->LookupAccumulator(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 881 } | 882 } |
| 882 | 883 |
| 883 void BytecodeGraphBuilder::VisitLdaLookupSlot() { | 884 void BytecodeGraphBuilder::VisitLdaLookupSlot() { |
| 884 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 885 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
| 885 } | 886 } |
| 886 | 887 |
| 887 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { | 888 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { |
| 888 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); | 889 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); |
| 889 } | 890 } |
| 890 | 891 |
| 891 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { | 892 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( |
| 892 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); | 893 uint32_t depth) { |
| 894 // Output environment where the context has an extension | |
| 895 Environment* slow_environment = nullptr; | |
| 893 | 896 |
| 894 // Check if any context in the depth has an extension. | 897 DCHECK_GT(depth, 0u); |
| 895 Environment* slow_environment = nullptr; | |
| 896 | 898 |
| 897 // We only need to check up to the last-but-one depth, because the an eval in | 899 // 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. | 900 // the same scope as the variable itself has no way of shadowing it. |
| 899 for (uint32_t d = 0; d < depth; d++) { | 901 for (uint32_t d = 0; d < depth; d++) { |
| 900 Node* extension_slot = | 902 Node* extension_slot = |
| 901 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), | 903 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), |
| 902 environment()->Context()); | 904 environment()->Context()); |
| 903 | 905 |
| 904 Node* check_no_extension = | 906 Node* check_no_extension = |
| 905 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 907 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 920 } | 922 } |
| 921 | 923 |
| 922 { | 924 { |
| 923 set_environment(true_environment); | 925 set_environment(true_environment); |
| 924 NewIfTrue(); | 926 NewIfTrue(); |
| 925 // Do nothing on if there is no extension, eventually falling through to | 927 // Do nothing on if there is no extension, eventually falling through to |
| 926 // the fast path. | 928 // the fast path. |
| 927 } | 929 } |
| 928 } | 930 } |
| 929 | 931 |
| 932 DCHECK(slow_environment != nullptr); | |
|
Michael Starzinger
2016/09/29 14:52:25
nit: DCHECK_NOT_NULL
Leszek Swirski
2016/09/29 15:40:18
Done.
| |
| 933 | |
| 934 return slow_environment; | |
| 935 } | |
| 936 | |
| 937 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { | |
| 938 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); | |
| 939 | |
| 940 // Check if any context in the depth has an extension. | |
| 941 Environment* slow_environment = CheckContextExtensions(depth); | |
| 942 | |
| 930 // Fast path, do a context load. | 943 // Fast path, do a context load. |
| 931 { | 944 { |
| 932 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); | 945 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); |
| 933 | 946 |
| 934 const Operator* op = javascript()->LoadContext(depth, slot_index, false); | 947 const Operator* op = javascript()->LoadContext(depth, slot_index, false); |
| 935 Node* context = environment()->Context(); | 948 Node* context = environment()->Context(); |
| 936 environment()->BindAccumulator(NewNode(op, context)); | 949 environment()->BindAccumulator(NewNode(op, context)); |
| 937 NewMerge(); | 950 NewMerge(); |
| 938 } | 951 } |
| 939 Environment* fast_environment = environment(); | 952 Environment* fast_environment = environment(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 960 | 973 |
| 961 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { | 974 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { |
| 962 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 975 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
| 963 } | 976 } |
| 964 | 977 |
| 965 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { | 978 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { |
| 966 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); | 979 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); |
| 967 } | 980 } |
| 968 | 981 |
| 969 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { | 982 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { |
| 970 // TODO(leszeks): Build the fast path here. | 983 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
| 984 | |
| 985 // Check if any context in the depth has an extension. | |
| 986 Environment* slow_environment = CheckContextExtensions(depth); | |
| 987 | |
| 988 // Fast path, do a global load. | |
| 989 { | |
| 990 FrameStateBeforeAndAfter states(this); | |
| 991 Node* node = BuildLoadGlobal(1, typeof_mode); | |
| 992 environment()->BindAccumulator(node, &states); | |
| 993 | |
| 994 NewMerge(); | |
| 995 } | |
| 996 Environment* fast_environment = environment(); | |
| 971 | 997 |
| 972 // Slow path, do a runtime load lookup. | 998 // Slow path, do a runtime load lookup. |
| 999 set_environment(slow_environment); | |
| 973 { | 1000 { |
| 974 FrameStateBeforeAndAfter states(this); | 1001 FrameStateBeforeAndAfter states(this); |
| 975 | 1002 |
| 976 Node* name = | 1003 Node* name = |
| 977 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); | 1004 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); |
| 978 | 1005 |
| 979 const Operator* op = | 1006 const Operator* op = |
| 980 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF | 1007 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF |
| 981 ? Runtime::kLoadLookupSlot | 1008 ? Runtime::kLoadLookupSlot |
| 982 : Runtime::kLoadLookupSlotInsideTypeof); | 1009 : Runtime::kLoadLookupSlotInsideTypeof); |
| 983 Node* value = NewNode(op, name); | 1010 Node* value = NewNode(op, name); |
| 984 environment()->BindAccumulator(value, &states); | 1011 environment()->BindAccumulator(value, &states); |
| 985 } | 1012 } |
| 1013 | |
| 1014 fast_environment->Merge(environment()); | |
| 1015 set_environment(fast_environment); | |
| 986 } | 1016 } |
| 987 | 1017 |
| 988 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { | 1018 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { |
| 989 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 1019 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
| 990 } | 1020 } |
| 991 | 1021 |
| 992 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() { | 1022 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() { |
| 993 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF); | 1023 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF); |
| 994 } | 1024 } |
| 995 | 1025 |
| (...skipping 1193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2189 // Phi does not exist yet, introduce one. | 2219 // Phi does not exist yet, introduce one. |
| 2190 value = NewPhi(inputs, value, control); | 2220 value = NewPhi(inputs, value, control); |
| 2191 value->ReplaceInput(inputs - 1, other); | 2221 value->ReplaceInput(inputs - 1, other); |
| 2192 } | 2222 } |
| 2193 return value; | 2223 return value; |
| 2194 } | 2224 } |
| 2195 | 2225 |
| 2196 } // namespace compiler | 2226 } // namespace compiler |
| 2197 } // namespace internal | 2227 } // namespace internal |
| 2198 } // namespace v8 | 2228 } // namespace v8 |
| OLD | NEW |