Index: src/compiler/escape-analysis.cc |
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc |
index 9372e620248fbee46e34093c835b6bdcea8a1ad8..b5cad6b93219ea1c11d015c7f143171f10ab63e7 100644 |
--- a/src/compiler/escape-analysis.cc |
+++ b/src/compiler/escape-analysis.cc |
@@ -687,7 +687,16 @@ void EscapeStatusAnalysis::Process(Node* node) { |
RevisitInputs(rep); |
RevisitUses(rep); |
} |
+ } else { |
+ Node* from = NodeProperties::GetValueInput(node, 0); |
+ if (SetEscaped(from)) { |
+ TRACE("Setting #%d (%s) to escaped because of unresolved load #%i\n", |
+ from->id(), from->op()->mnemonic(), node->id()); |
+ RevisitInputs(from); |
+ RevisitUses(from); |
+ } |
} |
+ |
RevisitUses(node); |
break; |
} |
@@ -791,6 +800,7 @@ bool EscapeStatusAnalysis::CheckUsesForEscape(Node* uses, Node* rep, |
case IrOpcode::kStateValues: |
case IrOpcode::kReferenceEqual: |
case IrOpcode::kFinishRegion: |
+ case IrOpcode::kCheckMaps: |
if (IsEscaped(use) && SetEscaped(rep)) { |
TRACE( |
"Setting #%d (%s) to escaped because of use by escaping node " |
@@ -891,7 +901,7 @@ EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, |
EscapeAnalysis::~EscapeAnalysis() {} |
-void EscapeAnalysis::Run() { |
+bool EscapeAnalysis::Run() { |
replacements_.resize(graph()->NodeCount()); |
status_analysis_->AssignAliases(); |
if (status_analysis_->AliasCount() > 0) { |
@@ -900,6 +910,9 @@ void EscapeAnalysis::Run() { |
status_analysis_->ResizeStatusVector(); |
RunObjectAnalysis(); |
status_analysis_->RunStatusAnalysis(); |
+ return true; |
+ } else { |
+ return false; |
} |
} |
@@ -1105,6 +1118,9 @@ bool EscapeAnalysis::Process(Node* node) { |
case IrOpcode::kLoadElement: |
ProcessLoadElement(node); |
break; |
+ case IrOpcode::kCheckMaps: |
+ ProcessCheckMaps(node); |
+ break; |
case IrOpcode::kStart: |
ProcessStart(node); |
break; |
@@ -1142,6 +1158,10 @@ void EscapeAnalysis::ProcessAllocationUsers(Node* node) { |
case IrOpcode::kFinishRegion: |
case IrOpcode::kObjectIsSmi: |
break; |
+ case IrOpcode::kCheckMaps: { |
+ CheckMapsParameters params = CheckMapsParametersOf(node->op()); |
+ if (params.flags() == CheckMapsFlag::kNone) break; |
+ } // Fallthrough. |
default: |
VirtualState* state = virtual_states_[node->id()]; |
if (VirtualObject* obj = |
@@ -1495,6 +1515,39 @@ void EscapeAnalysis::ProcessLoadField(Node* node) { |
} |
} |
+void EscapeAnalysis::ProcessCheckMaps(Node* node) { |
+ DCHECK_EQ(node->opcode(), IrOpcode::kCheckMaps); |
+ ForwardVirtualState(node); |
+ Node* checked = ResolveReplacement(NodeProperties::GetValueInput(node, 0)); |
+ VirtualState* state = virtual_states_[node->id()]; |
+ if (VirtualObject* object = GetVirtualObject(state, checked)) { |
+ if (!object->IsTracked()) { |
+ if (status_analysis_->SetEscaped(node)) { |
+ TRACE( |
+ "Setting #%d (%s) to escaped because checked object #%i is not " |
+ "tracked\n", |
+ node->id(), node->op()->mnemonic(), object->id()); |
+ } |
+ return; |
+ } |
+ CheckMapsParameters params = CheckMapsParametersOf(node->op()); |
+ |
+ Node* value = object->GetField(HeapObject::kMapOffset / kPointerSize); |
+ if (value) { |
+ value = ResolveReplacement(value); |
+ if (value->opcode() == IrOpcode::kHeapConstant && |
+ params.maps().contains(ZoneHandleSet<Map>( |
+ Handle<Map>::cast(OpParameter<Handle<HeapObject>>(value))))) { |
+ return; |
Benedikt Meurer
2017/02/13 15:02:01
Please add a TRACE message here. And a to-do that
|
+ } |
+ } |
+ } |
+ if (status_analysis_->SetEscaped(node)) { |
+ TRACE("Setting #%d (%s) to escaped (checking #%i)\n", node->id(), |
+ node->op()->mnemonic(), checked->id()); |
+ } |
+} |
+ |
void EscapeAnalysis::ProcessLoadElement(Node* node) { |
DCHECK_EQ(node->opcode(), IrOpcode::kLoadElement); |
ForwardVirtualState(node); |