Overview
Setup
Patch
diff --git a/src/compiler/escape-analysis.cc b/src/compiler/escape-analysis.cc
index 2a096b6933..3046d7b04e 100644
--- a/src/compiler/escape-analysis.cc
+++ b/src/compiler/escape-analysis.cc
@@ -178,7 +178,7 @@ class EscapeAnalysisTracker : public ZoneObject {
: VariableTracker::Scope(&tracker->variable_states_, node, reduction),
tracker_(tracker),
reducer_(reducer) {}
- const VirtualObject* GetVirtualObject(Node* node) {
+ VirtualObject* GetVirtualObject(Node* node) {
VirtualObject* vobject = tracker_->virtual_objects_.Get(node);
if (vobject) vobject->AddDependency(current_node());
return vobject;
@@ -576,10 +576,14 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current,
case IrOpcode::kStoreField: {
Node* object = current->ValueInput(0);
Node* value = current->ValueInput(1);
- const VirtualObject* vobject = current->GetVirtualObject(object);
+ VirtualObject* vobject = current->GetVirtualObject(object);
Variable var;
if (vobject && !vobject->HasEscaped() &&
vobject->FieldAt(OffsetOfFieldAccess(op)).To(&var)) {
+ // Attach cached map info to the virtual object.
+ if (OffsetOfFieldAccess(op) == HeapObject::kMapOffset) {
+ vobject->SetMap(value);
+ }
current->Set(var, value);
current->MarkForDeletion();
} else {
@@ -747,6 +751,17 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current,
// yet.
break;
}
+ } else if (vobject) {
+ Node* cache_map = vobject->Map();
+ if (cache_map) {
+ Type const map_type = NodeProperties::GetType(cache_map);
+ if (map_type.IsHeapConstant() &&
+ params.maps().contains(
+ map_type.AsHeapConstant()->Ref().AsMap().object())) {
+ current->MarkForDeletion();
+ break;
+ }
+ }
}
current->SetEscaped(checked);
break;
@@ -804,6 +819,12 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current,
for (int i = 0; i < value_input_count; ++i) {
Node* input = current->ValueInput(i);
current->SetEscaped(input);
+
+ // Invalidate associated map cache for all value input nodes.
+ VirtualObject* vobject = current->GetVirtualObject(input);
+ if (vobject) {
+ vobject->SetMap(nullptr);
+ }
}
if (OperatorProperties::HasContextInput(op)) {
current->SetEscaped(current->ContextInput());
diff --git a/src/compiler/escape-analysis.h b/src/compiler/escape-analysis.h
index 0fbc7d0bdd..ec56488388 100644
--- a/src/compiler/escape-analysis.h
+++ b/src/compiler/escape-analysis.h
@@ -147,11 +147,14 @@ class VirtualObject : public Dependable {
bool HasEscaped() const { return escaped_; }
const_iterator begin() const { return fields_.begin(); }
const_iterator end() const { return fields_.end(); }
+ Node* Map() const { return map_; }
+ void SetMap(Node* map) { map_ = map; }
private:
bool escaped_ = false;
Id id_;
ZoneVector<Variable> fields_;
+ Node* map_;
};
class EscapeAnalysisResult {