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.

R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12270 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent fb7345cd
......@@ -2038,6 +2038,11 @@ class FunctionLiteral: public Expression {
kIsFunction
};
enum IsParenthesizedFlag {
kIsParenthesized,
kNotParenthesized
};
DECLARE_NODE_TYPE(FunctionLiteral)
Handle<String> name() const { return name_; }
......@@ -2086,6 +2091,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) {
......@@ -2107,7 +2116,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),
......@@ -2126,7 +2136,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:
......@@ -2150,6 +2161,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> {};
};
......@@ -2953,12 +2965,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);
......
......@@ -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)) {
......
......@@ -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);
......
......@@ -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);
......
......@@ -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");
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment