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 871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
882 | 882 |
883 void BytecodeGraphBuilder::VisitLdaLookupSlot() { | 883 void BytecodeGraphBuilder::VisitLdaLookupSlot() { |
884 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 884 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
885 } | 885 } |
886 | 886 |
887 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { | 887 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { |
888 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); | 888 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); |
889 } | 889 } |
890 | 890 |
891 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { | 891 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { |
892 // TODO(leszeks): Build the fast path here. | 892 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
| 893 |
| 894 // Check if any context in the depth has an extension. |
| 895 Environment* slow_environment = nullptr; |
| 896 |
| 897 // 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. |
| 899 for (uint32_t d = 0; d < depth; d++) { |
| 900 Node* extension_slot = |
| 901 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), |
| 902 environment()->Context()); |
| 903 |
| 904 Node* check_no_extension = |
| 905 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
| 906 extension_slot, jsgraph()->TheHoleConstant()); |
| 907 |
| 908 NewBranch(check_no_extension); |
| 909 Environment* false_environment = environment(); |
| 910 Environment* true_environment = environment()->CopyForConditional(); |
| 911 |
| 912 { |
| 913 set_environment(false_environment); |
| 914 NewIfFalse(); |
| 915 // If there is an extension, merge into the slow path. |
| 916 if (slow_environment == nullptr) { |
| 917 slow_environment = false_environment; |
| 918 NewMerge(); |
| 919 } else { |
| 920 slow_environment->Merge(false_environment); |
| 921 } |
| 922 } |
| 923 |
| 924 { |
| 925 set_environment(true_environment); |
| 926 NewIfTrue(); |
| 927 // Do nothing on if there is no extension, eventually falling through to |
| 928 // the fast path. |
| 929 } |
| 930 } |
| 931 |
| 932 // Fast path, do a context load. |
| 933 { |
| 934 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); |
| 935 |
| 936 const Operator* op = javascript()->LoadContext(depth, slot_index, false); |
| 937 Node* context = environment()->Context(); |
| 938 environment()->BindAccumulator(NewNode(op, context)); |
| 939 NewMerge(); |
| 940 } |
| 941 Environment* fast_environment = environment(); |
893 | 942 |
894 // Slow path, do a runtime load lookup. | 943 // Slow path, do a runtime load lookup. |
| 944 set_environment(slow_environment); |
895 { | 945 { |
896 FrameStateBeforeAndAfter states(this); | 946 FrameStateBeforeAndAfter states(this); |
897 | 947 |
898 Node* name = | 948 Node* name = |
899 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); | 949 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); |
900 | 950 |
901 const Operator* op = | 951 const Operator* op = |
902 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF | 952 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF |
903 ? Runtime::kLoadLookupSlot | 953 ? Runtime::kLoadLookupSlot |
904 : Runtime::kLoadLookupSlotInsideTypeof); | 954 : Runtime::kLoadLookupSlotInsideTypeof); |
905 Node* value = NewNode(op, name); | 955 Node* value = NewNode(op, name); |
906 environment()->BindAccumulator(value, &states); | 956 environment()->BindAccumulator(value, &states); |
907 } | 957 } |
| 958 |
| 959 fast_environment->Merge(slow_environment); |
| 960 set_environment(fast_environment); |
908 } | 961 } |
909 | 962 |
910 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { | 963 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { |
911 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 964 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
912 } | 965 } |
913 | 966 |
914 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { | 967 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { |
915 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); | 968 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); |
916 } | 969 } |
917 | 970 |
(...skipping 1220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2138 // Phi does not exist yet, introduce one. | 2191 // Phi does not exist yet, introduce one. |
2139 value = NewPhi(inputs, value, control); | 2192 value = NewPhi(inputs, value, control); |
2140 value->ReplaceInput(inputs - 1, other); | 2193 value->ReplaceInput(inputs - 1, other); |
2141 } | 2194 } |
2142 return value; | 2195 return value; |
2143 } | 2196 } |
2144 | 2197 |
2145 } // namespace compiler | 2198 } // namespace compiler |
2146 } // namespace internal | 2199 } // namespace internal |
2147 } // namespace v8 | 2200 } // namespace v8 |
OLD | NEW |