| 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/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
| (...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 Node* node = NewNode(op, graph()->start()); | 510 Node* node = NewNode(op, graph()->start()); |
| 511 function_closure_.set(node); | 511 function_closure_.set(node); |
| 512 } | 512 } |
| 513 return function_closure_.get(); | 513 return function_closure_.get(); |
| 514 } | 514 } |
| 515 | 515 |
| 516 | 516 |
| 517 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { | 517 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { |
| 518 const Operator* op = | 518 const Operator* op = |
| 519 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); | 519 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); |
| 520 Node* native_context = NewNode(op, environment()->Context()); | 520 Node* native_context = NewNode(op); |
| 521 return NewNode(javascript()->LoadContext(0, index, true), native_context); | 521 Node* result = NewNode(javascript()->LoadContext(0, index, true)); |
| 522 NodeProperties::ReplaceContextInput(result, native_context); |
| 523 return result; |
| 522 } | 524 } |
| 523 | 525 |
| 524 | 526 |
| 525 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { | 527 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
| 526 FeedbackVectorSlot slot; | 528 FeedbackVectorSlot slot; |
| 527 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { | 529 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { |
| 528 slot = feedback_vector()->ToSlot(slot_id); | 530 slot = feedback_vector()->ToSlot(slot_id); |
| 529 } | 531 } |
| 530 return VectorSlotPair(feedback_vector(), slot); | 532 return VectorSlotPair(feedback_vector(), slot); |
| 531 } | 533 } |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 environment()->RecordAfterState(node, Environment::kAttachFrameState); | 772 environment()->RecordAfterState(node, Environment::kAttachFrameState); |
| 771 } | 773 } |
| 772 | 774 |
| 773 void BytecodeGraphBuilder::VisitLdaContextSlot() { | 775 void BytecodeGraphBuilder::VisitLdaContextSlot() { |
| 774 // TODO(mythria): immutable flag is also set to false. This information is not | 776 // TODO(mythria): immutable flag is also set to false. This information is not |
| 775 // available in bytecode array. update this code when the implementation | 777 // available in bytecode array. update this code when the implementation |
| 776 // changes. | 778 // changes. |
| 777 const Operator* op = javascript()->LoadContext( | 779 const Operator* op = javascript()->LoadContext( |
| 778 bytecode_iterator().GetUnsignedImmediateOperand(2), | 780 bytecode_iterator().GetUnsignedImmediateOperand(2), |
| 779 bytecode_iterator().GetIndexOperand(1), false); | 781 bytecode_iterator().GetIndexOperand(1), false); |
| 782 Node* node = NewNode(op); |
| 780 Node* context = | 783 Node* context = |
| 781 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 784 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 782 Node* node = NewNode(op, context); | 785 NodeProperties::ReplaceContextInput(node, context); |
| 783 environment()->BindAccumulator(node); | 786 environment()->BindAccumulator(node); |
| 784 } | 787 } |
| 785 | 788 |
| 786 void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() { | 789 void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() { |
| 787 // TODO(mythria): immutable flag is also set to false. This information is not | 790 // TODO(mythria): immutable flag is also set to false. This information is not |
| 788 // available in bytecode array. update this code when the implementation | 791 // available in bytecode array. update this code when the implementation |
| 789 // changes. | 792 // changes. |
| 790 const Operator* op = javascript()->LoadContext( | 793 const Operator* op = javascript()->LoadContext( |
| 791 0, bytecode_iterator().GetIndexOperand(0), false); | 794 0, bytecode_iterator().GetIndexOperand(0), false); |
| 792 Node* context = environment()->Context(); | 795 Node* node = NewNode(op); |
| 793 Node* node = NewNode(op, context); | |
| 794 environment()->BindAccumulator(node); | 796 environment()->BindAccumulator(node); |
| 795 } | 797 } |
| 796 | 798 |
| 797 void BytecodeGraphBuilder::VisitStaContextSlot() { | 799 void BytecodeGraphBuilder::VisitStaContextSlot() { |
| 798 const Operator* op = javascript()->StoreContext( | 800 const Operator* op = javascript()->StoreContext( |
| 799 bytecode_iterator().GetUnsignedImmediateOperand(2), | 801 bytecode_iterator().GetUnsignedImmediateOperand(2), |
| 800 bytecode_iterator().GetIndexOperand(1)); | 802 bytecode_iterator().GetIndexOperand(1)); |
| 803 Node* value = environment()->LookupAccumulator(); |
| 804 Node* node = NewNode(op, value); |
| 801 Node* context = | 805 Node* context = |
| 802 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 806 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 803 Node* value = environment()->LookupAccumulator(); | 807 NodeProperties::ReplaceContextInput(node, context); |
| 804 NewNode(op, context, value); | |
| 805 } | 808 } |
| 806 | 809 |
| 807 void BytecodeGraphBuilder::VisitStaCurrentContextSlot() { | 810 void BytecodeGraphBuilder::VisitStaCurrentContextSlot() { |
| 808 const Operator* op = | 811 const Operator* op = |
| 809 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0)); | 812 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0)); |
| 810 Node* context = environment()->Context(); | |
| 811 Node* value = environment()->LookupAccumulator(); | 813 Node* value = environment()->LookupAccumulator(); |
| 812 NewNode(op, context, value); | 814 NewNode(op, value); |
| 813 } | 815 } |
| 814 | 816 |
| 815 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) { | 817 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) { |
| 816 PrepareEagerCheckpoint(); | 818 PrepareEagerCheckpoint(); |
| 817 Node* name = | 819 Node* name = |
| 818 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); | 820 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0)); |
| 819 const Operator* op = | 821 const Operator* op = |
| 820 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF | 822 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF |
| 821 ? Runtime::kLoadLookupSlot | 823 ? Runtime::kLoadLookupSlot |
| 822 : Runtime::kLoadLookupSlotInsideTypeof); | 824 : Runtime::kLoadLookupSlotInsideTypeof); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 834 | 836 |
| 835 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( | 837 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions( |
| 836 uint32_t depth) { | 838 uint32_t depth) { |
| 837 // Output environment where the context has an extension | 839 // Output environment where the context has an extension |
| 838 Environment* slow_environment = nullptr; | 840 Environment* slow_environment = nullptr; |
| 839 | 841 |
| 840 // We only need to check up to the last-but-one depth, because the an eval in | 842 // We only need to check up to the last-but-one depth, because the an eval in |
| 841 // the same scope as the variable itself has no way of shadowing it. | 843 // the same scope as the variable itself has no way of shadowing it. |
| 842 for (uint32_t d = 0; d < depth; d++) { | 844 for (uint32_t d = 0; d < depth; d++) { |
| 843 Node* extension_slot = | 845 Node* extension_slot = |
| 844 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false), | 846 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false)); |
| 845 environment()->Context()); | |
| 846 | 847 |
| 847 Node* check_no_extension = | 848 Node* check_no_extension = |
| 848 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 849 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
| 849 extension_slot, jsgraph()->TheHoleConstant()); | 850 extension_slot, jsgraph()->TheHoleConstant()); |
| 850 | 851 |
| 851 NewBranch(check_no_extension); | 852 NewBranch(check_no_extension); |
| 852 Environment* true_environment = environment()->CopyForConditional(); | 853 Environment* true_environment = environment()->CopyForConditional(); |
| 853 | 854 |
| 854 { | 855 { |
| 855 NewIfFalse(); | 856 NewIfFalse(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 881 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); | 882 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2); |
| 882 | 883 |
| 883 // Check if any context in the depth has an extension. | 884 // Check if any context in the depth has an extension. |
| 884 Environment* slow_environment = CheckContextExtensions(depth); | 885 Environment* slow_environment = CheckContextExtensions(depth); |
| 885 | 886 |
| 886 // Fast path, do a context load. | 887 // Fast path, do a context load. |
| 887 { | 888 { |
| 888 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); | 889 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1); |
| 889 | 890 |
| 890 const Operator* op = javascript()->LoadContext(depth, slot_index, false); | 891 const Operator* op = javascript()->LoadContext(depth, slot_index, false); |
| 891 Node* context = environment()->Context(); | 892 environment()->BindAccumulator(NewNode(op)); |
| 892 environment()->BindAccumulator(NewNode(op, context)); | |
| 893 } | 893 } |
| 894 | 894 |
| 895 // Only build the slow path if there were any slow-path checks. | 895 // Only build the slow path if there were any slow-path checks. |
| 896 if (slow_environment != nullptr) { | 896 if (slow_environment != nullptr) { |
| 897 // Add a merge to the fast environment. | 897 // Add a merge to the fast environment. |
| 898 NewMerge(); | 898 NewMerge(); |
| 899 Environment* fast_environment = environment(); | 899 Environment* fast_environment = environment(); |
| 900 | 900 |
| 901 // Slow path, do a runtime load lookup. | 901 // Slow path, do a runtime load lookup. |
| 902 set_environment(slow_environment); | 902 set_environment(slow_environment); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1063 BuildKeyedStore(LanguageMode::SLOPPY); | 1063 BuildKeyedStore(LanguageMode::SLOPPY); |
| 1064 } | 1064 } |
| 1065 | 1065 |
| 1066 void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() { | 1066 void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() { |
| 1067 BuildKeyedStore(LanguageMode::STRICT); | 1067 BuildKeyedStore(LanguageMode::STRICT); |
| 1068 } | 1068 } |
| 1069 | 1069 |
| 1070 void BytecodeGraphBuilder::VisitLdaModuleVariable() { | 1070 void BytecodeGraphBuilder::VisitLdaModuleVariable() { |
| 1071 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0); | 1071 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0); |
| 1072 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1); | 1072 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1); |
| 1073 Node* module = | 1073 Node* module = NewNode( |
| 1074 NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 1074 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false)); |
| 1075 environment()->Context()); | |
| 1076 Node* value = NewNode(javascript()->LoadModule(cell_index), module); | 1075 Node* value = NewNode(javascript()->LoadModule(cell_index), module); |
| 1077 environment()->BindAccumulator(value); | 1076 environment()->BindAccumulator(value); |
| 1078 } | 1077 } |
| 1079 | 1078 |
| 1080 void BytecodeGraphBuilder::VisitStaModuleVariable() { | 1079 void BytecodeGraphBuilder::VisitStaModuleVariable() { |
| 1081 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0); | 1080 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0); |
| 1082 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1); | 1081 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1); |
| 1083 Node* module = | 1082 Node* module = NewNode( |
| 1084 NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 1083 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false)); |
| 1085 environment()->Context()); | |
| 1086 Node* value = environment()->LookupAccumulator(); | 1084 Node* value = environment()->LookupAccumulator(); |
| 1087 NewNode(javascript()->StoreModule(cell_index), module, value); | 1085 NewNode(javascript()->StoreModule(cell_index), module, value); |
| 1088 } | 1086 } |
| 1089 | 1087 |
| 1090 void BytecodeGraphBuilder::VisitPushContext() { | 1088 void BytecodeGraphBuilder::VisitPushContext() { |
| 1091 Node* new_context = environment()->LookupAccumulator(); | 1089 Node* new_context = environment()->LookupAccumulator(); |
| 1092 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), | 1090 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), |
| 1093 environment()->Context()); | 1091 environment()->Context()); |
| 1094 environment()->SetContext(new_context); | 1092 environment()->SetContext(new_context); |
| 1095 } | 1093 } |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2192 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2190 it->source_position().ScriptOffset(), start_position_.InliningId())); |
| 2193 it->Advance(); | 2191 it->Advance(); |
| 2194 } else { | 2192 } else { |
| 2195 DCHECK_GT(it->code_offset(), offset); | 2193 DCHECK_GT(it->code_offset(), offset); |
| 2196 } | 2194 } |
| 2197 } | 2195 } |
| 2198 | 2196 |
| 2199 } // namespace compiler | 2197 } // namespace compiler |
| 2200 } // namespace internal | 2198 } // namespace internal |
| 2201 } // namespace v8 | 2199 } // namespace v8 |
| OLD | NEW |