Revision: 12270
Author:   [email protected]
Date:     Tue Aug  7 07:47:36 2012
Log:      Force eager compilation of parenthesized functions.

This makes the compiler use eager compilation for function literals that
are parenthesized. We consider this to be a hint that the function will
be called immediatly and hence try to avoid parsing it twice. The parser
already respects this heuristic.

[email protected]

Review URL: https://chromiumcodereview.appspot.com/10836132
http://code.google.com/p/v8/source/detail?r=12270

Modified:
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/compiler.cc
 /branches/bleeding_edge/src/parser.cc
 /branches/bleeding_edge/src/parser.h
 /branches/bleeding_edge/test/cctest/test-func-name-inference.cc

=======================================
--- /branches/bleeding_edge/src/ast.h   Tue Aug  7 07:06:25 2012
+++ /branches/bleeding_edge/src/ast.h   Tue Aug  7 07:47:36 2012
@@ -2038,6 +2038,11 @@
     kIsFunction
   };

+  enum IsParenthesizedFlag {
+    kIsParenthesized,
+    kNotParenthesized
+  };
+
   DECLARE_NODE_TYPE(FunctionLiteral)

   Handle<String> name() const { return name_; }
@@ -2085,6 +2090,10 @@
   }

bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
+
+  bool is_parenthesized() {
+    return IsParenthesized::decode(bitfield_) == kIsParenthesized;
+  }

   int ast_node_count() { return ast_properties_.node_count(); }
   AstProperties::Flags* flags() { return ast_properties_.flags(); }
@@ -2107,7 +2116,8 @@
                   int parameter_count,
                   Type type,
                   ParameterFlag has_duplicate_parameters,
-                  IsFunctionFlag is_function)
+                  IsFunctionFlag is_function,
+                  IsParenthesizedFlag is_parenthesized)
       : Expression(isolate),
         name_(name),
         scope_(scope),
@@ -2126,7 +2136,8 @@
         IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
         Pretenure::encode(false) |
         HasDuplicateParameters::encode(has_duplicate_parameters) |
-        IsFunction::encode(is_function);
+        IsFunction::encode(is_function) |
+        IsParenthesized::encode(is_parenthesized);
   }

  private:
@@ -2150,6 +2161,7 @@
   class Pretenure: public BitField<bool, 3, 1> {};
   class HasDuplicateParameters: public BitField<ParameterFlag, 4, 1> {};
   class IsFunction: public BitField<IsFunctionFlag, 5, 1> {};
+  class IsParenthesized: public BitField<IsParenthesizedFlag, 6, 1> {};
 };


@@ -2953,12 +2965,14 @@
       int parameter_count,
       FunctionLiteral::ParameterFlag has_duplicate_parameters,
       FunctionLiteral::Type type,
