Turn the unresolved-references list into a linked list using the VariableProxies themselves
This is a first step towards reducing memory usage by scopes in the parser. Peak zone memory usage on octane-codeload goes down by ~10% BUG= Review-Url: https://codereview.chromium.org/2159573002 Cr-Commit-Position: refs/heads/master@{#37840}
This commit is contained in:
parent
9f640c93f4
commit
c908f4b8df
@ -178,7 +178,8 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position,
|
|||||||
IsAssignedField::encode(false) |
|
IsAssignedField::encode(false) |
|
||||||
IsResolvedField::encode(false)),
|
IsResolvedField::encode(false)),
|
||||||
end_position_(end_position),
|
end_position_(end_position),
|
||||||
raw_name_(var->raw_name()) {
|
raw_name_(var->raw_name()),
|
||||||
|
next_unresolved_(nullptr) {
|
||||||
BindTo(var);
|
BindTo(var);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +191,8 @@ VariableProxy::VariableProxy(Zone* zone, const AstRawString* name,
|
|||||||
IsAssignedField::encode(false) |
|
IsAssignedField::encode(false) |
|
||||||
IsResolvedField::encode(false)),
|
IsResolvedField::encode(false)),
|
||||||
end_position_(end_position),
|
end_position_(end_position),
|
||||||
raw_name_(name) {}
|
raw_name_(name),
|
||||||
|
next_unresolved_(nullptr) {}
|
||||||
|
|
||||||
void VariableProxy::BindTo(Variable* var) {
|
void VariableProxy::BindTo(Variable* var) {
|
||||||
DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
|
DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
|
||||||
|
@ -1665,6 +1665,8 @@ class VariableProxy final : public Expression {
|
|||||||
|
|
||||||
static int num_ids() { return parent_num_ids() + 1; }
|
static int num_ids() { return parent_num_ids() + 1; }
|
||||||
BailoutId BeforeId() const { return BailoutId(local_id(0)); }
|
BailoutId BeforeId() const { return BailoutId(local_id(0)); }
|
||||||
|
void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
|
||||||
|
VariableProxy* next_unresolved() { return next_unresolved_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VariableProxy(Zone* zone, Variable* var, int start_position,
|
VariableProxy(Zone* zone, Variable* var, int start_position,
|
||||||
@ -1693,6 +1695,7 @@ class VariableProxy final : public Expression {
|
|||||||
const AstRawString* raw_name_; // if !is_resolved_
|
const AstRawString* raw_name_; // if !is_resolved_
|
||||||
Variable* var_; // if is_resolved_
|
Variable* var_; // if is_resolved_
|
||||||
};
|
};
|
||||||
|
VariableProxy* next_unresolved_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
|
|||||||
variables_(zone),
|
variables_(zone),
|
||||||
temps_(4, zone),
|
temps_(4, zone),
|
||||||
params_(4, zone),
|
params_(4, zone),
|
||||||
unresolved_(16, zone),
|
unresolved_(nullptr),
|
||||||
decls_(4, zone),
|
decls_(4, zone),
|
||||||
module_descriptor_(scope_type == MODULE_SCOPE ? new (zone)
|
module_descriptor_(scope_type == MODULE_SCOPE ? new (zone)
|
||||||
ModuleDescriptor(zone)
|
ModuleDescriptor(zone)
|
||||||
@ -109,7 +109,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
|
|||||||
variables_(zone),
|
variables_(zone),
|
||||||
temps_(4, zone),
|
temps_(4, zone),
|
||||||
params_(4, zone),
|
params_(4, zone),
|
||||||
unresolved_(16, zone),
|
unresolved_(nullptr),
|
||||||
decls_(4, zone),
|
decls_(4, zone),
|
||||||
module_descriptor_(NULL),
|
module_descriptor_(NULL),
|
||||||
sloppy_block_function_map_(zone),
|
sloppy_block_function_map_(zone),
|
||||||
@ -133,7 +133,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope,
|
|||||||
variables_(zone),
|
variables_(zone),
|
||||||
temps_(0, zone),
|
temps_(0, zone),
|
||||||
params_(0, zone),
|
params_(0, zone),
|
||||||
unresolved_(0, zone),
|
unresolved_(nullptr),
|
||||||
decls_(0, zone),
|
decls_(0, zone),
|
||||||
module_descriptor_(NULL),
|
module_descriptor_(NULL),
|
||||||
sloppy_block_function_map_(zone),
|
sloppy_block_function_map_(zone),
|
||||||
@ -353,8 +353,15 @@ Scope* Scope::FinalizeBlockScope() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move unresolved variables
|
// Move unresolved variables
|
||||||
for (int i = 0; i < unresolved_.length(); i++) {
|
VariableProxy* unresolved = unresolved_;
|
||||||
outer_scope()->unresolved_.Add(unresolved_[i], zone());
|
if (outer_scope()->unresolved_ == nullptr) {
|
||||||
|
outer_scope()->unresolved_ = unresolved;
|
||||||
|
} else if (unresolved != nullptr) {
|
||||||
|
while (unresolved->next_unresolved() != nullptr) {
|
||||||
|
unresolved = unresolved->next_unresolved();
|
||||||
|
}
|
||||||
|
unresolved->set_next_unresolved(outer_scope()->unresolved_);
|
||||||
|
outer_scope()->unresolved_ = unresolved_;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropagateUsageFlagsToScope(outer_scope_);
|
PropagateUsageFlagsToScope(outer_scope_);
|
||||||
@ -529,13 +536,20 @@ Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
|
|||||||
|
|
||||||
|
|
||||||
bool Scope::RemoveUnresolved(VariableProxy* var) {
|
bool Scope::RemoveUnresolved(VariableProxy* var) {
|
||||||
// Most likely (always?) any variable we want to remove
|
if (unresolved_ == var) {
|
||||||
// was just added before, so we search backwards.
|
unresolved_ = var->next_unresolved();
|
||||||
for (int i = unresolved_.length(); i-- > 0;) {
|
var->set_next_unresolved(nullptr);
|
||||||
if (unresolved_[i] == var) {
|
|
||||||
unresolved_.Remove(i);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
VariableProxy* current = unresolved_;
|
||||||
|
while (current != nullptr) {
|
||||||
|
VariableProxy* next = current->next_unresolved();
|
||||||
|
if (var == next) {
|
||||||
|
current->set_next_unresolved(next->next_unresolved());
|
||||||
|
var->set_next_unresolved(nullptr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
current = next;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -822,8 +836,8 @@ Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) {
|
|||||||
// Collect non-local variables referenced in the scope.
|
// Collect non-local variables referenced in the scope.
|
||||||
// TODO(yangguo): store non-local variables explicitly if we can no longer
|
// TODO(yangguo): store non-local variables explicitly if we can no longer
|
||||||
// rely on unresolved_ to find them.
|
// rely on unresolved_ to find them.
|
||||||
for (int i = 0; i < unresolved_.length(); i++) {
|
for (VariableProxy* proxy = unresolved_; proxy != nullptr;
|
||||||
VariableProxy* proxy = unresolved_[i];
|
proxy = proxy->next_unresolved()) {
|
||||||
if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue;
|
if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue;
|
||||||
Handle<String> name = proxy->name();
|
Handle<String> name = proxy->name();
|
||||||
non_locals = StringSet::Add(non_locals, name);
|
non_locals = StringSet::Add(non_locals, name);
|
||||||
@ -1218,8 +1232,9 @@ bool Scope::ResolveVariablesRecursively(ParseInfo* info,
|
|||||||
DCHECK(info->script_scope()->is_script_scope());
|
DCHECK(info->script_scope()->is_script_scope());
|
||||||
|
|
||||||
// Resolve unresolved variables for this scope.
|
// Resolve unresolved variables for this scope.
|
||||||
for (int i = 0; i < unresolved_.length(); i++) {
|
for (VariableProxy* proxy = unresolved_; proxy != nullptr;
|
||||||
if (!ResolveVariable(info, unresolved_[i], factory)) return false;
|
proxy = proxy->next_unresolved()) {
|
||||||
|
if (!ResolveVariable(info, proxy, factory)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve unresolved variables for inner scopes.
|
// Resolve unresolved variables for inner scopes.
|
||||||
|
@ -183,14 +183,16 @@ class Scope: public ZoneObject {
|
|||||||
DCHECK(!already_resolved());
|
DCHECK(!already_resolved());
|
||||||
VariableProxy* proxy =
|
VariableProxy* proxy =
|
||||||
factory->NewVariableProxy(name, kind, start_position, end_position);
|
factory->NewVariableProxy(name, kind, start_position, end_position);
|
||||||
unresolved_.Add(proxy, zone_);
|
proxy->set_next_unresolved(unresolved_);
|
||||||
|
unresolved_ = proxy;
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddUnresolved(VariableProxy* proxy) {
|
void AddUnresolved(VariableProxy* proxy) {
|
||||||
DCHECK(!already_resolved());
|
DCHECK(!already_resolved());
|
||||||
DCHECK(!proxy->is_resolved());
|
DCHECK(!proxy->is_resolved());
|
||||||
unresolved_.Add(proxy, zone_);
|
proxy->set_next_unresolved(unresolved_);
|
||||||
|
unresolved_ = proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a unresolved variable. During parsing, an unresolved variable
|
// Remove a unresolved variable. During parsing, an unresolved variable
|
||||||
@ -629,8 +631,9 @@ class Scope: public ZoneObject {
|
|||||||
ZoneList<Variable*> params_;
|
ZoneList<Variable*> params_;
|
||||||
// Variables that must be looked up dynamically.
|
// Variables that must be looked up dynamically.
|
||||||
DynamicScopePart* dynamics_;
|
DynamicScopePart* dynamics_;
|
||||||
// Unresolved variables referred to from this scope.
|
// Unresolved variables referred to from this scope. The proxies themselves
|
||||||
ZoneList<VariableProxy*> unresolved_;
|
// form a linked list of all unresolved proxies.
|
||||||
|
VariableProxy* unresolved_;
|
||||||
// Declarations.
|
// Declarations.
|
||||||
ZoneList<Declaration*> decls_;
|
ZoneList<Declaration*> decls_;
|
||||||
// Convenience variable.
|
// Convenience variable.
|
||||||
|
Loading…
Reference in New Issue
Block a user