| 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 const Operator* op = common()->Parameter( | 128 const Operator* op = common()->Parameter( |
| 129 Linkage::kJSFunctionCallClosureParamIndex, "%closure"); | 129 Linkage::kJSFunctionCallClosureParamIndex, "%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 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 } | 609 } |
| 589 | 610 |
| 590 | 611 |
| 591 void BytecodeGraphBuilder::VisitCreateObjectLiteral( | 612 void BytecodeGraphBuilder::VisitCreateObjectLiteral( |
| 592 const interpreter::BytecodeArrayIterator& iterator) { | 613 const interpreter::BytecodeArrayIterator& iterator) { |
| 593 UNIMPLEMENTED(); | 614 UNIMPLEMENTED(); |
| 594 } | 615 } |
| 595 | 616 |
| 596 | 617 |
| 597 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, | 618 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, |
| 598 interpreter::Register callee, | 619 Node* callee, |
| 599 interpreter::Register receiver, | 620 interpreter::Register receiver, |
| 600 size_t arity) { | 621 size_t arity) { |
| 601 Node** all = info()->zone()->NewArray<Node*>(arity); | 622 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 602 all[0] = environment()->LookupRegister(callee); | 623 all[0] = callee; |
| 603 all[1] = environment()->LookupRegister(receiver); | 624 all[1] = environment()->LookupRegister(receiver); |
| 604 int reciever_index = receiver.index(); | 625 int reciever_index = receiver.index(); |
| 605 for (int i = 2; i < arity; ++i) { | 626 for (int i = 2; i < arity; ++i) { |
| 606 all[i] = environment()->LookupRegister( | 627 all[i] = environment()->LookupRegister( |
| 607 interpreter::Register(reciever_index + i - 1)); | 628 interpreter::Register(reciever_index + i - 1)); |
| 608 } | 629 } |
| 609 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 630 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); |
| 610 return value; | 631 return value; |
| 611 } | 632 } |
| 612 | 633 |
| 613 | 634 |
| 614 void BytecodeGraphBuilder::BuildCall( | 635 void BytecodeGraphBuilder::BuildCall( |
| 615 const interpreter::BytecodeArrayIterator& iterator) { | 636 const interpreter::BytecodeArrayIterator& iterator) { |
| 616 // TODO(rmcilroy): Set receiver_hint correctly based on whether the reciever | 637 // TODO(rmcilroy): Set receiver_hint correctly based on whether the reciever |
| 617 // register has been loaded with null / undefined explicitly or we are sure it | 638 // register has been loaded with null / undefined explicitly or we are sure it |
| 618 // is not null / undefined. | 639 // is not null / undefined. |
| 619 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 640 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
| 620 interpreter::Register callee = iterator.GetRegisterOperand(0); | 641 Node* callee = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 621 interpreter::Register reciever = iterator.GetRegisterOperand(1); | 642 interpreter::Register reciever = iterator.GetRegisterOperand(1); |
| 622 size_t arg_count = iterator.GetCountOperand(2); | 643 size_t arg_count = iterator.GetCountOperand(2); |
| 623 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3)); | 644 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(3)); |
| 624 | 645 |
| 625 const Operator* call = javascript()->CallFunction( | 646 const Operator* call = javascript()->CallFunction( |
| 626 arg_count + 2, language_mode(), feedback, receiver_hint); | 647 arg_count + 2, language_mode(), feedback, receiver_hint); |
| 627 Node* value = ProcessCallArguments(call, callee, reciever, arg_count + 2); | 648 Node* value = ProcessCallArguments(call, callee, reciever, arg_count + 2); |
| 628 AddEmptyFrameStateInputs(value); | 649 AddEmptyFrameStateInputs(value); |
| 629 environment()->BindAccumulator(value); | 650 environment()->BindAccumulator(value); |
| 630 } | 651 } |
| 631 | 652 |
| 632 | 653 |
| 633 void BytecodeGraphBuilder::VisitCall( | 654 void BytecodeGraphBuilder::VisitCall( |
| 634 const interpreter::BytecodeArrayIterator& iterator) { | 655 const interpreter::BytecodeArrayIterator& iterator) { |
| 635 BuildCall(iterator); | 656 BuildCall(iterator); |
| 636 } | 657 } |
| 637 | 658 |
| 638 | 659 |
| 639 void BytecodeGraphBuilder::VisitCallWide( | 660 void BytecodeGraphBuilder::VisitCallWide( |
| 640 const interpreter::BytecodeArrayIterator& iterator) { | 661 const interpreter::BytecodeArrayIterator& iterator) { |
| 641 BuildCall(iterator); | 662 BuildCall(iterator); |
| 642 } | 663 } |
| 643 | 664 |
| 644 | 665 |
| 666 void BytecodeGraphBuilder::VisitCallJSRuntime( |
| 667 const interpreter::BytecodeArrayIterator& iterator) { |
| 668 Node* callee = BuildLoadNativeContextField(iterator.GetIndexOperand(0)); |
| 669 interpreter::Register reciever = iterator.GetRegisterOperand(1); |
| 670 size_t arg_count = iterator.GetCountOperand(2); |
| 671 |
| 672 // Create node to perform the JS runtime call. |
| 673 const Operator* call = |
| 674 javascript()->CallFunction(arg_count + 2, language_mode()); |
| 675 Node* value = ProcessCallArguments(call, callee, reciever, arg_count + 2); |
| 676 AddEmptyFrameStateInputs(value); |
| 677 environment()->BindAccumulator(value); |
| 678 } |
| 679 |
| 680 |
| 681 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments( |
| 682 const Operator* call_runtime_op, interpreter::Register first_arg, |
| 683 size_t arity) { |
| 684 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 685 int first_arg_index = first_arg.index(); |
| 686 for (int i = 0; i < arity; ++i) { |
| 687 all[i] = environment()->LookupRegister( |
| 688 interpreter::Register(first_arg_index + i)); |
| 689 } |
| 690 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false); |
| 691 return value; |
| 692 } |
| 693 |
| 694 |
| 645 void BytecodeGraphBuilder::VisitCallRuntime( | 695 void BytecodeGraphBuilder::VisitCallRuntime( |
| 646 const interpreter::BytecodeArrayIterator& iterator) { | 696 const interpreter::BytecodeArrayIterator& iterator) { |
| 647 UNIMPLEMENTED(); | 697 Runtime::FunctionId functionId = |
| 698 static_cast<Runtime::FunctionId>(iterator.GetIndexOperand(0)); |
| 699 interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
| 700 size_t arg_count = iterator.GetCountOperand(2); |
| 701 |
| 702 // Create node to perform the runtime call. |
| 703 const Operator* call = javascript()->CallRuntime(functionId, arg_count); |
| 704 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count); |
| 705 AddEmptyFrameStateInputs(value); |
| 706 environment()->BindAccumulator(value); |
| 648 } | 707 } |
| 649 | 708 |
| 650 | 709 |
| 651 void BytecodeGraphBuilder::VisitCallJSRuntime( | 710 Node* BytecodeGraphBuilder::ProcessCallNewArguments( |
| 652 const interpreter::BytecodeArrayIterator& iterator) { | 711 const Operator* call_new_op, interpreter::Register callee, |
| 653 UNIMPLEMENTED(); | 712 interpreter::Register first_arg, size_t arity) { |
| 713 Node** all = info()->zone()->NewArray<Node*>(arity); |
| 714 all[0] = environment()->LookupRegister(callee); |
| 715 int first_arg_index = first_arg.index(); |
| 716 for (int i = 1; i < arity - 1; ++i) { |
| 717 all[i] = environment()->LookupRegister( |
| 718 interpreter::Register(first_arg_index + i - 1)); |
| 719 } |
| 720 // Original constructor is the same as the callee. |
| 721 all[arity - 1] = environment()->LookupRegister(callee); |
| 722 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false); |
| 723 return value; |
| 654 } | 724 } |
| 655 | 725 |
| 656 | 726 |
| 657 void BytecodeGraphBuilder::VisitNew( | 727 void BytecodeGraphBuilder::VisitNew( |
| 658 const interpreter::BytecodeArrayIterator& iterator) { | 728 const interpreter::BytecodeArrayIterator& iterator) { |
| 659 UNIMPLEMENTED(); | 729 interpreter::Register callee = iterator.GetRegisterOperand(0); |
| 730 interpreter::Register first_arg = iterator.GetRegisterOperand(1); |
| 731 size_t arg_count = iterator.GetCountOperand(2); |
| 732 |
| 733 const Operator* call = |
| 734 javascript()->CallConstruct(static_cast<int>(arg_count) + 2); |
| 735 Node* value = ProcessCallNewArguments(call, callee, first_arg, arg_count + 2); |
| 736 AddEmptyFrameStateInputs(value); |
| 737 environment()->BindAccumulator(value); |
| 660 } | 738 } |
| 661 | 739 |
| 662 | 740 |
| 663 void BytecodeGraphBuilder::VisitThrow( | 741 void BytecodeGraphBuilder::VisitThrow( |
| 664 const interpreter::BytecodeArrayIterator& iterator) { | 742 const interpreter::BytecodeArrayIterator& iterator) { |
| 665 UNIMPLEMENTED(); | 743 UNIMPLEMENTED(); |
| 666 } | 744 } |
| 667 | 745 |
| 668 | 746 |
| 669 void BytecodeGraphBuilder::BuildBinaryOp( | 747 void BytecodeGraphBuilder::BuildBinaryOp( |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 | 1147 |
| 1070 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { | 1148 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { |
| 1071 if (environment()->IsMarkedAsUnreachable()) return; | 1149 if (environment()->IsMarkedAsUnreachable()) return; |
| 1072 environment()->MarkAsUnreachable(); | 1150 environment()->MarkAsUnreachable(); |
| 1073 exit_controls_.push_back(exit); | 1151 exit_controls_.push_back(exit); |
| 1074 } | 1152 } |
| 1075 | 1153 |
| 1076 } // namespace compiler | 1154 } // namespace compiler |
| 1077 } // namespace internal | 1155 } // namespace internal |
| 1078 } // namespace v8 | 1156 } // namespace v8 |
| OLD | NEW |