Clean up Scope::CollectUsedVariables.
authorkeuchel@chromium.org <keuchel@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Nov 2011 14:50:19 +0000 (14:50 +0000)
committerkeuchel@chromium.org <keuchel@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Nov 2011 14:50:19 +0000 (14:50 +0000)
Review URL: http://codereview.chromium.org/8438071

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9874 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/liveedit.cc
src/scopeinfo.cc
src/scopes.cc
src/scopes.h
src/variables.cc
src/variables.h

index ce903d1f781cb4e7d52b09fb51f5fe495955e51e..9b77be17a7a33a18a1e85cd3aa6609fb30b3e84b 100644 (file)
@@ -855,38 +855,20 @@ class FunctionInfoListener {
       return HEAP->undefined_value();
     }
     do {
-      ZoneList<Variable*> list(10);
-      outer_scope->CollectUsedVariables(&list);
-      int j = 0;
-      for (int i = 0; i < list.length(); i++) {
-        Variable* var1 = list[i];
-        if (var1->IsContextSlot()) {
-          if (j != i) {
-            list[j] = var1;
-          }
-          j++;
-        }
-      }
+      ZoneList<Variable*> stack_list(outer_scope->StackLocalCount());
+      ZoneList<Variable*> context_list(outer_scope->ContextLocalCount());
+      outer_scope->CollectStackAndContextLocals(&stack_list, &context_list);
+      context_list.Sort(&Variable::CompareIndex);
 
-      // Sort it.
-      for (int k = 1; k < j; k++) {
-        int l = k;
-        for (int m = k + 1; m < j; m++) {
-          if (list[l]->index() > list[m]->index()) {
-            l = m;
-          }
-        }
-        list[k] = list[l];
-      }
-      for (int i = 0; i < j; i++) {
+      for (int i = 0; i < context_list.length(); i++) {
         SetElementNonStrict(scope_info_list,
                             scope_info_length,
-                            list[i]->name());
+                            context_list[i]->name());
         scope_info_length++;
         SetElementNonStrict(
             scope_info_list,
             scope_info_length,
-            Handle<Smi>(Smi::FromInt(list[i]->index())));
+            Handle<Smi>(Smi::FromInt(context_list[i]->index())));
         scope_info_length++;
       }
       SetElementNonStrict(scope_info_list,
index 5b652e13d4d102f6c6ec99d7b0690d7b1078ff47..6ea92cee303afe0b1b2995903882f596028c16a6 100644 (file)
@@ -38,45 +38,16 @@ namespace v8 {
 namespace internal {
 
 
-static int CompareLocal(Variable* const* v, Variable* const* w) {
-  int x = (*v)->index();
-  int y = (*w)->index();
-  // Consider sorting them according to type as well?
-  return x - y;
-}
-
-
 Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) {
-  ZoneList<Variable*> variables(32);  // 32 is a wild guess
-  ASSERT(variables.is_empty());
-  scope->CollectUsedVariables(&variables);
-
-  ZoneList<Variable*> stack_locals(scope->num_stack_slots());
-  ZoneList<Variable*> context_locals(scope->num_heap_slots());
-
   // Collect stack and context locals.
-  for (int i = 0; i < variables.length(); i++) {
-    Variable* var = variables[i];
-    ASSERT(var->is_used());
-    switch (var->location()) {
-      case Variable::UNALLOCATED:
-      case Variable::PARAMETER:
-        break;
-
-      case Variable::LOCAL:
-        stack_locals.Add(var);
-        break;
-
-      case Variable::CONTEXT:
-        context_locals.Add(var);
-        break;
-
-      case Variable::LOOKUP:
-        // We don't expect lookup variables in the locals list.
-        UNREACHABLE();
-        break;
-    }
-  }
+  ZoneList<Variable*> stack_locals(scope->StackLocalCount());
+  ZoneList<Variable*> context_locals(scope->ContextLocalCount());
+  scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
+  const int stack_local_count = stack_locals.length();
+  const int context_local_count = context_locals.length();
+  // Make sure we allocate the correct amount.
+  ASSERT(scope->StackLocalCount() == stack_local_count);
+  ASSERT(scope->ContextLocalCount() == context_local_count);
 
   // Determine use and location of the function variable if it is present.
   FunctionVariableInfo function_name_info;
@@ -99,8 +70,6 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) {
 
   const bool has_function_name = function_name_info != NONE;
   const int parameter_count = scope->num_parameters();
-  const int stack_local_count = stack_locals.length();
-  const int context_local_count = context_locals.length();
   const int length = kVariablePartIndex
       + parameter_count + stack_local_count + 2 * context_local_count
       + (has_function_name ? 2 : 0);
@@ -140,7 +109,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Scope* scope) {
   // according to usage, the allocated slot indices may not be in increasing
   // order with the variable list anymore. Thus, we first need to sort them by
   // context slot index before adding them to the ScopeInfo object.
-  context_locals.Sort(&CompareLocal);
+  context_locals.Sort(&Variable::CompareIndex);
 
   // Add context locals' names.
   ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
index 6ace292590203a8faeebac7c69ecb86dc59ed2b6..f9cebcddaafff5532c4aac23ab7af06dd9a7c220 100644 (file)
@@ -529,23 +529,31 @@ Declaration* Scope::CheckConflictingVarDeclarations() {
 }
 
 
-void Scope::CollectUsedVariables(ZoneList<Variable*>* locals) {
-  // Collect variables in this scope.
-  // Note that the function_ variable - if present - is not
-  // collected here but handled separately in ScopeInfo
-  // which is the current user of this function).
+void Scope::CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
+                                         ZoneList<Variable*>* context_locals) {
+  ASSERT(stack_locals != NULL);
+  ASSERT(context_locals != NULL);
+
+  // Collect temporaries which are always allocated on the stack.
   for (int i = 0; i < temps_.length(); i++) {
     Variable* var = temps_[i];
     if (var->is_used()) {
-      locals->Add(var);
+      ASSERT(var->IsStackLocal());
+      stack_locals->Add(var);
     }
   }
+
+  // Collect declared local variables.
   for (VariableMap::Entry* p = variables_.Start();
        p != NULL;
        p = variables_.Next(p)) {
     Variable* var = reinterpret_cast<Variable*>(p->value);
     if (var->is_used()) {
-      locals->Add(var);
+      if (var->IsStackLocal()) {
+        stack_locals->Add(var);
+      } else if (var->IsContextSlot()) {
+        context_locals->Add(var);
+      }
     }
   }
 }
@@ -1165,4 +1173,17 @@ void Scope::AllocateVariablesRecursively() {
   ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
 }
 
+
+int Scope::StackLocalCount() const {
+  return num_stack_slots() -
+      (function_ != NULL && function_->var()->IsStackLocal() ? 1 : 0);
+}
+
+
+int Scope::ContextLocalCount() const {
+  if (num_heap_slots() == 0) return 0;
+  return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
+      (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0);
+}
+
 } }  // namespace v8::internal
index c95def3b294eedba6a857324507f6efb30fcd0d0..d08e2948242d1e52e61c33853d5e8281a2063b27 100644 (file)
@@ -303,8 +303,11 @@ class Scope: public ZoneObject {
   // ---------------------------------------------------------------------------
   // Variable allocation.
 
-  // Collect all used locals in this scope.
-  void CollectUsedVariables(ZoneList<Variable*>* locals);
+  // Collect stack and context allocated local variables in this scope. Note
+  // that the function variable - if present - is not collected and should be
+  // handled separately.
+  void CollectStackAndContextLocals(ZoneList<Variable*>* stack_locals,
+                                    ZoneList<Variable*>* context_locals);
 
   // Resolve and fill in the allocation information for all variables
   // in this scopes. Must be called *after* all scopes have been
@@ -323,6 +326,9 @@ class Scope: public ZoneObject {
   int num_stack_slots() const { return num_stack_slots_; }
   int num_heap_slots() const { return num_heap_slots_; }
 
+  int StackLocalCount() const;
+  int ContextLocalCount() const;
+
   // Make sure this scope and all outer scopes are eagerly compiled.
   void ForceEagerCompilation()  { force_eager_compilation_ = true; }
 
index a0952a1f205524451045b3be4f257f05ca376dd6..aa6a010facd979a9912b25b90e72c6e9feceabae 100644 (file)
@@ -85,4 +85,12 @@ bool Variable::is_global() const {
   return mode_ != TEMPORARY && scope_ != NULL && scope_->is_global_scope();
 }
 
+
+int Variable::CompareIndex(Variable* const* v, Variable* const* w) {
+  int x = (*v)->index();
+  int y = (*w)->index();
+  // Consider sorting them according to type as well?
+  return x - y;
+}
+
 } }  // namespace v8::internal
index 15788fb091fd32e5d7dc31d916ab84803be1435c..f20bd399c542aefc74400fd957ff9c6a7a8fa229 100644 (file)
@@ -159,6 +159,8 @@ class Variable: public ZoneObject {
     index_ = index;
   }
 
+  static int CompareIndex(Variable* const* v, Variable* const* w);
+
  private:
   Scope* scope_;
   Handle<String> name_;