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