| 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 |