[counters] Use separate counters for background parsing

BUG=

Review-Url: https://codereview.chromium.org/2509683002
Cr-Commit-Position: refs/heads/master@{#41047}
This commit is contained in:
cbruni 2016-11-16 10:51:32 -08:00 committed by Commit bot
parent d3231f5144
commit 7e4e34bb8f
9 changed files with 78 additions and 42 deletions

View File

@ -728,11 +728,16 @@ class RuntimeCallTimer {
V(Object_DeleteProperty) \
V(OptimizeCode) \
V(ParseArrowFunctionLiteral) \
V(ParseBackgroundArrowFunctionLiteral) \
V(ParseBackgroundFunctionLiteral) \
V(ParseEval) \
V(ParseFunction) \
V(ParseFunctionLiteral) \
V(ParseProgram) \
V(PreParseArrowFunctionLiteral) \
V(PreParseBackgroundArrowFunctionLiteral) \
V(PreParseBackgroundNoVariableResolution) \
V(PreParseBackgroundWithVariableResolution) \
V(PreParseNoVariableResolution) \
V(PreParseWithVariableResolution) \
V(PropertyCallback) \

View File

@ -192,7 +192,8 @@ class ParserBase {
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
v8::Extension* extension, AstValueFactory* ast_value_factory,
RuntimeCallStats* runtime_call_stats)
RuntimeCallStats* runtime_call_stats,
bool parsing_on_main_thread = true)
: scope_state_(nullptr),
function_state_(nullptr),
extension_(extension),
@ -200,6 +201,7 @@ class ParserBase {
ast_value_factory_(ast_value_factory),
ast_node_factory_(ast_value_factory),
runtime_call_stats_(runtime_call_stats),
parsing_on_main_thread_(parsing_on_main_thread),
parsing_module_(false),
stack_limit_(stack_limit),
zone_(zone),
@ -1421,6 +1423,7 @@ class ParserBase {
AstValueFactory* ast_value_factory_; // Not owned.
typename Types::Factory ast_node_factory_;
RuntimeCallStats* runtime_call_stats_;
bool parsing_on_main_thread_;
bool parsing_module_;
uintptr_t stack_limit_;
@ -3887,10 +3890,14 @@ template <typename Impl>
typename ParserBase<Impl>::ExpressionT
ParserBase<Impl>::ParseArrowFunctionLiteral(
bool accept_IN, const FormalParametersT& formal_parameters, bool* ok) {
const RuntimeCallStats::CounterId counters[2][2] = {
{&RuntimeCallStats::ParseArrowFunctionLiteral,
&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral},
{&RuntimeCallStats::PreParseArrowFunctionLiteral,
&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral}};
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
Impl::IsPreParser() ? &RuntimeCallStats::ParseArrowFunctionLiteral
: &RuntimeCallStats::PreParseArrowFunctionLiteral);
counters[Impl::IsPreParser()][parsing_on_main_thread_]);
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
// ASI inserts `;` after arrow parameters if a line terminator is found.

View File

@ -582,7 +582,8 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
Parser::Parser(ParseInfo* info)
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
info->extension(), info->ast_value_factory(),
info->isolate()->counters()->runtime_call_stats()),
info->isolate()->counters()->runtime_call_stats(),
true),
scanner_(info->unicode_cache()),
reusable_preparser_(nullptr),
original_scope_(nullptr),
@ -591,7 +592,6 @@ Parser::Parser(ParseInfo* info)
compile_options_(info->compile_options()),
cached_parse_data_(nullptr),
total_preparse_skipped_(0),
parsing_on_main_thread_(true),
log_(nullptr) {
// Even though we were passed ParseInfo, we should not store it in
// Parser - this makes sure that Isolate is not accidentally accessed via
@ -664,7 +664,6 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
// It's OK to use the Isolate & counters here, since this function is only
// called in the main thread.
DCHECK(parsing_on_main_thread_);
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
: &RuntimeCallStats::ParseProgram);
@ -2577,8 +2576,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
bool is_lazy_top_level_function =
can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
&RuntimeCallStats::ParseFunctionLiteral);
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
parsing_on_main_thread_
? &RuntimeCallStats::ParseFunctionLiteral
: &RuntimeCallStats::ParseBackgroundFunctionLiteral);
// Determine whether we can still lazy parse the inner function.
// The preconditions are:
@ -2787,9 +2789,9 @@ Parser::LazyParsingResult Parser::SkipFunction(
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
if (reusable_preparser_ == NULL) {
reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
&pending_error_handler_,
runtime_call_stats_, stack_limit_);
reusable_preparser_ = new PreParser(
zone(), &scanner_, stack_limit_, ast_value_factory(),
&pending_error_handler_, runtime_call_stats_, parsing_on_main_thread_);
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
SET_ALLOW(natives);
SET_ALLOW(harmony_do_expressions);

View File

@ -1145,7 +1145,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// parsing.
int use_counts_[v8::Isolate::kUseCounterFeatureCount];
int total_preparse_skipped_;
bool parsing_on_main_thread_;
bool allow_lazy_;
ParserLogger* log_;
};

