Chromium Code Reviews| 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); |