| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 void UpdateControlDependency(Node* dependency) { | 53 void UpdateControlDependency(Node* dependency) { |
| 54 control_dependency_ = dependency; | 54 control_dependency_ = dependency; |
| 55 } | 55 } |
| 56 | 56 |
| 57 Node* Context() const { return context_; } | 57 Node* Context() const { return context_; } |
| 58 void SetContext(Node* new_context) { context_ = new_context; } | 58 void SetContext(Node* new_context) { context_ = new_context; } |
| 59 | 59 |
| 60 Environment* CopyForConditional() const; | 60 Environment* CopyForConditional() const; |
| 61 Environment* CopyForLoop(); | 61 Environment* CopyForLoop(); |
| 62 void Merge(Environment* other); | 62 void Merge(Environment* other); |
| 63 void PrepareForOsr(); |
| 63 | 64 |
| 64 private: | 65 private: |
| 65 explicit Environment(const Environment* copy); | 66 explicit Environment(const Environment* copy); |
| 66 void PrepareForLoop(); | 67 void PrepareForLoop(); |
| 67 bool StateValuesAreUpToDate(Node** state_values, int offset, int count, | 68 bool StateValuesAreUpToDate(Node** state_values, int offset, int count, |
| 68 int output_poke_start, int output_poke_end); | 69 int output_poke_start, int output_poke_end); |
| 69 bool StateValuesRequireUpdate(Node** state_values, int offset, int count); | 70 bool StateValuesRequireUpdate(Node** state_values, int offset, int count); |
| 70 void UpdateStateValues(Node** state_values, int offset, int count); | 71 void UpdateStateValues(Node** state_values, int offset, int count); |
| 71 | 72 |
| 72 int RegisterToValuesIndex(interpreter::Register the_register) const; | 73 int RegisterToValuesIndex(interpreter::Register the_register) const; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 for (int i = 0; i < size; i++) { | 352 for (int i = 0; i < size; i++) { |
| 352 values()->at(i) = builder()->NewPhi(1, values()->at(i), control); | 353 values()->at(i) = builder()->NewPhi(1, values()->at(i), control); |
| 353 } | 354 } |
| 354 | 355 |
| 355 // Connect to the loop end. | 356 // Connect to the loop end. |
| 356 Node* terminate = builder()->graph()->NewNode( | 357 Node* terminate = builder()->graph()->NewNode( |
| 357 builder()->common()->Terminate(), effect, control); | 358 builder()->common()->Terminate(), effect, control); |
| 358 builder()->exit_controls_.push_back(terminate); | 359 builder()->exit_controls_.push_back(terminate); |
| 359 } | 360 } |
| 360 | 361 |
| 362 void BytecodeGraphBuilder::Environment::PrepareForOsr() { |
| 363 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode()); |
| 364 DCHECK_EQ(1, GetControlDependency()->InputCount()); |
| 365 Node* start = graph()->start(); |
| 366 |
| 367 // Create a control node for the OSR entry point and merge it into the loop |
| 368 // header. Update the current environment's control dependency accordingly. |
| 369 Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start); |
| 370 Node* control = builder()->MergeControl(GetControlDependency(), entry); |
| 371 UpdateControlDependency(control); |
| 372 |
| 373 // Create a merge of the effect from the OSR entry and the existing effect |
| 374 // dependency. Update the current environment's effect dependency accordingly. |
| 375 Node* effect = builder()->MergeEffect(GetEffectDependency(), entry, control); |
| 376 UpdateEffectDependency(effect); |
| 377 |
| 378 // Rename all values in the environment which will extend or introduce Phi |
| 379 // nodes to contain the OSR values available at the entry point. |
| 380 Node* osr_context = graph()->NewNode( |
| 381 common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry); |
| 382 context_ = builder()->MergeValue(context_, osr_context, control); |
| 383 int size = static_cast<int>(values()->size()); |
| 384 for (int i = 0; i < size; i++) { |
| 385 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly. |
| 386 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount; |
| 387 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex; |
| 388 Node* osr_value = graph()->NewNode(common()->OsrValue(idx), entry); |
| 389 values_[i] = builder()->MergeValue(values_[i], osr_value, control); |
| 390 } |
| 391 } |
| 361 | 392 |
| 362 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( | 393 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( |
| 363 Node** state_values, int offset, int count) { | 394 Node** state_values, int offset, int count) { |
| 364 if (*state_values == nullptr) { | 395 if (*state_values == nullptr) { |
| 365 return true; | 396 return true; |
| 366 } | 397 } |
| 367 DCHECK_EQ((*state_values)->InputCount(), count); | 398 DCHECK_EQ((*state_values)->InputCount(), count); |
| 368 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); | 399 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); |
| 369 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 400 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
| 370 for (int i = 0; i < count; i++) { | 401 for (int i = 0; i < count; i++) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 : local_zone_(local_zone), | 471 : local_zone_(local_zone), |
| 441 jsgraph_(jsgraph), | 472 jsgraph_(jsgraph), |
| 442 bytecode_array_(handle(info->shared_info()->bytecode_array())), | 473 bytecode_array_(handle(info->shared_info()->bytecode_array())), |
| 443 exception_handler_table_( | 474 exception_handler_table_( |
| 444 handle(HandlerTable::cast(bytecode_array()->handler_table()))), | 475 handle(HandlerTable::cast(bytecode_array()->handler_table()))), |
| 445 feedback_vector_(handle(info->closure()->feedback_vector())), | 476 feedback_vector_(handle(info->closure()->feedback_vector())), |
| 446 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 477 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 447 FrameStateType::kInterpretedFunction, | 478 FrameStateType::kInterpretedFunction, |
| 448 bytecode_array()->parameter_count(), | 479 bytecode_array()->parameter_count(), |
| 449 bytecode_array()->register_count(), info->shared_info())), | 480 bytecode_array()->register_count(), info->shared_info())), |
| 481 osr_ast_id_(info->osr_ast_id()), |
| 450 merge_environments_(local_zone), | 482 merge_environments_(local_zone), |
| 451 exception_handlers_(local_zone), | 483 exception_handlers_(local_zone), |
| 452 current_exception_handler_(0), | 484 current_exception_handler_(0), |
| 453 input_buffer_size_(0), | 485 input_buffer_size_(0), |
| 454 input_buffer_(nullptr), | 486 input_buffer_(nullptr), |
| 455 exit_controls_(local_zone) {} | 487 exit_controls_(local_zone) {} |
| 456 | 488 |
| 457 Node* BytecodeGraphBuilder::GetNewTarget() { | 489 Node* BytecodeGraphBuilder::GetNewTarget() { |
| 458 if (!new_target_.is_set()) { | 490 if (!new_target_.is_set()) { |
| 459 int params = bytecode_array()->parameter_count(); | 491 int params = bytecode_array()->parameter_count(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 // parameters (including the receiver) plus new target, number of arguments, | 546 // parameters (including the receiver) plus new target, number of arguments, |
| 515 // context and closure. | 547 // context and closure. |
| 516 int actual_parameter_count = bytecode_array()->parameter_count() + 4; | 548 int actual_parameter_count = bytecode_array()->parameter_count() + 4; |
| 517 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 549 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
| 518 | 550 |
| 519 Environment env(this, bytecode_array()->register_count(), | 551 Environment env(this, bytecode_array()->register_count(), |
| 520 bytecode_array()->parameter_count(), graph()->start(), | 552 bytecode_array()->parameter_count(), graph()->start(), |
| 521 GetFunctionContext()); | 553 GetFunctionContext()); |
| 522 set_environment(&env); | 554 set_environment(&env); |
| 523 | 555 |
| 556 // For OSR add an {OsrNormalEntry} as the start of the top-level environment. |
| 557 // It will be replaced with {Dead} after typing and optimizations. |
| 558 if (!osr_ast_id_.IsNone()) NewNode(common()->OsrNormalEntry()); |
| 559 |
| 524 VisitBytecodes(); | 560 VisitBytecodes(); |
| 525 | 561 |
| 526 // Finish the basic structure of the graph. | 562 // Finish the basic structure of the graph. |
| 527 DCHECK_NE(0u, exit_controls_.size()); | 563 DCHECK_NE(0u, exit_controls_.size()); |
| 528 int const input_count = static_cast<int>(exit_controls_.size()); | 564 int const input_count = static_cast<int>(exit_controls_.size()); |
| 529 Node** const inputs = &exit_controls_.front(); | 565 Node** const inputs = &exit_controls_.front(); |
| 530 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); | 566 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); |
| 531 graph()->SetEnd(end); | 567 graph()->SetEnd(end); |
| 532 | 568 |
| 533 return true; | 569 return true; |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); | 1422 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); |
| 1387 } | 1423 } |
| 1388 | 1424 |
| 1389 void BytecodeGraphBuilder::VisitStackCheck() { | 1425 void BytecodeGraphBuilder::VisitStackCheck() { |
| 1390 FrameStateBeforeAndAfter states(this); | 1426 FrameStateBeforeAndAfter states(this); |
| 1391 Node* node = NewNode(javascript()->StackCheck()); | 1427 Node* node = NewNode(javascript()->StackCheck()); |
| 1392 environment()->RecordAfterState(node, &states); | 1428 environment()->RecordAfterState(node, &states); |
| 1393 } | 1429 } |
| 1394 | 1430 |
| 1395 void BytecodeGraphBuilder::VisitOsrPoll() { | 1431 void BytecodeGraphBuilder::VisitOsrPoll() { |
| 1396 // TODO(4764): Implement OSR graph construction. Not marked UNIMPLEMENTED to | 1432 // TODO(4764): This should be moved into the {VisitBytecodes} once we merge |
| 1397 // ensure the --ignition-osr flag can already be fuzzed without crashing. | 1433 // the polling with existing bytecode. This will also guarantee that we are |
| 1434 // not missing the OSR entry point, which we wouldn't catch right now. |
| 1435 if (osr_ast_id_.ToInt() == bytecode_iterator().current_offset()) { |
| 1436 environment()->PrepareForOsr(); |
| 1437 } |
| 1398 } | 1438 } |
| 1399 | 1439 |
| 1400 void BytecodeGraphBuilder::VisitReturn() { | 1440 void BytecodeGraphBuilder::VisitReturn() { |
| 1401 Node* control = | 1441 Node* control = |
| 1402 NewNode(common()->Return(), environment()->LookupAccumulator()); | 1442 NewNode(common()->Return(), environment()->LookupAccumulator()); |
| 1403 MergeControlToLeaveFunction(control); | 1443 MergeControlToLeaveFunction(control); |
| 1404 } | 1444 } |
| 1405 | 1445 |
| 1406 void BytecodeGraphBuilder::VisitDebugger() { | 1446 void BytecodeGraphBuilder::VisitDebugger() { |
| 1407 FrameStateBeforeAndAfter states(this); | 1447 FrameStateBeforeAndAfter states(this); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 // Phi does not exist yet, introduce one. | 1832 // Phi does not exist yet, introduce one. |
| 1793 value = NewPhi(inputs, value, control); | 1833 value = NewPhi(inputs, value, control); |
| 1794 value->ReplaceInput(inputs - 1, other); | 1834 value->ReplaceInput(inputs - 1, other); |
| 1795 } | 1835 } |
| 1796 return value; | 1836 return value; |
| 1797 } | 1837 } |
| 1798 | 1838 |
| 1799 } // namespace compiler | 1839 } // namespace compiler |
| 1800 } // namespace internal | 1840 } // namespace internal |
| 1801 } // namespace v8 | 1841 } // namespace v8 |
| OLD | NEW |