Revert "[parser][log] Log script id during background compilation"
This reverts commit aafd5c52ab
.
Reason for revert: Tentative revert for
https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Win64/24825
https://ci.chromium.org/p/v8/builders/luci.v8.ci/V8%20Win64%20-%20msvc/3242
Original change's description:
> [parser][log] Log script id during background compilation
>
> - Add separate script-create, script-reserve-id and script-details log events
> - Add log events for CompilationCache hits and puts
> - Simplify function event logging by only pass along the script id
> - Explicitly create Scripts in parse-processor.js on script events only
> - Create a temporary script id in the ParseInfo for use during background
> parsing and compilation
> - Clean up ParseInfo initialization to centralize creation and use of
> script ids
> - Allow creating Scripts with predefined script ids
>
> Bug: chromium:757467, chromium:850038
> Change-Id: I02dfd1d5725795b9fe0ea94ef57b287b934a1efe
> Reviewed-on: https://chromium-review.googlesource.com/1097131
> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Commit-Queue: Camillo Bruni <cbruni@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#53978}
TBR=ulan@chromium.org,cbruni@chromium.org,gsathya@chromium.org,leszeks@chromium.org
Change-Id: I629f72f51d5e086e2b54658c1fdd18cec268aab2
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:757467, chromium:850038
Reviewed-on: https://chromium-review.googlesource.com/1112538
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53984}
This commit is contained in:
parent
eb785dc0cc
commit
a800e05007
@ -160,7 +160,6 @@ MaybeHandle<SharedFunctionInfo> CompilationCacheScript::Lookup(
|
||||
resource_options));
|
||||
#endif
|
||||
isolate()->counters()->compilation_cache_hits()->Increment();
|
||||
LOG(isolate(), CompilationCacheEvent("hit", "script", *function_info));
|
||||
} else {
|
||||
isolate()->counters()->compilation_cache_misses()->Increment();
|
||||
}
|
||||
@ -275,23 +274,14 @@ InfoCellPair CompilationCache::LookupEval(Handle<String> source,
|
||||
InfoCellPair result;
|
||||
if (!IsEnabled()) return result;
|
||||
|
||||
const char* cache_type;
|
||||
|
||||
if (context->IsNativeContext()) {
|
||||
result = eval_global_.Lookup(source, outer_info, context, language_mode,
|
||||
position);
|
||||
cache_type = "eval-global";
|
||||
|
||||
} else {
|
||||
DCHECK_NE(position, kNoSourcePosition);
|
||||
Handle<Context> native_context(context->native_context(), isolate());
|
||||
result = eval_contextual_.Lookup(source, outer_info, native_context,
|
||||
language_mode, position);
|
||||
cache_type = "eval-contextual";
|
||||
}
|
||||
|
||||
if (result.has_shared()) {
|
||||
LOG(isolate(), CompilationCacheEvent("hit", cache_type, result.shared()));
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -309,7 +299,6 @@ void CompilationCache::PutScript(Handle<String> source,
|
||||
LanguageMode language_mode,
|
||||
Handle<SharedFunctionInfo> function_info) {
|
||||
if (!IsEnabled()) return;
|
||||
LOG(isolate(), CompilationCacheEvent("put", "script", *function_info));
|
||||
|
||||
script_.Put(source, native_context, language_mode, function_info);
|
||||
}
|
||||
@ -322,26 +311,24 @@ void CompilationCache::PutEval(Handle<String> source,
|
||||
int position) {
|
||||
if (!IsEnabled()) return;
|
||||
|
||||
const char* cache_type;
|
||||
HandleScope scope(isolate());
|
||||
if (context->IsNativeContext()) {
|
||||
eval_global_.Put(source, outer_info, function_info, context, feedback_cell,
|
||||
position);
|
||||
cache_type = "eval-global";
|
||||
} else {
|
||||
DCHECK_NE(position, kNoSourcePosition);
|
||||
Handle<Context> native_context(context->native_context(), isolate());
|
||||
eval_contextual_.Put(source, outer_info, function_info, native_context,
|
||||
feedback_cell, position);
|
||||
cache_type = "eval-contextual";
|
||||
}
|
||||
LOG(isolate(), CompilationCacheEvent("put", cache_type, *function_info));
|
||||
}
|
||||
|
||||
void CompilationCache::PutRegExp(Handle<String> source,
|
||||
JSRegExp::Flags flags,
|
||||
Handle<FixedArray> data) {
|
||||
if (!IsEnabled()) return;
|
||||
if (!IsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
reg_exp_.Put(source, flags, data);
|
||||
}
|
||||
|
@ -220,9 +220,9 @@ class CompilationCache {
|
||||
// The number of sub caches covering the different types to cache.
|
||||
static const int kSubCacheCount = 4;
|
||||
|
||||
bool IsEnabled() const { return FLAG_compilation_cache && enabled_; }
|
||||
bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
|
||||
|
||||
Isolate* isolate() const { return isolate_; }
|
||||
Isolate* isolate() { return isolate_; }
|
||||
|
||||
Isolate* isolate_;
|
||||
|
||||
|
@ -116,22 +116,14 @@ void UnoptimizedCompileJob::PrepareOnMainThread(Isolate* isolate) {
|
||||
static_cast<void*>(this));
|
||||
}
|
||||
|
||||
ParseInfo* parse_info = new ParseInfo(isolate, shared_);
|
||||
parse_info_.reset(parse_info);
|
||||
|
||||
unicode_cache_.reset(new UnicodeCache());
|
||||
parse_info_->set_unicode_cache(unicode_cache_.get());
|
||||
parse_info_->set_function_literal_id(shared_->function_literal_id());
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) {
|
||||
parse_info_->set_runtime_call_stats(new (parse_info_->zone())
|
||||
RuntimeCallStats());
|
||||
}
|
||||
|
||||
Handle<Script> script = parse_info->script();
|
||||
HandleScope scope(isolate);
|
||||
|
||||
unicode_cache_.reset(new UnicodeCache());
|
||||
Handle<Script> script(Script::cast(shared_->script()), isolate);
|
||||
DCHECK(script->type() != Script::TYPE_NATIVE);
|
||||
|
||||
Handle<String> source(String::cast(script->source()), isolate);
|
||||
parse_info_.reset(new ParseInfo(isolate->allocator()));
|
||||
parse_info_->InitFromIsolate(isolate);
|
||||
if (source->IsExternalTwoByteString() || source->IsExternalOneByteString()) {
|
||||
std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
|
||||
source, shared_->StartPosition(), shared_->EndPosition()));
|
||||
@ -198,15 +190,29 @@ void UnoptimizedCompileJob::PrepareOnMainThread(Isolate* isolate) {
|
||||
shared_->EndPosition() - offset));
|
||||
parse_info_->set_character_stream(std::move(stream));
|
||||
}
|
||||
parser_.reset(new Parser(parse_info_.get()));
|
||||
parser_->DeserializeScopeChain(isolate, parse_info_.get(),
|
||||
parse_info_->maybe_outer_scope_info());
|
||||
parse_info_->set_hash_seed(isolate->heap()->HashSeed());
|
||||
parse_info_->set_is_named_expression(shared_->is_named_expression());
|
||||
parse_info_->set_function_flags(shared_->flags());
|
||||
parse_info_->set_start_position(shared_->StartPosition());
|
||||
parse_info_->set_end_position(shared_->EndPosition());
|
||||
parse_info_->set_unicode_cache(unicode_cache_.get());
|
||||
parse_info_->set_language_mode(shared_->language_mode());
|
||||
parse_info_->set_function_literal_id(shared_->function_literal_id());
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) {
|
||||
parse_info_->set_runtime_call_stats(new (parse_info_->zone())
|
||||
RuntimeCallStats());
|
||||
}
|
||||
|
||||
parser_.reset(new Parser(parse_info_.get()));
|
||||
MaybeHandle<ScopeInfo> outer_scope_info;
|
||||
if (shared_->HasOuterScopeInfo()) {
|
||||
outer_scope_info = handle(shared_->GetOuterScopeInfo(), isolate);
|
||||
}
|
||||
parser_->DeserializeScopeChain(isolate, parse_info_.get(), outer_scope_info);
|
||||
|
||||
// Initailize the name after setting up the ast_value_factory.
|
||||
Handle<String> name(shared_->Name());
|
||||
parse_info_->set_function_name(
|
||||
parse_info_->ast_value_factory()->GetString(name));
|
||||
|
||||
set_status(Status::kPrepared);
|
||||
}
|
||||
|
||||
@ -272,8 +278,7 @@ void UnoptimizedCompileJob::FinalizeOnMainThread(Isolate* isolate) {
|
||||
}
|
||||
|
||||
Handle<Script> script(Script::cast(shared_->script()), isolate);
|
||||
DCHECK_EQ(*parse_info_->script(), shared_->script());
|
||||
|
||||
parse_info_->set_script(script);
|
||||
parser_->UpdateStatistics(isolate, script);
|
||||
parse_info_->UpdateBackgroundParseStatisticsOnMainThread(isolate);
|
||||
parser_->HandleSourceURLComments(isolate, script);
|
||||
|
@ -119,7 +119,7 @@ void LogFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
LOG(isolate, FunctionEvent(name.c_str(), script->id(), time_taken_ms,
|
||||
LOG(isolate, FunctionEvent(name.c_str(), nullptr, script->id(), time_taken_ms,
|
||||
shared->StartPosition(), shared->EndPosition(),
|
||||
shared->DebugName()));
|
||||
}
|
||||
@ -972,8 +972,8 @@ BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* source,
|
||||
|
||||
// Prepare the data for the internalization phase and compilation phase, which
|
||||
// will happen in the main thread after parsing.
|
||||
ParseInfo* info = new ParseInfo(isolate);
|
||||
LOG(isolate, ScriptEvent("background-compile", info->script_id()));
|
||||
ParseInfo* info = new ParseInfo(isolate->allocator());
|
||||
info->InitFromIsolate(isolate);
|
||||
if (V8_UNLIKELY(FLAG_runtime_stats)) {
|
||||
info->set_runtime_call_stats(new (info->zone()) RuntimeCallStats());
|
||||
} else {
|
||||
@ -1278,16 +1278,18 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||
script = Handle<Script>(Script::cast(shared_info->script()), isolate);
|
||||
allow_eval_cache = true;
|
||||
} else {
|
||||
ParseInfo parse_info(isolate);
|
||||
script = parse_info.CreateScript(isolate, source, options);
|
||||
script = isolate->factory()->NewScript(source);
|
||||
if (isolate->NeedsSourcePositionsForProfiling()) {
|
||||
Script::InitLineEnds(script);
|
||||
}
|
||||
if (!script_name.is_null()) {
|
||||
// TODO(cbruni): check whether we can store this data in options
|
||||
script->set_name(*script_name);
|
||||
script->set_line_offset(line_offset);
|
||||
script->set_column_offset(column_offset);
|
||||
LOG(isolate, ScriptDetails(*script));
|
||||
}
|
||||
script->set_origin_options(options);
|
||||
script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
|
||||
|
||||
script->set_eval_from_shared(*outer_info);
|
||||
if (eval_position == kNoSourcePosition) {
|
||||
// If the position is missing, attempt to get the code offset by
|
||||
@ -1305,6 +1307,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||
}
|
||||
script->set_eval_from_position(eval_position);
|
||||
|
||||
ParseInfo parse_info(isolate, script);
|
||||
parse_info.set_eval();
|
||||
parse_info.set_language_mode(language_mode);
|
||||
parse_info.set_parse_restriction(restriction);
|
||||
@ -1598,20 +1601,29 @@ struct ScriptCompileTimerScope {
|
||||
}
|
||||
};
|
||||
|
||||
Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
|
||||
Handle<String> source,
|
||||
Handle<Script> NewScript(Isolate* isolate, Handle<String> source,
|
||||
Compiler::ScriptDetails script_details,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives) {
|
||||
// Create a script object describing the script to be compiled.
|
||||
Handle<Script> script =
|
||||
parse_info->CreateScript(isolate, source, origin_options, natives);
|
||||
Handle<Script> script = isolate->factory()->NewScript(source);
|
||||
if (isolate->NeedsSourcePositionsForProfiling()) {
|
||||
Script::InitLineEnds(script);
|
||||
}
|
||||
if (natives == NATIVES_CODE) {
|
||||
script->set_type(Script::TYPE_NATIVE);
|
||||
} else if (natives == EXTENSION_CODE) {
|
||||
script->set_type(Script::TYPE_EXTENSION);
|
||||
} else if (natives == INSPECTOR_CODE) {
|
||||
script->set_type(Script::TYPE_INSPECTOR);
|
||||
}
|
||||
Handle<Object> script_name;
|
||||
if (script_details.name_obj.ToHandle(&script_name)) {
|
||||
script->set_name(*script_name);
|
||||
script->set_line_offset(script_details.line_offset);
|
||||
script->set_column_offset(script_details.column_offset);
|
||||
}
|
||||
script->set_origin_options(origin_options);
|
||||
Handle<Object> source_map_url;
|
||||
if (script_details.source_map_url.ToHandle(&source_map_url)) {
|
||||
script->set_source_mapping_url(*source_map_url);
|
||||
@ -1620,7 +1632,6 @@ Handle<Script> NewScript(Isolate* isolate, ParseInfo* parse_info,
|
||||
if (script_details.host_defined_options.ToHandle(&host_defined_options)) {
|
||||
script->set_host_defined_options(*host_defined_options);
|
||||
}
|
||||
LOG(isolate, ScriptDetails(*script));
|
||||
return script;
|
||||
}
|
||||
|
||||
@ -1692,12 +1703,12 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
|
||||
}
|
||||
|
||||
if (maybe_result.is_null()) {
|
||||
ParseInfo parse_info(isolate);
|
||||
// No cache entry found compile the script.
|
||||
NewScript(isolate, &parse_info, source, script_details, origin_options,
|
||||
natives);
|
||||
Handle<Script> script =
|
||||
NewScript(isolate, source, script_details, origin_options, natives);
|
||||
|
||||
// Compile the function and add it to the isolate cache.
|
||||
ParseInfo parse_info(isolate, script);
|
||||
Zone compile_zone(isolate->allocator(), ZONE_NAME);
|
||||
if (origin_options.IsModule()) parse_info.set_module();
|
||||
parse_info.set_extension(extension);
|
||||
@ -1765,11 +1776,11 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
|
||||
Handle<SharedFunctionInfo> wrapped;
|
||||
Handle<Script> script;
|
||||
if (!maybe_result.ToHandle(&wrapped)) {
|
||||
ParseInfo parse_info(isolate);
|
||||
script = NewScript(isolate, &parse_info, source, script_details,
|
||||
origin_options, NOT_NATIVES_CODE);
|
||||
script = NewScript(isolate, source, script_details, origin_options,
|
||||
NOT_NATIVES_CODE);
|
||||
script->set_wrapped_arguments(*arguments);
|
||||
|
||||
ParseInfo parse_info(isolate, script);
|
||||
parse_info.set_eval(); // Use an eval scope as declaration scope.
|
||||
parse_info.set_wrapped_as_function();
|
||||
// parse_info.set_eager(compile_options == ScriptCompiler::kEagerCompile);
|
||||
@ -1836,9 +1847,9 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
if (maybe_result.is_null()) {
|
||||
// No cache entry found, finalize compilation of the script and add it to
|
||||
// the isolate cache.
|
||||
Handle<Script> script =
|
||||
NewScript(isolate, parse_info, source, script_details, origin_options,
|
||||
NOT_NATIVES_CODE);
|
||||
Handle<Script> script = NewScript(isolate, source, script_details,
|
||||
origin_options, NOT_NATIVES_CODE);
|
||||
parse_info->set_script(script);
|
||||
streaming_data->parser->UpdateStatistics(isolate, script);
|
||||
streaming_data->parser->HandleSourceURLComments(isolate, script);
|
||||
|
||||
|
@ -1515,18 +1515,13 @@ Handle<AccessorInfo> Factory::NewAccessorInfo() {
|
||||
}
|
||||
|
||||
Handle<Script> Factory::NewScript(Handle<String> source, PretenureFlag tenure) {
|
||||
return NewScriptWithId(source, isolate()->heap()->NextScriptId(), tenure);
|
||||
}
|
||||
|
||||
Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id,
|
||||
PretenureFlag tenure) {
|
||||
DCHECK(tenure == TENURED || tenure == TENURED_READ_ONLY);
|
||||
// Create and initialize script object.
|
||||
Heap* heap = isolate()->heap();
|
||||
Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE, tenure));
|
||||
script->set_source(*source);
|
||||
script->set_name(heap->undefined_value());
|
||||
script->set_id(script_id);
|
||||
script->set_id(isolate()->heap()->NextScriptId());
|
||||
script->set_line_offset(0);
|
||||
script->set_column_offset(0);
|
||||
script->set_context_data(heap->undefined_value());
|
||||
@ -1540,7 +1535,6 @@ Handle<Script> Factory::NewScriptWithId(Handle<String> source, int script_id,
|
||||
script->set_flags(0);
|
||||
script->set_host_defined_options(*empty_fixed_array());
|
||||
heap->set_script_list(*FixedArrayOfWeakCells::Add(script_list(), script));
|
||||
LOG(isolate(), ScriptEvent("create", script_id));
|
||||
return script;
|
||||
}
|
||||
|
||||
|
@ -401,8 +401,6 @@ class V8_EXPORT_PRIVATE Factory {
|
||||
|
||||
Handle<Script> NewScript(Handle<String> source,
|
||||
PretenureFlag tenure = TENURED);
|
||||
Handle<Script> NewScriptWithId(Handle<String> source, int script_id,
|
||||
PretenureFlag tenure = TENURED);
|
||||
|
||||
Handle<BreakPointInfo> NewBreakPointInfo(int source_position);
|
||||
Handle<BreakPoint> NewBreakPoint(int id, Handle<String> condition);
|
||||
|
81
src/log.cc
81
src/log.cc
@ -1530,84 +1530,49 @@ void Logger::SuspectReadEvent(Name* name, Object* obj) {
|
||||
|
||||
namespace {
|
||||
void AppendFunctionMessage(Log::MessageBuilder& msg, const char* reason,
|
||||
int script_id, double time_delta, int start_position,
|
||||
int end_position, base::ElapsedTimer* timer) {
|
||||
msg << "function" << Logger::kNext << reason << Logger::kNext << script_id
|
||||
<< Logger::kNext << start_position << Logger::kNext << end_position
|
||||
Script* script, int script_id, double time_delta,
|
||||
int start_position, int end_position,
|
||||
base::ElapsedTimer* timer) {
|
||||
msg << "function" << Logger::kNext << reason << Logger::kNext;
|
||||
if (script) {
|
||||
if (script->name()->IsString()) {
|
||||
msg << String::cast(script->name());
|
||||
}
|
||||
msg << Logger::kNext << script->id();
|
||||
} else {
|
||||
msg << Logger::kNext << script_id;
|
||||
}
|
||||
msg << Logger::kNext << start_position << Logger::kNext << end_position
|
||||
<< Logger::kNext << time_delta << Logger::kNext
|
||||
<< timer->Elapsed().InMicroseconds() << Logger::kNext;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
|
||||
int start_position, int end_position,
|
||||
String* function_name) {
|
||||
void Logger::FunctionEvent(const char* reason, Script* script, int script_id,
|
||||
double time_delta, int start_position,
|
||||
int end_position, String* function_name) {
|
||||
if (!log_->IsEnabled() || !FLAG_log_function_events) return;
|
||||
Log::MessageBuilder msg(log_);
|
||||
AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
|
||||
end_position, &timer_);
|
||||
AppendFunctionMessage(msg, reason, script, script_id, time_delta,
|
||||
start_position, end_position, &timer_);
|
||||
if (function_name) msg << function_name;
|
||||
msg.WriteToLogFile();
|
||||
}
|
||||
|
||||
void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
|
||||
int start_position, int end_position,
|
||||
const char* function_name,
|
||||
void Logger::FunctionEvent(const char* reason, Script* script, int script_id,
|
||||
double time_delta, int start_position,
|
||||
int end_position, const char* function_name,
|
||||
size_t function_name_length) {
|
||||
if (!log_->IsEnabled() || !FLAG_log_function_events) return;
|
||||
Log::MessageBuilder msg(log_);
|
||||
AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
|
||||
end_position, &timer_);
|
||||
AppendFunctionMessage(msg, reason, script, script_id, time_delta,
|
||||
start_position, end_position, &timer_);
|
||||
if (function_name_length > 0) {
|
||||
msg.AppendStringPart(function_name, function_name_length);
|
||||
}
|
||||
msg.WriteToLogFile();
|
||||
}
|
||||
|
||||
namespace {
|
||||
void AppendCompilationCacheMessage(Log::MessageBuilder& msg,
|
||||
SharedFunctionInfo* sfi) {
|
||||
int script_id = -1;
|
||||
if (sfi->script()->IsScript()) {
|
||||
script_id = Script::cast(sfi->script())->id();
|
||||
}
|
||||
msg << script_id << Logger::kNext << sfi->StartPosition() << Logger::kNext
|
||||
<< sfi->EndPosition();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void Logger::CompilationCacheEvent(const char* action, const char* cache_type,
|
||||
SharedFunctionInfo* sfi) {
|
||||
if (!log_->IsEnabled() || !FLAG_log_function_events) return;
|
||||
Log::MessageBuilder msg(log_);
|
||||
msg << "compilation-cache" << Logger::kNext << action << Logger::kNext
|
||||
<< cache_type << Logger::kNext;
|
||||
AppendCompilationCacheMessage(msg, sfi);
|
||||
msg.WriteToLogFile();
|
||||
}
|
||||
|
||||
void Logger::ScriptEvent(const char* event_name, int script_id) {
|
||||
if (!log_->IsEnabled() || !FLAG_log_function_events) return;
|
||||
Log::MessageBuilder msg(log_);
|
||||
msg << "script" << Logger::kNext << event_name << Logger::kNext << script_id;
|
||||
msg.WriteToLogFile();
|
||||
}
|
||||
|
||||
void Logger::ScriptDetails(Script* script) {
|
||||
if (!log_->IsEnabled() || !FLAG_log_function_events) return;
|
||||
Log::MessageBuilder msg(log_);
|
||||
msg << "script-details" << Logger::kNext << script->id() << Logger::kNext;
|
||||
if (script->name()->IsString()) {
|
||||
msg << String::cast(script->name());
|
||||
}
|
||||
msg << Logger::kNext << script->line_offset() << Logger::kNext
|
||||
<< script->column_offset() << Logger::kNext;
|
||||
if (script->source_mapping_url()->IsString()) {
|
||||
msg << String::cast(script->source_mapping_url());
|
||||
}
|
||||
msg.WriteToLogFile();
|
||||
}
|
||||
|
||||
void Logger::RuntimeCallTimerEvent() {
|
||||
RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats();
|
||||
RuntimeCallCounter* counter = stats->current_counter();
|
||||
|
16
src/log.h
16
src/log.h
@ -165,20 +165,14 @@ class Logger : public CodeEventListener {
|
||||
// object.
|
||||
void SuspectReadEvent(Name* name, Object* obj);
|
||||
|
||||
// ==== Events logged by --log-function-events ====
|
||||
void FunctionEvent(const char* reason, int script_id, double time_delta_ms,
|
||||
int start_position = -1, int end_position = -1,
|
||||
String* function_name = nullptr);
|
||||
void FunctionEvent(const char* reason, int script_id, double time_delta_ms,
|
||||
int start_position, int end_position,
|
||||
void FunctionEvent(const char* reason, Script* script, int script_id,
|
||||
double time_delta_ms, int start_position = -1,
|
||||
int end_position = -1, String* function_name = nullptr);
|
||||
void FunctionEvent(const char* reason, Script* script, int script_id,
|
||||
double time_delta_ms, int start_position, int end_position,
|
||||
const char* function_name = nullptr,
|
||||
size_t function_name_length = 0);
|
||||
|
||||
void CompilationCacheEvent(const char* action, const char* cache_type,
|
||||
SharedFunctionInfo* sfi);
|
||||
void ScriptEvent(const char* event_name, int script_id);
|
||||
void ScriptDetails(Script* script);
|
||||
|
||||
// ==== Events logged by --log-api. ====
|
||||
void ApiSecurityCheck();
|
||||
void ApiNamedPropertyAccess(const char* tag, JSObject* holder, Object* name);
|
||||
|
@ -16,7 +16,7 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator)
|
||||
ParseInfo::ParseInfo(AccountingAllocator* zone_allocator)
|
||||
: zone_(std::make_shared<Zone>(zone_allocator, ZONE_NAME)),
|
||||
flags_(0),
|
||||
extension_(nullptr),
|
||||
@ -25,7 +25,6 @@ ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator)
|
||||
stack_limit_(0),
|
||||
hash_seed_(0),
|
||||
function_flags_(0),
|
||||
script_id_(-1),
|
||||
start_position_(0),
|
||||
end_position_(0),
|
||||
parameters_end_pos_(kNoSourcePosition),
|
||||
@ -37,25 +36,12 @@ ParseInfo::ParseInfo(Isolate* isolate, AccountingAllocator* zone_allocator)
|
||||
function_name_(nullptr),
|
||||
runtime_call_stats_(nullptr),
|
||||
source_range_map_(nullptr),
|
||||
literal_(nullptr) {
|
||||
set_hash_seed(isolate->heap()->HashSeed());
|
||||
set_stack_limit(isolate->stack_guard()->real_climit());
|
||||
set_unicode_cache(isolate->unicode_cache());
|
||||
set_runtime_call_stats(isolate->counters()->runtime_call_stats());
|
||||
set_logger(isolate->logger());
|
||||
set_ast_string_constants(isolate->ast_string_constants());
|
||||
if (isolate->is_block_code_coverage()) set_block_coverage_enabled();
|
||||
if (isolate->is_collecting_type_profile()) set_collect_type_profile();
|
||||
}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate)
|
||||
: ParseInfo(isolate, isolate->allocator()) {
|
||||
script_id_ = isolate->heap()->NextScriptId();
|
||||
LOG(isolate, ScriptEvent("reserve-id", script_id_));
|
||||
}
|
||||
literal_(nullptr) {}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
|
||||
: ParseInfo(isolate, isolate->allocator()) {
|
||||
: ParseInfo(isolate->allocator()) {
|
||||
InitFromIsolate(isolate);
|
||||
|
||||
// Do not support re-parsing top-level function of a wrapped script.
|
||||
// TODO(yangguo): consider whether we need a top-level function in a
|
||||
// wrapped script at all.
|
||||
@ -74,6 +60,10 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
|
||||
|
||||
Handle<Script> script(Script::cast(shared->script()), isolate);
|
||||
set_script(script);
|
||||
set_native(script->type() == Script::TYPE_NATIVE);
|
||||
set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
|
||||
set_module(script->origin_options().IsModule());
|
||||
DCHECK(!(is_eval() && is_module()));
|
||||
|
||||
if (shared->HasOuterScopeInfo()) {
|
||||
set_outer_scope_info(handle(shared->GetOuterScopeInfo(), isolate));
|
||||
@ -87,17 +77,70 @@ ParseInfo::ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared)
|
||||
(shared->HasFeedbackMetadata()
|
||||
? shared->feedback_metadata()->HasTypeProfileSlot()
|
||||
: script->IsUserJavaScript()));
|
||||
if (block_coverage_enabled() && script->IsUserJavaScript()) {
|
||||
AllocateSourceRangeMap();
|
||||
}
|
||||
}
|
||||
|
||||
ParseInfo::ParseInfo(Isolate* isolate, Handle<Script> script)
|
||||
: ParseInfo(isolate, isolate->allocator()) {
|
||||
SetScriptForToplevelCompile(isolate, script);
|
||||
: ParseInfo(isolate->allocator()) {
|
||||
InitFromIsolate(isolate);
|
||||
|
||||
set_allow_lazy_parsing();
|
||||
set_toplevel();
|
||||
set_script(script);
|
||||
set_wrapped_as_function(script->is_wrapped());
|
||||
|
||||
set_native(script->type() == Script::TYPE_NATIVE);
|
||||
set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
|
||||
set_module(script->origin_options().IsModule());
|
||||
DCHECK(!(is_eval() && is_module()));
|
||||
|
||||
set_collect_type_profile(isolate->is_collecting_type_profile() &&
|
||||
script->IsUserJavaScript());
|
||||
if (block_coverage_enabled() && script->IsUserJavaScript()) {
|
||||
AllocateSourceRangeMap();
|
||||
}
|
||||
}
|
||||
|
||||
ParseInfo::~ParseInfo() {}
|
||||
|
||||
// static
|
||||
ParseInfo* ParseInfo::AllocateWithoutScript(Isolate* isolate,
|
||||
Handle<SharedFunctionInfo> shared) {
|
||||
ParseInfo* p = new ParseInfo(isolate->allocator());
|
||||
|
||||
p->InitFromIsolate(isolate);
|
||||
p->set_toplevel(shared->is_toplevel());
|
||||
p->set_allow_lazy_parsing(FLAG_lazy_inner_functions);
|
||||
p->set_is_named_expression(shared->is_named_expression());
|
||||
p->set_function_flags(shared->flags());
|
||||
p->set_start_position(shared->StartPosition());
|
||||
p->set_end_position(shared->EndPosition());
|
||||
p->function_literal_id_ = shared->function_literal_id();
|
||||
p->set_language_mode(shared->language_mode());
|
||||
|
||||
// BUG(5946): This function exists as a workaround until we can
|
||||
// get rid of %SetCode in our native functions. The ParseInfo
|
||||
// is explicitly set up for the case that:
|
||||
// a) you have a native built-in,
|
||||
// b) it's being run for the 2nd-Nth time in an isolate,
|
||||
// c) we've already compiled bytecode and therefore don't need
|
||||
// to parse.
|
||||
// We tolerate a ParseInfo without a Script in this case.
|
||||
p->set_native(true);
|
||||
p->set_eval(false);
|
||||
p->set_module(false);
|
||||
DCHECK_NE(shared->kind(), FunctionKind::kModule);
|
||||
|
||||
Handle<HeapObject> scope_info(shared->GetOuterScopeInfo(), isolate);
|
||||
if (!scope_info->IsTheHole(isolate) &&
|
||||
Handle<ScopeInfo>::cast(scope_info)->length() > 0) {
|
||||
p->set_outer_scope_info(Handle<ScopeInfo>::cast(scope_info));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
DeclarationScope* ParseInfo::scope() const { return literal()->scope(); }
|
||||
|
||||
bool ParseInfo::is_declaration() const {
|
||||
@ -113,6 +156,18 @@ bool ParseInfo::requires_instance_fields_initializer() const {
|
||||
function_flags_);
|
||||
}
|
||||
|
||||
void ParseInfo::InitFromIsolate(Isolate* isolate) {
|
||||
DCHECK_NOT_NULL(isolate);
|
||||
set_hash_seed(isolate->heap()->HashSeed());
|
||||
set_stack_limit(isolate->stack_guard()->real_climit());
|
||||
set_unicode_cache(isolate->unicode_cache());
|
||||
set_runtime_call_stats(isolate->counters()->runtime_call_stats());
|
||||
set_logger(isolate->logger());
|
||||
set_ast_string_constants(isolate->ast_string_constants());
|
||||
if (isolate->is_block_code_coverage()) set_block_coverage_enabled();
|
||||
if (isolate->is_collecting_type_profile()) set_collect_type_profile();
|
||||
}
|
||||
|
||||
void ParseInfo::EmitBackgroundParseStatisticsOnBackgroundThread() {
|
||||
// If runtime call stats was enabled by tracing, emit a trace event at the
|
||||
// end of background parsing on the background thread.
|
||||
@ -146,38 +201,6 @@ void ParseInfo::ShareZone(ParseInfo* other) {
|
||||
zone_ = other->zone_;
|
||||
}
|
||||
|
||||
Handle<Script> ParseInfo::CreateScript(Isolate* isolate, Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives) {
|
||||
// Create a script object describing the script to be compiled.
|
||||
Handle<Script> script;
|
||||
if (script_id_ == -1) {
|
||||
script = isolate->factory()->NewScript(source);
|
||||
} else {
|
||||
script = isolate->factory()->NewScriptWithId(source, script_id_);
|
||||
}
|
||||
if (isolate->NeedsSourcePositionsForProfiling()) {
|
||||
Script::InitLineEnds(script);
|
||||
}
|
||||
switch (natives) {
|
||||
case NATIVES_CODE:
|
||||
script->set_type(Script::TYPE_NATIVE);
|
||||
break;
|
||||
case EXTENSION_CODE:
|
||||
script->set_type(Script::TYPE_EXTENSION);
|
||||
break;
|
||||
case INSPECTOR_CODE:
|
||||
script->set_type(Script::TYPE_INSPECTOR);
|
||||
break;
|
||||
case NOT_NATIVES_CODE:
|
||||
break;
|
||||
}
|
||||
script->set_origin_options(origin_options);
|
||||
|
||||
SetScriptForToplevelCompile(isolate, script);
|
||||
return script;
|
||||
}
|
||||
|
||||
AstValueFactory* ParseInfo::GetOrCreateAstValueFactory() {
|
||||
if (!ast_value_factory_.get()) {
|
||||
ast_value_factory_.reset(
|
||||
@ -204,30 +227,5 @@ void ParseInfo::set_character_stream(
|
||||
character_stream_.swap(character_stream);
|
||||
}
|
||||
|
||||
void ParseInfo::SetScriptForToplevelCompile(Isolate* isolate,
|
||||
Handle<Script> script) {
|
||||
set_script(script);
|
||||
set_allow_lazy_parsing();
|
||||
set_toplevel();
|
||||
set_collect_type_profile(isolate->is_collecting_type_profile() &&
|
||||
script->IsUserJavaScript());
|
||||
set_wrapped_as_function(script->is_wrapped());
|
||||
}
|
||||
|
||||
void ParseInfo::set_script(Handle<Script> script) {
|
||||
script_ = script;
|
||||
DCHECK(script_id_ == -1 || script_id_ == script->id());
|
||||
script_id_ = script->id();
|
||||
|
||||
set_native(script->type() == Script::TYPE_NATIVE);
|
||||
set_eval(script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
|
||||
set_module(script->origin_options().IsModule());
|
||||
DCHECK(!(is_eval() && is_module()));
|
||||
|
||||
if (block_coverage_enabled() && script->IsUserJavaScript()) {
|
||||
AllocateSourceRangeMap();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -37,16 +37,16 @@ class Zone;
|
||||
// A container for the inputs, configuration options, and outputs of parsing.
|
||||
class V8_EXPORT_PRIVATE ParseInfo {
|
||||
public:
|
||||
ParseInfo(Isolate*);
|
||||
ParseInfo(Isolate*, AccountingAllocator* zone_allocator);
|
||||
ParseInfo(AccountingAllocator* zone_allocator);
|
||||
ParseInfo(Isolate* isolate, Handle<Script> script);
|
||||
ParseInfo(Isolate* isolate, Handle<SharedFunctionInfo> shared);
|
||||
|
||||
~ParseInfo();
|
||||
|
||||
Handle<Script> CreateScript(Isolate* isolate, Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
NativesFlag natives = NOT_NATIVES_CODE);
|
||||
void InitFromIsolate(Isolate* isolate);
|
||||
|
||||
static ParseInfo* AllocateWithoutScript(Isolate* isolate,
|
||||
Handle<SharedFunctionInfo> shared);
|
||||
|
||||
// Either returns the ast-value-factory associcated with this ParseInfo, or
|
||||
// creates and returns a new factory if none exists.
|
||||
@ -208,11 +208,11 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
MaybeHandle<ScopeInfo> maybe_outer_scope_info() const {
|
||||
return maybe_outer_scope_info_;
|
||||
}
|
||||
void clear_script() { script_ = Handle<Script>::null(); }
|
||||
void set_outer_scope_info(Handle<ScopeInfo> outer_scope_info) {
|
||||
maybe_outer_scope_info_ = outer_scope_info;
|
||||
}
|
||||
|
||||
int script_id() const { return script_id_; }
|
||||
void set_script(Handle<Script> script) { script_ = script; }
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
LanguageMode language_mode() const {
|
||||
@ -227,9 +227,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
void UpdateBackgroundParseStatisticsOnMainThread(Isolate* isolate);
|
||||
|
||||
private:
|
||||
void SetScriptForToplevelCompile(Isolate* isolate, Handle<Script> script);
|
||||
void set_script(Handle<Script> script);
|
||||
|
||||
// Various configuration flags for parsing.
|
||||
enum Flag {
|
||||
// ---------- Input flags ---------------------------
|
||||
@ -262,7 +259,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
|
||||
// TODO(leszeks): Move any remaining flags used here either to the flags_
|
||||
// field or to other fields.
|
||||
int function_flags_;
|
||||
int script_id_;
|
||||
int start_position_;
|
||||
int end_position_;
|
||||
int parameters_end_pos_;
|
||||
|
@ -4479,8 +4479,9 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
|
||||
const char* event_name =
|
||||
is_lazy_top_level_function ? "preparse-no-resolution" : "parse";
|
||||
const char* name = "arrow function";
|
||||
logger_->FunctionEvent(event_name, script_id(), ms, scope->start_position(),
|
||||
scope->end_position(), name, strlen(name));
|
||||
logger_->FunctionEvent(event_name, nullptr, script_id(), ms,
|
||||
scope->start_position(), scope->end_position(), name,
|
||||
strlen(name));
|
||||
}
|
||||
|
||||
return function_literal;
|
||||
|
@ -523,8 +523,7 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
start = 0;
|
||||
end = String::cast(script->source())->length();
|
||||
}
|
||||
LOG(isolate,
|
||||
FunctionEvent(event_name, script->id(), ms, start, end, "", 0));
|
||||
LOG(isolate, FunctionEvent(event_name, script, -1, ms, start, end, "", 0));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -715,9 +714,10 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
|
||||
// We need to make sure that the debug-name is available.
|
||||
ast_value_factory()->Internalize(isolate);
|
||||
DeclarationScope* function_scope = result->scope();
|
||||
Script* script = *info->script();
|
||||
std::unique_ptr<char[]> function_name = result->GetDebugName();
|
||||
LOG(isolate,
|
||||
FunctionEvent("parse-function", info->script()->id(), ms,
|
||||
FunctionEvent("parse-function", script, -1, ms,
|
||||
function_scope->start_position(),
|
||||
function_scope->end_position(), function_name.get(),
|
||||
strlen(function_name.get())));
|
||||
@ -2655,7 +2655,7 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
|
||||
: "preparse-resolution")
|
||||
: "full-parse";
|
||||
logger_->FunctionEvent(
|
||||
event_name, script_id(), ms, scope->start_position(),
|
||||
event_name, nullptr, script_id(), ms, scope->start_position(),
|
||||
scope->end_position(),
|
||||
reinterpret_cast<const char*>(function_name->raw_data()),
|
||||
function_name->byte_length());
|
||||
@ -3436,7 +3436,9 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
RuntimeCallTimerScope runtimeTimer(
|
||||
runtime_call_stats_, RuntimeCallCounterId::kParseBackgroundProgram);
|
||||
parsing_on_main_thread_ = false;
|
||||
set_script_id(info->script_id());
|
||||
if (!info->script().is_null()) {
|
||||
set_script_id(info->script()->id());
|
||||
}
|
||||
|
||||
DCHECK_NULL(info->literal());
|
||||
FunctionLiteral* result = nullptr;
|
||||
|
@ -366,7 +366,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
name_byte_length = string->byte_length();
|
||||
}
|
||||
logger_->FunctionEvent(
|
||||
event_name, script_id(), ms, function_scope->start_position(),
|
||||
event_name, nullptr, script_id(), ms, function_scope->start_position(),
|
||||
function_scope->end_position(), name, name_byte_length);
|
||||
}
|
||||
|
||||
|
@ -67,9 +67,9 @@ RUNTIME_FUNCTION(Runtime_FunctionFirstExecution) {
|
||||
OptimizationMarker::kLogFirstExecution);
|
||||
DCHECK(FLAG_log_function_events);
|
||||
Handle<SharedFunctionInfo> sfi(function->shared());
|
||||
LOG(isolate, FunctionEvent(
|
||||
"first-execution", Script::cast(sfi->script())->id(), 0,
|
||||
sfi->StartPosition(), sfi->EndPosition(), sfi->DebugName()));
|
||||
LOG(isolate, FunctionEvent("first-execution", Script::cast(sfi->script()), -1,
|
||||
0, sfi->StartPosition(), sfi->EndPosition(),
|
||||
sfi->DebugName()));
|
||||
function->feedback_vector()->ClearOptimizationMarker();
|
||||
// Return the code to continue execution, we don't care at this point whether
|
||||
// this is for lazy compilation or has been eagerly complied.
|
||||
|
@ -126,30 +126,25 @@ class ScopedLoggerInitializer {
|
||||
|
||||
v8::Isolate* isolate() { return isolate_; }
|
||||
|
||||
i::Isolate* i_isolate() { return reinterpret_cast<i::Isolate*>(isolate()); }
|
||||
|
||||
Logger* logger() { return logger_; }
|
||||
|
||||
void PrintLog(int requested_nof_lines = 0, const char* start = nullptr) {
|
||||
if (requested_nof_lines <= 0) {
|
||||
void PrintLog(int nofLines = 0) {
|
||||
if (nofLines <= 0) {
|
||||
printf("%s", log_.start());
|
||||
return;
|
||||
}
|
||||
// Try to print the last {requested_nof_lines} of the log.
|
||||
if (start == nullptr) start = log_.start();
|
||||
// Try to print the last {nofLines} of the log.
|
||||
const char* start = log_.start();
|
||||
const char* current = log_.end();
|
||||
int nof_lines = requested_nof_lines;
|
||||
while (current > start && nof_lines > 0) {
|
||||
while (current > start && nofLines > 0) {
|
||||
current--;
|
||||
if (*current == '\n') nof_lines--;
|
||||
if (*current == '\n') nofLines--;
|
||||
}
|
||||
printf(
|
||||
"======================================================\n"
|
||||
"Last %i log lines:\n"
|
||||
"======================================================\n"
|
||||
"...\n%s\n"
|
||||
"Last log lines:\n...%s\n"
|
||||
"======================================================\n",
|
||||
requested_nof_lines, current);
|
||||
current);
|
||||
}
|
||||
|
||||
v8::Local<v8::String> GetLogString() {
|
||||
@ -164,14 +159,12 @@ class ScopedLoggerInitializer {
|
||||
CHECK(exists);
|
||||
}
|
||||
|
||||
const char* GetEndPosition() { return log_.start() + log_.length(); }
|
||||
|
||||
const char* FindLine(const char* prefix, const char* suffix = nullptr,
|
||||
const char* start = nullptr) {
|
||||
// Make sure that StopLogging() has been called before.
|
||||
CHECK(log_.size());
|
||||
if (start == nullptr) start = log_.start();
|
||||
const char* end = GetEndPosition();
|
||||
const char* end = log_.start() + log_.length();
|
||||
return FindLogLine(start, end, prefix, suffix);
|
||||
}
|
||||
|
||||
@ -183,7 +176,7 @@ class ScopedLoggerInitializer {
|
||||
const char* suffix = pairs[0][1];
|
||||
const char* last_position = FindLine(prefix, suffix, start);
|
||||
if (last_position == nullptr) {
|
||||
PrintLog(100, start);
|
||||
PrintLog(50);
|
||||
V8_Fatal(__FILE__, __LINE__, "Could not find log line: %s ... %s", prefix,
|
||||
suffix);
|
||||
}
|
||||
@ -193,13 +186,13 @@ class ScopedLoggerInitializer {
|
||||
suffix = pairs[i][1];
|
||||
const char* position = FindLine(prefix, suffix, start);
|
||||
if (position == nullptr) {
|
||||
PrintLog(100, start);
|
||||
PrintLog(50);
|
||||
V8_Fatal(__FILE__, __LINE__, "Could not find log line: %s ... %s",
|
||||
prefix, suffix);
|
||||
}
|
||||
// Check that all string positions are in order.
|
||||
if (position <= last_position) {
|
||||
PrintLog(100, start);
|
||||
PrintLog(50);
|
||||
V8_Fatal(__FILE__, __LINE__,
|
||||
"Log statements not in expected order (prev=%p, current=%p): "
|
||||
"%s ... %s",
|
||||
@ -1061,19 +1054,8 @@ TEST(LogFunctionEvents) {
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
v8::Isolate* isolate = v8::Isolate::New(create_params);
|
||||
|
||||
{
|
||||
ScopedLoggerInitializer logger(saved_log, saved_prof, isolate);
|
||||
|
||||
// Run some warmup code to help ignoring existing log entries.
|
||||
CompileRun(
|
||||
"function warmUp(a) {"
|
||||
" let b = () => 1;"
|
||||
" return function(c) { return a+b+c; };"
|
||||
"};"
|
||||
"warmUp(1)(2);"
|
||||
"(function warmUpEndMarkerFunction(){})();");
|
||||
|
||||
const char* source_text =
|
||||
"function lazyNotExecutedFunction() { return 'lazy' };"
|
||||
"function lazyFunction() { "
|
||||
@ -1089,14 +1071,13 @@ TEST(LogFunctionEvents) {
|
||||
|
||||
logger.StopLogging();
|
||||
|
||||
// Ignore all the log entries that happened before warmup
|
||||
// TODO(cbruni): Extend with first-execution log statements.
|
||||
CHECK_NULL(
|
||||
logger.FindLine("function,compile-lazy,", ",lazyNotExecutedFunction"));
|
||||
// Only consider the log starting from the first preparse statement on.
|
||||
const char* start =
|
||||
logger.FindLine("function,first-execution", "warmUpEndMarkerFunction");
|
||||
CHECK_NOT_NULL(start);
|
||||
logger.FindLine("function,preparse-", ",lazyNotExecutedFunction");
|
||||
const char* pairs[][2] = {
|
||||
// Create a new script
|
||||
{"script,create", nullptr},
|
||||
{"script-details", nullptr},
|
||||
// Step 1: parsing top-level script, preparsing functions
|
||||
{"function,preparse-", ",lazyNotExecutedFunction"},
|
||||
// Missing name for preparsing lazyInnerFunction
|
||||
@ -1111,7 +1092,7 @@ TEST(LogFunctionEvents) {
|
||||
|
||||
// Step 2: compiling top-level script and eager functions
|
||||
// - Compiling script without name.
|
||||
{"function,compile,", nullptr},
|
||||
{"function,compile,,", nullptr},
|
||||
{"function,compile,", ",eagerFunction"},
|
||||
|
||||
// Step 3: start executing script
|
||||
|
@ -326,7 +326,7 @@ function createFunktionList(metric, time, funktions) {
|
||||
<h2>Data</h2>
|
||||
<form name="fileForm">
|
||||
<p>
|
||||
<input id="uploadInput" type="file" name="files" onchange="loadFile();" accept=".log"> trace entries: <span id="count">0</span>
|
||||
<input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace entries: <span id="count">0</span>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
|
@ -65,12 +65,12 @@ function timestampMin(list) {
|
||||
|
||||
// ===========================================================================
|
||||
class Script {
|
||||
constructor(id) {
|
||||
this.file = '';
|
||||
this.id = id;
|
||||
constructor(file, id) {
|
||||
this.file = file;
|
||||
this.isNative = false;
|
||||
this.id = id;
|
||||
if (id === void 0 || id <= 0) {
|
||||
throw new Error(`Invalid id=${id} for script`);
|
||||
throw new Error(`Invalid id=${id} for script with file='${file}'`);
|
||||
}
|
||||
this.isEval = false;
|
||||
this.funktions = [];
|
||||
@ -91,6 +91,7 @@ class Script {
|
||||
this.ownBytes = -1;
|
||||
this.finalized = false;
|
||||
this.summary = '';
|
||||
this.setFile(file);
|
||||
}
|
||||
|
||||
setFile(name) {
|
||||
@ -690,30 +691,21 @@ class ParseProcessor extends LogReader {
|
||||
// Avoid accidental leaking of __proto__ properties and force this object
|
||||
// to be in dictionary-mode.
|
||||
__proto__: null,
|
||||
// "function",{event type},
|
||||
// {script id},{start position},{end position},{time},{timestamp},
|
||||
// {function name}
|
||||
// "function", {event type},
|
||||
// {script file},{script id},{start position},{end position},
|
||||
// {time},{timestamp},{function name}
|
||||
'function': {
|
||||
parsers: [
|
||||
parseString, parseInt, parseInt, parseInt, parseFloat, parseInt,
|
||||
parseString
|
||||
parseString, parseString, parseInt, parseInt, parseInt, parseFloat,
|
||||
parseInt, parseString
|
||||
],
|
||||
processor: this.processFunctionEvent
|
||||
},
|
||||
// "compilation-cache", "hit"|"put", {type}, {start position},
|
||||
// {end position}
|
||||
'compilation-cache': {
|
||||
parsers: [parseString, parseString, parseInt, parseInt],
|
||||
'compilation-cache' : {
|
||||
parsers: [parseString, parseString, parseString, parseInt, parseInt],
|
||||
processor: this.processCompilationCacheEvent
|
||||
},
|
||||
'script': {
|
||||
parsers: [parseString, parseInt],
|
||||
processor: this.processScriptEvent
|
||||
},
|
||||
// "script-details", {script_id}, {file}, {line}, {column}, {size}
|
||||
'script-details': {
|
||||
parsers: [parseInt, parseString, parseInt, parseInt, parseInt],
|
||||
processor: this.processScriptDetails
|
||||
}
|
||||
};
|
||||
this.functionEventDispatchTable_ = {
|
||||
@ -809,14 +801,14 @@ class ParseProcessor extends LogReader {
|
||||
}
|
||||
|
||||
processFunctionEvent(
|
||||
eventName, scriptId, startPosition, endPosition, duration, timestamp,
|
||||
functionName) {
|
||||
eventName, file, scriptId, startPosition, endPosition, duration,
|
||||
timestamp, functionName) {
|
||||
let handlerFn = this.functionEventDispatchTable_[eventName];
|
||||
if (handlerFn === undefined) {
|
||||
console.error('Couldn\'t find handler for function event:' + eventName);
|
||||
}
|
||||
handlerFn(
|
||||
scriptId, startPosition, endPosition, duration, timestamp,
|
||||
file, scriptId, startPosition, endPosition, duration, timestamp,
|
||||
functionName);
|
||||
}
|
||||
|
||||
@ -824,16 +816,28 @@ class ParseProcessor extends LogReader {
|
||||
this.entries.push(entry);
|
||||
}
|
||||
|
||||
lookupScript(id) {
|
||||
return this.idToScript.get(id);
|
||||
lookupScript(file, id) {
|
||||
// During preparsing we only have the temporary ranges and no script yet.
|
||||
let script;
|
||||
if (this.idToScript.has(id)) {
|
||||
script = this.idToScript.get(id);
|
||||
} else {
|
||||
script = new Script(file, id);
|
||||
this.idToScript.set(id, script);
|
||||
}
|
||||
if (file.length > 0 && script.file.length === 0) {
|
||||
script.setFile(file);
|
||||
this.fileToScript.set(file, script);
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
getOrCreateFunction(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
if (scriptId == -1) {
|
||||
lookupFunktion(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
if (file == "" && scriptId == -1) {
|
||||
return this.lookupFunktionByRange(startPosition, endPosition);
|
||||
}
|
||||
let script = this.lookupScript(scriptId);
|
||||
let script = this.lookupScript(file, scriptId);
|
||||
let funktion = script.funktionAtPosition(startPosition);
|
||||
if (funktion === void 0) {
|
||||
funktion = new Funktion(functionName, startPosition, endPosition, script);
|
||||
@ -859,36 +863,21 @@ class ParseProcessor extends LogReader {
|
||||
return results[0];
|
||||
}
|
||||
|
||||
processScriptEvent(eventName, scriptId) {
|
||||
if (eventName == 'create' || eventName == 'reserve-id') {
|
||||
if (this.idToScript.has(scriptId)) return;
|
||||
let script = new Script(scriptId);
|
||||
this.idToScript.set(scriptId, script);
|
||||
} else {
|
||||
console.log('Unhandled script event: ' + eventName);
|
||||
}
|
||||
}
|
||||
|
||||
processScriptDetails(scriptId, file, startLine, startColumn, size) {
|
||||
let script = this.lookupScript(scriptId);
|
||||
script.setFile(file);
|
||||
}
|
||||
|
||||
processEval(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let script = this.lookupScript(scriptId);
|
||||
processEval(file, scriptId, startPosition,
|
||||
endPosition, duration, timestamp, functionName) {
|
||||
let script = this.lookupScript(file, scriptId);
|
||||
script.isEval = true;
|
||||
}
|
||||
|
||||
processFull(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
processFull(file, scriptId, startPosition,
|
||||
endPosition, duration, timestamp, functionName) {
|
||||
if (startPosition == 0) {
|
||||
// This should only happen for eval.
|
||||
let script = this.lookupScript(scriptId);
|
||||
let script = this.lookupScript(file, scriptId);
|
||||
script.isEval = true;
|
||||
return;
|
||||
}
|
||||
let funktion = this.getOrCreateFunction(...arguments);
|
||||
let funktion = this.lookupFunktion(...arguments);
|
||||
// TODO(cbruni): this should never happen, emit differen event from the
|
||||
// parser.
|
||||
if (funktion.parseTimestamp > 0) return;
|
||||
@ -896,17 +885,17 @@ class ParseProcessor extends LogReader {
|
||||
funktion.parseTime = duration;
|
||||
}
|
||||
|
||||
processParseFunction(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.getOrCreateFunction(...arguments);
|
||||
processParseFunction(file, scriptId, startPosition,
|
||||
endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.lookupFunktion(...arguments);
|
||||
funktion.parseTimestamp = startOf(timestamp, duration);
|
||||
funktion.parseTime = duration;
|
||||
}
|
||||
|
||||
processScript(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
processScript(file, scriptId, startPosition,
|
||||
endPosition, duration, timestamp, functionName) {
|
||||
// TODO timestamp and duration
|
||||
let script = this.lookupScript(scriptId);
|
||||
let script = this.lookupScript(file, scriptId);
|
||||
let ts = startOf(timestamp, duration);
|
||||
script.parseTimestamp = ts;
|
||||
script.firstEventTimestamp = ts;
|
||||
@ -914,9 +903,9 @@ class ParseProcessor extends LogReader {
|
||||
script.parseTime = duration;
|
||||
}
|
||||
|
||||
processPreparseResolution(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.getOrCreateFunction(...arguments);
|
||||
processPreparseResolution(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.lookupFunktion(...arguments);
|
||||
// TODO(cbruni): this should never happen, emit different event from the
|
||||
// parser.
|
||||
if (funktion.resolutionTimestamp > 0) return;
|
||||
@ -924,16 +913,16 @@ class ParseProcessor extends LogReader {
|
||||
funktion.resolutionTime = duration;
|
||||
}
|
||||
|
||||
processPreparseNoResolution(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.getOrCreateFunction(...arguments);
|
||||
processPreparseNoResolution(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.lookupFunktion(...arguments);
|
||||
funktion.preparseTimestamp = startOf(timestamp, duration);
|
||||
funktion.preparseTime = duration;
|
||||
}
|
||||
|
||||
processFirstExecution(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let script = this.lookupScript(scriptId);
|
||||
processFirstExecution(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let script = this.lookupScript(file, scriptId);
|
||||
if (startPosition === 0) {
|
||||
// undefined = eval fn execution
|
||||
if (script) {
|
||||
@ -949,16 +938,17 @@ class ParseProcessor extends LogReader {
|
||||
}
|
||||
}
|
||||
|
||||
processCompileLazy(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.getOrCreateFunction(...arguments);
|
||||
processCompileLazy(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let funktion = this.lookupFunktion(...arguments);
|
||||
funktion.lazyCompileTimestamp = startOf(timestamp, duration);
|
||||
funktion.lazyCompileTime = duration;
|
||||
}
|
||||
|
||||
processCompile(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
let script = this.lookupScript(scriptId);
|
||||
processCompile(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
|
||||
let script = this.lookupScript(file, scriptId);
|
||||
if (startPosition === 0) {
|
||||
script.compileTimestamp = startOf(timestamp, duration);
|
||||
script.compileTime = duration;
|
||||
@ -974,12 +964,12 @@ class ParseProcessor extends LogReader {
|
||||
}
|
||||
}
|
||||
|
||||
processCompileEval(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
processCompileEval(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
}
|
||||
|
||||
processOptimizeLazy(
|
||||
scriptId, startPosition, endPosition, duration, timestamp, functionName) {
|
||||
processOptimizeLazy(file, scriptId,
|
||||
startPosition, endPosition, duration, timestamp, functionName) {
|
||||
}
|
||||
|
||||
processCompilationCacheEvent(eventType, cacheType, startPosition,
|
||||
|
Loading…
Reference in New Issue
Block a user