Author: [email protected]
Date: Wed May 13 09:27:40 2009
New Revision: 1937

Modified:
    branches/bleeding_edge/src/scopes.cc
    branches/bleeding_edge/src/scopes.h

Log:
Avoid linear search for non-locals in the scope code
when resolving variables inside with and eval scopes.
Review URL: http://codereview.chromium.org/114024

Modified: branches/bleeding_edge/src/scopes.cc
==============================================================================
--- branches/bleeding_edge/src/scopes.cc        (original)
+++ branches/bleeding_edge/src/scopes.cc        Wed May 13 09:27:40 2009
@@ -112,7 +112,9 @@
      locals_(false),
      temps_(0),
      params_(0),
-    nonlocals_(0),
+    dynamics_(false),
+    dynamics_local_(false),
+    dynamics_global_(false),
      unresolved_(0),
      decls_(0) {
  }
@@ -126,7 +128,6 @@
      locals_(),
      temps_(4),
      params_(4),
-    nonlocals_(4),
      unresolved_(16),
      decls_(4),
      receiver_(NULL),
@@ -405,6 +406,14 @@
  }


+static void PrintMap(PrettyPrinter* printer, int indent, LocalsMap* map) {
+  for (LocalsMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
+    Variable* var = reinterpret_cast<Variable*>(p->value);
+    PrintVar(printer, indent, var);
+  }
+}
+
+
  void Scope::Print(int n) {
    int n0 = (n > 0 ? n : 0);
    int n1 = n0 + 2;  // indentation
@@ -465,14 +474,12 @@
    }

    Indent(n1, "// local vars\n");
-  for (LocalsMap::Entry* p = locals_.Start(); p != NULL; p =  
locals_.Next(p)) {
-    Variable* var = reinterpret_cast<Variable*>(p->value);
-    PrintVar(&printer, n1, var);
-  }
+  PrintMap(&printer, n1, &locals_);

-  Indent(n1, "// nonlocal vars\n");
-  for (int i = 0; i < nonlocals_.length(); i++)
-    PrintVar(&printer, n1, nonlocals_[i]);
+  Indent(n1, "// dynamic vars\n");
+  PrintMap(&printer, n1, &dynamics_);
+  PrintMap(&printer, n1, &dynamics_local_);
+  PrintMap(&printer, n1, &dynamics_global_);

    // Print inner scopes (disable by providing negative n).
    if (n >= 0) {
@@ -490,20 +497,28 @@
  Variable* Scope::NonLocal(Handle<String> name, Variable::Mode mode) {
    // Space optimization: reuse existing non-local with the same name
    // and mode.
-  for (int i = 0; i < nonlocals_.length(); i++) {
-    Variable* var = nonlocals_[i];
-    if (var->name().is_identical_to(name) && var->mode() == mode) {
-      return var;
-    }
+  LocalsMap* map = NULL;
+  switch (mode) {
+    case Variable::DYNAMIC:
+      map = &dynamics_;
+      break;
+    case Variable::DYNAMIC_LOCAL:
+      map = &dynamics_local_;
+      break;
+    case Variable::DYNAMIC_GLOBAL:
+      map = &dynamics_global_;
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  Variable* var = map->Lookup(name);
+  if (var == NULL) {
+    // Declare a new non-local.
+    var = map->Declare(NULL, name, mode, true, false);
+    // Allocate it by giving it a dynamic lookup.
+    var->rewrite_ = new Slot(var, Slot::LOOKUP, -1);
    }
-
-  // Otherwise create a new non-local and add it to the list.
-  Variable* var = new Variable(NULL, name, mode, true, false);
-  nonlocals_.Add(var);
-
-  // Allocate it by giving it a dynamic lookup.
-  var->rewrite_ = new Slot(var, Slot::LOOKUP, -1);
-
    return var;
  }

@@ -617,14 +632,6 @@
          ASSERT(global_scope != NULL);
          var = new Variable(global_scope, proxy->name(),
                             Variable::DYNAMIC, true, false);
-        // Ideally we simply rewrite these variables into property
-        // accesses. Unfortunately, we cannot do this here at the
-        // moment because then we can't differentiate between
-        // global variable ('x') and global property ('this.x') access.
-        // If 'x' doesn't exist, the former leads to an error, while the
-        // latter returns undefined. Sigh...
-        // var->rewrite_ = new Property(new Literal(env_->global()),
-        //                              new Literal(proxy->name()));

        } else if (scope_inside_with_) {
          // If we are inside a with statement we give up and look up

Modified: branches/bleeding_edge/src/scopes.h
==============================================================================
--- branches/bleeding_edge/src/scopes.h (original)
+++ branches/bleeding_edge/src/scopes.h Wed May 13 09:27:40 2009
@@ -278,7 +278,9 @@
    // parameter list in source order
    ZoneList<Variable*> params_;
    // variables that must be looked up dynamically
-  ZoneList<Variable*> nonlocals_;
+  LocalsMap dynamics_;
+  LocalsMap dynamics_local_;
+  LocalsMap dynamics_global_;
    // unresolved variables referred to from this scope
    ZoneList<VariableProxy*> unresolved_;
    // declarations

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to