Tune context allocation for variables accessed from inner scopes.
authorkeuchel@chromium.org <keuchel@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Nov 2011 14:33:46 +0000 (14:33 +0000)
committerkeuchel@chromium.org <keuchel@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Nov 2011 14:33:46 +0000 (14:33 +0000)
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

src/scopes.cc
src/variables.cc
src/variables.h

index 464ea42206880f8b2ff5d6315211a5318c6c79f8..6ace292590203a8faeebac7c69ecb86dc59ed2b6 100644 (file)
@@ -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)) {
index faa95ed595a7f8e2f0df2a1486e5f5055ada6579..a0952a1f205524451045b3be4f257f05ca376dd6 100644 (file)
@@ -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.
index 4273a59c1a7b7a8930959bfba732b9ef8edd03ca..15788fb091fd32e5d7dc31d916ab84803be1435c 100644 (file)
@@ -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_;
 };