Index: src/compiler/escape-analysis-reducer.cc |
diff --git a/src/compiler/escape-analysis-reducer.cc b/src/compiler/escape-analysis-reducer.cc |
index 1f53582bae98386d9fcd89108f813b61909dcf19..cceef43f0448d2d2f7d5b600d01ecbfd598032e7 100644 |
--- a/src/compiler/escape-analysis-reducer.cc |
+++ b/src/compiler/escape-analysis-reducer.cc |
@@ -35,7 +35,7 @@ Reduction EscapeAnalysisReducer::Reduce(Node* node) { |
return ReduceReferenceEqual(node); |
case IrOpcode::kStateValues: |
case IrOpcode::kFrameState: |
- return ReplaceWithDeoptDummy(node); |
+ return ReduceStateValueInputs(node); |
default: |
break; |
} |
@@ -141,22 +141,54 @@ Reduction EscapeAnalysisReducer::ReduceReferenceEqual(Node* node) { |
} |
-// TODO(sigurds): This is a temporary solution until escape analysis |
-// supports deoptimization. |
-Reduction EscapeAnalysisReducer::ReplaceWithDeoptDummy(Node* node) { |
+void EscapeAnalysisReducer::CreateObjectState(Node* effect, Node* node) { |
+ if ((node->opcode() == IrOpcode::kFinishRegion || |
+ node->opcode() == IrOpcode::kAllocate) && |
+ escape_status()->IsVirtual(node)) { |
+ VirtualObject* vobj = |
+ escape_analysis()->GetVirtualObject(effect, node->id()); |
+ if (!vobj->GetObjectState()) { |
+ DCHECK_NOT_NULL(vobj); |
+ Node* obj_state = jsgraph()->graph()->NewNode( |
+ jsgraph()->common()->ObjectState(static_cast<int>(vobj->fields()), |
+ vobj->id()), |
+ static_cast<int>(vobj->fields()), vobj->fields_array()); |
+ vobj->SetObjectState(obj_state); |
+ // Now fix uses of other objects. |
+ for (size_t i = 0; i < vobj->fields(); ++i) { |
+ if (Node* field = vobj->GetField(i)) { |
+ CreateObjectState(effect, field); |
+ VirtualObject* vobj = |
+ escape_analysis()->GetVirtualObject(effect, field->id()); |
+ if (vobj && vobj->GetObjectState()) { |
+ NodeProperties::ReplaceValueInput(obj_state, vobj->GetObjectState(), |
+ static_cast<int>(i)); |
+ } |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+ |
+Reduction EscapeAnalysisReducer::ReduceStateValueInputs(Node* node) { |
DCHECK(node->opcode() == IrOpcode::kStateValues || |
node->opcode() == IrOpcode::kFrameState); |
+ Node* effect = escape_analysis()->GetEffect(node); |
+ DCHECK_NOT_NULL(effect); |
Reduction r = NoChange(); |
for (int i = 0; i < node->op()->ValueInputCount(); ++i) { |
Node* input = NodeProperties::GetValueInput(node, i); |
if (input->opcode() == IrOpcode::kFinishRegion || |
- input->opcode() == IrOpcode::kAllocate || |
- input->opcode() == IrOpcode::kPhi) { |
+ input->opcode() == IrOpcode::kAllocate) { |
if (escape_status()->IsVirtual(input)) { |
- NodeProperties::ReplaceValueInput(node, jsgraph()->UndefinedConstant(), |
- i); |
+ CreateObjectState(effect, input); |
Jarin
2015/12/02 12:24:34
Nit: could not you return the ObjectState from Cre
sigurds
2015/12/02 16:35:12
Done.
|
+ VirtualObject* vobj = |
+ escape_analysis()->GetVirtualObject(effect, input->id()); |
+ NodeProperties::ReplaceValueInput(node, vobj->GetObjectState(), i); |
if (FLAG_trace_turbo_escape) { |
- PrintF("Replaced state value (#%d) input with dummy\n", node->id()); |
+ PrintF("Replaced state value (#%d) input with object state #%d\n", |
+ node->id(), vobj->GetObjectState()->id()); |
} |
r = Changed(node); |
} |
@@ -165,7 +197,6 @@ Reduction EscapeAnalysisReducer::ReplaceWithDeoptDummy(Node* node) { |
return r; |
} |
- |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |