Commit c899ad5e authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[tools][log] Add support for disassembled code

- Add FLAG_log_code_disassemble
- Add code-disassamble log entries for Code and BytecodeArray
- Add basic code-panel to system-analyzer

Bug: v8:10644
Change-Id: I1abb339a42b55df01265d63d0f0d8c1ac2e041dc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2565517Reviewed-by: 's avatarSathya Gunasekaran  <gsathya@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71556}
parent 2afb00c0
...@@ -1712,6 +1712,9 @@ DEFINE_BOOL(log_all, false, "Log all events to the log file.") ...@@ -1712,6 +1712,9 @@ DEFINE_BOOL(log_all, false, "Log all events to the log file.")
DEFINE_BOOL(log_api, false, "Log API events to the log file.") DEFINE_BOOL(log_api, false, "Log API events to the log file.")
DEFINE_BOOL(log_code, false, DEFINE_BOOL(log_code, false,
"Log code events to the log file without profiling.") "Log code events to the log file without profiling.")
DEFINE_BOOL(log_code_disassemble, false,
"Log all disassembled code to the log file.")
DEFINE_IMPLICATION(log_code_disassemble, log_code)
DEFINE_BOOL(log_handles, false, "Log global handle events.") DEFINE_BOOL(log_handles, false, "Log global handle events.")
DEFINE_BOOL(log_suspect, false, "Log suspect operations.") DEFINE_BOOL(log_suspect, false, "Log suspect operations.")
DEFINE_BOOL(log_source_code, false, "Log source code.") DEFINE_BOOL(log_source_code, false, "Log source code.")
...@@ -1721,6 +1724,7 @@ DEFINE_BOOL(log_function_events, false, ...@@ -1721,6 +1724,7 @@ DEFINE_BOOL(log_function_events, false,
DEFINE_IMPLICATION(log_all, log_api) DEFINE_IMPLICATION(log_all, log_api)
DEFINE_IMPLICATION(log_all, log_code) DEFINE_IMPLICATION(log_all, log_code)
DEFINE_IMPLICATION(log_all, log_code_disassemble)
DEFINE_IMPLICATION(log_all, log_suspect) DEFINE_IMPLICATION(log_all, log_suspect)
DEFINE_IMPLICATION(log_all, log_handles) DEFINE_IMPLICATION(log_all, log_handles)
DEFINE_IMPLICATION(log_all, log_internal_timer_events) DEFINE_IMPLICATION(log_all, log_internal_timer_events)
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "src/logging/log-utils.h" #include "src/logging/log-utils.h"
#include "src/objects/api-callbacks.h" #include "src/objects/api-callbacks.h"
#include "src/objects/code-kind.h" #include "src/objects/code-kind.h"
#include "src/objects/code.h"
#include "src/profiler/tick-sample.h" #include "src/profiler/tick-sample.h"
#include "src/snapshot/embedded/embedded-data.h" #include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/string-stream.h" #include "src/strings/string-stream.h"
...@@ -978,6 +979,10 @@ void Profiler::Run() { ...@@ -978,6 +979,10 @@ void Profiler::Run() {
// //
// Logger class implementation. // Logger class implementation.
// //
#define MSG_BUILDER() \
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); \
if (!msg_ptr) return; \
Log::MessageBuilder& msg = *msg_ptr.get();
Logger::Logger(Isolate* isolate) Logger::Logger(Isolate* isolate)
: isolate_(isolate), : isolate_(isolate),
...@@ -1006,9 +1011,7 @@ void Logger::RemoveCodeEventListener(CodeEventListener* listener) { ...@@ -1006,9 +1011,7 @@ void Logger::RemoveCodeEventListener(CodeEventListener* listener) {
} }
void Logger::ProfilerBeginEvent() { void Logger::ProfilerBeginEvent() {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "profiler" << kNext << "begin" << kNext << FLAG_prof_sampling_interval; msg << "profiler" << kNext << "begin" << kNext << FLAG_prof_sampling_interval;
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
...@@ -1018,9 +1021,7 @@ void Logger::StringEvent(const char* name, const char* value) { ...@@ -1018,9 +1021,7 @@ void Logger::StringEvent(const char* name, const char* value) {
} }
void Logger::UncheckedStringEvent(const char* name, const char* value) { void Logger::UncheckedStringEvent(const char* name, const char* value) {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << name << kNext << value; msg << name << kNext << value;
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
...@@ -1030,9 +1031,7 @@ void Logger::IntPtrTEvent(const char* name, intptr_t value) { ...@@ -1030,9 +1031,7 @@ void Logger::IntPtrTEvent(const char* name, intptr_t value) {
} }
void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << name << kNext; msg << name << kNext;
msg.AppendFormatString("%" V8PRIdPTR, value); msg.AppendFormatString("%" V8PRIdPTR, value);
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1040,18 +1039,14 @@ void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) { ...@@ -1040,18 +1039,14 @@ void Logger::UncheckedIntPtrTEvent(const char* name, intptr_t value) {
void Logger::HandleEvent(const char* name, Address* location) { void Logger::HandleEvent(const char* name, Address* location) {
if (!FLAG_log_handles) return; if (!FLAG_log_handles) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << name << kNext << reinterpret_cast<void*>(location); msg << name << kNext << reinterpret_cast<void*>(location);
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
void Logger::ApiSecurityCheck() { void Logger::ApiSecurityCheck() {
if (!FLAG_log_api) return; if (!FLAG_log_api) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "api" << kNext << "check-security"; msg << "api" << kNext << "check-security";
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
...@@ -1060,9 +1055,7 @@ void Logger::SharedLibraryEvent(const std::string& library_path, ...@@ -1060,9 +1055,7 @@ void Logger::SharedLibraryEvent(const std::string& library_path,
uintptr_t start, uintptr_t end, uintptr_t start, uintptr_t end,
intptr_t aslr_slide) { intptr_t aslr_slide) {
if (!FLAG_prof_cpp) return; if (!FLAG_prof_cpp) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "shared-library" << kNext << library_path.c_str() << kNext msg << "shared-library" << kNext << library_path.c_str() << kNext
<< reinterpret_cast<void*>(start) << kNext << reinterpret_cast<void*>(end) << reinterpret_cast<void*>(start) << kNext << reinterpret_cast<void*>(end)
<< kNext << aslr_slide; << kNext << aslr_slide;
...@@ -1071,17 +1064,13 @@ void Logger::SharedLibraryEvent(const std::string& library_path, ...@@ -1071,17 +1064,13 @@ void Logger::SharedLibraryEvent(const std::string& library_path,
void Logger::CurrentTimeEvent() { void Logger::CurrentTimeEvent() {
DCHECK(FLAG_log_internal_timer_events); DCHECK(FLAG_log_internal_timer_events);
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "current-time" << kNext << Time(); msg << "current-time" << kNext << Time();
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
void Logger::TimerEvent(Logger::StartEnd se, const char* name) { void Logger::TimerEvent(Logger::StartEnd se, const char* name) {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
switch (se) { switch (se) {
case START: case START:
msg << "timer-event-start"; msg << "timer-event-start";
...@@ -1099,9 +1088,7 @@ void Logger::TimerEvent(Logger::StartEnd se, const char* name) { ...@@ -1099,9 +1088,7 @@ void Logger::TimerEvent(Logger::StartEnd se, const char* name) {
void Logger::BasicBlockCounterEvent(const char* name, int block_id, void Logger::BasicBlockCounterEvent(const char* name, int block_id,
double count) { double count) {
if (!FLAG_turbo_profiling_log_builtins) return; if (!FLAG_turbo_profiling_log_builtins) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << ProfileDataFromFileConstants::kBlockCounterMarker << kNext << name msg << ProfileDataFromFileConstants::kBlockCounterMarker << kNext << name
<< kNext << block_id << kNext << count; << kNext << block_id << kNext << count;
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1109,9 +1096,7 @@ void Logger::BasicBlockCounterEvent(const char* name, int block_id, ...@@ -1109,9 +1096,7 @@ void Logger::BasicBlockCounterEvent(const char* name, int block_id,
void Logger::BuiltinHashEvent(const char* name, int hash) { void Logger::BuiltinHashEvent(const char* name, int hash) {
if (!FLAG_turbo_profiling_log_builtins) return; if (!FLAG_turbo_profiling_log_builtins) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << ProfileDataFromFileConstants::kBuiltinHashMarker << kNext << name msg << ProfileDataFromFileConstants::kBuiltinHashMarker << kNext << name
<< kNext << hash; << kNext << hash;
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1134,9 +1119,7 @@ void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder, ...@@ -1134,9 +1119,7 @@ void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder,
Object property_name) { Object property_name) {
DCHECK(property_name.IsName()); DCHECK(property_name.IsName());
if (!FLAG_log_api) return; if (!FLAG_log_api) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "api" << kNext << tag << kNext << holder.class_name() << kNext msg << "api" << kNext << tag << kNext << holder.class_name() << kNext
<< Name::cast(property_name); << Name::cast(property_name);
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1145,9 +1128,7 @@ void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder, ...@@ -1145,9 +1128,7 @@ void Logger::ApiNamedPropertyAccess(const char* tag, JSObject holder,
void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder, void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder,
uint32_t index) { uint32_t index) {
if (!FLAG_log_api) return; if (!FLAG_log_api) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "api" << kNext << tag << kNext << holder.class_name() << kNext msg << "api" << kNext << tag << kNext << holder.class_name() << kNext
<< index; << index;
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1155,27 +1136,21 @@ void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder, ...@@ -1155,27 +1136,21 @@ void Logger::ApiIndexedPropertyAccess(const char* tag, JSObject holder,
void Logger::ApiObjectAccess(const char* tag, JSObject object) { void Logger::ApiObjectAccess(const char* tag, JSObject object) {
if (!FLAG_log_api) return; if (!FLAG_log_api) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "api" << kNext << tag << kNext << object.class_name(); msg << "api" << kNext << tag << kNext << object.class_name();
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
void Logger::ApiEntryCall(const char* name) { void Logger::ApiEntryCall(const char* name) {
if (!FLAG_log_api) return; if (!FLAG_log_api) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "api" << kNext << name; msg << "api" << kNext << name;
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
void Logger::NewEvent(const char* name, void* object, size_t size) { void Logger::NewEvent(const char* name, void* object, size_t size) {
if (!FLAG_log) return; if (!FLAG_log) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "new" << kNext << name << kNext << object << kNext msg << "new" << kNext << name << kNext << object << kNext
<< static_cast<unsigned int>(size); << static_cast<unsigned int>(size);
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1183,9 +1158,7 @@ void Logger::NewEvent(const char* name, void* object, size_t size) { ...@@ -1183,9 +1158,7 @@ void Logger::NewEvent(const char* name, void* object, size_t size) {
void Logger::DeleteEvent(const char* name, void* object) { void Logger::DeleteEvent(const char* name, void* object) {
if (!FLAG_log) return; if (!FLAG_log) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "delete" << kNext << name << kNext << object; msg << "delete" << kNext << name << kNext << object;
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
...@@ -1212,103 +1185,40 @@ void AppendCodeCreateHeader( ...@@ -1212,103 +1185,40 @@ void AppendCodeCreateHeader(
} }
} // namespace } // namespace
// We log source code information in the form:
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code, //
const char* name) { // code-source-info <addr>,<script>,<start>,<end>,<pos>,<inline-pos>,<fns>
if (!is_listening_to_code_events()) return; //
if (!FLAG_log_code) return; // where
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); // <addr> is code object address
if (!msg_ptr) return; // <script> is script id
Log::MessageBuilder& msg = *msg_ptr.get(); // <start> is the starting position inside the script
AppendCodeCreateHeader(msg, tag, *code, Time()); // <end> is the end position inside the script
msg << name; // <pos> is source position table encoded in the string,
msg.WriteToLogFile(); // it is a sequence of C<code-offset>O<script-offset>[I<inlining-id>]
} // where
// <code-offset> is the offset within the code object
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code, // <script-offset> is the position within the script
Handle<Name> name) { // <inlining-id> is the offset in the <inlining> table
if (!is_listening_to_code_events()) return; // <inlining> table is a sequence of strings of the form
if (!FLAG_log_code) return; // F<function-id>O<script-offset>[I<inlining-id>]
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); // where
if (!msg_ptr) return; // <function-id> is an index into the <fns> function table
Log::MessageBuilder& msg = *msg_ptr.get(); // <fns> is the function table encoded as a sequence of strings
AppendCodeCreateHeader(msg, tag, *code, Time()); // S<shared-function-info-address>
msg << *name;
msg.WriteToLogFile(); void Logger::LogSourceCodeInformation(Handle<AbstractCode> code,
} Handle<SharedFunctionInfo> shared) {
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
Handle<SharedFunctionInfo> shared,
Handle<Name> script_name) {
if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return;
if (*code == AbstractCode::cast(
isolate_->builtins()->builtin(Builtins::kCompileLazy))) {
return;
}
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
AppendCodeCreateHeader(msg, tag, *code, Time());
msg << *script_name << kNext << reinterpret_cast<void*>(shared->address())
<< kNext << ComputeMarker(*shared, *code);
msg.WriteToLogFile();
}
// Although, it is possible to extract source and line from
// the SharedFunctionInfo object, we left it to caller
// to leave logging functions free from heap allocations.
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
Handle<SharedFunctionInfo> shared,
Handle<Name> script_name, int line, int column) {
if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return;
{
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
AppendCodeCreateHeader(msg, tag, *code, Time());
msg << shared->DebugNameCStr().get() << " " << *script_name << ":" << line
<< ":" << column << kNext << reinterpret_cast<void*>(shared->address())
<< kNext << ComputeMarker(*shared, *code);
msg.WriteToLogFile();
}
if (!FLAG_log_source_code) return;
Object script_object = shared->script(); Object script_object = shared->script();
if (!script_object.IsScript()) return; if (!script_object.IsScript()) return;
Script script = Script::cast(script_object); Script script = Script::cast(script_object);
if (!EnsureLogScriptSource(script)) return; EnsureLogScriptSource(script);
// We log source code information in the form: MSG_BUILDER();
// msg << "code-source-info" << Logger::kNext
// code-source-info <addr>,<script>,<start>,<end>,<pos>,<inline-pos>,<fns> << reinterpret_cast<void*>(code->InstructionStart()) << Logger::kNext
// << script.id() << Logger::kNext << shared->StartPosition()
// where << Logger::kNext << shared->EndPosition() << Logger::kNext;
// <addr> is code object address
// <script> is script id
// <start> is the starting position inside the script
// <end> is the end position inside the script
// <pos> is source position table encoded in the string,
// it is a sequence of C<code-offset>O<script-offset>[I<inlining-id>]
// where
// <code-offset> is the offset within the code object
// <script-offset> is the position within the script
// <inlining-id> is the offset in the <inlining> table
// <inlining> table is a sequence of strings of the form
// F<function-id>O<script-offset>[I<inlining-id>]
// where
// <function-id> is an index into the <fns> function table
// <fns> is the function table encoded as a sequence of strings
// S<shared-function-info-address>
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "code-source-info" << kNext
<< reinterpret_cast<void*>(code->InstructionStart()) << kNext
<< script.id() << kNext << shared->StartPosition() << kNext
<< shared->EndPosition() << kNext;
SourcePositionTableIterator iterator(code->source_position_table()); SourcePositionTableIterator iterator(code->source_position_table());
bool hasInlined = false; bool hasInlined = false;
...@@ -1320,7 +1230,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code, ...@@ -1320,7 +1230,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
hasInlined = true; hasInlined = true;
} }
} }
msg << kNext; msg << Logger::kNext;
int maxInlinedId = -1; int maxInlinedId = -1;
if (hasInlined) { if (hasInlined) {
PodArray<InliningPosition> inlining_positions = PodArray<InliningPosition> inlining_positions =
...@@ -1343,11 +1253,10 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code, ...@@ -1343,11 +1253,10 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
} }
} }
} }
msg << kNext; msg << Logger::kNext;
if (hasInlined) { if (hasInlined) {
DeoptimizationData deopt_data = DeoptimizationData::cast( DeoptimizationData deopt_data = DeoptimizationData::cast(
Handle<Code>::cast(code)->deoptimization_data()); Handle<Code>::cast(code)->deoptimization_data());
msg << std::hex; msg << std::hex;
for (int i = 0; i <= maxInlinedId; i++) { for (int i = 0; i <= maxInlinedId; i++) {
msg << "S" msg << "S"
...@@ -1359,13 +1268,102 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code, ...@@ -1359,13 +1268,102 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
void Logger::LogCodeDisassemble(Handle<AbstractCode> code) {
if (!FLAG_log_code_disassemble) return;
MSG_BUILDER();
msg << "code-disassemble" << Logger::kNext
<< reinterpret_cast<void*>(code->InstructionStart()) << Logger::kNext
<< CodeKindToString(code->kind()) << Logger::kNext;
{
std::ostringstream stream;
if (code->IsCode()) {
#ifdef ENABLE_DISASSEMBLER
Code::cast(*code).Disassemble(nullptr, stream, isolate_);
#endif
} else {
BytecodeArray::cast(*code).Disassemble(stream);
}
std::string string = stream.str();
msg.AppendString(string.c_str(), string.length());
}
msg.WriteToLogFile();
}
// Builtins and Bytecode handlers
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
const char* name) {
if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return;
{
MSG_BUILDER();
AppendCodeCreateHeader(msg, tag, *code, Time());
msg << name;
msg.WriteToLogFile();
}
LogCodeDisassemble(code);
}
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
Handle<Name> name) {
if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return;
{
MSG_BUILDER();
AppendCodeCreateHeader(msg, tag, *code, Time());
msg << *name;
msg.WriteToLogFile();
}
LogCodeDisassemble(code);
}
// Scripts
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
Handle<SharedFunctionInfo> shared,
Handle<Name> script_name) {
if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return;
if (*code == AbstractCode::cast(
isolate_->builtins()->builtin(Builtins::kCompileLazy))) {
return;
}
{
MSG_BUILDER();
AppendCodeCreateHeader(msg, tag, *code, Time());
msg << *script_name << kNext << reinterpret_cast<void*>(shared->address())
<< kNext << ComputeMarker(*shared, *code);
msg.WriteToLogFile();
}
LogSourceCodeInformation(code, shared);
LogCodeDisassemble(code);
}
// Functions
// Although, it is possible to extract source and line from
// the SharedFunctionInfo object, we left it to caller
// to leave logging functions free from heap allocations.
void Logger::CodeCreateEvent(LogEventsAndTags tag, Handle<AbstractCode> code,
Handle<SharedFunctionInfo> shared,
Handle<Name> script_name, int line, int column) {
if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return;
{
MSG_BUILDER();
AppendCodeCreateHeader(msg, tag, *code, Time());
msg << shared->DebugNameCStr().get() << " " << *script_name << ":" << line
<< ":" << column << kNext << reinterpret_cast<void*>(shared->address())
<< kNext << ComputeMarker(*shared, *code);
msg.WriteToLogFile();
}
LogSourceCodeInformation(code, shared);
LogCodeDisassemble(code);
}
void Logger::CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code, void Logger::CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
wasm::WasmName name) { wasm::WasmName name) {
if (!is_listening_to_code_events()) return; if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return; if (!FLAG_log_code) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
AppendCodeCreateHeader(msg, tag, CodeKind::WASM_FUNCTION, AppendCodeCreateHeader(msg, tag, CodeKind::WASM_FUNCTION,
code->instructions().begin(), code->instructions().begin(),
code->instructions().length(), Time()); code->instructions().length(), Time());
...@@ -1386,9 +1384,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code, ...@@ -1386,9 +1384,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag, const wasm::WasmCode* code,
void Logger::CallbackEventInternal(const char* prefix, Handle<Name> name, void Logger::CallbackEventInternal(const char* prefix, Handle<Name> name,
Address entry_point) { Address entry_point) {
if (!FLAG_log_code) return; if (!FLAG_log_code) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT] << kNext msg << kLogEventsNames[CodeEventListener::CODE_CREATION_EVENT] << kNext
<< kLogEventsNames[CodeEventListener::CALLBACK_TAG] << kNext << -2 << kLogEventsNames[CodeEventListener::CALLBACK_TAG] << kNext << -2
<< kNext << Time() << kNext << reinterpret_cast<void*>(entry_point) << kNext << Time() << kNext << reinterpret_cast<void*>(entry_point)
...@@ -1412,9 +1408,7 @@ void Logger::RegExpCodeCreateEvent(Handle<AbstractCode> code, ...@@ -1412,9 +1408,7 @@ void Logger::RegExpCodeCreateEvent(Handle<AbstractCode> code,
Handle<String> source) { Handle<String> source) {
if (!is_listening_to_code_events()) return; if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return; if (!FLAG_log_code) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
AppendCodeCreateHeader(msg, CodeEventListener::REG_EXP_TAG, *code, Time()); AppendCodeCreateHeader(msg, CodeEventListener::REG_EXP_TAG, *code, Time());
msg << *source; msg << *source;
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1441,9 +1435,7 @@ void Logger::CodeDisableOptEvent(Handle<AbstractCode> code, ...@@ -1441,9 +1435,7 @@ void Logger::CodeDisableOptEvent(Handle<AbstractCode> code,
Handle<SharedFunctionInfo> shared) { Handle<SharedFunctionInfo> shared) {
if (!is_listening_to_code_events()) return; if (!is_listening_to_code_events()) return;
if (!FLAG_log_code) return; if (!FLAG_log_code) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT] << kNext msg << kLogEventsNames[CodeEventListener::CODE_DISABLE_OPT_EVENT] << kNext
<< shared->DebugNameCStr().get() << kNext << shared->DebugNameCStr().get() << kNext
<< GetBailoutReason(shared->disable_optimization_reason()); << GetBailoutReason(shared->disable_optimization_reason());
...@@ -1452,9 +1444,7 @@ void Logger::CodeDisableOptEvent(Handle<AbstractCode> code, ...@@ -1452,9 +1444,7 @@ void Logger::CodeDisableOptEvent(Handle<AbstractCode> code,
void Logger::ProcessDeoptEvent(Handle<Code> code, SourcePosition position, void Logger::ProcessDeoptEvent(Handle<Code> code, SourcePosition position,
const char* kind, const char* reason) { const char* kind, const char* reason) {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "code-deopt" << kNext << Time() << kNext << code->CodeSize() << kNext msg << "code-deopt" << kNext << Time() << kNext << code->CodeSize() << kNext
<< reinterpret_cast<void*>(code->InstructionStart()); << reinterpret_cast<void*>(code->InstructionStart());
...@@ -1529,9 +1519,7 @@ void Logger::CodeLinePosInfoRecordEvent( ...@@ -1529,9 +1519,7 @@ void Logger::CodeLinePosInfoRecordEvent(
void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
if (code_name == nullptr) return; // Not a code object. if (code_name == nullptr) return; // Not a code object.
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << kLogEventsNames[CodeEventListener::SNAPSHOT_CODE_NAME_EVENT] << kNext msg << kLogEventsNames[CodeEventListener::SNAPSHOT_CODE_NAME_EVENT] << kNext
<< pos << kNext << code_name; << pos << kNext << code_name;
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1540,9 +1528,7 @@ void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) { ...@@ -1540,9 +1528,7 @@ void Logger::CodeNameEvent(Address addr, int pos, const char* code_name) {
void Logger::MoveEventInternal(LogEventsAndTags event, Address from, void Logger::MoveEventInternal(LogEventsAndTags event, Address from,
Address to) { Address to) {
if (!FLAG_log_code) return; if (!FLAG_log_code) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << kLogEventsNames[event] << kNext << reinterpret_cast<void*>(from) msg << kLogEventsNames[event] << kNext << reinterpret_cast<void*>(from)
<< kNext << reinterpret_cast<void*>(to); << kNext << reinterpret_cast<void*>(to);
msg.WriteToLogFile(); msg.WriteToLogFile();
...@@ -1550,9 +1536,7 @@ void Logger::MoveEventInternal(LogEventsAndTags event, Address from, ...@@ -1550,9 +1536,7 @@ void Logger::MoveEventInternal(LogEventsAndTags event, Address from,
void Logger::ResourceEvent(const char* name, const char* tag) { void Logger::ResourceEvent(const char* name, const char* tag) {
if (!FLAG_log) return; if (!FLAG_log) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << name << kNext << tag << kNext; msg << name << kNext << tag << kNext;
uint32_t sec, usec; uint32_t sec, usec;
...@@ -1566,9 +1550,7 @@ void Logger::ResourceEvent(const char* name, const char* tag) { ...@@ -1566,9 +1550,7 @@ void Logger::ResourceEvent(const char* name, const char* tag) {
void Logger::SuspectReadEvent(Name name, Object obj) { void Logger::SuspectReadEvent(Name name, Object obj) {
if (!FLAG_log_suspect) return; if (!FLAG_log_suspect) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
String class_name = obj.IsJSObject() ? JSObject::cast(obj).class_name() String class_name = obj.IsJSObject() ? JSObject::cast(obj).class_name()
: ReadOnlyRoots(isolate_).empty_string(); : ReadOnlyRoots(isolate_).empty_string();
msg << "suspect-read" << kNext << class_name << kNext << name; msg << "suspect-read" << kNext << class_name << kNext << name;
...@@ -1596,9 +1578,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta, ...@@ -1596,9 +1578,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
int start_position, int end_position, int start_position, int end_position,
String function_name) { String function_name) {
if (!FLAG_log_function_events) return; if (!FLAG_log_function_events) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
AppendFunctionMessage(msg, reason, script_id, time_delta, start_position, AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
end_position, Time()); end_position, Time());
if (!function_name.is_null()) msg << function_name; if (!function_name.is_null()) msg << function_name;
...@@ -1610,9 +1590,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta, ...@@ -1610,9 +1590,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
const char* function_name, const char* function_name,
size_t function_name_length, bool is_one_byte) { size_t function_name_length, bool is_one_byte) {
if (!FLAG_log_function_events) return; if (!FLAG_log_function_events) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
AppendFunctionMessage(msg, reason, script_id, time_delta, start_position, AppendFunctionMessage(msg, reason, script_id, time_delta, start_position,
end_position, Time()); end_position, Time());
if (function_name_length > 0) { if (function_name_length > 0) {
...@@ -1624,9 +1602,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta, ...@@ -1624,9 +1602,7 @@ void Logger::FunctionEvent(const char* reason, int script_id, double time_delta,
void Logger::CompilationCacheEvent(const char* action, const char* cache_type, void Logger::CompilationCacheEvent(const char* action, const char* cache_type,
SharedFunctionInfo sfi) { SharedFunctionInfo sfi) {
if (!FLAG_log_function_events) return; if (!FLAG_log_function_events) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
int script_id = -1; int script_id = -1;
if (sfi.script().IsScript()) { if (sfi.script().IsScript()) {
script_id = Script::cast(sfi.script()).id(); script_id = Script::cast(sfi.script()).id();
...@@ -1640,9 +1616,7 @@ void Logger::CompilationCacheEvent(const char* action, const char* cache_type, ...@@ -1640,9 +1616,7 @@ void Logger::CompilationCacheEvent(const char* action, const char* cache_type,
void Logger::ScriptEvent(ScriptEventType type, int script_id) { void Logger::ScriptEvent(ScriptEventType type, int script_id) {
if (!FLAG_log_function_events) return; if (!FLAG_log_function_events) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "script" << Logger::kNext; msg << "script" << Logger::kNext;
switch (type) { switch (type) {
case ScriptEventType::kReserveId: case ScriptEventType::kReserveId:
...@@ -1668,9 +1642,7 @@ void Logger::ScriptEvent(ScriptEventType type, int script_id) { ...@@ -1668,9 +1642,7 @@ void Logger::ScriptEvent(ScriptEventType type, int script_id) {
void Logger::ScriptDetails(Script script) { void Logger::ScriptDetails(Script script) {
if (!FLAG_log_function_events) return; if (!FLAG_log_function_events) return;
{ {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "script-details" << Logger::kNext << script.id() << Logger::kNext; msg << "script-details" << Logger::kNext << script.id() << Logger::kNext;
if (script.name().IsString()) { if (script.name().IsString()) {
msg << String::cast(script.name()); msg << String::cast(script.name());
...@@ -1686,9 +1658,6 @@ void Logger::ScriptDetails(Script script) { ...@@ -1686,9 +1658,6 @@ void Logger::ScriptDetails(Script script) {
} }
bool Logger::EnsureLogScriptSource(Script script) { bool Logger::EnsureLogScriptSource(Script script) {
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
if (!msg_ptr) return false;
Log::MessageBuilder& msg = *msg_ptr.get();
// Make sure the script is written to the log file. // Make sure the script is written to the log file.
int script_id = script.id(); int script_id = script.id();
if (logged_source_code_.find(script_id) != logged_source_code_.end()) { if (logged_source_code_.find(script_id) != logged_source_code_.end()) {
...@@ -1698,6 +1667,11 @@ bool Logger::EnsureLogScriptSource(Script script) { ...@@ -1698,6 +1667,11 @@ bool Logger::EnsureLogScriptSource(Script script) {
logged_source_code_.insert(script_id); logged_source_code_.insert(script_id);
Object source_object = script.source(); Object source_object = script.source();
if (!source_object.IsString()) return false; if (!source_object.IsString()) return false;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder();
if (!msg_ptr) return false;
Log::MessageBuilder& msg = *msg_ptr.get();
String source_code = String::cast(source_object); String source_code = String::cast(source_object);
msg << "script-source" << kNext << script_id << kNext; msg << "script-source" << kNext << script_id << kNext;
...@@ -1718,9 +1692,7 @@ void Logger::RuntimeCallTimerEvent() { ...@@ -1718,9 +1692,7 @@ void Logger::RuntimeCallTimerEvent() {
RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats(); RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats();
RuntimeCallCounter* counter = stats->current_counter(); RuntimeCallCounter* counter = stats->current_counter();
if (counter == nullptr) return; if (counter == nullptr) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "active-runtime-timer" << kNext << counter->name(); msg << "active-runtime-timer" << kNext << counter->name();
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
...@@ -1731,9 +1703,7 @@ void Logger::TickEvent(TickSample* sample, bool overflow) { ...@@ -1731,9 +1703,7 @@ void Logger::TickEvent(TickSample* sample, bool overflow) {
v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) { v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) {
RuntimeCallTimerEvent(); RuntimeCallTimerEvent();
} }
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << kLogEventsNames[CodeEventListener::TICK_EVENT] << kNext msg << kLogEventsNames[CodeEventListener::TICK_EVENT] << kNext
<< reinterpret_cast<void*>(sample->pc) << kNext << Time(); << reinterpret_cast<void*>(sample->pc) << kNext << Time();
if (sample->has_external_callback) { if (sample->has_external_callback) {
...@@ -1754,9 +1724,7 @@ void Logger::ICEvent(const char* type, bool keyed, Handle<Map> map, ...@@ -1754,9 +1724,7 @@ void Logger::ICEvent(const char* type, bool keyed, Handle<Map> map,
Handle<Object> key, char old_state, char new_state, Handle<Object> key, char old_state, char new_state,
const char* modifier, const char* slow_stub_reason) { const char* modifier, const char* slow_stub_reason) {
if (!FLAG_trace_ic) return; if (!FLAG_trace_ic) return;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
if (keyed) msg << "Keyed"; if (keyed) msg << "Keyed";
int line; int line;
int column; int column;
...@@ -1790,9 +1758,7 @@ void Logger::MapEvent(const char* type, Handle<Map> from, Handle<Map> to, ...@@ -1790,9 +1758,7 @@ void Logger::MapEvent(const char* type, Handle<Map> from, Handle<Map> to,
if (!isolate_->bootstrapper()->IsActive()) { if (!isolate_->bootstrapper()->IsActive()) {
pc = isolate_->GetAbstractPC(&line, &column); pc = isolate_->GetAbstractPC(&line, &column);
} }
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "map" << kNext << type << kNext << Time() << kNext msg << "map" << kNext << type << kNext << Time() << kNext
<< AsHex::Address(from.is_null() ? kNullAddress : from->ptr()) << kNext << AsHex::Address(from.is_null() ? kNullAddress : from->ptr()) << kNext
<< AsHex::Address(to.is_null() ? kNullAddress : to->ptr()) << kNext << AsHex::Address(to.is_null() ? kNullAddress : to->ptr()) << kNext
...@@ -1816,9 +1782,7 @@ void Logger::MapEvent(const char* type, Handle<Map> from, Handle<Map> to, ...@@ -1816,9 +1782,7 @@ void Logger::MapEvent(const char* type, Handle<Map> from, Handle<Map> to,
void Logger::MapCreate(Map map) { void Logger::MapCreate(Map map) {
if (!FLAG_trace_maps) return; if (!FLAG_trace_maps) return;
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "map-create" << kNext << Time() << kNext << AsHex::Address(map.ptr()); msg << "map-create" << kNext << Time() << kNext << AsHex::Address(map.ptr());
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
...@@ -1826,9 +1790,7 @@ void Logger::MapCreate(Map map) { ...@@ -1826,9 +1790,7 @@ void Logger::MapCreate(Map map) {
void Logger::MapDetails(Map map) { void Logger::MapDetails(Map map) {
if (!FLAG_trace_maps) return; if (!FLAG_trace_maps) return;
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
std::unique_ptr<Log::MessageBuilder> msg_ptr = log_->NewMessageBuilder(); MSG_BUILDER();
if (!msg_ptr) return;
Log::MessageBuilder& msg = *msg_ptr.get();
msg << "map-details" << kNext << Time() << kNext << AsHex::Address(map.ptr()) msg << "map-details" << kNext << Time() << kNext << AsHex::Address(map.ptr())
<< kNext; << kNext;
if (FLAG_trace_maps_details) { if (FLAG_trace_maps_details) {
...@@ -1923,10 +1885,6 @@ static int EnumerateWasmModuleObjects( ...@@ -1923,10 +1885,6 @@ static int EnumerateWasmModuleObjects(
return module_objects_count; return module_objects_count;
} }
void Logger::LogCodeObject(Object object) {
existing_code_logger_.LogCodeObject(object);
}
void Logger::LogCodeObjects() { existing_code_logger_.LogCodeObjects(); } void Logger::LogCodeObjects() { existing_code_logger_.LogCodeObjects(); }
void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared, void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
...@@ -2307,6 +2265,7 @@ void ExistingCodeLogger::LogExistingFunction( ...@@ -2307,6 +2265,7 @@ void ExistingCodeLogger::LogExistingFunction(
} }
#undef CALL_CODE_EVENT_HANDLER #undef CALL_CODE_EVENT_HANDLER
#undef MSG_BUILDER
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -280,9 +280,6 @@ class Logger : public CodeEventListener { ...@@ -280,9 +280,6 @@ class Logger : public CodeEventListener {
V8_INLINE static CodeEventListener::LogEventsAndTags ToNativeByScript( V8_INLINE static CodeEventListener::LogEventsAndTags ToNativeByScript(
CodeEventListener::LogEventsAndTags, Script); CodeEventListener::LogEventsAndTags, Script);
// Used for logging stubs found in the snapshot.
void LogCodeObject(Object code_object);
private: private:
void UpdateIsLogging(bool value); void UpdateIsLogging(bool value);
...@@ -314,6 +311,10 @@ class Logger : public CodeEventListener { ...@@ -314,6 +311,10 @@ class Logger : public CodeEventListener {
// each script is logged only once. // each script is logged only once.
bool EnsureLogScriptSource(Script script); bool EnsureLogScriptSource(Script script);
void LogSourceCodeInformation(Handle<AbstractCode> code,
Handle<SharedFunctionInfo> shared);
void LogCodeDisassemble(Handle<AbstractCode> code);
int64_t Time(); int64_t Time();
Isolate* isolate_; Isolate* isolate_;
......
...@@ -86,8 +86,16 @@ export class Script { ...@@ -86,8 +86,16 @@ export class Script {
} }
class SourcePositionInfo{ class SourceInfo{
constructor(script, startPos, endPos, sourcePositionTable, inliningPositions, inlinedFunctions) { script;
start;
end;
positions;
inlined ;
fns;
disassemble;
setSourcePositionInfo(script, startPos, endPos, sourcePositionTable, inliningPositions, inlinedFunctions) {
this.script = script; this.script = script;
this.start = startPos; this.start = startPos;
this.end = endPos; this.end = endPos;
...@@ -95,6 +103,10 @@ class SourcePositionInfo{ ...@@ -95,6 +103,10 @@ class SourcePositionInfo{
this.inlined = inliningPositions; this.inlined = inliningPositions;
this.fns = inlinedFunctions; this.fns = inlinedFunctions;
} }
setDisassemble(code) {
this.disassemble = code;
}
} }
/** /**
...@@ -297,8 +309,6 @@ export class Profile { ...@@ -297,8 +309,6 @@ export class Profile {
const script = this.getOrCreateScript(scriptId); const script = this.getOrCreateScript(scriptId);
const entry = this.codeMap_.findDynamicEntryByStartAddress(start); const entry = this.codeMap_.findDynamicEntryByStartAddress(start);
if (!entry) return; if (!entry) return;
const codeId = entry.codeId;
// Resolve the inlined functions list. // Resolve the inlined functions list.
if (inlinedFunctions.length > 0) { if (inlinedFunctions.length > 0) {
inlinedFunctions = inlinedFunctions.substring(1).split("S"); inlinedFunctions = inlinedFunctions.substring(1).split("S");
...@@ -317,12 +327,21 @@ export class Profile { ...@@ -317,12 +327,21 @@ export class Profile {
inlinedFunctions = []; inlinedFunctions = [];
} }
entry.source = this.getOrCreateSourceInfo(entry).setSourcePositionInfo(
new SourcePositionInfo(
script, startPos, endPos, sourcePositionTable, inliningPositions, script, startPos, endPos, sourcePositionTable, inliningPositions,
inlinedFunctions); inlinedFunctions);
} }
addDisassemble(start, kind, disassemble) {
const entry = this.codeMap_.findDynamicEntryByStartAddress(start);
if (!entry) return;
this.getOrCreateSourceInfo(entry).setDisassemble(disassemble);
}
getOrCreateSourceInfo(entry) {
return entry.source ?? (entry.source = new SourceInfo());
}
addScriptSource(id, url, source) { addScriptSource(id, url, source) {
const script = this.getOrCreateScript(id); const script = this.getOrCreateScript(id);
script.update(url, source); script.update(url, source);
......
...@@ -20,7 +20,7 @@ found in the LICENSE file. --> ...@@ -20,7 +20,7 @@ found in the LICENSE file. -->
let module = await import('./index.mjs'); let module = await import('./index.mjs');
globalThis.app = new module.App("#log-file-reader", "#map-panel", "#map-stats-panel", globalThis.app = new module.App("#log-file-reader", "#map-panel", "#map-stats-panel",
"#timeline-panel", "#ic-panel", "#map-track", "#ic-track", "#deopt-track", "#timeline-panel", "#ic-panel", "#map-track", "#ic-track", "#deopt-track",
"#code-track", "#source-panel", "#tool-tip"); "#code-track", "#source-panel", "#code-panel", "#tool-tip");
})(); })();
</script> </script>
...@@ -110,6 +110,7 @@ found in the LICENSE file. --> ...@@ -110,6 +110,7 @@ found in the LICENSE file. -->
<stats-panel id="map-stats-panel"></stats-panel> <stats-panel id="map-stats-panel"></stats-panel>
<ic-panel id="ic-panel" onchange="app.handleSelectIc(event)"></ic-panel> <ic-panel id="ic-panel" onchange="app.handleSelectIc(event)"></ic-panel>
<source-panel id="source-panel"></source-panel> <source-panel id="source-panel"></source-panel>
<code-panel id="code-panel"></code-panel>
</div> </div>
</section> </section>
...@@ -133,29 +134,53 @@ found in the LICENSE file. --> ...@@ -133,29 +134,53 @@ found in the LICENSE file. -->
For generating a v8.log file from <a href="https://v8.dev/docs/build">d8</a>: For generating a v8.log file from <a href="https://v8.dev/docs/build">d8</a>:
<ul> <ul>
<li> <li>
<code>/path/do/d8 --trace-maps --trace_ic --log-source-code $FILE</code> <code>/path/do/d8 $LOG_FLAGS $FILE</code>
</li> </li>
</ul> </ul>
For generating a v8.log file from Chrome: For generating a v8.log file from Chrome:
<ul> <ul>
<li> <li>
<code>/path/to/chrome --user-data-dir=/var/tmp/chr$RANDOM --no-sandbox <code>/path/to/chrome --user-data-dir=/var/tmp/chr$RANDOM --no-sandbox
--js-flags='--trace-ic --trace-maps --log-source-code --js-flags='$LOG_FLAGS
$WEBSITE_URL</code> $WEBSITE_URL</code>
</li> </li>
</ul> </ul>
<h3>Log Options:</h3> <h3><code>LOG_FLAGS</code>:</h3>
<dl class="d8-options"> <dl class="d8-options">
<dt><code>--trace-maps</code></dt> <dt>
<a href="https://source.chromium.org/search?q=FLAG_log_all">
<code>--log-all</code>
</a>
</dt>
<dd>Enable all V8 logging options.</dd>
<dt>
<a href="https://source.chromium.org/search?q=FLAG_trace_maps">
<code>--trace-maps</code>
</a>
</dt>
<dd>Log<a href="https://v8.dev/blog/fast-properties" target="_blank"> <dd>Log<a href="https://v8.dev/blog/fast-properties" target="_blank">
Maps</a></dd> Maps</a></dd>
<dt><code>--trace-ic</code></dt> <dt>
<a href="https://source.chromium.org/search?q=FLAG_trace_ic">
<code>--trace-ic</code>
</a>
</dt>
<dd>Log <dd>Log
<a href="https://mathiasbynens.be/notes/shapes-ics" target="_blank"> <a href="https://mathiasbynens.be/notes/shapes-ics" target="_blank">
ICs</a></dd> ICs</a></dd>
<dt><code>--log-source-code</code></dt> <dt>
<a href="https://source.chromium.org/search?q=FLAG_log_source_code">
<code>--log-source-code</code>
</a>
</dt>
<dd>Log source code</dd> <dd>Log source code</dd>
<dt>
<a href="https://source.chromium.org/search?q=FLAG_log_code_disassemble">
<code>--log-code-disassemble</code>
</a>
</dt>
<dd>Log detailed generated generated code</dd>
</dl> </dl>
<h3>Keyboard Shortcuts for Navigation</h3> <h3>Keyboard Shortcuts for Navigation</h3>
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import {SourcePosition} from '../profile.mjs'; import {SourcePosition} from '../profile.mjs';
import {State} from './app-model.mjs'; import {State} from './app-model.mjs';
import {CodeLogEntry} from './log/code.mjs';
import {IcLogEntry} from './log/ic.mjs'; import {IcLogEntry} from './log/ic.mjs';
import {MapLogEntry} from './log/map.mjs'; import {MapLogEntry} from './log/map.mjs';
import {Processor} from './processor.mjs'; import {Processor} from './processor.mjs';
...@@ -19,7 +20,7 @@ class App { ...@@ -19,7 +20,7 @@ class App {
constructor( constructor(
fileReaderId, mapPanelId, mapStatsPanelId, timelinePanelId, icPanelId, fileReaderId, mapPanelId, mapStatsPanelId, timelinePanelId, icPanelId,
mapTrackId, icTrackId, deoptTrackId, codeTrackId, sourcePanelId, mapTrackId, icTrackId, deoptTrackId, codeTrackId, sourcePanelId,
toolTipId) { codePanelId, toolTipId) {
this._view = { this._view = {
__proto__: null, __proto__: null,
logFileReader: $(fileReaderId), logFileReader: $(fileReaderId),
...@@ -32,6 +33,7 @@ class App { ...@@ -32,6 +33,7 @@ class App {
deoptTrack: $(deoptTrackId), deoptTrack: $(deoptTrackId),
codeTrack: $(codeTrackId), codeTrack: $(codeTrackId),
sourcePanel: $(sourcePanelId), sourcePanel: $(sourcePanelId),
codePanel: $(codePanelId),
toolTip: $(toolTipId), toolTip: $(toolTipId),
}; };
this.toggleSwitch = $('.theme-switch input[type="checkbox"]'); this.toggleSwitch = $('.theme-switch input[type="checkbox"]');
...@@ -50,6 +52,7 @@ class App { ...@@ -50,6 +52,7 @@ class App {
import('./view/stats-panel.mjs'), import('./view/stats-panel.mjs'),
import('./view/map-panel.mjs'), import('./view/map-panel.mjs'),
import('./view/source-panel.mjs'), import('./view/source-panel.mjs'),
import('./view/code-panel.mjs'),
import('./view/tool-tip.mjs'), import('./view/tool-tip.mjs'),
]); ]);
document.addEventListener( document.addEventListener(
...@@ -71,6 +74,8 @@ class App { ...@@ -71,6 +74,8 @@ class App {
this.showIcEntries(e.entries); this.showIcEntries(e.entries);
} else if (entry instanceof SourcePosition) { } else if (entry instanceof SourcePosition) {
this.showSourcePositionEntries(e.entries); this.showSourcePositionEntries(e.entries);
} else if (e.entries[0] instanceof CodeLogEntry) {
this.showCodeEntries(e.entries);
} else { } else {
throw new Error('Unknown selection type!'); throw new Error('Unknown selection type!');
} }
...@@ -96,6 +101,7 @@ class App { ...@@ -96,6 +101,7 @@ class App {
showCodeEntries(entries) { showCodeEntries(entries) {
// TODO: creat list panel // TODO: creat list panel
this._state.selectedCodeLogEntries = entries; this._state.selectedCodeLogEntries = entries;
this._view.codePanel.selectedEntries = entries;
} }
showSourcePositionEntries(entries) { showSourcePositionEntries(entries) {
...@@ -125,6 +131,8 @@ class App { ...@@ -125,6 +131,8 @@ class App {
this.selectICLogEntry(e.entry); this.selectICLogEntry(e.entry);
} else if (entry instanceof SourcePosition) { } else if (entry instanceof SourcePosition) {
this.selectSourcePosition(e.entry); this.selectSourcePosition(e.entry);
} else if (e.entry instanceof CodeLogEntry) {
this.selectCodeLogEntry(e.entry);
} else { } else {
throw new Error('Unknown selection type!'); throw new Error('Unknown selection type!');
} }
...@@ -142,6 +150,11 @@ class App { ...@@ -142,6 +150,11 @@ class App {
this._view.icPanel.selectedEntry = [entry]; this._view.icPanel.selectedEntry = [entry];
} }
selectCodeLogEntry(entry) {
this._state.code = entry;
this._view.codePanel.entry = entry;
}
selectSourcePosition(sourcePositions) { selectSourcePosition(sourcePositions) {
if (!sourcePositions.script) return; if (!sourcePositions.script) return;
this._view.sourcePanel.selectedSourcePositions = [sourcePositions]; this._view.sourcePanel.selectedSourcePositions = [sourcePositions];
...@@ -179,6 +192,7 @@ class App { ...@@ -179,6 +192,7 @@ class App {
this._view.mapStatsPanel.timeline = mapTimeline; this._view.mapStatsPanel.timeline = mapTimeline;
this._view.icPanel.timeline = icTimeline; this._view.icPanel.timeline = icTimeline;
this._view.sourcePanel.data = processor.scripts; this._view.sourcePanel.data = processor.scripts;
this._view.codePanel.timeline = codeTimeline;
this.refreshTimelineTrackView(); this.refreshTimelineTrackView();
} catch (e) { } catch (e) {
this._view.logFileReader.error = 'Log file contains errors!' this._view.logFileReader.error = 'Log file contains errors!'
......
...@@ -15,6 +15,7 @@ export class DeoptLogEntry extends LogEntry { ...@@ -15,6 +15,7 @@ export class DeoptLogEntry extends LogEntry {
this._codeSize = codeSize; this._codeSize = codeSize;
this._inliningId = inliningId; this._inliningId = inliningId;
} }
toString() { toString() {
return `Deopt(${this.type})${this._deoptReason}: ${this._deoptLocation}`; return `Deopt(${this.type})${this._deoptReason}: ${this._deoptLocation}`;
} }
...@@ -26,7 +27,12 @@ export class CodeLogEntry extends LogEntry { ...@@ -26,7 +27,12 @@ export class CodeLogEntry extends LogEntry {
this._kind = kind; this._kind = kind;
this._entry = entry; this._entry = entry;
} }
toString() { toString() {
return `Code(${this.type}): ${this._entry.toString()}`; return `Code(${this.type}): ${this._entry.toString()}`;
} }
get disassemble() {
return this._entry?.source?.disassemble;
}
} }
...@@ -60,6 +60,14 @@ export class Processor extends LogReader { ...@@ -60,6 +60,14 @@ export class Processor extends LogReader {
], ],
processor: this.processCodeSourceInfo processor: this.processCodeSourceInfo
}, },
'code-disassemble': {
parsers: [
parseInt,
parseString,
parseString,
],
processor: this.processCodeDisassemble
},
'script-source': { 'script-source': {
parsers: [parseInt, parseString, parseString], parsers: [parseInt, parseString, parseString],
processor: this.processScriptSource processor: this.processScriptSource
...@@ -176,15 +184,18 @@ export class Processor extends LogReader { ...@@ -176,15 +184,18 @@ export class Processor extends LogReader {
processCodeCreation(type, kind, timestamp, start, size, name, maybe_func) { processCodeCreation(type, kind, timestamp, start, size, name, maybe_func) {
let entry; let entry;
let stateName = '';
if (maybe_func.length) { if (maybe_func.length) {
const funcAddr = parseInt(maybe_func[0]); const funcAddr = parseInt(maybe_func[0]);
stateName = maybe_func[1] ?? '';
const state = Profile.parseState(maybe_func[1]); const state = Profile.parseState(maybe_func[1]);
entry = this._profile.addFuncCode( entry = this._profile.addFuncCode(
type, name, timestamp, start, size, funcAddr, state); type, name, timestamp, start, size, funcAddr, state);
} else { } else {
entry = this._profile.addCode(type, name, timestamp, start, size); entry = this._profile.addCode(type, name, timestamp, start, size);
} }
this._codeTimeline.push(new CodeLogEntry(type, timestamp, kind, entry)); this._codeTimeline.push(
new CodeLogEntry(type + stateName, timestamp, kind, entry));
} }
processCodeDeopt( processCodeDeopt(
...@@ -229,6 +240,10 @@ export class Processor extends LogReader { ...@@ -229,6 +240,10 @@ export class Processor extends LogReader {
inlinedFunctions); inlinedFunctions);
} }
processCodeDisassemble(start, kind, disassemble) {
this._profile.addDisassemble(start, kind, disassemble);
}
processPropertyIC( processPropertyIC(
type, pc, time, line, column, old_state, new_state, map, key, modifier, type, pc, time, line, column, old_state, new_state, map, key, modifier,
slow_reason) { slow_reason) {
......
<!-- Copyright 2020 the V8 project authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<head>
<link href="./index.css" rel="stylesheet">
</head>
<style>
</style>
<div class="panel">
<h2>Code Panel</h2>
<div class="panelBody">
<pre id="code"></pre>
</div>
</div>
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {IcLogEntry} from '../log/ic.mjs';
import {MapLogEntry} from '../log/map.mjs';
import {FocusEvent, SelectionEvent, ToolTipEvent} from './events.mjs';
import {delay, DOM, formatBytes, V8CustomElement} from './helper.mjs';
DOM.defineCustomElement(
'view/code-panel',
(templateText) => class CodePanel extends V8CustomElement {
_timeline;
_selectedEntries;
_entry;
constructor() {
super(templateText);
}
set timeline(timeline) {
this._timeline = timeline;
this.update();
}
set selectedEntries(entries) {
this._selectedEntries = entries;
this.update();
}
set entry(entry) {
this._entry = entry;
this.update();
}
get codeNode() {
return this.$('#code');
}
_update() {
this.codeNode.innerText = this._entry?.disassemble ?? '';
}
});
\ No newline at end of file
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