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 |