Chromium Code Reviews| 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 Node* start = graph()->start(); | |
| 365 | |
| 366 // Create a control node for the OSR entry point and merge it into the loop | |
| 367 // header. Update the current environment's control dependency accordingly. | |
| 368 Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start); | |
|
Jarin
2016/07/26 14:46:36
Could we possibly DCHECK that the control dependen
Michael Starzinger
2016/07/26 14:58:51
Done. The first invariant yes, I added a check of
| |
| 369 Node* control = builder()->MergeControl(GetControlDependency(), entry); | |
| 370 UpdateControlDependency(control); | |
| 371 | |
| 372 // Create a merge of the effect from the OSR entry and the existing effect | |
| 373 // dependency. Update the current environment's effect dependency accordingly. | |
| 374 Node* effect = builder()->MergeEffect(GetEffectDependency(), entry, control); | |
| 375 UpdateEffectDependency(effect); | |
| 376 | |
| 377 // Rename all values in the environment which will extend or introduce Phi | |
| 378 // nodes to contain the OSR values available at the entry point. | |
| 379 Node* osr_context = graph()->NewNode( | |
| 380 common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry); | |
| 381 context_ = builder()->MergeValue(context_, osr_context, control); | |
| 382 for (size_t i = 0; i < values_.size(); i++) { | |
| 383 int index = | |
| 384 static_cast<int>(i) + InterpreterFrameConstants::kExtraSlotCount; | |
| 385 Node* osr_value = graph()->NewNode(common()->OsrValue(index), entry); | |
| 386 values_[i] = builder()->MergeValue(values_[i], osr_value, control); | |
| 387 } | |
| 388 } | |
| 361 | 389 |
| 362 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( | 390 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( |
| 363 Node** state_values, int offset, int count) { | 391 Node** state_values, int offset, int count) { |
| 364 if (*state_values == nullptr) { | 392 if (*state_values == nullptr) { |
| 365 return true; | 393 return true; |
| 366 } | 394 } |
| 367 DCHECK_EQ((*state_values)->InputCount(), count); | 395 DCHECK_EQ((*state_values)->InputCount(), count); |
| 368 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); | 396 DCHECK_LE(static_cast<size_t>(offset + count), values()->size()); |
| 369 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 397 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
| 370 for (int i = 0; i < count; i++) { | 398 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), | 468 : local_zone_(local_zone), |
| 441 jsgraph_(jsgraph), | 469 jsgraph_(jsgraph), |
| 442 bytecode_array_(handle(info->shared_info()->bytecode_array())), | 470 bytecode_array_(handle(info->shared_info()->bytecode_array())), |
| 443 exception_handler_table_( | 471 exception_handler_table_( |
| 444 handle(HandlerTable::cast(bytecode_array()->handler_table()))), | 472 handle(HandlerTable::cast(bytecode_array()->handler_table()))), |
| 445 feedback_vector_(handle(info->closure()->feedback_vector())), | 473 feedback_vector_(handle(info->closure()->feedback_vector())), |
| 446 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( | 474 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( |
| 447 FrameStateType::kInterpretedFunction, | 475 FrameStateType::kInterpretedFunction, |
| 448 bytecode_array()->parameter_count(), | 476 bytecode_array()->parameter_count(), |
| 449 bytecode_array()->register_count(), info->shared_info())), | 477 bytecode_array()->register_count(), info->shared_info())), |
| 478 osr_ast_id_(info->osr_ast_id()), | |
| 450 merge_environments_(local_zone), | 479 merge_environments_(local_zone), |
| 451 exception_handlers_(local_zone), | 480 exception_handlers_(local_zone), |
| 452 current_exception_handler_(0), | 481 current_exception_handler_(0), |
| 453 input_buffer_size_(0), | 482 input_buffer_size_(0), |
| 454 input_buffer_(nullptr), | 483 input_buffer_(nullptr), |
| 455 exit_controls_(local_zone) {} | 484 exit_controls_(local_zone) {} |
| 456 | 485 |
| 457 Node* BytecodeGraphBuilder::GetNewTarget() { | 486 Node* BytecodeGraphBuilder::GetNewTarget() { |
| 458 if (!new_target_.is_set()) { | 487 if (!new_target_.is_set()) { |
| 459 int params = bytecode_array()->parameter_count(); | 488 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, | 543 // parameters (including the receiver) plus new target, number of arguments, |
| 515 // context and closure. | 544 // context and closure. |
| 516 int actual_parameter_count = bytecode_array()->parameter_count() + 4; | 545 int actual_parameter_count = bytecode_array()->parameter_count() + 4; |
| 517 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); | 546 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count))); |
| 518 | 547 |
| 519 Environment env(this, bytecode_array()->register_count(), | 548 Environment env(this, bytecode_array()->register_count(), |
| 520 bytecode_array()->parameter_count(), graph()->start(), | 549 bytecode_array()->parameter_count(), graph()->start(), |
| 521 GetFunctionContext()); | 550 GetFunctionContext()); |
| 522 set_environment(&env); | 551 set_environment(&env); |
| 523 | 552 |
| 553 // For OSR add an {OsrNormalEntry} as the start of the top-level environment. | |
| 554 // It will be replaced with {Dead} after typing and optimizations. | |
| 555 if (!osr_ast_id_.IsNone()) NewNode(common()->OsrNormalEntry()); | |
| 556 | |
| 524 VisitBytecodes(); | 557 VisitBytecodes(); |
| 525 | 558 |
| 526 // Finish the basic structure of the graph. | 559 // Finish the basic structure of the graph. |
| 527 DCHECK_NE(0u, exit_controls_.size()); | 560 DCHECK_NE(0u, exit_controls_.size()); |
| 528 int const input_count = static_cast<int>(exit_controls_.size()); | 561 int const input_count = static_cast<int>(exit_controls_.size()); |
| 529 Node** const inputs = &exit_controls_.front(); | 562 Node** const inputs = &exit_controls_.front(); |
| 530 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); | 563 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); |
| 531 graph()->SetEnd(end); | 564 graph()->SetEnd(end); |
| 532 | 565 |
| 533 return true; | 566 return true; |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1386 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); | 1419 BuildJumpIfEqual(jsgraph()->UndefinedConstant()); |
| 1387 } | 1420 } |
| 1388 | 1421 |
| 1389 void BytecodeGraphBuilder::VisitStackCheck() { | 1422 void BytecodeGraphBuilder::VisitStackCheck() { |
| 1390 FrameStateBeforeAndAfter states(this); | 1423 FrameStateBeforeAndAfter states(this); |
| 1391 Node* node = NewNode(javascript()->StackCheck()); | 1424 Node* node = NewNode(javascript()->StackCheck()); |
| 1392 environment()->RecordAfterState(node, &states); | 1425 environment()->RecordAfterState(node, &states); |
| 1393 } | 1426 } |
| 1394 | 1427 |
| 1395 void BytecodeGraphBuilder::VisitOsrPoll() { | 1428 void BytecodeGraphBuilder::VisitOsrPoll() { |
| 1396 // TODO(4764): Implement OSR graph construction. Not marked UNIMPLEMENTED to | 1429 // TODO(4764): This should be moved into the {VisitBytecodes} once we merge |
| 1397 // ensure the --ignition-osr flag can already be fuzzed without crashing. | 1430 // the polling with existing bytecode. This will also guarantee that we are |
| 1431 // not missing the OSR entry point, which we wouldn't catch right now. | |
| 1432 if (osr_ast_id_.ToInt() == bytecode_iterator().current_offset()) { | |
| 1433 environment()->PrepareForOsr(); | |
| 1434 } | |
| 1398 } | 1435 } |
| 1399 | 1436 |
| 1400 void BytecodeGraphBuilder::VisitReturn() { | 1437 void BytecodeGraphBuilder::VisitReturn() { |
| 1401 Node* control = | 1438 Node* control = |
| 1402 NewNode(common()->Return(), environment()->LookupAccumulator()); | 1439 NewNode(common()->Return(), environment()->LookupAccumulator()); |
| 1403 MergeControlToLeaveFunction(control); | 1440 MergeControlToLeaveFunction(control); |
| 1404 } | 1441 } |
| 1405 | 1442 |
| 1406 void BytecodeGraphBuilder::VisitDebugger() { | 1443 void BytecodeGraphBuilder::VisitDebugger() { |
| 1407 FrameStateBeforeAndAfter states(this); | 1444 FrameStateBeforeAndAfter states(this); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1792 // Phi does not exist yet, introduce one. | 1829 // Phi does not exist yet, introduce one. |
| 1793 value = NewPhi(inputs, value, control); | 1830 value = NewPhi(inputs, value, control); |
| 1794 value->ReplaceInput(inputs - 1, other); | 1831 value->ReplaceInput(inputs - 1, other); |
| 1795 } | 1832 } |
| 1796 return value; | 1833 return value; |
| 1797 } | 1834 } |
| 1798 | 1835 |
| 1799 } // namespace compiler | 1836 } // namespace compiler |
| 1800 } // namespace internal | 1837 } // namespace internal |
| 1801 } // namespace v8 | 1838 } // namespace v8 |
| OLD | NEW |