[counters] Implement off-isolate RuntimeCallStats for the Preparser
BUG= Review-Url: https://codereview.chromium.org/2490643002 Cr-Commit-Position: refs/heads/master@{#41001}
This commit is contained in:
parent
e29fcbee9c
commit
bb6a626b76
@ -13,14 +13,19 @@ namespace internal {
|
||||
RuntimeCallTimerScope::RuntimeCallTimerScope(
|
||||
Isolate* isolate, RuntimeCallStats::CounterId counter_id) {
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) {
|
||||
Initialize(isolate, counter_id);
|
||||
Initialize(isolate->counters()->runtime_call_stats(), counter_id);
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeCallTimerScope::RuntimeCallTimerScope(
|
||||
HeapObject* heap_object, RuntimeCallStats::CounterId counter_id) {
|
||||
RuntimeCallTimerScope(heap_object->GetIsolate(), counter_id);
|
||||
}
|
||||
|
||||
RuntimeCallTimerScope::RuntimeCallTimerScope(
|
||||
RuntimeCallStats* stats, RuntimeCallStats::CounterId counter_id) {
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) {
|
||||
Initialize(heap_object->GetIsolate(), counter_id);
|
||||
Initialize(stats, counter_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
117
src/counters.cc
117
src/counters.cc
@ -284,10 +284,36 @@ void RuntimeCallCounter::Dump(v8::tracing::TracedValue* value) {
|
||||
value->EndArray();
|
||||
}
|
||||
|
||||
void RuntimeCallCounter::Add(RuntimeCallCounter* other) {
|
||||
count += other->count;
|
||||
time += other->time;
|
||||
}
|
||||
|
||||
// static
|
||||
const RuntimeCallStats::CounterId RuntimeCallStats::counters[] = {
|
||||
#define CALL_RUNTIME_COUNTER(name) &RuntimeCallStats::name,
|
||||
FOR_EACH_MANUAL_COUNTER(CALL_RUNTIME_COUNTER) //
|
||||
#undef CALL_RUNTIME_COUNTER
|
||||
#define CALL_RUNTIME_COUNTER(name, nargs, ressize) \
|
||||
&RuntimeCallStats::Runtime_##name, //
|
||||
FOR_EACH_INTRINSIC(CALL_RUNTIME_COUNTER) //
|
||||
#undef CALL_RUNTIME_COUNTER
|
||||
#define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Builtin_##name,
|
||||
BUILTIN_LIST_C(CALL_BUILTIN_COUNTER) //
|
||||
#undef CALL_BUILTIN_COUNTER
|
||||
#define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::API_##name,
|
||||
FOR_EACH_API_COUNTER(CALL_BUILTIN_COUNTER) //
|
||||
#undef CALL_BUILTIN_COUNTER
|
||||
#define CALL_BUILTIN_COUNTER(name) &RuntimeCallStats::Handler_##name,
|
||||
FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER)
|
||||
#undef CALL_BUILTIN_COUNTER
|
||||
};
|
||||
|
||||
// static
|
||||
void RuntimeCallStats::Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer,
|
||||
CounterId counter_id) {
|
||||
RuntimeCallCounter* counter = &(stats->*counter_id);
|
||||
DCHECK(counter->name != NULL);
|
||||
timer->Start(counter, stats->current_timer_.Value());
|
||||
stats->current_timer_.SetValue(timer);
|
||||
}
|
||||
@ -301,12 +327,20 @@ void RuntimeCallStats::Leave(RuntimeCallStats* stats, RuntimeCallTimer* timer) {
|
||||
// buried one that's leaving. We don't care about keeping nested timings
|
||||
// accurate, just avoid crashing by keeping the chain intact.
|
||||
RuntimeCallTimer* next = stats->current_timer_.Value();
|
||||
while (next && next->parent() != timer) next = next->parent();
|
||||
if (next == nullptr) return;
|
||||
while (next->parent() != timer) next = next->parent();
|
||||
next->parent_.SetValue(timer->Stop());
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeCallStats::Add(RuntimeCallStats* other) {
|
||||
for (const RuntimeCallStats::CounterId counter_id :
|
||||
RuntimeCallStats::counters) {
|
||||
RuntimeCallCounter* counter = &(this->*counter_id);
|
||||
RuntimeCallCounter* other_counter = &(other->*counter_id);
|
||||
counter->Add(other_counter);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void RuntimeCallStats::CorrectCurrentCounterId(RuntimeCallStats* stats,
|
||||
CounterId counter_id) {
|
||||
@ -321,27 +355,11 @@ void RuntimeCallStats::Print(std::ostream& os) {
|
||||
if (current_timer_.Value() != nullptr) {
|
||||
current_timer_.Value()->Elapsed();
|
||||
}
|
||||
|
||||
#define PRINT_COUNTER(name) entries.Add(&this->name);
|
||||
FOR_EACH_MANUAL_COUNTER(PRINT_COUNTER)
|
||||
#undef PRINT_COUNTER
|
||||
|
||||
#define PRINT_COUNTER(name, nargs, ressize) entries.Add(&this->Runtime_##name);
|
||||
FOR_EACH_INTRINSIC(PRINT_COUNTER)
|
||||
#undef PRINT_COUNTER
|
||||
|
||||
#define PRINT_COUNTER(name) entries.Add(&this->Builtin_##name);
|
||||
BUILTIN_LIST_C(PRINT_COUNTER)
|
||||
#undef PRINT_COUNTER
|
||||
|
||||
#define PRINT_COUNTER(name) entries.Add(&this->API_##name);
|
||||
FOR_EACH_API_COUNTER(PRINT_COUNTER)
|
||||
#undef PRINT_COUNTER
|
||||
|
||||
#define PRINT_COUNTER(name) entries.Add(&this->Handler_##name);
|
||||
FOR_EACH_HANDLER_COUNTER(PRINT_COUNTER)
|
||||
#undef PRINT_COUNTER
|
||||
|
||||
for (const RuntimeCallStats::CounterId counter_id :
|
||||
RuntimeCallStats::counters) {
|
||||
RuntimeCallCounter* counter = &(this->*counter_id);
|
||||
entries.Add(counter);
|
||||
}
|
||||
entries.Print(os);
|
||||
}
|
||||
|
||||
@ -356,54 +374,21 @@ void RuntimeCallStats::Reset() {
|
||||
current_timer_.SetValue(current_timer_.Value()->Stop());
|
||||
}
|
||||
|
||||
#define RESET_COUNTER(name) this->name.Reset();
|
||||
FOR_EACH_MANUAL_COUNTER(RESET_COUNTER)
|
||||
#undef RESET_COUNTER
|
||||
|
||||
#define RESET_COUNTER(name, nargs, result_size) this->Runtime_##name.Reset();
|
||||
FOR_EACH_INTRINSIC(RESET_COUNTER)
|
||||
#undef RESET_COUNTER
|
||||
|
||||
#define RESET_COUNTER(name) this->Builtin_##name.Reset();
|
||||
BUILTIN_LIST_C(RESET_COUNTER)
|
||||
#undef RESET_COUNTER
|
||||
|
||||
#define RESET_COUNTER(name) this->API_##name.Reset();
|
||||
FOR_EACH_API_COUNTER(RESET_COUNTER)
|
||||
#undef RESET_COUNTER
|
||||
|
||||
#define RESET_COUNTER(name) this->Handler_##name.Reset();
|
||||
FOR_EACH_HANDLER_COUNTER(RESET_COUNTER)
|
||||
#undef RESET_COUNTER
|
||||
for (const RuntimeCallStats::CounterId counter_id :
|
||||
RuntimeCallStats::counters) {
|
||||
RuntimeCallCounter* counter = &(this->*counter_id);
|
||||
counter->Reset();
|
||||
}
|
||||
|
||||
in_use_ = true;
|
||||
}
|
||||
|
||||
void RuntimeCallStats::Dump(v8::tracing::TracedValue* value) {
|
||||
#define DUMP_COUNTER(name) \
|
||||
if (this->name.count > 0) this->name.Dump(value);
|
||||
FOR_EACH_MANUAL_COUNTER(DUMP_COUNTER)
|
||||
#undef DUMP_COUNTER
|
||||
|
||||
#define DUMP_COUNTER(name, nargs, result_size) \
|
||||
if (this->Runtime_##name.count > 0) this->Runtime_##name.Dump(value);
|
||||
FOR_EACH_INTRINSIC(DUMP_COUNTER)
|
||||
#undef DUMP_COUNTER
|
||||
|
||||
#define DUMP_COUNTER(name) \
|
||||
if (this->Builtin_##name.count > 0) this->Builtin_##name.Dump(value);
|
||||
BUILTIN_LIST_C(DUMP_COUNTER)
|
||||
#undef DUMP_COUNTER
|
||||
|
||||
#define DUMP_COUNTER(name) \
|
||||
if (this->API_##name.count > 0) this->API_##name.Dump(value);
|
||||
FOR_EACH_API_COUNTER(DUMP_COUNTER)
|
||||
#undef DUMP_COUNTER
|
||||
|
||||
#define DUMP_COUNTER(name) \
|
||||
if (this->Handler_##name.count > 0) this->Handler_##name.Dump(value);
|
||||
FOR_EACH_HANDLER_COUNTER(DUMP_COUNTER)
|
||||
#undef DUMP_COUNTER
|
||||
for (const RuntimeCallStats::CounterId counter_id :
|
||||
RuntimeCallStats::counters) {
|
||||
RuntimeCallCounter* counter = &(this->*counter_id);
|
||||
if (counter->count > 0) counter->Dump(value);
|
||||
}
|
||||
|
||||
in_use_ = false;
|
||||
}
|
||||
|
@ -488,6 +488,7 @@ struct RuntimeCallCounter {
|
||||
explicit RuntimeCallCounter(const char* name) : name(name) {}
|
||||
V8_NOINLINE void Reset();
|
||||
V8_NOINLINE void Dump(v8::tracing::TracedValue* value);
|
||||
void Add(RuntimeCallCounter* other);
|
||||
|
||||
const char* name;
|
||||
int64_t count = 0;
|
||||
@ -537,6 +538,8 @@ class RuntimeCallTimer {
|
||||
timer_.Restart();
|
||||
}
|
||||
|
||||
const char* name() { return counter_->name; }
|
||||
|
||||
RuntimeCallCounter* counter_ = nullptr;
|
||||
base::AtomicValue<RuntimeCallTimer*> parent_;
|
||||
base::ElapsedTimer timer_;
|
||||
@ -724,8 +727,14 @@ class RuntimeCallTimer {
|
||||
V(Map_TransitionToDataProperty) \
|
||||
V(Object_DeleteProperty) \
|
||||
V(OptimizeCode) \
|
||||
V(ParseProgram) \
|
||||
V(ParseArrowFunctionLiteral) \
|
||||
V(ParseEval) \
|
||||
V(ParseFunction) \
|
||||
V(ParseFunctionLiteral) \
|
||||
V(ParseProgram) \
|
||||
V(PreParseArrowFunctionLiteral) \
|
||||
V(PreParseNoVariableResolution) \
|
||||
V(PreParseWithVariableResolution) \
|
||||
V(PropertyCallback) \
|
||||
V(PrototypeMap_TransitionToAccessorProperty) \
|
||||
V(PrototypeMap_TransitionToDataProperty) \
|
||||
@ -803,7 +812,7 @@ class RuntimeCallTimer {
|
||||
V(StoreIC_StoreTransitionDH) \
|
||||
V(StoreIC_StoreViaSetter)
|
||||
|
||||
class RuntimeCallStats {
|
||||
class RuntimeCallStats : public ZoneObject {
|
||||
public:
|
||||
typedef RuntimeCallCounter RuntimeCallStats::*CounterId;
|
||||
|
||||
@ -828,6 +837,8 @@ class RuntimeCallStats {
|
||||
FOR_EACH_HANDLER_COUNTER(CALL_BUILTIN_COUNTER)
|
||||
#undef CALL_BUILTIN_COUNTER
|
||||
|
||||
static const CounterId counters[];
|
||||
|
||||
// Starting measuring the time for a function. This will establish the
|
||||
// connection to the parent counter for properly calculating the own times.
|
||||
static void Enter(RuntimeCallStats* stats, RuntimeCallTimer* timer,
|
||||
@ -844,6 +855,8 @@ class RuntimeCallStats {
|
||||
CounterId counter_id);
|
||||
|
||||
void Reset();
|
||||
// Add all entries from another stats object.
|
||||
void Add(RuntimeCallStats* other);
|
||||
void Print(std::ostream& os);
|
||||
V8_NOINLINE void Dump(v8::tracing::TracedValue* value);
|
||||
|
||||
@ -862,17 +875,17 @@ class RuntimeCallStats {
|
||||
bool in_use_;
|
||||
};
|
||||
|
||||
#define TRACE_RUNTIME_CALL_STATS(isolate, counter_name) \
|
||||
do { \
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) { \
|
||||
RuntimeCallStats::CorrectCurrentCounterId( \
|
||||
isolate->counters()->runtime_call_stats(), \
|
||||
&RuntimeCallStats::counter_name); \
|
||||
} \
|
||||
#define CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats, counter_name) \
|
||||
do { \
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) { \
|
||||
RuntimeCallStats::CorrectCurrentCounterId( \
|
||||
runtime_call_stats, &RuntimeCallStats::counter_name); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
#define TRACE_HANDLER_STATS(isolate, counter_name) \
|
||||
TRACE_RUNTIME_CALL_STATS(isolate, Handler_##counter_name)
|
||||
#define TRACE_HANDLER_STATS(isolate, counter_name) \
|
||||
CHANGE_CURRENT_RUNTIME_COUNTER(isolate->counters()->runtime_call_stats(), \
|
||||
Handler_##counter_name)
|
||||
|
||||
#define HISTOGRAM_RANGE_LIST(HR) \
|
||||
/* Generic range histograms */ \
|
||||
@ -1295,23 +1308,23 @@ class RuntimeCallTimerScope {
|
||||
// stats are disabled and the isolate is not directly available.
|
||||
inline RuntimeCallTimerScope(HeapObject* heap_object,
|
||||
RuntimeCallStats::CounterId counter_id);
|
||||
inline RuntimeCallTimerScope(RuntimeCallStats* stats,
|
||||
RuntimeCallStats::CounterId counter_id);
|
||||
|
||||
inline ~RuntimeCallTimerScope() {
|
||||
if (V8_UNLIKELY(isolate_ != nullptr)) {
|
||||
RuntimeCallStats::Leave(isolate_->counters()->runtime_call_stats(),
|
||||
&timer_);
|
||||
if (V8_UNLIKELY(stats_ != nullptr)) {
|
||||
RuntimeCallStats::Leave(stats_, &timer_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
V8_INLINE void Initialize(Isolate* isolate,
|
||||
V8_INLINE void Initialize(RuntimeCallStats* stats,
|
||||
RuntimeCallStats::CounterId counter_id) {
|
||||
isolate_ = isolate;
|
||||
RuntimeCallStats::Enter(isolate_->counters()->runtime_call_stats(), &timer_,
|
||||
counter_id);
|
||||
stats_ = stats;
|
||||
RuntimeCallStats::Enter(stats_, &timer_, counter_id);
|
||||
}
|
||||
|
||||
Isolate* isolate_ = nullptr;
|
||||
RuntimeCallStats* stats_ = nullptr;
|
||||
RuntimeCallTimer timer_;
|
||||
};
|
||||
|
||||
|
@ -191,13 +191,15 @@ class ParserBase {
|
||||
const Impl* impl() const { return static_cast<const Impl*>(this); }
|
||||
|
||||
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
|
||||
v8::Extension* extension, AstValueFactory* ast_value_factory)
|
||||
v8::Extension* extension, AstValueFactory* ast_value_factory,
|
||||
RuntimeCallStats* runtime_call_stats)
|
||||
: scope_state_(nullptr),
|
||||
function_state_(nullptr),
|
||||
extension_(extension),
|
||||
fni_(nullptr),
|
||||
ast_value_factory_(ast_value_factory),
|
||||
ast_node_factory_(ast_value_factory),
|
||||
runtime_call_stats_(runtime_call_stats),
|
||||
parsing_module_(false),
|
||||
stack_limit_(stack_limit),
|
||||
zone_(zone),
|
||||
@ -1420,6 +1422,7 @@ class ParserBase {
|
||||
FuncNameInferrer* fni_;
|
||||
AstValueFactory* ast_value_factory_; // Not owned.
|
||||
typename Types::Factory ast_node_factory_;
|
||||
RuntimeCallStats* runtime_call_stats_;
|
||||
bool parsing_module_;
|
||||
uintptr_t stack_limit_;
|
||||
|
||||
@ -3887,6 +3890,11 @@ template <typename Impl>
|
||||
typename ParserBase<Impl>::ExpressionT
|
||||
ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
bool accept_IN, const FormalParametersT& formal_parameters, bool* ok) {
|
||||
RuntimeCallTimerScope runtime_timer(
|
||||
runtime_call_stats_,
|
||||
Impl::IsPreParser() ? &RuntimeCallStats::ParseArrowFunctionLiteral
|
||||
: &RuntimeCallStats::PreParseArrowFunctionLiteral);
|
||||
|
||||
if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
|
||||
// ASI inserts `;` after arrow parameters if a line terminator is found.
|
||||
// `=> ...` is never a valid expression, so report as syntax error.
|
||||
|
@ -581,7 +581,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->extension(), info->ast_value_factory(),
|
||||
info->isolate()->counters()->runtime_call_stats()),
|
||||
scanner_(info->unicode_cache()),
|
||||
reusable_preparser_(nullptr),
|
||||
original_scope_(nullptr),
|
||||
@ -665,7 +666,9 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
// called in the main thread.
|
||||
DCHECK(parsing_on_main_thread_);
|
||||
|
||||
RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseProgram);
|
||||
RuntimeCallTimerScope runtime_timer(
|
||||
runtime_call_stats_, info->is_eval() ? &RuntimeCallStats::ParseEval
|
||||
: &RuntimeCallStats::ParseProgram);
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseProgram");
|
||||
Handle<String> source(String::cast(info->script()->source()));
|
||||
isolate->counters()->total_parse_size()->Increment(source->length());
|
||||
@ -828,7 +831,7 @@ FunctionLiteral* Parser::ParseFunction(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(isolate,
|
||||
RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
|
||||
&RuntimeCallStats::ParseFunction);
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseFunction");
|
||||
Handle<String> source(String::cast(info->script()->source()));
|
||||
@ -2575,6 +2578,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
bool is_lazy_top_level_function =
|
||||
can_preparse && impl()->AllowsLazyParsingWithoutUnresolvedVariables();
|
||||
|
||||
RuntimeCallTimerScope runtime_timer(runtime_call_stats_,
|
||||
&RuntimeCallStats::ParseFunctionLiteral);
|
||||
|
||||
// Determine whether we can still lazy parse the inner function.
|
||||
// The preconditions are:
|
||||
// - Lazy compilation has to be enabled.
|
||||
@ -2692,6 +2698,13 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
: (use_temp_zone ? "Preparse resolution" : "Full parse"),
|
||||
scope->start_position(), scope->end_position(),
|
||||
function_name->byte_length(), function_name->raw_data());
|
||||
if (is_lazy_top_level_function) {
|
||||
CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_,
|
||||
PreParseNoVariableResolution);
|
||||
} else if (use_temp_zone) {
|
||||
CHANGE_CURRENT_RUNTIME_COUNTER(runtime_call_stats_,
|
||||
PreParseWithVariableResolution);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate function name. We can do this only after parsing the function,
|
||||
@ -3284,7 +3297,8 @@ PreParser::PreParseResult Parser::ParseFunctionWithPreParser(
|
||||
|
||||
if (reusable_preparser_ == NULL) {
|
||||
reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
|
||||
&pending_error_handler_, stack_limit_);
|
||||
&pending_error_handler_,
|
||||
runtime_call_stats_, stack_limit_);
|
||||
reusable_preparser_->set_allow_lazy(true);
|
||||
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
|
||||
SET_ALLOW(natives);
|
||||
@ -3758,6 +3772,15 @@ void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) {
|
||||
}
|
||||
isolate->counters()->total_preparse_skipped()->Increment(
|
||||
total_preparse_skipped_);
|
||||
if (!parsing_on_main_thread_ &&
|
||||
FLAG_runtime_stats ==
|
||||
v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE) {
|
||||
// Copy over the counters from the background thread to the main counters on
|
||||
// the isolate.
|
||||
// TODO(cbruni,lpy): properly attach the runtime stats to the trace for
|
||||
// background parsing.
|
||||
isolate->counters()->runtime_call_stats()->Add(runtime_call_stats_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3803,6 +3826,10 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
|
||||
ParserLogger logger;
|
||||
if (produce_cached_parse_data()) log_ = &logger;
|
||||
if (FLAG_runtime_stats) {
|
||||
// Create separate runtime stats for background parsing.
|
||||
runtime_call_stats_ = new (zone()) RuntimeCallStats();
|
||||
}
|
||||
|
||||
std::unique_ptr<Utf16CharacterStream> stream;
|
||||
Utf16CharacterStream* stream_ptr;
|
||||
@ -3842,6 +3869,10 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
if (result != NULL) *info->cached_data() = logger.GetScriptData();
|
||||
log_ = NULL;
|
||||
}
|
||||
if (FLAG_runtime_stats) {
|
||||
// TODO(cbruni,lpy): properly attach the runtime stats to the trace for
|
||||
// background parsing.
|
||||
}
|
||||
}
|
||||
|
||||
Parser::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
|
||||
|
@ -201,6 +201,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
cached_parse_data_ = NULL;
|
||||
}
|
||||
|
||||
static bool const IsPreParser() { return false; }
|
||||
|
||||
// Parses the source code represented by the compilation info and sets its
|
||||
// function literal. Returns false (and deallocates any allocated AST
|
||||
// nodes) if parsing failed.
|
||||
@ -1148,7 +1150,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_;
|
||||
ParserLogger* log_;
|
||||
};
|
||||
|
@ -86,6 +86,11 @@ PreParserIdentifier PreParser::GetSymbol() const {
|
||||
PreParser::PreParseResult PreParser::PreParseFunction(
|
||||
FunctionKind kind, DeclarationScope* function_scope, bool parsing_module,
|
||||
bool is_inner_function, bool may_abort, int* use_counts) {
|
||||
RuntimeCallTimerScope runtime_timer(
|
||||
runtime_call_stats_,
|
||||
track_unresolved_variables_
|
||||
? &RuntimeCallStats::PreParseWithVariableResolution
|
||||
: &RuntimeCallStats::PreParseNoVariableResolution);
|
||||
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
|
||||
parsing_module_ = parsing_module;
|
||||
use_counts_ = use_counts;
|
||||
@ -179,6 +184,11 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
LanguageMode language_mode, bool* ok) {
|
||||
// Function ::
|
||||
// '(' FormalParameterList? ')' '{' FunctionBody '}'
|
||||
RuntimeCallTimerScope runtime_timer(
|
||||
runtime_call_stats_,
|
||||
track_unresolved_variables_
|
||||
? &RuntimeCallStats::PreParseWithVariableResolution
|
||||
: &RuntimeCallStats::PreParseNoVariableResolution);
|
||||
|
||||
// Parse function body.
|
||||
PreParserStatementList body;
|
||||
|
@ -840,13 +840,15 @@ class PreParser : public ParserBase<PreParser> {
|
||||
|
||||
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
|
||||
PendingCompilationErrorHandler* pending_error_handler,
|
||||
uintptr_t stack_limit)
|
||||
RuntimeCallStats* runtime_call_stats, uintptr_t stack_limit)
|
||||
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
|
||||
ast_value_factory),
|
||||
ast_value_factory, runtime_call_stats),
|
||||
use_counts_(nullptr),
|
||||
track_unresolved_variables_(false),
|
||||
pending_error_handler_(pending_error_handler) {}
|
||||
|
||||
static bool const IsPreParser() { return true; }
|
||||
|
||||
PreParserLogger* logger() { return &log_; }
|
||||
|
||||
// Pre-parse the program from the character stream; returns true on
|
||||
|
@ -174,8 +174,9 @@ TEST(ScanHTMLEndComments) {
|
||||
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, stack_limit);
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, &ast_value_factory, &pending_error_handler,
|
||||
CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
@ -191,8 +192,9 @@ TEST(ScanHTMLEndComments) {
|
||||
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, stack_limit);
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, &ast_value_factory, &pending_error_handler,
|
||||
CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
// Even in the case of a syntax error, kPreParseSuccess is returned.
|
||||
@ -365,8 +367,9 @@ TEST(StandAlonePreParser) {
|
||||
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, stack_limit);
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, &ast_value_factory, &pending_error_handler,
|
||||
CcTest::i_isolate()->counters()->runtime_call_stats(), stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
preparser.set_allow_natives(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
@ -379,6 +382,7 @@ TEST(StandAlonePreParser) {
|
||||
TEST(StandAlonePreParserNoNatives) {
|
||||
v8::V8::Initialize();
|
||||
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
CcTest::i_isolate()->stack_guard()->SetStackLimit(
|
||||
i::GetCurrentStackPosition() - 128 * 1024);
|
||||
|
||||
@ -388,10 +392,10 @@ TEST(StandAlonePreParserNoNatives) {
|
||||
NULL
|
||||
};
|
||||
|
||||
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
|
||||
uintptr_t stack_limit = isolate->stack_guard()->real_climit();
|
||||
for (int i = 0; programs[i]; i++) {
|
||||
auto stream = i::ScannerStream::ForTesting(programs[i]);
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
i::Scanner scanner(isolate->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
|
||||
// Preparser defaults to disallowing natives syntax.
|
||||
@ -399,8 +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, stack_limit);
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, &ast_value_factory, &pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(), stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
@ -468,6 +473,7 @@ TEST(RegressChromium62639) {
|
||||
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());
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
@ -522,27 +528,29 @@ TEST(Regress928) {
|
||||
|
||||
TEST(PreParseOverflow) {
|
||||
v8::V8::Initialize();
|
||||
i::Isolate* isolate = CcTest::i_isolate();
|
||||
|
||||
CcTest::i_isolate()->stack_guard()->SetStackLimit(
|
||||
i::GetCurrentStackPosition() - 128 * 1024);
|
||||
isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
|
||||
128 * 1024);
|
||||
|
||||
size_t kProgramSize = 1024 * 1024;
|
||||
std::unique_ptr<char[]> program(i::NewArray<char>(kProgramSize + 1));
|
||||
memset(program.get(), '(', kProgramSize);
|
||||
program[kProgramSize] = '\0';
|
||||
|
||||
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
|
||||
uintptr_t stack_limit = isolate->stack_guard()->real_climit();
|
||||
|
||||
auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize);
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
i::Scanner scanner(isolate->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
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, stack_limit);
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, &ast_value_factory, &pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(), stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
|
||||
@ -1337,8 +1345,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, stack_limit);
|
||||
i::PreParser preparser(
|
||||
&zone, &scanner, &ast_value_factory, &pending_error_handler,
|
||||
isolate->counters()->runtime_call_stats(), stack_limit);
|
||||
SetParserFlags(&preparser, flags);
|
||||
scanner.Initialize(stream.get());
|
||||
i::PreParser::PreParseResult result =
|
||||
|
Loading…
Reference in New Issue
Block a user