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 #include "src/interpreter/bytecodes.h" |
10 | 11 |
11 namespace v8 { | 12 namespace v8 { |
12 namespace internal { | 13 namespace internal { |
13 namespace compiler { | 14 namespace compiler { |
14 | 15 |
15 // Issues: | 16 // Issues: |
16 // - Need to deal with FrameState / FrameStateBeforeAndAfter / StateValue. | 17 // - Need to deal with FrameState / FrameStateBeforeAndAfter / StateValue. |
17 // - Scopes - intimately tied to AST. Need to eval what is needed. | 18 // - Scopes - intimately tied to AST. Need to eval what is needed. |
18 // - Need to resolve closure parameter treatment. | 19 // - Need to resolve closure parameter treatment. |
19 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, | 20 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 | 67 |
67 void BytecodeGraphBuilder::Environment::BindRegister( | 68 void BytecodeGraphBuilder::Environment::BindRegister( |
68 interpreter::Register the_register, Node* node) { | 69 interpreter::Register the_register, Node* node) { |
69 int values_index = RegisterToValuesIndex(the_register); | 70 int values_index = RegisterToValuesIndex(the_register); |
70 values()->at(values_index) = node; | 71 values()->at(values_index) = node; |
71 } | 72 } |
72 | 73 |
73 | 74 |
74 Node* BytecodeGraphBuilder::Environment::LookupRegister( | 75 Node* BytecodeGraphBuilder::Environment::LookupRegister( |
75 interpreter::Register the_register) const { | 76 interpreter::Register the_register) const { |
76 int values_index = RegisterToValuesIndex(the_register); | 77 if (the_register.is_function_context()) { |
77 return values()->at(values_index); | 78 return builder()->GetFunctionContext(); |
| 79 } else if (the_register.is_function_closure()) { |
| 80 return builder()->GetFunctionClosure(); |
| 81 } else if (the_register.is_new_target()) { |
| 82 return builder()->GetNewTarget(); |
| 83 } else { |
| 84 int values_index = RegisterToValuesIndex(the_register); |
| 85 return values()->at(values_index); |
| 86 } |
78 } | 87 } |
79 | 88 |
80 | 89 |
81 void BytecodeGraphBuilder::Environment::BindAccumulator(Node* node) { | 90 void BytecodeGraphBuilder::Environment::BindAccumulator(Node* node) { |
82 accumulator_ = node; | 91 accumulator_ = node; |
83 } | 92 } |
84 | 93 |
85 | 94 |
86 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { | 95 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { |
87 return accumulator_; | 96 return accumulator_; |
(...skipping 16 matching lines...) Expand all Loading... |
104 : local_zone_(local_zone), | 113 : local_zone_(local_zone), |
105 info_(compilation_info), | 114 info_(compilation_info), |
106 jsgraph_(jsgraph), | 115 jsgraph_(jsgraph), |
107 input_buffer_size_(0), | 116 input_buffer_size_(0), |
108 input_buffer_(nullptr), | 117 input_buffer_(nullptr), |
109 exit_controls_(local_zone) { | 118 exit_controls_(local_zone) { |
110 bytecode_array_ = handle(info()->shared_info()->bytecode_array()); | 119 bytecode_array_ = handle(info()->shared_info()->bytecode_array()); |
111 } | 120 } |
112 | 121 |
113 | 122 |
| 123 Node* BytecodeGraphBuilder::GetNewTarget() { |
| 124 if (!new_target_.is_set()) { |
| 125 int params = bytecode_array()->parameter_count(); |
| 126 int index = Linkage::GetJSCallNewTargetParamIndex(params); |
| 127 const Operator* op = common()->Parameter(index, "%new.target"); |
| 128 Node* node = NewNode(op, graph()->start()); |
| 129 new_target_.set(node); |
| 130 } |
| 131 return new_target_.get(); |
| 132 } |
| 133 |
| 134 |
114 Node* BytecodeGraphBuilder::GetFunctionContext() { | 135 Node* BytecodeGraphBuilder::GetFunctionContext() { |
115 if (!function_context_.is_set()) { | 136 if (!function_context_.is_set()) { |
116 int params = bytecode_array()->parameter_count(); | 137 int params = bytecode_array()->parameter_count(); |
117 int index = Linkage::GetJSCallContextParamIndex(params); | 138 int index = Linkage::GetJSCallContextParamIndex(params); |
118 const Operator* op = common()->Parameter(index, "%context"); | 139 const Operator* op = common()->Parameter(index, "%context"); |
119 Node* node = NewNode(op, graph()->start()); | 140 Node* node = NewNode(op, graph()->start()); |
120 function_context_.set(node); | 141 function_context_.set(node); |
121 } | 142 } |
122 return function_context_.get(); | 143 return function_context_.get(); |
123 } | 144 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 // parameters (including the receiver) plus new target, number of arguments, | 218 // parameters (including the receiver) plus new target, number of arguments, |
198 // context and closure. | 219 // context and closure. |
199 int actual_parameter_count = bytecode_array()->parameter_count() + 4; | 220 int actual_parameter_count = bytecode_array()->parameter_count() + 4; |
200 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 221 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
201 | 222 |
202 Environment env(this, bytecode_array()->register_count(), | 223 Environment env(this, bytecode_array()->register_count(), |
203 bytecode_array()->parameter_count(), graph()->start(), | 224 bytecode_array()->parameter_count(), graph()->start(), |
204 GetFunctionContext()); | 225 GetFunctionContext()); |
205 set_environment(&env); | 226 set_environment(&env); |
206 | 227 |
207 // Build function context only if there are context allocated variables. | 228 CreateGraphBody(stack_check); |
208 if (info()->num_heap_slots() > 0) { | |
209 UNIMPLEMENTED(); // TODO(oth): Write ast-graph-builder equivalent. | |
210 } else { | |
211 // Simply use the outer function context in building the graph. | |
212 CreateGraphBody(stack_check); | |
213 } | |
214 | 229 |
215 // Finish the basic structure of the graph. | 230 // Finish the basic structure of the graph. |
216 DCHECK_NE(0u, exit_controls_.size()); | 231 DCHECK_NE(0u, exit_controls_.size()); |
217 int const input_count = static_cast<int>(exit_controls_.size()); | 232 int const input_count = static_cast<int>(exit_controls_.size()); |
218 Node** const inputs = &exit_controls_.front(); | 233 Node** const inputs = &exit_controls_.front(); |
219 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); | 234 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); |
220 graph()->SetEnd(end); | 235 graph()->SetEnd(end); |
221 | 236 |
222 return true; | 237 return true; |
223 } | 238 } |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 | 451 |
437 void BytecodeGraphBuilder::VisitStaGlobalStrictWide( | 452 void BytecodeGraphBuilder::VisitStaGlobalStrictWide( |
438 const interpreter::BytecodeArrayIterator& iterator) { | 453 const interpreter::BytecodeArrayIterator& iterator) { |
439 DCHECK(is_strict(language_mode())); | 454 DCHECK(is_strict(language_mode())); |
440 BuildStoreGlobal(iterator); | 455 BuildStoreGlobal(iterator); |
441 } | 456 } |
442 | 457 |
443 | 458 |
444 void BytecodeGraphBuilder::VisitLdaContextSlot( | 459 void BytecodeGraphBuilder::VisitLdaContextSlot( |
445 const interpreter::BytecodeArrayIterator& iterator) { | 460 const interpreter::BytecodeArrayIterator& iterator) { |
446 UNIMPLEMENTED(); | 461 // TODO(mythria): LoadContextSlots are unrolled by the required depth when |
| 462 // generating bytecode. Hence the value of depth is always 0. Update this |
| 463 // code, when the implementation changes. |
| 464 // TODO(mythria): immutable flag is also set to false. This information is not |
| 465 // available in bytecode array. update this code when the implementation |
| 466 // changes. |
| 467 const Operator* op = |
| 468 javascript()->LoadContext(0, iterator.GetIndexOperand(1), false); |
| 469 Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 470 Node* node = NewNode(op, context); |
| 471 environment()->BindAccumulator(node); |
447 } | 472 } |
448 | 473 |
449 | 474 |
450 void BytecodeGraphBuilder::VisitStaContextSlot( | 475 void BytecodeGraphBuilder::VisitStaContextSlot( |
451 const interpreter::BytecodeArrayIterator& iterator) { | 476 const interpreter::BytecodeArrayIterator& iterator) { |
452 UNIMPLEMENTED(); | 477 // TODO(mythria): LoadContextSlots are unrolled by the required depth when |
| 478 // generating bytecode. Hence the value of depth is always 0. Update this |
| 479 // code, when the implementation changes. |
| 480 const Operator* op = |
| 481 javascript()->StoreContext(0, iterator.GetIndexOperand(1)); |
| 482 Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 483 Node* value = environment()->LookupAccumulator(); |
| 484 Node* node = NewNode(op, context, value); |
| 485 CHECK(node != nullptr); |
| 486 environment()->BindAccumulator(value); |
453 } | 487 } |
454 | 488 |
455 | 489 |
456 void BytecodeGraphBuilder::BuildNamedLoad( | 490 void BytecodeGraphBuilder::BuildNamedLoad( |
457 const interpreter::BytecodeArrayIterator& iterator) { | 491 const interpreter::BytecodeArrayIterator& iterator) { |
458 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); | 492 Node* object = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
459 Handle<Name> name = | 493 Handle<Name> name = |
460 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); | 494 Handle<Name>::cast(iterator.GetConstantForIndexOperand(1)); |
461 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); | 495 VectorSlotPair feedback = CreateVectorSlotPair(iterator.GetIndexOperand(2)); |
462 | 496 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 | 651 |
618 void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide( | 652 void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide( |
619 const interpreter::BytecodeArrayIterator& iterator) { | 653 const interpreter::BytecodeArrayIterator& iterator) { |
620 DCHECK(is_strict(language_mode())); | 654 DCHECK(is_strict(language_mode())); |
621 BuildKeyedStore(iterator); | 655 BuildKeyedStore(iterator); |
622 } | 656 } |
623 | 657 |
624 | 658 |
625 void BytecodeGraphBuilder::VisitPushContext( | 659 void BytecodeGraphBuilder::VisitPushContext( |
626 const interpreter::BytecodeArrayIterator& iterator) { | 660 const interpreter::BytecodeArrayIterator& iterator) { |
627 UNIMPLEMENTED(); | 661 Node* context = environment()->LookupAccumulator(); |
| 662 environment()->BindRegister(iterator.GetRegisterOperand(0), context); |
| 663 environment()->SetContext(context); |
628 } | 664 } |
629 | 665 |
630 | 666 |
631 void BytecodeGraphBuilder::VisitPopContext( | 667 void BytecodeGraphBuilder::VisitPopContext( |
632 const interpreter::BytecodeArrayIterator& iterator) { | 668 const interpreter::BytecodeArrayIterator& iterator) { |
633 UNIMPLEMENTED(); | 669 Node* context = environment()->LookupRegister(iterator.GetRegisterOperand(0)); |
| 670 environment()->SetContext(context); |
634 } | 671 } |
635 | 672 |
636 | 673 |
637 void BytecodeGraphBuilder::VisitCreateClosure( | 674 void BytecodeGraphBuilder::VisitCreateClosure( |
638 const interpreter::BytecodeArrayIterator& iterator) { | 675 const interpreter::BytecodeArrayIterator& iterator) { |
639 Handle<SharedFunctionInfo> shared_info = | 676 Handle<SharedFunctionInfo> shared_info = |
640 Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0)); | 677 Handle<SharedFunctionInfo>::cast(iterator.GetConstantForIndexOperand(0)); |
641 PretenureFlag tenured = | 678 PretenureFlag tenured = |
642 iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED; | 679 iterator.GetImmediateOperand(1) ? TENURED : NOT_TENURED; |
643 const Operator* op = javascript()->CreateClosure(shared_info, tenured); | 680 const Operator* op = javascript()->CreateClosure(shared_info, tenured); |
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 | 1296 |
1260 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { | 1297 void BytecodeGraphBuilder::UpdateControlDependencyToLeaveFunction(Node* exit) { |
1261 if (environment()->IsMarkedAsUnreachable()) return; | 1298 if (environment()->IsMarkedAsUnreachable()) return; |
1262 environment()->MarkAsUnreachable(); | 1299 environment()->MarkAsUnreachable(); |
1263 exit_controls_.push_back(exit); | 1300 exit_controls_.push_back(exit); |
1264 } | 1301 } |
1265 | 1302 |
1266 } // namespace compiler | 1303 } // namespace compiler |
1267 } // namespace internal | 1304 } // namespace internal |
1268 } // namespace v8 | 1305 } // namespace v8 |
OLD | NEW |