Log debug info of WASM for Intel VTune Amplifier
This CL logs debug information of WASM in Intel VTune Amplifer via VTune's JIT Profiling API. With this CL, the profiling information of JITted code and its corresponding C/C++ source code is displayed optionally. To use this feature, a runtime flag "vtune_prof_annotat e_wasm" should be passed to the VTune-enabled V8 engine. Currently, the inline function in C/C++ is not well supported due to the limitation of source map. As a drive-by fix, the dynamically allocated event-specific data of JavaScript (src/third_party/vtune/vtune-jit.cc) is managed with C++ containers for safety. Change-Id: Ic27420fcdcd775bc5c7778abf5cff6edf0fb38b6 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1782126 Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Zhiguo Zhou <zhiguo.zhou@intel.com> Cr-Commit-Position: refs/heads/master@{#64351}
This commit is contained in:
parent
282766c26d
commit
ec5807099f
14
include/v8.h
14
include/v8.h
@ -7447,6 +7447,20 @@ struct JitCodeEvent {
|
||||
PositionType position_type;
|
||||
};
|
||||
|
||||
struct wasm_source_info_t {
|
||||
// Source file name.
|
||||
const char* filename;
|
||||
// Length of filename.
|
||||
size_t filename_size;
|
||||
// Line number table, which maps offsets of JITted code to line numbers of
|
||||
// source file.
|
||||
const line_info_t* line_number_table;
|
||||
// Number of entries in the line number table.
|
||||
size_t line_number_table_size;
|
||||
};
|
||||
|
||||
wasm_source_info_t* wasm_source_info;
|
||||
|
||||
union {
|
||||
// Only valid for CODE_ADDED.
|
||||
struct name_t name;
|
||||
|
@ -2082,7 +2082,7 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
|
||||
EscapableHandleScope handle_scope(isolate);
|
||||
Local<Context> context = Context::New(isolate, nullptr, global_template);
|
||||
DCHECK(!context.IsEmpty());
|
||||
if (i::FLAG_perf_prof_annotate_wasm) {
|
||||
if (i::FLAG_perf_prof_annotate_wasm || i::FLAG_vtune_prof_annotate_wasm) {
|
||||
isolate->SetWasmLoadSourceMapCallback(ReadFile);
|
||||
}
|
||||
InitializeModuleEmbedderData(context);
|
||||
|
@ -1507,6 +1507,10 @@ DEFINE_STRING(redirect_code_traces_to, nullptr,
|
||||
DEFINE_BOOL(print_opt_source, false,
|
||||
"print source code of optimized and inlined functions")
|
||||
|
||||
DEFINE_BOOL(vtune_prof_annotate_wasm, false,
|
||||
"Used when v8_enable_vtunejit is enabled, load wasm source map and "
|
||||
"provide annotate support (experimental).")
|
||||
|
||||
DEFINE_BOOL(win64_unwinding_info, true, "Enable unwinding info for Windows/x64")
|
||||
|
||||
#ifdef V8_TARGET_ARCH_ARM
|
||||
|
@ -690,6 +690,42 @@ void JitLogger::LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
|
||||
event.name.str = name;
|
||||
event.name.len = length;
|
||||
event.isolate = reinterpret_cast<v8::Isolate*>(isolate_);
|
||||
|
||||
wasm::WasmModuleSourceMap* source_map =
|
||||
code->native_module()->GetWasmSourceMap();
|
||||
wasm::WireBytesRef code_ref =
|
||||
code->native_module()->module()->functions[code->index()].code;
|
||||
uint32_t code_offset = code_ref.offset();
|
||||
uint32_t code_end_offset = code_ref.end_offset();
|
||||
|
||||
std::vector<v8::JitCodeEvent::line_info_t> mapping_info;
|
||||
std::string filename;
|
||||
std::unique_ptr<JitCodeEvent::wasm_source_info_t> wasm_source_info;
|
||||
|
||||
if (source_map && source_map->IsValid() &&
|
||||
source_map->HasSource(code_offset, code_end_offset)) {
|
||||
size_t last_line_number = 0;
|
||||
|
||||
for (SourcePositionTableIterator iterator(code->source_positions());
|
||||
!iterator.done(); iterator.Advance()) {
|
||||
uint32_t offset = iterator.source_position().ScriptOffset() + code_offset;
|
||||
if (!source_map->HasValidEntry(code_offset, offset)) continue;
|
||||
if (filename.empty()) {
|
||||
filename = source_map->GetFilename(offset);
|
||||
}
|
||||
mapping_info.push_back({static_cast<size_t>(iterator.code_offset()),
|
||||
last_line_number, JitCodeEvent::POSITION});
|
||||
last_line_number = source_map->GetSourceLine(offset) + 1;
|
||||
}
|
||||
|
||||
wasm_source_info = std::make_unique<JitCodeEvent::wasm_source_info_t>();
|
||||
wasm_source_info->filename = filename.c_str();
|
||||
wasm_source_info->filename_size = filename.size();
|
||||
wasm_source_info->line_number_table_size = mapping_info.size();
|
||||
wasm_source_info->line_number_table = mapping_info.data();
|
||||
|
||||
event.wasm_source_info = wasm_source_info.get();
|
||||
}
|
||||
code_event_handler_(&event);
|
||||
}
|
||||
|
||||
|
63
src/third_party/vtune/vtune-jit.cc
vendored
63
src/third_party/vtune/vtune-jit.cc
vendored
@ -60,7 +60,10 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "v8-vtune.h"
|
||||
#include "vtune-jit.h"
|
||||
@ -136,7 +139,7 @@ static JITCodeLineInfo* UntagLineInfo(void* ptr) {
|
||||
// function name and some other info. It comes from all the
|
||||
// Logger::CodeCreateEvent(...) function. This function get the
|
||||
// pure function name from the input parameter.
|
||||
static char* GetFunctionNameFromMixedName(const char* str, int length) {
|
||||
static std::string GetFunctionNameFromMixedName(const char* str, int length) {
|
||||
int index = 0;
|
||||
int count = 0;
|
||||
char* start_ptr = NULL;
|
||||
@ -144,7 +147,7 @@ static char* GetFunctionNameFromMixedName(const char* str, int length) {
|
||||
while (str[index++] != ':' && (index < length)) {}
|
||||
|
||||
if (str[index] == '*' || str[index] == '~' ) index++;
|
||||
if (index >= length) return NULL;
|
||||
if (index >= length) return std::string();
|
||||
|
||||
start_ptr = const_cast<char*>(str + index);
|
||||
|
||||
@ -152,11 +155,7 @@ static char* GetFunctionNameFromMixedName(const char* str, int length) {
|
||||
count++;
|
||||
}
|
||||
|
||||
char* result = new char[count + 1];
|
||||
memcpy(result, start_ptr, count);
|
||||
result[count] = '\0';
|
||||
|
||||
return result;
|
||||
return std::string(start_ptr, count);
|
||||
}
|
||||
|
||||
// The JitCodeEventHandler for Vtune.
|
||||
@ -164,16 +163,16 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
|
||||
if (VTUNERUNNING && event != NULL) {
|
||||
switch (event->type) {
|
||||
case v8::JitCodeEvent::CODE_ADDED: {
|
||||
char* temp_file_name = NULL;
|
||||
char* temp_method_name =
|
||||
GetFunctionNameFromMixedName(event->name.str,
|
||||
static_cast<int>(event->name.len));
|
||||
std::unique_ptr<char[]> temp_file_name;
|
||||
std::string temp_method_name = GetFunctionNameFromMixedName(
|
||||
event->name.str, static_cast<int>(event->name.len));
|
||||
std::vector<LineNumberInfo> jmethod_line_number_table;
|
||||
iJIT_Method_Load jmethod;
|
||||
memset(&jmethod, 0, sizeof jmethod);
|
||||
jmethod.method_id = iJIT_GetNewMethodID();
|
||||
jmethod.method_load_address = event->code_start;
|
||||
jmethod.method_size = static_cast<unsigned int>(event->code_len);
|
||||
jmethod.method_name = temp_method_name;
|
||||
jmethod.method_name = const_cast<char*>(temp_method_name.c_str());
|
||||
|
||||
Local<UnboundScript> script = event->script;
|
||||
|
||||
@ -182,10 +181,10 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
|
||||
if ((*script->GetScriptName())->IsString()) {
|
||||
Local<String> script_name =
|
||||
Local<String>::Cast(script->GetScriptName());
|
||||
temp_file_name =
|
||||
new char[script_name->Utf8Length(event->isolate) + 1];
|
||||
script_name->WriteUtf8(event->isolate, temp_file_name);
|
||||
jmethod.source_file_name = temp_file_name;
|
||||
temp_file_name.reset(
|
||||
new char[script_name->Utf8Length(event->isolate) + 1]);
|
||||
script_name->WriteUtf8(event->isolate, temp_file_name.get());
|
||||
jmethod.source_file_name = temp_file_name.get();
|
||||
}
|
||||
|
||||
JitInfoMap::iterator entry =
|
||||
@ -197,9 +196,8 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
|
||||
line_info->GetLineNumInfo();
|
||||
|
||||
jmethod.line_number_size = (unsigned int)vtunelineinfo->size();
|
||||
jmethod.line_number_table =
|
||||
reinterpret_cast<LineNumberInfo*>(
|
||||
malloc(sizeof(LineNumberInfo)*jmethod.line_number_size));
|
||||
jmethod_line_number_table.resize(jmethod.line_number_size);
|
||||
jmethod.line_number_table = jmethod_line_number_table.data();
|
||||
|
||||
std::list<JITCodeLineInfo::LineNumInfo>::iterator Iter;
|
||||
int index = 0;
|
||||
@ -213,14 +211,33 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
|
||||
}
|
||||
GetEntries()->erase(event->code_start);
|
||||
}
|
||||
} else if (event->wasm_source_info != nullptr) {
|
||||
const char* filename = event->wasm_source_info->filename;
|
||||
size_t filename_size = event->wasm_source_info->filename_size;
|
||||
const v8::JitCodeEvent::line_info_t* line_number_table =
|
||||
event->wasm_source_info->line_number_table;
|
||||
size_t line_number_table_size =
|
||||
event->wasm_source_info->line_number_table_size;
|
||||
|
||||
temp_file_name.reset(new char[filename_size + 1]);
|
||||
memcpy(temp_file_name.get(), filename, filename_size);
|
||||
temp_file_name[filename_size] = '\0';
|
||||
jmethod.source_file_name = temp_file_name.get();
|
||||
|
||||
jmethod.line_number_size = line_number_table_size;
|
||||
jmethod_line_number_table.resize(jmethod.line_number_size);
|
||||
jmethod.line_number_table = jmethod_line_number_table.data();
|
||||
|
||||
for (size_t index = 0; index < line_number_table_size; ++index) {
|
||||
jmethod.line_number_table[index].LineNumber =
|
||||
line_number_table[index].pos;
|
||||
jmethod.line_number_table[index].Offset =
|
||||
line_number_table[index].offset;
|
||||
}
|
||||
}
|
||||
|
||||
iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
|
||||
reinterpret_cast<void*>(&jmethod));
|
||||
if (temp_method_name)
|
||||
delete []temp_method_name;
|
||||
if (temp_file_name)
|
||||
delete []temp_file_name;
|
||||
break;
|
||||
}
|
||||
// TODO(chunyang.dai@intel.com): code_move will be supported.
|
||||
|
Loading…
Reference in New Issue
Block a user