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