View File

@ -179,11 +179,14 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
LanguageMode language_mode, bool* ok) {
// Function ::
// '(' FormalParameterList? ')' '{' FunctionBody '}'
const RuntimeCallStats::CounterId counters[2][2] = {
{&RuntimeCallStats::PreParseWithVariableResolution,
&RuntimeCallStats::PreParseBackgroundWithVariableResolution},
{&RuntimeCallStats::PreParseNoVariableResolution,
&RuntimeCallStats::PreParseBackgroundNoVariableResolution}};
RuntimeCallTimerScope runtime_timer(
runtime_call_stats_,
track_unresolved_variables_
? &RuntimeCallStats::PreParseWithVariableResolution
: &RuntimeCallStats::PreParseNoVariableResolution);
counters[track_unresolved_variables_][parsing_on_main_thread_]);
// Parse function body.
PreParserStatementList body;

View File

@ -838,11 +838,14 @@ class PreParser : public ParserBase<PreParser> {
kPreParseSuccess
};
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
PreParser(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
AstValueFactory* ast_value_factory,
PendingCompilationErrorHandler* pending_error_handler,
RuntimeCallStats* runtime_call_stats, uintptr_t stack_limit)
RuntimeCallStats* runtime_call_stats,
bool parsing_on_main_thread = true)
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
ast_value_factory, runtime_call_stats),
ast_value_factory, runtime_call_stats,
parsing_on_main_thread),
use_counts_(nullptr),
track_unresolved_variables_(false),
pending_error_handler_(pending_error_handler) {}

View File

