Reviewers: ulan,

https://chromiumcodereview.appspot.com/10836132/diff/1/src/ast.h
File src/ast.h (right):

https://chromiumcodereview.appspot.com/10836132/diff/1/src/ast.h#newcode2035
src/ast.h:2035: enum IsParenthesizedFlag {
I am torn between "IsParenthesizedFlag" and just "ParenthesizedFlag",
WDYT?

Description:
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]


Please review this at https://chromiumcodereview.appspot.com/10836132/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/ast.h
  M src/compiler.cc
  M src/parser.h
  M src/parser.cc
  M test/cctest/test-func-name-inference.cc


Index: src/ast.h
diff --git a/src/ast.h b/src/ast.h
index 63ee29ae0e80af35b73a11c94314364d9a11b8a8..bb1b9ce7cb542604960347383530286356cc709e 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -2032,6 +2032,11 @@ class FunctionLiteral: public Expression {
     kIsFunction
   };

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

   Handle<String> name() const { return name_; }
@@ -2080,6 +2085,10 @@ class FunctionLiteral: public Expression {

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(); }
   void set_ast_properties(AstProperties* ast_properties) {
@@ -2101,7 +2110,8 @@ class FunctionLiteral: public Expression {
                   int parameter_count,
                   Type type,
                   ParameterFlag has_duplicate_parameters,
-                  IsFunctionFlag is_function)
+                  IsFunctionFlag is_function,
+                  IsParenthesizedFlag is_parenthesized)
       : Expression(isolate),
         name_(name),
         scope_(scope),
@@ -2120,7 +2130,8 @@ class FunctionLiteral: public Expression {
         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:
@@ -2144,6 +2155,7 @@ class FunctionLiteral: public Expression {
   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> {};
 };


@@ -2947,12 +2959,14 @@ class AstNodeFactory BASE_EMBEDDED {
       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);
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index cca5aebda2222a9c591351a75f7da3cfca573582..7b51362546416aa1c8d59a98b5d47f96d23919a4 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -929,7 +929,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
   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)) {
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 5ee217ca5c16a12f3142c0219c8cc0e013dbf486..30f65bc44c5b84ffe2e7f5d79ee5b75f99a39086 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -615,8 +615,9 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
   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 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
           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 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source,
   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 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
   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 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
     }

     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 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
                                      fproxy,
                                      factory()->NewThisFunction(),
                                      RelocInfo::kNoPosition)),
-                  zone());
+                                     zone());
       }
       ParseSourceElements(body, Token::RBRACE, false, CHECK_OK);

@@ -4725,7 +4731,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> function_name,
                                     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);

Index: src/parser.h
diff --git a/src/parser.h b/src/parser.h
index 5127c84a2e19827c4efc1858138132b26ebaf772..3315b56201de9687b0995464069ea4c725f2ee3e 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -536,8 +536,21 @@ class Parser {
     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);
Index: test/cctest/test-func-name-inference.cc
diff --git a/test/cctest/test-func-name-inference.cc b/test/cctest/test-func-name-inference.cc index 762cc9f0fab1eae4406914222112edb8ef3855eb..a6ccc0991b45ba06e47ee72da6043b5be57bdf39 100644
--- a/test/cctest/test-func-name-inference.cc
+++ b/test/cctest/test-func-name-inference.cc
@@ -398,7 +398,9 @@ TEST(AssignmentAndCall) {
   // 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