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 |