@ -175,8 +175,9 @@ TEST(ScanHTMLEndComments) {
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
&zone, &scanner, &ast_value_factory, &pending_error_handler,
CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler,
CcTest::i_isolate()->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(!pending_error_handler.has_pending_error());
@ -192,8 +193,9 @@ TEST(ScanHTMLEndComments) {
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
&zone, &scanner, &ast_value_factory, &pending_error_handler,
CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler,
CcTest::i_isolate()->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@ -366,8 +368,9 @@ TEST(StandAlonePreParser) {
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
&zone, &scanner, &ast_value_factory, &pending_error_handler,
CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler,
CcTest::i_isolate()->counters()->runtime_call_stats());
preparser.set_allow_natives(true);
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@ -400,9 +403,9 @@ TEST(StandAlonePreParserNoNatives) {
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
&zone, &scanner, &ast_value_factory, &pending_error_handler,
isolate->counters()->runtime_call_stats(), stack_limit);
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler,
isolate->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
CHECK(pending_error_handler.has_pending_error());
@ -467,10 +470,10 @@ TEST(RegressChromium62639) {
i::AstValueFactory ast_value_factory(&zone,
CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(&zone, &scanner, &ast_value_factory,
&pending_error_handler,
isolate->counters()->runtime_call_stats(),
CcTest::i_isolate()->stack_guard()->real_climit());
i::PreParser preparser(&zone, &scanner,
CcTest::i_isolate()->stack_guard()->real_climit(),
&ast_value_factory, &pending_error_handler,
isolate->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
// Even in the case of a syntax error, kPreParseSuccess is returned.
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
@ -543,9 +546,9 @@ TEST(PreParseOverflow) {
i::AstValueFactory ast_value_factory(&zone,
CcTest::i_isolate()->heap()->HashSeed());
i::PendingCompilationErrorHandler pending_error_handler;
i::PreParser preparser(
&zone, &scanner, &ast_value_factory, &pending_error_handler,
isolate->counters()->runtime_call_stats(), stack_limit);
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler,
isolate->counters()->runtime_call_stats());
i::PreParser::PreParseResult result = preparser.PreParseProgram();
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
}
@ -1327,9 +1330,9 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
i::AstValueFactory ast_value_factory(
&zone, CcTest::i_isolate()->heap()->HashSeed());
i::PreParser preparser(
&zone, &scanner, &ast_value_factory, &pending_error_handler,
isolate->counters()->runtime_call_stats(), stack_limit);
i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
&pending_error_handler,
isolate->counters()->runtime_call_stats());
SetParserFlags(&preparser, flags);
scanner.Initialize(stream.get());
i::PreParser::PreParseResult result =

View File

@ -1365,6 +1365,7 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
Group.groups.get('ic').entry(),
Group.groups.get('optimize').entry(),
Group.groups.get('compile').entry(),
Group.groups.get('parse-background').entry(),
Group.groups.get('parse').entry(),
Group.groups.get('callback').entry(),
Group.groups.get('api').entry(),
@ -1554,19 +1555,24 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
Group.groups = new Map();
Group.add = function(name, group) {
this.groups.set(name, group);
return group;
}
Group.add('total', new Group('Total', /.*Total.*/, '#BBB'));
Group.add('ic', new Group('IC', /.*IC.*/, "#3366CC"));
Group.add('optimize', new Group('Optimize',
/StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/, "#DC3912"));
Group.add('compile', new Group('Compile', /.*Compile.*/, "#FFAA00"));
Group.add('parse-background',
new Group('Parse-Background', /.*ParseBackground.*/, "#af744d"));
Group.add('parse', new Group('Parse', /.*Parse.*/, "#FF6600"));
Group.add('callback', new Group('Callback', /.*Callback.*/, "#109618"));
Group.add('api', new Group('API', /.*API.*/, "#990099"));
Group.add('gc', new Group('GC', /GC|AllocateInTargetSpace/, "#0099C6"));
Group.add('javascript', new Group('JavaScript', /JS_Execution/, "#DD4477"));
Group.add('runtime', new Group('Runtime', /.*/, "#88BB00"));
Group.add('unclassified', new Group('Unclassified', /.*/, "#000"));
var group =
Group.add('unclassified', new Group('Unclassified', /.*/, "#000"));
group.enabled = false;
class GroupedEntry extends Entry {
constructor(group) {

View File

@ -347,6 +347,7 @@ def read_stats(path, domain, args):
('Group-Optimize',
re.compile("StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*")),
('Group-Compile', re.compile(".*Compile.*")),
('Group-ParseBackground', re.compile(".*ParseBackground.*")),
('Group-Parse', re.compile(".*Parse.*")),
('Group-Callback', re.compile(".*Callback.*")),
('Group-API', re.compile(".*API.*")),
@ -385,12 +386,19 @@ def read_stats(path, domain, args):
entries[group_name]['count'] += count
break
# Calculate the V8-Total (all groups except Callback)
total_v8 = { 'time': 0, 'count': 0 }
group_data = { 'time': 0, 'count': 0 }
for group_name, regexp in groups:
if group_name == 'Group-Callback': continue
total_v8['time'] += entries[group_name]['time']
total_v8['count'] += entries[group_name]['count']
entries['Group-Total-V8'] = total_v8
group_data['time'] += entries[group_name]['time']
group_data['count'] += entries[group_name]['count']
entries['Group-Total-V8'] = group_data
# Calculate the Parse-Total group
group_data = { 'time': 0, 'count': 0 }
for group_name, regexp in groups:
if !group_name.startswith('Group-Parse'): continue
group_data['time'] += entries[group_name]['time']
group_data['count'] += entries[group_name]['count']
entries['Group-Parse-Total'] = group_data
# Append the sums as single entries to domain.
for key in entries:
if key not in domain: domain[key] = { 'time_list': [], 'count_list': [] }