Commit 9a31804b authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[profiler] Clean up CodeEvent tags

Clean-up and slightly unify the CodeEvent tags:

  * Remove INTERPRETED_FUNCTION_TAG. It was only used for interpreter
    trampoline copies, which are used for
    --interpreted-frames-native-stack.  However, even actual bytecode
    compilation doesn't use INTERPRETED_FUNCTION_TAG, so we can remove
    it for simplicity.

  * The tag used by the above is now the same as for the bytecode
    creation event, i.e. EVAL_TAG, SCRIPT_TAG, FUNCTION_TAG or
    LAZY_COMPILE, depending on whether this was a script, and eval, an
    eager or a lazy compile (respectively.

  * Baseline was also using INTERPRETED_FUNCTION_TAG, so now it does the
    same thing as above.

  * Existing code is now logged as FUNCTION_TAG rather than
    LAZY_COMPILE, because we lost the laziness information.

  * The SCRIPT_TAG is set based on the SharedFunctionInfo flags, not
    the compilation flags, so that eager inner functions are labelled as
    FUNCTION_TAG rather than SCRIPT_TAG.

Bug: v8:11420,v8:11429
Change-Id: I0286002674255ff4ba8f5d865df372a3e2975b16
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2713104Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73047}
parent d7be571c
......@@ -516,8 +516,9 @@ bool UseAsmWasm(FunctionLiteral* literal, bool asm_wasm_broken) {
}
#endif
void InstallInterpreterTrampolineCopy(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info) {
void InstallInterpreterTrampolineCopy(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
CodeEventListener::LogEventsAndTags log_tag) {
DCHECK(FLAG_interpreted_frames_native_stack);
if (!shared_info->function_data(kAcquireLoad).IsBytecodeArray()) {
DCHECK(!shared_info->HasBytecodeArray());
......@@ -548,8 +549,6 @@ void InstallInterpreterTrampolineCopy(Isolate* isolate,
handle(script->name().IsString() ? String::cast(script->name())
: ReadOnlyRoots(isolate).empty_string(),
isolate);
CodeEventListener::LogEventsAndTags log_tag = Logger::ToNativeByScript(
CodeEventListener::INTERPRETED_FUNCTION_TAG, *script);
PROFILE(isolate, CodeCreateEvent(log_tag, abstract_code, shared_info,
script_name, line_num, column_num));
}
......@@ -586,18 +585,9 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
void LogUnoptimizedCompilation(Isolate* isolate,
Handle<SharedFunctionInfo> shared_info,
UnoptimizedCompileFlags flags,
CodeEventListener::LogEventsAndTags log_tag,
base::TimeDelta time_taken_to_execute,
base::TimeDelta time_taken_to_finalize) {
CodeEventListener::LogEventsAndTags log_tag;
if (flags.is_toplevel()) {
log_tag = flags.is_eval() ? CodeEventListener::EVAL_TAG
: CodeEventListener::SCRIPT_TAG;
} else {
log_tag = flags.is_lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
: CodeEventListener::FUNCTION_TAG;
}
RecordUnoptimizedFunctionCompilation(isolate, log_tag, shared_info,
time_taken_to_execute,
time_taken_to_finalize);
......@@ -1341,8 +1331,17 @@ void FinalizeUnoptimizedCompilation(
if (need_source_positions) {
SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, shared_info);
}
CodeEventListener::LogEventsAndTags log_tag;
if (shared_info->is_toplevel()) {
log_tag = flags.is_eval() ? CodeEventListener::EVAL_TAG
: CodeEventListener::SCRIPT_TAG;
} else {
log_tag = flags.is_lazy_compile() ? CodeEventListener::LAZY_COMPILE_TAG
: CodeEventListener::FUNCTION_TAG;
}
log_tag = Logger::ToNativeByScript(log_tag, *script);
if (FLAG_interpreted_frames_native_stack) {
InstallInterpreterTrampolineCopy(isolate, shared_info);
InstallInterpreterTrampolineCopy(isolate, shared_info, log_tag);
}
if (FLAG_always_sparkplug) {
CompileSharedWithBaseline(isolate, shared_info, Compiler::KEEP_EXCEPTION,
......@@ -1353,7 +1352,7 @@ void FinalizeUnoptimizedCompilation(
isolate->debug()->InstallCoverageInfo(shared_info, coverage_info);
}
LogUnoptimizedCompilation(isolate, shared_info, flags,
LogUnoptimizedCompilation(isolate, shared_info, log_tag,
finalize_data.time_taken_to_execute(),
finalize_data.time_taken_to_finalize());
}
......
......@@ -41,20 +41,19 @@ using WasmName = Vector<const char>;
V(BYTECODE_FLUSH_EVENT, bytecode-flush)
// clang-format on
#define TAGS_LIST(V) \
V(BUILTIN_TAG, Builtin) \
V(CALLBACK_TAG, Callback) \
V(EVAL_TAG, Eval) \
V(FUNCTION_TAG, Function) \
V(INTERPRETED_FUNCTION_TAG, InterpretedFunction) \
V(HANDLER_TAG, Handler) \
V(BYTECODE_HANDLER_TAG, BytecodeHandler) \
V(LAZY_COMPILE_TAG, LazyCompile) \
V(REG_EXP_TAG, RegExp) \
V(SCRIPT_TAG, Script) \
V(STUB_TAG, Stub) \
V(NATIVE_FUNCTION_TAG, Function) \
V(NATIVE_LAZY_COMPILE_TAG, LazyCompile) \
#define TAGS_LIST(V) \
V(BUILTIN_TAG, Builtin) \
V(CALLBACK_TAG, Callback) \
V(EVAL_TAG, Eval) \
V(FUNCTION_TAG, Function) \
V(HANDLER_TAG, Handler) \
V(BYTECODE_HANDLER_TAG, BytecodeHandler) \
V(LAZY_COMPILE_TAG, LazyCompile) \
V(REG_EXP_TAG, RegExp) \
V(SCRIPT_TAG, Script) \
V(STUB_TAG, Stub) \
V(NATIVE_FUNCTION_TAG, Function) \
V(NATIVE_LAZY_COMPILE_TAG, LazyCompile) \
V(NATIVE_SCRIPT_TAG, Script)
// Note that 'NATIVE_' cases for functions and scripts are mapped onto
// original tags when writing to the log.
......
......@@ -81,11 +81,20 @@ static v8::CodeEventType GetCodeEventTypeForTag(
}
static const char* ComputeMarker(SharedFunctionInfo shared, AbstractCode code) {
CodeKind kind = code.kind();
// We record interpreter trampoline builting copies as having the
// "interpreted" marker.
if (FLAG_interpreted_frames_native_stack && kind == CodeKind::BUILTIN &&
code.GetCode().is_interpreter_trampoline_builtin() &&
code.GetCode() !=
*BUILTIN_CODE(shared.GetIsolate(), InterpreterEntryTrampoline)) {
kind = CodeKind::INTERPRETED_FUNCTION;
}
if (shared.optimization_disabled() &&
code.kind() == CodeKind::INTERPRETED_FUNCTION) {
kind == CodeKind::INTERPRETED_FUNCTION) {
return "";
}
return CodeKindToMarker(code.kind());
return CodeKindToMarker(kind);
}
static const char* ComputeMarker(const wasm::WasmCode* code) {
......@@ -2183,17 +2192,14 @@ void ExistingCodeLogger::LogCompiledFunctions() {
LogExistingFunction(
shared,
Handle<AbstractCode>(
AbstractCode::cast(shared->InterpreterTrampoline()), isolate_),
CodeEventListener::INTERPRETED_FUNCTION_TAG);
AbstractCode::cast(shared->InterpreterTrampoline()), isolate_));
}
if (shared->HasBaselineData()) {
// TODO(v8:11429): Add a tag for baseline code. Or use CodeKind?
LogExistingFunction(
shared,
Handle<AbstractCode>(
AbstractCode::cast(shared->baseline_data().baseline_code()),
isolate_),
CodeEventListener::INTERPRETED_FUNCTION_TAG);
isolate_));
}
if (pair.second.is_identical_to(BUILTIN_CODE(isolate_, CompileLazy)))
continue;
......@@ -2218,7 +2224,7 @@ void ExistingCodeLogger::LogExistingFunction(
Script::GetColumnNumber(script, shared->StartPosition()) + 1;
if (script->name().IsString()) {
Handle<String> script_name(String::cast(script->name()), isolate_);
if (line_num > 0) {
if (!shared->is_toplevel()) {
CALL_CODE_EVENT_HANDLER(
CodeCreateEvent(Logger::ToNativeByScript(tag, *script), code,
shared, script_name, line_num, column_num))
......
......@@ -91,7 +91,7 @@ class ExistingCodeLogger {
void LogExistingFunction(Handle<SharedFunctionInfo> shared,
Handle<AbstractCode> code,
CodeEventListener::LogEventsAndTags tag =
CodeEventListener::LAZY_COMPILE_TAG);
CodeEventListener::FUNCTION_TAG);
void LogCodeObject(Object object);
private:
......
......@@ -314,7 +314,6 @@ CpuProfileNode::SourceType ProfileNode::source_type() const {
case CodeEventListener::SCRIPT_TAG:
case CodeEventListener::LAZY_COMPILE_TAG:
case CodeEventListener::FUNCTION_TAG:
case CodeEventListener::INTERPRETED_FUNCTION_TAG:
return CpuProfileNode::kScript;
case CodeEventListener::BUILTIN_TAG:
case CodeEventListener::HANDLER_TAG:
......
......@@ -252,9 +252,8 @@ void CreateInterpreterDataForDeserializedCode(Isolate* isolate,
int line_num = script->GetLineNumber(info->StartPosition()) + 1;
int column_num = script->GetColumnNumber(info->StartPosition()) + 1;
PROFILE(isolate,
CodeCreateEvent(CodeEventListener::INTERPRETED_FUNCTION_TAG,
abstract_code, info, name_handle, line_num,
column_num));
CodeCreateEvent(CodeEventListener::FUNCTION_TAG, abstract_code,
info, name_handle, line_num, column_num));
}
}
#endif // V8_TARGET_ARCH_ARM
......@@ -385,11 +384,13 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
script->GetLineNumber(shared_info->StartPosition()) + 1;
int column_num =
script->GetColumnNumber(shared_info->StartPosition()) + 1;
PROFILE(isolate,
CodeCreateEvent(
CodeEventListener::SCRIPT_TAG,
handle(shared_info->abstract_code(isolate), isolate),
shared_info, name, line_num, column_num));
PROFILE(
isolate,
CodeCreateEvent(
shared_info->is_toplevel() ? CodeEventListener::SCRIPT_TAG
: CodeEventListener::FUNCTION_TAG,
handle(shared_info->abstract_code(isolate), isolate),
shared_info, name, line_num, column_num));
}
}
}
......
......@@ -2212,16 +2212,22 @@ TEST(FunctionDetails) {
const v8::CpuProfile* profile = i::ProfilerExtension::last_profile;
reinterpret_cast<const i::CpuProfile*>(profile)->Print();
// The tree should look like this:
// 0 (root) 0 #1
// 0 "" 19 #2 no reason script_b:1
// 0 baz 19 #3 TryCatchStatement script_b:3
// 0 foo 18 #4 TryCatchStatement script_a:2
// 1 bar 18 #5 no reason script_a:3
// 0 (root):0 3 0 #1
// 0 :0 0 5 #2 script_b:0
// 0 baz:3 0 5 #3 script_b:3
// bailed out due to 'Optimization is always disabled'
// 0 foo:4 0 4 #4 script_a:4
// bailed out due to 'Optimization is always disabled'
// 0 bar:5 0 4 #5 script_a:5
// bailed out due to 'Optimization is always disabled'
// 0 startProfiling:0 2 0 #6
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
CHECK_EQ(root->GetParent(), nullptr);
const v8::CpuProfileNode* script = GetChild(env, root, "");
CheckFunctionDetails(env->GetIsolate(), script, "", "script_b", true,
script_b->GetUnboundScript()->GetId(), 1, 1, root);
script_b->GetUnboundScript()->GetId(),
v8::CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo, root);
const v8::CpuProfileNode* baz = GetChild(env, script, "baz");
CheckFunctionDetails(env->GetIsolate(), baz, "baz", "script_b", true,
script_b->GetUnboundScript()->GetId(), 3, 16, script);
......@@ -2290,7 +2296,7 @@ TEST(FunctionDetailsInlining) {
// The tree should look like this:
// 0 (root) 0 #1
// 5 (program) 0 #6
// 2 14 #2 script_a:1
// 2 14 #2 script_a:0
// ;;; deopted at script_id: 14 position: 299 with reason 'Insufficient
// type feedback for call'.
// 1 alpha 14 #4 script_a:1
......@@ -2301,7 +2307,9 @@ TEST(FunctionDetailsInlining) {
CHECK_EQ(root->GetParent(), nullptr);
const v8::CpuProfileNode* script = GetChild(env, root, "");
CheckFunctionDetails(env->GetIsolate(), script, "", "script_a", false,
script_a->GetUnboundScript()->GetId(), 1, 1, root);
script_a->GetUnboundScript()->GetId(),
v8::CpuProfileNode::kNoLineNumberInfo,
v8::CpuProfileNode::kNoColumnNumberInfo, root);
const v8::CpuProfileNode* alpha = FindChild(env, script, "alpha");
// Return early if profiling didn't sample alpha.
if (!alpha) return;
......
......@@ -577,8 +577,9 @@ UNINITIALIZED_TEST(LogInterpretedFramesNativeStack) {
logger.StopLogging();
CHECK(logger.ContainsLine(
{"InterpretedFunction", "testLogInterpretedFramesNativeStack"}));
CHECK(logger.ContainsLinesInOrder(
{{"LazyCompile", "testLogInterpretedFramesNativeStack"},
{"LazyCompile", "testLogInterpretedFramesNativeStack"}}));
}
isolate->Dispose();
}
......@@ -629,7 +630,11 @@ UNINITIALIZED_TEST(LogInterpretedFramesNativeStackWithSerialization) {
.ToLocalChecked();
if (has_cache) {
logger.StopLogging();
CHECK(logger.ContainsLine({"InterpretedFunction", "eyecatcher"}));
logger.PrintLog();
// Function is logged twice: once as interpreted, and once as the
// interpreter entry trampoline builtin.
CHECK(logger.ContainsLinesInOrder(
{{"Function", "eyecatcher"}, {"Function", "eyecatcher"}}));
}
v8::Local<v8::Value> arg = v8_num(3);
v8::Local<v8::Value> result =
......@@ -667,13 +672,16 @@ UNINITIALIZED_TEST(ExternalCodeEventListener) {
"testCodeEventListenerBeforeStart('1', 1);";
CompileRun(source_text_before_start);
CHECK_EQ(code_event_handler.CountLines("Function",
"testCodeEventListenerBeforeStart"),
0);
CHECK_EQ(code_event_handler.CountLines("LazyCompile",
"testCodeEventListenerBeforeStart"),
0);
code_event_handler.Enable();
CHECK_GE(code_event_handler.CountLines("LazyCompile",
CHECK_GE(code_event_handler.CountLines("Function",
"testCodeEventListenerBeforeStart"),
1);
......@@ -715,9 +723,9 @@ UNINITIALIZED_TEST(ExternalCodeEventListenerInnerFunctions) {
v8::Local<v8::UnboundScript> script =
v8::ScriptCompiler::CompileUnboundScript(isolate1, &source)
.ToLocalChecked();
CHECK_EQ(code_event_handler.CountLines("Script", "f1"),
CHECK_EQ(code_event_handler.CountLines("Function", "f1"),
i::FLAG_stress_background_compile ? 2 : 1);
CHECK_EQ(code_event_handler.CountLines("Script", "f2"),
CHECK_EQ(code_event_handler.CountLines("Function", "f2"),
i::FLAG_stress_background_compile ? 2 : 1);
cache = v8::ScriptCompiler::CreateCodeCache(script);
}
......@@ -743,8 +751,8 @@ UNINITIALIZED_TEST(ExternalCodeEventListenerInnerFunctions) {
isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache)
.ToLocalChecked();
}
CHECK_EQ(code_event_handler.CountLines("Script", "f1"), 1);
CHECK_EQ(code_event_handler.CountLines("Script", "f2"), 1);
CHECK_EQ(code_event_handler.CountLines("Function", "f1"), 1);
CHECK_EQ(code_event_handler.CountLines("Function", "f2"), 1);
}
isolate2->Dispose();
}
......@@ -772,24 +780,24 @@ UNINITIALIZED_TEST(ExternalCodeEventListenerWithInterpretedFramesNativeStack) {
"testCodeEventListenerBeforeStart('1', 1);";
CompileRun(source_text_before_start);
CHECK_EQ(code_event_handler.CountLines("InterpretedFunction",
CHECK_EQ(code_event_handler.CountLines("Function",
"testCodeEventListenerBeforeStart"),
0);
code_event_handler.Enable();
CHECK_GE(code_event_handler.CountLines("InterpretedFunction",
CHECK_GE(code_event_handler.CountLines("Function",
"testCodeEventListenerBeforeStart"),
1);
2);
const char* source_text_after_start =
"function testCodeEventListenerAfterStart(a,b) { return a + b };"
"testCodeEventListenerAfterStart('1', 1);";
CompileRun(source_text_after_start);
CHECK_GE(code_event_handler.CountLines("InterpretedFunction",
CHECK_GE(code_event_handler.CountLines("LazyCompile",
"testCodeEventListenerAfterStart"),
1);
2);
CHECK_EQ(
code_event_handler.CountLines("Builtin", "InterpreterEntryTrampoline"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment