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 |