Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 24510e3da77c339a120564d12c04cbf1fdfb5a15..12c283674f24349bbcae29caf692e50d7dadc2fe 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -739,13 +739,13 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
} |
-Parser::Parser(CompilationInfo* info) |
- : ParserBase<ParserTraits>( |
- &scanner_, info->isolate()->stack_guard()->real_climit(), |
- info->extension(), NULL, info->zone(), info->ast_node_id_gen(), this), |
+Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed, |
+ UnicodeCache* unicode_cache) |
+ : ParserBase<ParserTraits>(&scanner_, stack_limit, info->extension(), NULL, |
+ info->zone(), info->ast_node_id_gen(), this), |
isolate_(info->isolate()), |
script_(info->script()), |
- scanner_(isolate_->unicode_cache()), |
+ scanner_(unicode_cache), |
reusable_preparser_(NULL), |
original_scope_(NULL), |
target_stack_(NULL), |
@@ -755,7 +755,10 @@ Parser::Parser(CompilationInfo* info) |
has_pending_error_(false), |
pending_error_message_(NULL), |
pending_error_arg_(NULL), |
- pending_error_char_arg_(NULL) { |
+ pending_error_char_arg_(NULL), |
+ total_preparse_skipped_(0), |
+ pre_parse_timer_(NULL), |
+ hash_seed_(hash_seed) { |
DCHECK(!script_.is_null()); |
set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
@@ -775,6 +778,9 @@ Parser::Parser(CompilationInfo* info) |
FunctionLiteral* Parser::ParseProgram() { |
// TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
// see comment for HistogramTimerScope class. |
+ |
+ // It's OK to use the counters here, since this function is only called in |
+ // the main thread. |
HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
Handle<String> source(String::cast(script_->source())); |
isolate()->counters()->total_parse_size()->Increment(source->length()); |
@@ -808,6 +814,7 @@ FunctionLiteral* Parser::ParseProgram() { |
scanner_.Initialize(&stream); |
result = DoParseProgram(info(), source); |
} |
+ HandleSourceURLComments(); |
if (FLAG_trace_parse && result != NULL) { |
double ms = timer.Elapsed().InMillisecondsF(); |
@@ -876,8 +883,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
int beg_pos = scanner()->location().beg_pos; |
ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
- HandleSourceURLComments(); |
- |
if (ok && strict_mode() == STRICT) { |
CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
} |
@@ -896,7 +901,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
} |
} |
- ast_value_factory_->Internalize(isolate()); |
if (ok) { |
result = factory()->NewFunctionLiteral( |
ast_value_factory_->empty_string(), ast_value_factory_, scope_, body, |
@@ -910,10 +914,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
result->set_ast_properties(factory()->visitor()->ast_properties()); |
result->set_dont_optimize_reason( |
factory()->visitor()->dont_optimize_reason()); |
- } else if (stack_overflow()) { |
- isolate()->StackOverflow(); |
- } else { |
- ThrowPendingError(); |
} |
} |
@@ -925,6 +925,8 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
FunctionLiteral* Parser::ParseLazy() { |
+ // It's OK to use the counters here, since this function is only called in |
+ // the main thread. |
HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
Handle<String> source(String::cast(script_->source())); |
isolate()->counters()->total_parse_size()->Increment(source->length()); |
@@ -1017,14 +1019,7 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
// Make sure the target stack is empty. |
DCHECK(target_stack_ == NULL); |
- ast_value_factory_->Internalize(isolate()); |
- if (result == NULL) { |
- if (stack_overflow()) { |
- isolate()->StackOverflow(); |
- } else { |
- ThrowPendingError(); |
- } |
- } else { |
+ if (result != NULL) { |
Handle<String> inferred_name(shared_info->inferred_name()); |
result->set_inferred_name(inferred_name); |
} |
@@ -3654,8 +3649,7 @@ void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
if (!*ok) { |
return; |
} |
- isolate()->counters()->total_preparse_skipped()->Increment( |
- scope_->end_position() - function_block_pos); |
+ total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
*materialized_literal_count = entry.literal_count(); |
*expected_property_count = entry.property_count(); |
scope_->SetStrictMode(entry.strict_mode()); |
@@ -3683,8 +3677,7 @@ void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
if (!*ok) { |
return; |
} |
- isolate()->counters()->total_preparse_skipped()->Increment( |
- scope_->end_position() - function_block_pos); |
+ total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
*materialized_literal_count = logger.literals(); |
*expected_property_count = logger.properties(); |
scope_->SetStrictMode(logger.strict_mode()); |
@@ -3762,12 +3755,15 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
SingletonLogger* logger) { |
- HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); |
+ // This function may be called on a background thread too; record only the |
+ // main thread preparse times. |
+ if (pre_parse_timer_ != NULL) { |
+ pre_parse_timer_->Start(); |
+ } |
DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
if (reusable_preparser_ == NULL) { |
- intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
- reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
+ reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); |
reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
reusable_preparser_->set_allow_modules(allow_modules()); |
reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
@@ -3782,6 +3778,9 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
reusable_preparser_->PreParseLazyFunction(strict_mode(), |
is_generator(), |
logger); |
+ if (pre_parse_timer_ != NULL) { |
+ pre_parse_timer_->Stop(); |
+ } |
return result; |
} |
@@ -3965,13 +3964,28 @@ void Parser::ThrowPendingError() { |
} |
-void Parser::InternalizeUseCounts() { |
+void Parser::Internalize() { |
+ // Internalize strings. |
+ ast_value_factory_->Internalize(isolate()); |
+ |
+ // Error processing. |
+ if (info()->function() == NULL) { |
+ if (stack_overflow()) { |
+ isolate()->StackOverflow(); |
+ } else { |
+ ThrowPendingError(); |
+ } |
+ } |
+ |
+ // Move statistics to Isolate. |
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
++feature) { |
for (int i = 0; i < use_counts_[feature]; ++i) { |
isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
} |
} |
+ isolate()->counters()->total_preparse_skipped()->Increment( |
+ total_preparse_skipped_); |
} |
@@ -4811,8 +4825,7 @@ bool Parser::Parse() { |
FunctionLiteral* result = NULL; |
ast_value_factory_ = info()->ast_value_factory(); |
if (ast_value_factory_ == NULL) { |
- ast_value_factory_ = |
- new AstValueFactory(zone(), isolate()->heap()->HashSeed()); |
+ ast_value_factory_ = new AstValueFactory(zone(), hash_seed_); |
} |
if (allow_natives_syntax() || extension_ != NULL) { |
// If intrinsics are allowed, the Parser cannot operate independent of the |
@@ -4820,7 +4833,7 @@ bool Parser::Parse() { |
// and values right after they're created. |
ast_value_factory_->Internalize(isolate()); |
} |
- |
+ pre_parse_timer_ = isolate()->counters()->pre_parse(); |
if (info()->is_lazy()) { |
DCHECK(!info()->is_eval()); |
if (info()->shared_info()->is_function()) { |
@@ -4833,15 +4846,14 @@ bool Parser::Parse() { |
result = ParseProgram(); |
} |
info()->SetFunction(result); |
+ |
+ Internalize(); |
DCHECK(ast_value_factory_->IsInternalized()); |
// info takes ownership of ast_value_factory_. |
if (info()->ast_value_factory() == NULL) { |
info()->SetAstValueFactory(ast_value_factory_); |
} |
ast_value_factory_ = NULL; |
- |
- InternalizeUseCounts(); |
- |
return (result != NULL); |
} |