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/compiler/linkage.h" | 7 #include "src/compiler/linkage.h" |
8 #include "src/compiler/operator-properties.h" | 8 #include "src/compiler/operator-properties.h" |
9 #include "src/interpreter/bytecode-array-iterator.h" | 9 #include "src/interpreter/bytecode-array-iterator.h" |
10 | 10 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 if (!function_closure_.is_set()) { | 127 if (!function_closure_.is_set()) { |
128 int index = Linkage::kJSCallClosureParamIndex; | 128 int index = Linkage::kJSCallClosureParamIndex; |
129 const Operator* op = common()->Parameter(index, "%closure"); | 129 const Operator* op = common()->Parameter(index, "%closure"); |
130 Node* node = NewNode(op, graph()->start()); | 130 Node* node = NewNode(op, graph()->start()); |
131 function_closure_.set(node); | 131 function_closure_.set(node); |
132 } | 132 } |
133 return function_closure_.get(); | 133 return function_closure_.get(); |
134 } | 134 } |
135 | 135 |
136 | 136 |
| 137 Node* BytecodeGraphBuilder::BuildLoadObjectField(Node* object, int offset) { |
| 138 return NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
| 139 jsgraph()->IntPtrConstant(offset - kHeapObjectTag)); |
| 140 } |
| 141 |
| 142 |
137 Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object, | 143 Node* BytecodeGraphBuilder::BuildLoadImmutableObjectField(Node* object, |
138 int offset) { | 144 int offset) { |
139 return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, | 145 return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object, |
140 jsgraph()->IntPtrConstant(offset - kHeapObjectTag), | 146 jsgraph()->IntPtrConstant(offset - kHeapObjectTag), |
141 graph()->start(), graph()->start()); | 147 graph()->start(), graph()->start()); |
142 } | 148 } |
143 | 149 |
144 | 150 |
| 151 Node* BytecodeGraphBuilder::BuildLoadGlobalObject() { |
| 152 const Operator* load_op = |
| 153 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); |
| 154 return NewNode(load_op, GetFunctionContext()); |
| 155 } |
| 156 |
| 157 |
| 158 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { |
| 159 Node* global = BuildLoadGlobalObject(); |
| 160 Node* native_context = |
| 161 BuildLoadObjectField(global, JSGlobalObject::kNativeContextOffset); |
| 162 return NewNode(javascript()->LoadContext(0, index, true), native_context); |
| 163 } |
| 164 |
| 165 |
145 Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() { | 166 Node* BytecodeGraphBuilder::BuildLoadFeedbackVector() { |
146 if (!feedback_vector_.is_set()) { | 167 if (!feedback_vector_.is_set()) { |
147 Node* closure = GetFunctionClosure(); | 168 Node* closure = GetFunctionClosure(); |
148 Node* shared = BuildLoadImmutableObjectField( | 169 Node* shared = BuildLoadImmutableObjectField( |
149 closure, JSFunction::kSharedFunctionInfoOffset); | 170 closure, JSFunction::kSharedFunctionInfoOffset); |
150 Node* vector = BuildLoadImmutableObjectField( | 171 Node* vector = BuildLoadImmutableObjectField( |
151 shared, SharedFunctionInfo::kFeedbackVectorOffset); | 172 shared, SharedFunctionInfo::kFeedbackVectorOffset); |
152 feedback_vector_.set(vector); | 173 feedback_vector_.set(vector); |
153 } | 174 } |
154 return feedback_vector_.get(); | 175 return feedback_vector_.get(); |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 } | 664 } |
644 | 665 |
645 | 666 |
646 void BytecodeGraphBuilder::VisitCreateObjectLiteral( | 667 void BytecodeGraphBuilder::VisitCreateObjectLiteral( |
647 const interpreter::BytecodeArrayIterator& iterator) { | 668 const interpreter::BytecodeArrayIterator& iterator) { |
648 UNIMPLEMENTED(); | 669 UNIMPLEMENTED(); |
649 } | 670 } |
650 | 671 |
651 | 672 |
652 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 673 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
653 interpreter::Register callee, | 674 Node* callee, |
654 interpreter::Register receiver, | 675 interpreter::Register receiver, |
655 size_t arity) { | 676 size_t arity) { |
656 Node** all = info()->zone()->NewArray<Node*>(arity); | 677 Node** all = info()->zone()->NewArray<Node*>(static_cast<int>(arity)); |
657 all[0] = environment()->LookupRegister(callee); | 678 all[0] = callee; |
658 all[1] = environment()->LookupRegister(receiver); | 679 all[1] = environment()->LookupRegister(receiver); |
659 int receiver_index = receiver.index(); | 680 int receiver_index = receiver.index(); |
660 for (int i = 2; i < static_cast<int>(arity); ++i) { | 681 for (int i = 2; i < static_cast<int>(arity); ++i) { |
661 all[i] = environment()->LookupRegister( | 682 all[i] = environment()->LookupRegister( |
662 interpreter::Register(receiver_index + i - 1)); | 683 interpreter::Register(receiver_index + i - 1)); |
663 } | 684 } |
664 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 685 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); |
665 return value; | 686 return value; |
666 } | 687 } |
667 | 688 |
668 | 689 |
669 void BytecodeGraphBuilder::BuildCall( | 690 void BytecodeGraphBuilder::BuildCall( |
670 const interpreter::BytecodeArrayIterator& iterator) { | 691 const interpreter::BytecodeArrayIterator& iterator) { |
671 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver | 692 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver |
672 // register has been loaded with null / undefined explicitly or we are sure it | 693 // register has been loaded with null / undefined explicitly or we are sure it |
673 // is not null / undefined. | 694 // is not null / undefined. |
674 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 695 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
675 interpreter::Register callee = iterator.GetRegisterOperand(0); | 696 Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
676 interpreter::Register receiver = iterator.GetRegisterOperand(1); | 697 interpreter::Register receiver = iterator.GetRegisterOperand(1); |
677 size_t arg_count = iterator.GetCountOperand(2); | 698 size_t arg_count = iterator.GetCountOperand(2); |
678 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3)); | 699 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3)); |
679 | 700 |
680 const Operator* call = javascript()->CallFunction( | 701 const Operator* call = javascript()->CallFunction( |
681 arg_count + 2, language_mode(), feedback, receiver_hint); | 702 arg_count + 2, language_mode(), feedback, receiver_hint); |
682 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); | 703 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); |
683 AddEmptyFrameStateInputs(value); | 704 AddEmptyFrameStateInputs(value); |
684 environment()->BindAccumulator(value); | 705 environment()->BindAccumulator(value); |
685 } | 706 } |
686 | 707 |
687 | 708 |
688 void BytecodeGraphBuilder::VisitCall( | 709 void BytecodeGraphBuilder::VisitCall( |
689 const interpreter::BytecodeArrayIterator& iterator) { | 710 const interpreter::BytecodeArrayIterator& iterator) { |
690 BuildCall(iterator); | 711 BuildCall(iterator); |
691 } | 712 } |
692 | 713 |
693 | 714 |
694 void BytecodeGraphBuilder::VisitCallWide( | 715 void BytecodeGraphBuilder::VisitCallWide( |
695 const interpreter::BytecodeArrayIterator& iterator) { | 716 const interpreter::BytecodeArrayIterator& iterator) { |
696 BuildCall(iterator); | 717 BuildCall(iterator); |
697 } | 718 } |
698 | 719 |
699 | 720 |
| 721 void BytecodeGraphBuilder::VisitCallJSRuntime( |
| 722 const interpreter::BytecodeArrayIterator& iterator) { |
| 723 Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0)); |
| 724 interpreter::Register receiver = iterator.GetRegisterOperand(1); |
| 725 size_t arg_count = iterator.GetCountOperand(2); |
| 726 |
| 727 // Create node to perform the JS runtime call. |
| 728 const Operator* call = |
| 729 javascript()->CallFunction(arg_count + 2, language_mode()); |
| 730 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 2); |
| 731 AddEmptyFrameStateInputs(value); |
| 732 environment()->BindAccumulator(value); |
| 733 } |
| 734 |
| 735 |
| 736 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( |
| 737 const Operator* call_runtime_op, interpreter::Register first_arg, |
| 738 size_t arity) { |
| 739 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 740 int first_arg_index = first_arg.index(); |
| 741 for (int i = 0; i < static_cast<int>(arity); ++i) { |
| 742 all[i] = environment()->LookupRegister( |
| 743 interpreter::Register(first_arg_index + i)); |
| 744 } |
| 745 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false); |
| 746 return value; |
| 747 } |
| 748 |
| 749 |
700 void BytecodeGraphBuilder::VisitCallRuntime( | 750 void BytecodeGraphBuilder::VisitCallRuntime( |
701 const interpreter::BytecodeArrayIterator& iterator) { | 751 const interpreter::BytecodeArrayIterator& iterator) { |
702 UNIMPLEMENTED(); | 752 Runtime::FunctionId functionId = |
| 753 static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0)); |
| 754 interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
| 755 size_t arg_count = iterator.GetCountOperand(2); |
| 756 |
| 757 // Create node to perform the runtime call. |
| 758 const Operator* call = javascript()->CallRuntime(functionId, arg_count); |
| 759 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); |
| 760 AddEmptyFrameStateInputs(value); |
| 761 environment()->BindAccumulator(value); |
703 } | 762 } |
704 | 763 |
705 | 764 |
706 void BytecodeGraphBuilder::VisitCallJSRuntime( | 765 Node* BytecodeGraphBuilder::ProcessCallNewArguments( |
707 const interpreter::BytecodeArrayIterator& iterator) { | 766 const Operator* call_new_op, interpreter::Register callee, |
708 UNIMPLEMENTED(); | 767 interpreter::Register first_arg, size_t arity) { |
| 768 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 769 all[0] = environment()->LookupRegister(callee); |
| 770 int first_arg_index = first_arg.index(); |
| 771 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) { |
| 772 all[i] = environment()->LookupRegister( |
| 773 interpreter::Register(first_arg_index + i - 1)); |
| 774 } |
| 775 // Original constructor is the same as the callee. |
| 776 all[arity - 1] = environment()->LookupRegister(callee); |
| 777 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false); |
| 778 return value; |
709 } | 779 } |
710 | 780 |
711 | 781 |
712 void BytecodeGraphBuilder::VisitNew( | 782 void BytecodeGraphBuilder::VisitNew( |
713 const interpreter::BytecodeArrayIterator& iterator) { | 783 const interpreter::BytecodeArrayIterator& iterator) { |
714 UNIMPLEMENTED(); | 784 interpreter::Register callee = iterator.GetRegisterOperand(0); |
| 785 interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
| 786 size_t arg_count = iterator.GetCountOperand(2); |
| 787 |
| 788 const Operator* call = |
| 789 javascript()->CallConstruct(static_cast<int>(arg_count) + 2); |
| 790 Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2); |
| 791 AddEmptyFrameStateInputs(value); |
| 792 environment()->BindAccumulator(value); |
715 } | 793 } |
716 | 794 |
717 | 795 |
718 void BytecodeGraphBuilder::VisitThrow( | 796 void BytecodeGraphBuilder::VisitThrow( |
719 const interpreter::BytecodeArrayIterator& iterator) { | 797 const interpreter::BytecodeArrayIterator& iterator) { |
720 UNIMPLEMENTED(); | 798 UNIMPLEMENTED(); |
721 } | 799 } |
722 | 800 |
723 | 801 |
724 void BytecodeGraphBuilder::BuildBinaryOp( | 802 void BytecodeGraphBuilder::BuildBinaryOp( |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1142 | 1220 |
1143 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { | 1221 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { |
1144 if (environment()->IsMarkedAsUnreachable()) return; | 1222 if (environment()->IsMarkedAsUnreachable()) return; |
1145 environment()->MarkAsUnreachable(); | 1223 environment()->MarkAsUnreachable(); |
1146 exit_controls_.push_back(exit); | 1224 exit_controls_.push_back(exit); |
1147 } | 1225 } |
1148 | 1226 |
1149 } // namespace compiler | 1227 } // namespace compiler |
1150 } // namespace internal | 1228 } // namespace internal |
1151 } // namespace v8 | 1229 } // namespace v8 |
OLD | NEW |