-      FunctionLiteral::IsFunctionFlag is_function) {
+      FunctionLiteral::IsFunctionFlag is_function,
+      FunctionLiteral::IsParenthesizedFlag is_parenthesized) {
     FunctionLiteral* lit = new(zone_) FunctionLiteral(
         isolate_, name, scope, body,
         materialized_literal_count, expected_property_count, handler_count,
has_only_simple_this_property_assignments, this_property_assignments,
-        parameter_count, type, has_duplicate_parameters, is_function);
+        parameter_count, type, has_duplicate_parameters, is_function,
+        is_parenthesized);
     // Top-level literal doesn't count for the AST's properties.
     if (is_function == FunctionLiteral::kIsFunction) {
       visitor_.VisitFunctionLiteral(lit);
=======================================
--- /branches/bleeding_edge/src/compiler.cc     Mon Aug  6 07:13:09 2012
+++ /branches/bleeding_edge/src/compiler.cc     Tue Aug  7 07:47:36 2012
@@ -929,7 +929,7 @@
   Handle<ScopeInfo> scope_info(ScopeInfo::Empty());

   // Generate code
-  if (FLAG_lazy && allow_lazy) {
+  if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
     Handle<Code> code = info.isolate()->builtins()->LazyCompile();
     info.SetCode(code);
   } else if (GenerateCode(&info)) {
=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Aug  6 07:13:09 2012
+++ /branches/bleeding_edge/src/parser.cc       Tue Aug  7 07:47:36 2012
@@ -615,8 +615,9 @@
   if (pre_data_ != NULL) pre_data_->Initialize();

   // Compute the parsing mode.
-  mode_ = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
-  if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
+  Mode mode = (FLAG_lazy && allow_lazy_) ? PARSE_LAZILY : PARSE_EAGERLY;
+  if (allow_natives_syntax_ || extension_ != NULL) mode = PARSE_EAGERLY;
+  ParsingModeScope parsing_mode(this, mode);

   Handle<String> no_name = isolate()->factory()->empty_symbol();

@@ -662,7 +663,8 @@
           0,
           FunctionLiteral::kNoDuplicateParameters,
           FunctionLiteral::ANONYMOUS_EXPRESSION,
-          FunctionLiteral::kGlobalOrEval);
+          FunctionLiteral::kGlobalOrEval,
+          FunctionLiteral::kNotParenthesized);
       result->set_ast_properties(factory()->visitor()->ast_properties());
     } else if (stack_overflow_) {
       isolate()->StackOverflow();
@@ -723,7 +725,7 @@
   fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
   fni_->PushEnclosingName(name);

-  mode_ = PARSE_EAGERLY;
+  ParsingModeScope parsing_mode(this, PARSE_EAGERLY);

   // Place holder for the result.
   FunctionLiteral* result = NULL;
@@ -4487,6 +4489,9 @@
   Handle<FixedArray> this_property_assignments;
   FunctionLiteral::ParameterFlag duplicate_parameters =
       FunctionLiteral::kNoDuplicateParameters;
+ FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
+      ? FunctionLiteral::kIsParenthesized
+      : FunctionLiteral::kNotParenthesized;
   AstProperties ast_properties;
   // Parse function body.
   { FunctionState function_state(this, scope, isolate());
@@ -4635,6 +4640,7 @@
     }

     if (!is_lazily_compiled) {
+      ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
       body = new(zone()) ZoneList<Statement*>(8, zone());
       if (fvar != NULL) {
         VariableProxy* fproxy = top_scope_->NewUnresolved(
@@ -4645,7 +4651,7 @@
                                      fproxy,
                                      factory()->NewThisFunction(),
                                      RelocInfo::kNoPosition)),
-                  zone());
+                                     zone());
       }
       ParseSourceElements(body, Token::RBRACE, false, CHECK_OK);

@@ -4725,7 +4731,8 @@
                                     num_parameters,
                                     duplicate_parameters,
                                     type,
-                                    FunctionLiteral::kIsFunction);
+                                    FunctionLiteral::kIsFunction,
+                                    parenthesized);
   function_literal->set_function_token_position(function_token_position);
   function_literal->set_ast_properties(&ast_properties);

=======================================
--- /branches/bleeding_edge/src/parser.h        Tue Jul 17 04:31:05 2012
+++ /branches/bleeding_edge/src/parser.h        Tue Aug  7 07:47:36 2012
@@ -536,8 +536,21 @@
     AstNodeFactory<AstConstructionVisitor> factory_;
   };

-
-
+  class ParsingModeScope BASE_EMBEDDED {
+   public:
+    ParsingModeScope(Parser* parser, Mode mode)
+        : parser_(parser),
+          old_mode_(parser->mode()) {
+      parser_->mode_ = mode;
+    }
+    ~ParsingModeScope() {
+      parser_->mode_ = old_mode_;
+    }
+
+   private:
+    Parser* parser_;
+    Mode old_mode_;
+  };

   FunctionLiteral* ParseLazy(Utf16CharacterStream* source,
                              ZoneScope* zone_scope);
=======================================
--- /branches/bleeding_edge/test/cctest/test-func-name-inference.cc Thu May 24 05:41:55 2012 +++ /branches/bleeding_edge/test/cctest/test-func-name-inference.cc Tue Aug 7 07:47:36 2012
@@ -398,7 +398,9 @@
   // The inferred name is empty, because this is an assignment of a result.
   CheckFunctionName(script, "return 1", "");
   // See MultipleAssignments test.
-  CheckFunctionName(script, "return 2", "Enclosing.Bar");
+  // TODO(2276): Lazy compiling the enclosing outer closure would yield
+  // in "Enclosing.Bar" being the inferred name here.
+  CheckFunctionName(script, "return 2", "Bar");
 }


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

Reply via email to