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