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) |
|
||||
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());
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user