Chromium Code Reviews| Index: src/compiler/bytecode-graph-builder.cc |
| diff --git a/src/compiler/bytecode-graph-builder.cc b/src/compiler/bytecode-graph-builder.cc |
| index 5d9b54853a19d78bf41bfe65ab9320ba04aa97b7..4179856f8a9ea25953205965db2585e97a1baafd 100644 |
| --- a/src/compiler/bytecode-graph-builder.cc |
| +++ b/src/compiler/bytecode-graph-builder.cc |
| @@ -60,6 +60,7 @@ class BytecodeGraphBuilder::Environment : public ZoneObject { |
| Environment* CopyForConditional() const; |
| Environment* CopyForLoop(); |
| void Merge(Environment* other); |
| + void PrepareForOsr(); |
| private: |
| explicit Environment(const Environment* copy); |
| @@ -358,6 +359,33 @@ void BytecodeGraphBuilder::Environment::PrepareForLoop() { |
| builder()->exit_controls_.push_back(terminate); |
| } |
| +void BytecodeGraphBuilder::Environment::PrepareForOsr() { |
| + DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode()); |
| + Node* start = graph()->start(); |
| + |
| + // Create a control node for the OSR entry point and merge it into the loop |
| + // header. Update the current environment's control dependency accordingly. |
| + 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
|
| + Node* control = builder()->MergeControl(GetControlDependency(), entry); |
| + UpdateControlDependency(control); |
| + |
| + // Create a merge of the effect from the OSR entry and the existing effect |
| + // dependency. Update the current environment's effect dependency accordingly. |
| + Node* effect = builder()->MergeEffect(GetEffectDependency(), entry, control); |
| + UpdateEffectDependency(effect); |
| + |
| + // Rename all values in the environment which will extend or introduce Phi |
| + // nodes to contain the OSR values available at the entry point. |
| + Node* osr_context = graph()->NewNode( |
| + common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry); |
| + context_ = builder()->MergeValue(context_, osr_context, control); |
| + for (size_t i = 0; i < values_.size(); i++) { |
| + int index = |
| + static_cast<int>(i) + InterpreterFrameConstants::kExtraSlotCount; |
| + Node* osr_value = graph()->NewNode(common()->OsrValue(index), entry); |
| + values_[i] = builder()->MergeValue(values_[i], osr_value, control); |
| + } |
| +} |
| bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( |
| Node** state_values, int offset, int count) { |
| @@ -447,6 +475,7 @@ BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone, |
| FrameStateType::kInterpretedFunction, |
| bytecode_array()->parameter_count(), |
| bytecode_array()->register_count(), info->shared_info())), |
| + osr_ast_id_(info->osr_ast_id()), |
| merge_environments_(local_zone), |
| exception_handlers_(local_zone), |
| current_exception_handler_(0), |
| @@ -521,6 +550,10 @@ bool BytecodeGraphBuilder::CreateGraph() { |
| GetFunctionContext()); |
| set_environment(&env); |
| + // For OSR add an {OsrNormalEntry} as the start of the top-level environment. |
| + // It will be replaced with {Dead} after typing and optimizations. |
| + if (!osr_ast_id_.IsNone()) NewNode(common()->OsrNormalEntry()); |
| + |
| VisitBytecodes(); |
| // Finish the basic structure of the graph. |
| @@ -1393,8 +1426,12 @@ void BytecodeGraphBuilder::VisitStackCheck() { |
| } |
| void BytecodeGraphBuilder::VisitOsrPoll() { |
| - // TODO(4764): Implement OSR graph construction. Not marked UNIMPLEMENTED to |
| - // ensure the --ignition-osr flag can already be fuzzed without crashing. |
| + // TODO(4764): This should be moved into the {VisitBytecodes} once we merge |
| + // the polling with existing bytecode. This will also guarantee that we are |
| + // not missing the OSR entry point, which we wouldn't catch right now. |
| + if (osr_ast_id_.ToInt() == bytecode_iterator().current_offset()) { |
| + environment()->PrepareForOsr(); |
| + } |
| } |
| void BytecodeGraphBuilder::VisitReturn() { |