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:
verwaest 2016-07-18 06:53:58 -07:00 committed by Commit bot
parent 9f640c93f4
commit c908f4b8df
4 changed files with 43 additions and 20 deletions

View File

@ -178,7 +178,8 @@ VariableProxy::VariableProxy(Zone* zone, Variable* var, int start_position,
IsAssignedField::encode(false) |
IsResolvedField::encode(false)),
end_position_(end_position),
raw_name_(var->raw_name()) {
raw_name_(var->raw_name()),
next_unresolved_(nullptr) {
BindTo(var);
}
@ -190,7 +191,8 @@ VariableProxy::VariableProxy(Zone* zone, const AstRawString* name,
IsAssignedField::encode(false) |
IsResolvedField::encode(false)),
end_position_(end_position),
raw_name_(name) {}
raw_name_(name),
next_unresolved_(nullptr) {}
void VariableProxy::BindTo(Variable* var) {
DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());

View File

@ -1665,6 +1665,8 @@ class VariableProxy final : public Expression {
static int num_ids() { return parent_num_ids() + 1; }
BailoutId BeforeId() const { return BailoutId(local_id(0)); }
void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
VariableProxy* next_unresolved() { return next_unresolved_; }
protected:
VariableProxy(Zone* zone, Variable* var, int start_position,
@ -1693,6 +1695,7 @@ class VariableProxy final : public Expression {
const AstRawString* raw_name_; // if !is_resolved_
Variable* var_; // if is_resolved_
};
VariableProxy* next_unresolved_;
};

View File

@ -88,7 +88,7 @@ Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
variables_(zone),
temps_(4, zone),
params_(4, zone),
unresolved_(16, zone),
unresolved_(nullptr),
decls_(4, zone),
module_descriptor_(scope_type == MODULE_SCOPE ? new (zone)
ModuleDescriptor(zone)
@ -109,7 +109,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope, ScopeType scope_type,
variables_(zone),
temps_(4, zone),
params_(4, zone),
unresolved_(16, zone),
unresolved_(nullptr),
decls_(4, zone),
module_descriptor_(NULL),
sloppy_block_function_map_(zone),
@ -133,7 +133,7 @@ Scope::Scope(Zone* zone, Scope* inner_scope,
variables_(zone),
temps_(0, zone),
params_(0, zone),
unresolved_(0, zone),
unresolved_(nullptr),
decls_(0, zone),
module_descriptor_(NULL),
sloppy_block_function_map_(zone),
@ -353,8 +353,15 @@ Scope* Scope::FinalizeBlockScope() {
}
// Move unresolved variables
for (int i = 0; i < unresolved_.length(); i++) {
outer_scope()->unresolved_.Add(unresolved_[i], zone());
VariableProxy* unresolved = unresolved_;
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_);
@ -529,13 +536,20 @@ Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
bool Scope::RemoveUnresolved(VariableProxy* var) {
// Most likely (always?) any variable we want to remove
// was just added before, so we search backwards.
for (int i = unresolved_.length(); i-- > 0;) {
if (unresolved_[i] == var) {
unresolved_.Remove(i);
if (unresolved_ == var) {
unresolved_ = var->next_unresolved();
var->set_next_unresolved(nullptr);
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;
}
@ -822,8 +836,8 @@ Handle<StringSet> Scope::CollectNonLocals(Handle<StringSet> non_locals) {
// Collect non-local variables referenced in the scope.
// TODO(yangguo): store non-local variables explicitly if we can no longer
// rely on unresolved_ to find them.
for (int i = 0; i < unresolved_.length(); i++) {
VariableProxy* proxy = unresolved_[i];
for (VariableProxy* proxy = unresolved_; proxy != nullptr;
proxy = proxy->next_unresolved()) {
if (proxy->is_resolved() && proxy->var()->IsStackAllocated()) continue;
Handle<String> name = proxy->name();
non_locals = StringSet::Add(non_locals, name);
@ -1218,8 +1232,9 @@ bool Scope::ResolveVariablesRecursively(ParseInfo* info,
DCHECK(info->script_scope()->is_script_scope());
// Resolve unresolved variables for this scope.
for (int i = 0; i < unresolved_.length(); i++) {
if (!ResolveVariable(info, unresolved_[i], factory)) return false;
for (VariableProxy* proxy = unresolved_; proxy != nullptr;
proxy = proxy->next_unresolved()) {
if (!ResolveVariable(info, proxy, factory)) return false;
}
// Resolve unresolved variables for inner scopes.

View File

@ -183,14 +183,16 @@ class Scope: public ZoneObject {
DCHECK(!already_resolved());
VariableProxy* proxy =
factory->NewVariableProxy(name, kind, start_position, end_position);
unresolved_.Add(proxy, zone_);
proxy->set_next_unresolved(unresolved_);
unresolved_ = proxy;
return proxy;
}
void AddUnresolved(VariableProxy* proxy) {
DCHECK(!already_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
@ -629,8 +631,9 @@ class Scope: public ZoneObject {
ZoneList<Variable*> params_;
// Variables that must be looked up dynamically.
DynamicScopePart* dynamics_;
// Unresolved variables referred to from this scope.
ZoneList<VariableProxy*> unresolved_;
// Unresolved variables referred to from this scope. The proxies themselves
// form a linked list of all unresolved proxies.
VariableProxy* unresolved_;
// Declarations.
ZoneList<Declaration*> decls_;
// Convenience variable.