Refactor code generation for global declarations.
authorrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 16 Apr 2012 12:26:16 +0000 (12:26 +0000)
committerrossberg@chromium.org <rossberg@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 16 Apr 2012 12:26:16 +0000 (12:26 +0000)
(Baseline is http://codereview.chromium.org/9704054/)

R=fschneider@chromium.org
BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9722043

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

src/arm/full-codegen-arm.cc
src/full-codegen.cc
src/full-codegen.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/full-codegen-ia32.cc
src/x64/full-codegen-x64.cc

index 08e6be4..54a6e25 100644 (file)
@@ -806,7 +806,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
   bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_.Add(variable->name());
+      globals_.Add(variable->binding_needs_init()
+                       ? isolate()->factory()->the_hole_value()
+                       : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
@@ -861,9 +864,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
   VariableProxy* proxy = declaration->proxy();
   Variable* variable = proxy->var();
   switch (variable->location()) {
-    case Variable::UNALLOCATED:
-      ++global_count_;
+    case Variable::UNALLOCATED: {
+      globals_.Add(variable->name());
+      Handle<SharedFunctionInfo> function =
+          Compiler::BuildFunctionInfo(declaration->fun(), script());
+      // Check for stack-overflow exception.
+      if (function.is_null()) return SetStackOverflow();
+      globals_.Add(function);
       break;
+    }
 
     case Variable::PARAMETER:
     case Variable::LOCAL: {
@@ -911,7 +920,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = proxy->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      // TODO(rossberg): initialize module instance object
       break;
 
     case Variable::CONTEXT: {
@@ -934,7 +943,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
   Variable* variable = proxy->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      // TODO(rossberg)
       break;
 
     case Variable::CONTEXT: {
index 8c0f476..310805d 100644 (file)
@@ -568,48 +568,17 @@ void FullCodeGenerator::DoTest(const TestContext* context) {
 
 void FullCodeGenerator::VisitDeclarations(
     ZoneList<Declaration*>* declarations) {
-  int save_global_count = global_count_;
-  global_count_ = 0;
-
+  ASSERT(globals_.is_empty());
   AstVisitor::VisitDeclarations(declarations);
-
-  // Batch declare global functions and variables.
-  if (global_count_ > 0) {
-    Handle<FixedArray> array =
-       isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
-    int length = declarations->length();
-    for (int j = 0, i = 0; i < length; i++) {
-      Declaration* decl = declarations->at(i);
-      Variable* var = decl->proxy()->var();
-
-      if (var->IsUnallocated()) {
-        array->set(j++, *(var->name()));
-        FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
-        if (fun_decl == NULL) {
-          if (var->binding_needs_init()) {
-            // In case this binding needs initialization use the hole.
-            array->set_the_hole(j++);
-          } else {
-            array->set_undefined(j++);
-          }
-        } else {
-          Handle<SharedFunctionInfo> function =
-              Compiler::BuildFunctionInfo(fun_decl->fun(), script());
-          // Check for stack-overflow exception.
-          if (function.is_null()) {
-            SetStackOverflow();
-            return;
-          }
-          array->set(j++, *function);
-        }
-      }
-    }
+  if (!globals_.is_empty()) {
     // Invoke the platform-dependent code generator to do the actual
     // declaration the global functions and variables.
+    Handle<FixedArray> array =
+       isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
+    for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
     DeclareGlobals(array);
+    globals_.Clear();
   }
-
-  global_count_ = save_global_count;
 }
 
 
index a7ef6d1..7c56766 100644 (file)
@@ -83,7 +83,7 @@ class FullCodeGenerator: public AstVisitor {
         scope_(info->scope()),
         nesting_stack_(NULL),
         loop_depth_(0),
-        global_count_(0),
+        globals_(10),
         context_(NULL),
         bailout_entries_(info->HasDeoptimizationSupport()
                          ? info->function()->ast_node_count() : 0),
@@ -778,7 +778,7 @@ class FullCodeGenerator: public AstVisitor {
   Label return_label_;
   NestedStatement* nesting_stack_;
   int loop_depth_;
-  int global_count_;
+  ZoneList<Handle<Object> > globals_;
   const ExpressionContext* context_;
   ZoneList<BailoutEntry> bailout_entries_;
   ZoneList<BailoutEntry> stack_checks_;
index b132570..8b8d327 100644 (file)
@@ -612,6 +612,7 @@ HGraphBuilder::HGraphBuilder(CompilationInfo* info,
       graph_(NULL),
       current_block_(NULL),
       inlined_count_(0),
+      globals_(10),
       zone_(info->isolate()->zone()),
       inline_bailout_(false) {
   // This is not initialized in the initializer list because the
@@ -7160,70 +7161,40 @@ void HGraphBuilder::VisitThisFunction(ThisFunction* expr) {
 
 
 void HGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
-  int length = declarations->length();
-  int save_global_count = global_count_;
-  global_count_ = 0;
-
+  ASSERT(globals_.is_empty());
   AstVisitor::VisitDeclarations(declarations);
-
-  // Batch declare global functions and variables.
-  if (global_count_ > 0) {
+  if (!globals_.is_empty()) {
     Handle<FixedArray> array =
-        isolate()->factory()->NewFixedArray(2 * global_count_, TENURED);
-    for (int j = 0, i = 0; i < length; i++) {
-      Declaration* decl = declarations->at(i);
-      Variable* var = decl->proxy()->var();
-
-      if (var->IsUnallocated()) {
-        array->set(j++, *(var->name()));
-        FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration();
-        if (fun_decl == NULL) {
-          if (var->binding_needs_init()) {
-            // In case this binding needs initialization use the hole.
-            array->set_the_hole(j++);
-          } else {
-            array->set_undefined(j++);
-          }
-        } else {
-          Handle<SharedFunctionInfo> function =
-              Compiler::BuildFunctionInfo(fun_decl->fun(), info()->script());
-          // Check for stack-overflow exception.
-          if (function.is_null()) {
-            SetStackOverflow();
-            return;
-          }
-          array->set(j++, *function);
-        }
-      }
-    }
+       isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
+    for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
     int flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
                 DeclareGlobalsNativeFlag::encode(info()->is_native()) |
                 DeclareGlobalsLanguageMode::encode(info()->language_mode());
-    HInstruction* result =
-        new(zone()) HDeclareGlobals(environment()->LookupContext(),
-                                    array,
-                                    flags);
+    HInstruction* result = new(zone()) HDeclareGlobals(
+        environment()->LookupContext(), array, flags);
     AddInstruction(result);
+    globals_.Clear();
   }
-
-  global_count_ = save_global_count;
 }
 
 
 void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
   VariableProxy* proxy = declaration->proxy();
   VariableMode mode = declaration->mode();
-  Variable* var = proxy->var();
+  Variable* variable = proxy->var();
   bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
-  switch (var->location()) {
+  switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_.Add(variable->name());
+      globals_.Add(variable->binding_needs_init()
+                       ? isolate()->factory()->the_hole_value()
+                       : isolate()->factory()->undefined_value());
       return;
     case Variable::PARAMETER:
     case Variable::LOCAL:
       if (hole_init) {
         HValue* value = graph()->GetConstantHole();
-        environment()->Bind(var, value);
+        environment()->Bind(variable, value);
       }
       break;
     case Variable::CONTEXT:
@@ -7231,7 +7202,7 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
         HValue* value = graph()->GetConstantHole();
         HValue* context = environment()->LookupContext();
         HStoreContextSlot* store = new HStoreContextSlot(
-            context, var->index(), HStoreContextSlot::kNoCheck, value);
+            context, variable->index(), HStoreContextSlot::kNoCheck, value);
         AddInstruction(store);
         if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
       }
@@ -7244,16 +7215,22 @@ void HGraphBuilder::VisitVariableDeclaration(VariableDeclaration* declaration) {
 
 void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
   VariableProxy* proxy = declaration->proxy();
-  Variable* var = proxy->var();
-  switch (var->location()) {
-    case Variable::UNALLOCATED:
-      ++global_count_;
+  Variable* variable = proxy->var();
+  switch (variable->location()) {
+    case Variable::UNALLOCATED: {
+      globals_.Add(variable->name());
+      Handle<SharedFunctionInfo> function =
+          Compiler::BuildFunctionInfo(declaration->fun(), info()->script());
+      // Check for stack-overflow exception.
+      if (function.is_null()) return SetStackOverflow();
+      globals_.Add(function);
       return;
+    }
     case Variable::PARAMETER:
     case Variable::LOCAL: {
       CHECK_ALIVE(VisitForValue(declaration->fun()));
       HValue* value = Pop();
-      environment()->Bind(var, value);
+      environment()->Bind(variable, value);
       break;
     }
     case Variable::CONTEXT: {
@@ -7261,7 +7238,7 @@ void HGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* declaration) {
       HValue* value = Pop();
       HValue* context = environment()->LookupContext();
       HStoreContextSlot* store = new HStoreContextSlot(
-          context, var->index(), HStoreContextSlot::kNoCheck, value);
+          context, variable->index(), HStoreContextSlot::kNoCheck, value);
       AddInstruction(store);
       if (store->HasObservableSideEffects()) AddSimulate(proxy->id());
       break;
@@ -7276,9 +7253,10 @@ void HGraphBuilder::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   VariableProxy* proxy = declaration->proxy();
   Variable* var = proxy->var();
   switch (var->location()) {
-    case Variable::UNALLOCATED:
-      ++global_count_;
+    case Variable::UNALLOCATED: {
+      // TODO(rossberg)
       return;
+    }
     case Variable::CONTEXT: {
       // TODO(rossberg)
       break;
@@ -7295,9 +7273,10 @@ void HGraphBuilder::VisitImportDeclaration(ImportDeclaration* declaration) {
   VariableProxy* proxy = declaration->proxy();
   Variable* var = proxy->var();
   switch (var->location()) {
-    case Variable::UNALLOCATED:
-      ++global_count_;
+    case Variable::UNALLOCATED: {
+      // TODO(rossberg)
       return;
+    }
     case Variable::CONTEXT: {
       // TODO(rossberg)
       break;
index c246015..b84ae70 100644 (file)
@@ -1162,7 +1162,7 @@ class HGraphBuilder: public AstVisitor {
   HBasicBlock* current_block_;
 
   int inlined_count_;
-  int global_count_;
+  ZoneList<Handle<Object> > globals_;
 
   Zone* zone_;
 
index b313b7d..9242041 100644 (file)
@@ -782,7 +782,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
   bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_.Add(variable->name());
+      globals_.Add(variable->binding_needs_init()
+                       ? isolate()->factory()->the_hole_value()
+                       : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
@@ -836,9 +839,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
   VariableProxy* proxy = declaration->proxy();
   Variable* variable = proxy->var();
   switch (variable->location()) {
-    case Variable::UNALLOCATED:
-      ++global_count_;
+    case Variable::UNALLOCATED: {
+      globals_.Add(variable->name());
+      Handle<SharedFunctionInfo> function =
+          Compiler::BuildFunctionInfo(declaration->fun(), script());
+      // Check for stack-overflow exception.
+      if (function.is_null()) return SetStackOverflow();
+      globals_.Add(function);
       break;
+    }
 
     case Variable::PARAMETER:
     case Variable::LOCAL: {
@@ -883,7 +892,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = proxy->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      // TODO(rossberg): initialize module instance object
       break;
 
     case Variable::CONTEXT: {
@@ -906,7 +915,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
   Variable* variable = proxy->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      // TODO(rossberg)
       break;
 
     case Variable::CONTEXT: {
index f30528b..da04ca9 100644 (file)
@@ -779,7 +779,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
   bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      globals_.Add(variable->name());
+      globals_.Add(variable->binding_needs_init()
+                       ? isolate()->factory()->the_hole_value()
+                       : isolate()->factory()->undefined_value());
       break;
 
     case Variable::PARAMETER:
@@ -833,9 +836,15 @@ void FullCodeGenerator::VisitFunctionDeclaration(
   VariableProxy* proxy = declaration->proxy();
   Variable* variable = proxy->var();
   switch (variable->location()) {
-    case Variable::UNALLOCATED:
-      ++global_count_;
+    case Variable::UNALLOCATED: {
+      globals_.Add(variable->name());
+      Handle<SharedFunctionInfo> function =
+          Compiler::BuildFunctionInfo(declaration->fun(), script());
+      // Check for stack-overflow exception.
+      if (function.is_null()) return SetStackOverflow();
+      globals_.Add(function);
       break;
+    }
 
     case Variable::PARAMETER:
     case Variable::LOCAL: {
@@ -881,7 +890,7 @@ void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
   Variable* variable = proxy->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      // TODO(rossberg): initialize module instance object
       break;
 
     case Variable::CONTEXT: {
@@ -904,7 +913,7 @@ void FullCodeGenerator::VisitImportDeclaration(ImportDeclaration* declaration) {
   Variable* variable = proxy->var();
   switch (variable->location()) {
     case Variable::UNALLOCATED:
-      ++global_count_;
+      // TODO(rossberg)
       break;
 
     case Variable::CONTEXT: {