Commit ea185392 authored by keuchel@chromium.org's avatar keuchel@chromium.org

Tune context allocation for variables accessed from inner scopes.

After introduction of with scopes we have enough static information to omit
context allocation in the case that a variable is accessed from a nested block
or catch scope of the same function. Only variables accessed from the inside of
a nested function or with scope are forced to be allocated in the context.

This essentially reverts
http://code.google.com/p/v8/source/detail?r=9281 .
which in turn reverted an earlier change.

Review URL: http://codereview.chromium.org/8431001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9872 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 79cadcc9
......@@ -704,9 +704,9 @@ static void PrintVar(int indent, Variable* var) {
PrintName(var->name());
PrintF("; // ");
PrintLocation(var);
if (var->is_accessed_from_inner_scope()) {
if (var->has_forced_context_allocation()) {
if (!var->IsUnallocated()) PrintF(", ");
PrintF("inner scope access");
PrintF("forced context allocation");
}
PrintF("\n");
}
......@@ -852,7 +852,9 @@ Variable* Scope::LookupRecursive(Handle<String> name,
*binding_kind = BOUND;
} else if (outer_scope_ != NULL) {
var = outer_scope_->LookupRecursive(name, context, binding_kind);
if (*binding_kind == BOUND) var->MarkAsAccessedFromInnerScope();
if (*binding_kind == BOUND && (is_function_scope() || is_with_scope())) {
var->ForceContextAllocation();
}
}
if (is_with_scope()) {
......@@ -984,7 +986,7 @@ bool Scope::MustAllocate(Variable* var) {
// via an eval() call. This is only possible if the variable has a
// visible name.
if ((var->is_this() || var->name()->length() > 0) &&
(var->is_accessed_from_inner_scope() ||
(var->has_forced_context_allocation() ||
scope_calls_eval_ ||
inner_scope_calls_eval_ ||
scope_contains_with_ ||
......@@ -1007,7 +1009,7 @@ bool Scope::MustAllocateInContext(Variable* var) {
// catch-bound variables are always allocated in a context.
if (var->mode() == TEMPORARY) return false;
if (is_catch_scope() || is_block_scope()) return true;
return var->is_accessed_from_inner_scope() ||
return var->has_forced_context_allocation() ||
scope_calls_eval_ ||
inner_scope_calls_eval_ ||
scope_contains_with_ ||
......@@ -1071,9 +1073,8 @@ void Scope::AllocateParameterLocals() {
Variable* var = params_[i];
ASSERT(var->scope() == this);
if (uses_nonstrict_arguments) {
// Give the parameter a use from an inner scope, to force allocation
// to the context.
var->MarkAsAccessedFromInnerScope();
// Force context allocation of the parameter.
var->ForceContextAllocation();
}
if (MustAllocate(var)) {
......
......@@ -69,7 +69,7 @@ Variable::Variable(Scope* scope,
initializer_position_(RelocInfo::kNoPosition),
local_if_not_shadowed_(NULL),
is_valid_LHS_(is_valid_LHS),
is_accessed_from_inner_scope_(false),
force_context_allocation_(false),
is_used_(false),
initialization_flag_(initialization_flag) {
// Names must be canonicalized for fast equality checks.
......
......@@ -93,12 +93,12 @@ class Variable: public ZoneObject {
Handle<String> name() const { return name_; }
VariableMode mode() const { return mode_; }
bool is_accessed_from_inner_scope() const {
return is_accessed_from_inner_scope_;
bool has_forced_context_allocation() const {
return force_context_allocation_;
}
void MarkAsAccessedFromInnerScope() {
void ForceContextAllocation() {
ASSERT(mode_ != TEMPORARY);
is_accessed_from_inner_scope_ = true;
force_context_allocation_ = true;
}
bool is_used() { return is_used_; }
void set_is_used(bool flag) { is_used_ = flag; }
......@@ -178,7 +178,7 @@ class Variable: public ZoneObject {
bool is_valid_LHS_;
// Usage info.
bool is_accessed_from_inner_scope_; // set by variable resolver
bool force_context_allocation_; // set by variable resolver
bool is_used_;
InitializationFlag initialization_flag_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment