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/bytecode-branch-analysis.h" | 7 #include "src/compiler/bytecode-branch-analysis.h" |
8 #include "src/compiler/linkage.h" | 8 #include "src/compiler/linkage.h" |
9 #include "src/compiler/operator-properties.h" | 9 #include "src/compiler/operator-properties.h" |
10 #include "src/interpreter/bytecodes.h" | 10 #include "src/interpreter/bytecodes.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { | 495 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) { |
496 const Operator* op = | 496 const Operator* op = |
497 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); | 497 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); |
498 Node* native_context = NewNode(op, environment()->Context()); | 498 Node* native_context = NewNode(op, environment()->Context()); |
499 return NewNode(javascript()->LoadContext(0, index, true), native_context); | 499 return NewNode(javascript()->LoadContext(0, index, true), native_context); |
500 } | 500 } |
501 | 501 |
502 | 502 |
503 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { | 503 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) { |
504 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); | 504 Handle<TypeFeedbackVector> feedback_vector = info()->feedback_vector(); |
505 FeedbackVectorSlot slot; | 505 FeedbackVectorSlot slot = feedback_vector->ToSlot(slot_id); |
506 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) { | |
507 slot = feedback_vector->ToSlot(slot_id); | |
508 } | |
509 return VectorSlotPair(feedback_vector, slot); | 506 return VectorSlotPair(feedback_vector, slot); |
510 } | 507 } |
511 | 508 |
512 bool BytecodeGraphBuilder::CreateGraph() { | 509 bool BytecodeGraphBuilder::CreateGraph() { |
513 // Set up the basic structure of the graph. Outputs for {Start} are | 510 // Set up the basic structure of the graph. Outputs for {Start} are |
514 // the formal parameters (including the receiver) plus context and | 511 // the formal parameters (including the receiver) plus context and |
515 // closure. | 512 // closure. |
516 | 513 |
517 // Set up the basic structure of the graph. Outputs for {Start} are the formal | 514 // Set up the basic structure of the graph. Outputs for {Start} are the formal |
518 // parameters (including the receiver) plus new target, number of arguments, | 515 // parameters (including the receiver) plus new target, number of arguments, |
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 all[1] = environment()->LookupRegister(receiver); | 1031 all[1] = environment()->LookupRegister(receiver); |
1035 int receiver_index = receiver.index(); | 1032 int receiver_index = receiver.index(); |
1036 for (int i = 2; i < static_cast<int>(arity); ++i) { | 1033 for (int i = 2; i < static_cast<int>(arity); ++i) { |
1037 all[i] = environment()->LookupRegister( | 1034 all[i] = environment()->LookupRegister( |
1038 interpreter::Register(receiver_index + i - 1)); | 1035 interpreter::Register(receiver_index + i - 1)); |
1039 } | 1036 } |
1040 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); | 1037 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false); |
1041 return value; | 1038 return value; |
1042 } | 1039 } |
1043 | 1040 |
1044 void BytecodeGraphBuilder::BuildCall() { | 1041 void BytecodeGraphBuilder::BuildCallWithFeedbackSlot() { |
1045 FrameStateBeforeAndAfter states(this); | 1042 FrameStateBeforeAndAfter states(this); |
1046 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver | 1043 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver |
1047 // register has been loaded with null / undefined explicitly or we are sure it | 1044 // register has been loaded with null / undefined explicitly or we are sure it |
1048 // is not null / undefined. | 1045 // is not null / undefined. |
1049 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; | 1046 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
1050 Node* callee = | 1047 Node* callee = |
1051 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); | 1048 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
1052 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1049 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1053 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1050 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
1054 VectorSlotPair feedback = | 1051 int slot_id = bytecode_iterator().GetIndexOperand(3); |
1055 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3)); | 1052 VectorSlotPair feedback = CreateVectorSlotPair(slot_id); |
1056 | 1053 |
1057 // TODO(ishell): provide correct tail_call_mode value to CallFunction. | 1054 // TODO(ishell): provide correct tail_call_mode value to CallFunction. |
1058 const Operator* call = javascript()->CallFunction( | 1055 const Operator* call = javascript()->CallFunction( |
1059 arg_count + 1, language_mode(), feedback, receiver_hint); | 1056 arg_count + 1, language_mode(), feedback, receiver_hint); |
1060 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); | 1057 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
1061 environment()->BindAccumulator(value, &states); | 1058 environment()->BindAccumulator(value, &states); |
1062 } | 1059 } |
1063 | 1060 |
| 1061 void BytecodeGraphBuilder::BuildCall() { |
| 1062 FrameStateBeforeAndAfter states(this); |
| 1063 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver |
| 1064 // register has been loaded with null / undefined explicitly or we are sure it |
| 1065 // is not null / undefined. |
| 1066 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; |
| 1067 Node* callee = |
| 1068 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); |
| 1069 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
| 1070 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
| 1071 |
| 1072 // TODO(ishell): provide correct tail_call_mode value to CallFunction. |
| 1073 const Operator* call = javascript()->CallFunction( |
| 1074 arg_count + 1, language_mode(), VectorSlotPair(), receiver_hint); |
| 1075 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); |
| 1076 environment()->BindAccumulator(value, &states); |
| 1077 } |
| 1078 |
| 1079 void BytecodeGraphBuilder::VisitCallIC() { BuildCallWithFeedbackSlot(); } |
| 1080 |
| 1081 void BytecodeGraphBuilder::VisitCallICWide() { BuildCallWithFeedbackSlot(); } |
| 1082 |
1064 void BytecodeGraphBuilder::VisitCall() { BuildCall(); } | 1083 void BytecodeGraphBuilder::VisitCall() { BuildCall(); } |
1065 | 1084 |
1066 void BytecodeGraphBuilder::VisitCallWide() { BuildCall(); } | 1085 void BytecodeGraphBuilder::VisitCallWide() { BuildCall(); } |
1067 | 1086 |
1068 void BytecodeGraphBuilder::BuildCallJSRuntime() { | 1087 void BytecodeGraphBuilder::BuildCallJSRuntime() { |
1069 FrameStateBeforeAndAfter states(this); | 1088 FrameStateBeforeAndAfter states(this); |
1070 Node* callee = | 1089 Node* callee = |
1071 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); | 1090 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0)); |
1072 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); | 1091 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); |
1073 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); | 1092 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 // Phi does not exist yet, introduce one. | 1809 // Phi does not exist yet, introduce one. |
1791 value = NewPhi(inputs, value, control); | 1810 value = NewPhi(inputs, value, control); |
1792 value->ReplaceInput(inputs - 1, other); | 1811 value->ReplaceInput(inputs - 1, other); |
1793 } | 1812 } |
1794 return value; | 1813 return value; |
1795 } | 1814 } |
1796 | 1815 |
1797 } // namespace compiler | 1816 } // namespace compiler |
1798 } // namespace internal | 1817 } // namespace internal |
1799 } // namespace v8 | 1818 } // namespace v8 |
OLD | NEW |