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 |