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 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
889 | 889 |
890 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { | 890 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() { |
891 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); | 891 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF); |
892 } | 892 } |
893 | 893 |
894 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( | 894 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( |
895 uint32_t depth) { | 895 uint32_t depth) { |
896 // Output environment where the context has an extension | 896 // Output environment where the context has an extension |
897 Environment* slow_environment = nullptr; | 897 Environment* slow_environment = nullptr; |
898 | 898 |
899 DCHECK_GT(depth, 0u); | |
900 | |
901 // 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 |
902 // 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. |
903 for (uint32_t d = 0; d < depth; d++) { | 901 for (uint32_t d = 0; d < depth; d++) { |
904 Node* extension_slot = | 902 Node* extension_slot = |
905 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), | 903 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), |
906 environment()->Context()); | 904 environment()->Context()); |
907 | 905 |
908 Node* check_no_extension = | 906 Node* check_no_extension = |
909 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 907 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
910 extension_slot, jsgraph()->TheHoleConstant()); | 908 extension_slot, jsgraph()->TheHoleConstant()); |
(...skipping 13 matching lines...) Expand all Loading... | |
924 } | 922 } |
925 | 923 |
926 { | 924 { |
927 set_environment(true_environment); | 925 set_environment(true_environment); |
928 NewIfTrue(); | 926 NewIfTrue(); |
929 // 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 |
930 // the fast path. | 928 // the fast path. |
931 } | 929 } |
932 } | 930 } |
933 | 931 |
934 DCHECK_NOT_NULL(slow_environment); | 932 // The depth can be zero, in which case no slow-path checks are built, and the |
933 // slow path environment can be null. | |
934 DCHECK(depth == 0 || slow_environment != nullptr); | |
935 | 935 |
936 return slow_environment; | 936 return slow_environment; |
937 } | 937 } |
938 | 938 |
939 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { | 939 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) { |
940 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); | 940 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
941 | 941 |
942 // Check if any context in the depth has an extension. | 942 // Check if any context in the depth has an extension. |
943 Environment* slow_environment = CheckContextExtensions(depth); | 943 Environment* slow_environment = CheckContextExtensions(depth); |
944 | 944 |
945 // Fast path, do a context load. | 945 // Fast path, do a context load. |
946 { | 946 { |
947 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); | 947 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); |
948 | 948 |
949 const Operator* op = javascript()->LoadContext(depth, slot_index, false); | 949 const Operator* op = javascript()->LoadContext(depth, slot_index, false); |
950 Node* context = environment()->Context(); | 950 Node* context = environment()->Context(); |
951 environment()->BindAccumulator(NewNode(op, context)); | 951 environment()->BindAccumulator(NewNode(op, context)); |
952 NewMerge(); | 952 NewMerge(); |
Michael Starzinger
2016/10/04 09:43:10
nit: Shouldn't we only create the singleton merge
Leszek Swirski
2016/10/04 10:46:55
Done.
| |
953 } | 953 } |
954 Environment* fast_environment = environment(); | |
955 | 954 |
956 // Slow path, do a runtime load lookup. | 955 // Only build the slow path if there were any slow-path checks. |
957 set_environment(slow_environment); | 956 if (slow_environment != nullptr) { |
958 { | 957 Environment* fast_environment = environment(); |
959 FrameStateBeforeAndAfter states(this); | |
960 | 958 |
961 Node* name = | 959 // Slow path, do a runtime load lookup. |
962 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); | 960 set_environment(slow_environment); |
961 { | |
962 FrameStateBeforeAndAfter states(this); | |
963 | 963 |
964 const Operator* op = | 964 Node* name = jsgraph()->Constant( |
965 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF | 965 bytecode_iterator().GetConstantForIndexOperand(0)); |
966 ? Runtime::kLoadLookupSlot | 966 |
967 : Runtime::kLoadLookupSlotInsideTypeof); | 967 const Operator* op = |
968 Node* value = NewNode(op, name); | 968 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF |
969 environment()->BindAccumulator(value, &states); | 969 ? Runtime::kLoadLookupSlot |
970 : Runtime::kLoadLookupSlotInsideTypeof); | |
971 Node* value = NewNode(op, name); | |
972 environment()->BindAccumulator(value, &states); | |
973 } | |
974 | |
975 fast_environment->Merge(environment()); | |
976 set_environment(fast_environment); | |
970 } | 977 } |
971 | |
972 fast_environment->Merge(environment()); | |
973 set_environment(fast_environment); | |
974 } | 978 } |
975 | 979 |
976 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { | 980 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() { |
977 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 981 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
978 } | 982 } |
979 | 983 |
980 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { | 984 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() { |
981 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); | 985 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF); |
982 } | 986 } |
983 | 987 |
984 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { | 988 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) { |
985 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); | 989 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
986 | 990 |
987 // Check if any context in the depth has an extension. | 991 // Check if any context in the depth has an extension. |
988 Environment* slow_environment = CheckContextExtensions(depth); | 992 Environment* slow_environment = CheckContextExtensions(depth); |
989 | 993 |
990 // Fast path, do a global load. | 994 // Fast path, do a global load. |
991 { | 995 { |
992 FrameStateBeforeAndAfter states(this); | 996 FrameStateBeforeAndAfter states(this); |
993 Node* node = | 997 Node* node = |
994 BuildLoadGlobal(bytecode_iterator().GetIndexOperand(1), typeof_mode); | 998 BuildLoadGlobal(bytecode_iterator().GetIndexOperand(1), typeof_mode); |
995 environment()->BindAccumulator(node, &states); | 999 environment()->BindAccumulator(node, &states); |
996 | 1000 |
997 NewMerge(); | 1001 NewMerge(); |
Michael Starzinger
2016/10/04 09:43:10
nit: Likewise.
Leszek Swirski
2016/10/04 10:46:55
Done.
| |
998 } | 1002 } |
999 Environment* fast_environment = environment(); | |
1000 | 1003 |
1001 // Slow path, do a runtime load lookup. | 1004 // Only build the slow path if there were any slow-path checks. |
1002 set_environment(slow_environment); | 1005 if (slow_environment != nullptr) { |
1003 { | 1006 Environment* fast_environment = environment(); |
1004 FrameStateBeforeAndAfter states(this); | |
1005 | 1007 |
1006 Node* name = | 1008 // Slow path, do a runtime load lookup. |
1007 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); | 1009 set_environment(slow_environment); |
1010 { | |
1011 FrameStateBeforeAndAfter states(this); | |
1008 | 1012 |
1009 const Operator* op = | 1013 Node* name = jsgraph()->Constant( |
1010 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF | 1014 bytecode_iterator().GetConstantForIndexOperand(0)); |
1011 ? Runtime::kLoadLookupSlot | 1015 |
1012 : Runtime::kLoadLookupSlotInsideTypeof); | 1016 const Operator* op = |
1013 Node* value = NewNode(op, name); | 1017 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF |
1014 environment()->BindAccumulator(value, &states); | 1018 ? Runtime::kLoadLookupSlot |
1019 : Runtime::kLoadLookupSlotInsideTypeof); | |
1020 Node* value = NewNode(op, name); | |
1021 environment()->BindAccumulator(value, &states); | |
1022 } | |
1023 | |
1024 fast_environment->Merge(environment()); | |
1025 set_environment(fast_environment); | |
1015 } | 1026 } |
1016 | |
1017 fast_environment->Merge(environment()); | |
1018 set_environment(fast_environment); | |
1019 } | 1027 } |
1020 | 1028 |
1021 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { | 1029 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() { |
1022 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF); | 1030 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF); |
1023 } | 1031 } |
1024 | 1032 |
1025 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() { | 1033 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() { |
1026 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF); | 1034 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF); |
1027 } | 1035 } |
1028 | 1036 |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2225 // Phi does not exist yet, introduce one. | 2233 // Phi does not exist yet, introduce one. |
2226 value = NewPhi(inputs, value, control); | 2234 value = NewPhi(inputs, value, control); |
2227 value->ReplaceInput(inputs - 1, other); | 2235 value->ReplaceInput(inputs - 1, other); |
2228 } | 2236 } |
2229 return value; | 2237 return value; |
2230 } | 2238 } |
2231 | 2239 |
2232 } // namespace compiler | 2240 } // namespace compiler |
2233 } // namespace internal | 2241 } // namespace internal |
2234 } // namespace v8 | 2242 } // namespace v8 |
OLD | NEW |