Commit ec580709 authored by Zhou, Zhiguo's avatar Zhou, Zhiguo Committed by Commit Bot

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/+/1782126Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Zhiguo Zhou <zhiguo.zhou@intel.com>
Cr-Commit-Position: refs/heads/master@{#64351}
parent 282766c2
...@@ -7447,6 +7447,20 @@ struct JitCodeEvent { ...@@ -7447,6 +7447,20 @@ struct JitCodeEvent {
PositionType position_type; 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 { union {
// Only valid for CODE_ADDED. // Only valid for CODE_ADDED.
struct name_t name; struct name_t name;
......
...@@ -2082,7 +2082,7 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) { ...@@ -2082,7 +2082,7 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
EscapableHandleScope handle_scope(isolate); EscapableHandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate, nullptr, global_template); Local<Context> context = Context::New(isolate, nullptr, global_template);
DCHECK(!context.IsEmpty()); 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); isolate->SetWasmLoadSourceMapCallback(ReadFile);
} }
InitializeModuleEmbedderData(context); InitializeModuleEmbedderData(context);
......
...@@ -1507,6 +1507,10 @@ DEFINE_STRING(redirect_code_traces_to, nullptr, ...@@ -1507,6 +1507,10 @@ DEFINE_STRING(redirect_code_traces_to, nullptr,
DEFINE_BOOL(print_opt_source, false, DEFINE_BOOL(print_opt_source, false,
"print source code of optimized and inlined functions") "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") DEFINE_BOOL(win64_unwinding_info, true, "Enable unwinding info for Windows/x64")
#ifdef V8_TARGET_ARCH_ARM #ifdef V8_TARGET_ARCH_ARM
......
...@@ -690,6 +690,42 @@ void JitLogger::LogRecordedBuffer(const wasm::WasmCode* code, const char* name, ...@@ -690,6 +690,42 @@ void JitLogger::LogRecordedBuffer(const wasm::WasmCode* code, const char* name,
event.name.str = name; event.name.str = name;
event.name.len = length; event.name.len = length;
event.isolate = reinterpret_cast<v8::Isolate*>(isolate_); 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); code_event_handler_(&event);
} }
......
...@@ -60,7 +60,10 @@ ...@@ -60,7 +60,10 @@
#include <string.h> #include <string.h>
#include <list> #include <list>
#include <memory>
#include <string>
#include <unordered_map> #include <unordered_map>
#include <vector>
#include "v8-vtune.h" #include "v8-vtune.h"
#include "vtune-jit.h" #include "vtune-jit.h"
...@@ -136,7 +139,7 @@ static JITCodeLineInfo* UntagLineInfo(void* ptr) { ...@@ -136,7 +139,7 @@ static JITCodeLineInfo* UntagLineInfo(void* ptr) {
// function name and some other info. It comes from all the // function name and some other info. It comes from all the
// Logger::CodeCreateEvent(...) function. This function get the // Logger::CodeCreateEvent(...) function. This function get the
// pure function name from the input parameter. // 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 index = 0;
int count = 0; int count = 0;
char* start_ptr = NULL; char* start_ptr = NULL;
...@@ -144,7 +147,7 @@ static char* GetFunctionNameFromMixedName(const char* str, int length) { ...@@ -144,7 +147,7 @@ static char* GetFunctionNameFromMixedName(const char* str, int length) {
while (str[index++] != ':' && (index < length)) {} while (str[index++] != ':' && (index < length)) {}
if (str[index] == '*' || str[index] == '~' ) index++; if (str[index] == '*' || str[index] == '~' ) index++;
if (index >= length) return NULL; if (index >= length) return std::string();
start_ptr = const_cast<char*>(str + index); start_ptr = const_cast<char*>(str + index);
...@@ -152,11 +155,7 @@ static char* GetFunctionNameFromMixedName(const char* str, int length) { ...@@ -152,11 +155,7 @@ static char* GetFunctionNameFromMixedName(const char* str, int length) {
count++; count++;
} }
char* result = new char[count + 1]; return std::string(start_ptr, count);
memcpy(result, start_ptr, count);
result[count] = '\0';
return result;
} }
// The JitCodeEventHandler for Vtune. // The JitCodeEventHandler for Vtune.
...@@ -164,16 +163,16 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) { ...@@ -164,16 +163,16 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
if (VTUNERUNNING && event != NULL) { if (VTUNERUNNING && event != NULL) {
switch (event->type) { switch (event->type) {
case v8::JitCodeEvent::CODE_ADDED: { case v8::JitCodeEvent::CODE_ADDED: {
char* temp_file_name = NULL; std::unique_ptr<char[]> temp_file_name;
char* temp_method_name = std::string temp_method_name = GetFunctionNameFromMixedName(
GetFunctionNameFromMixedName(event->name.str, event->name.str, static_cast<int>(event->name.len));
static_cast<int>(event->name.len)); std::vector<LineNumberInfo> jmethod_line_number_table;
iJIT_Method_Load jmethod; iJIT_Method_Load jmethod;
memset(&jmethod, 0, sizeof jmethod); memset(&jmethod, 0, sizeof jmethod);
jmethod.method_id = iJIT_GetNewMethodID(); jmethod.method_id = iJIT_GetNewMethodID();
jmethod.method_load_address = event->code_start; jmethod.method_load_address = event->code_start;
jmethod.method_size = static_cast<unsigned int>(event->code_len); 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; Local<UnboundScript> script = event->script;
...@@ -182,10 +181,10 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) { ...@@ -182,10 +181,10 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
if ((*script->GetScriptName())->IsString()) { if ((*script->GetScriptName())->IsString()) {
Local<String> script_name = Local<String> script_name =
Local<String>::Cast(script->GetScriptName()); Local<String>::Cast(script->GetScriptName());
temp_file_name = temp_file_name.reset(
new char[script_name->Utf8Length(event->isolate) + 1]; new char[script_name->Utf8Length(event->isolate) + 1]);
script_name->WriteUtf8(event->isolate, temp_file_name); script_name->WriteUtf8(event->isolate, temp_file_name.get());
jmethod.source_file_name = temp_file_name; jmethod.source_file_name = temp_file_name.get();
} }
JitInfoMap::iterator entry = JitInfoMap::iterator entry =
...@@ -197,9 +196,8 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) { ...@@ -197,9 +196,8 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
line_info->GetLineNumInfo(); line_info->GetLineNumInfo();
jmethod.line_number_size = (unsigned int)vtunelineinfo->size(); jmethod.line_number_size = (unsigned int)vtunelineinfo->size();
jmethod.line_number_table = jmethod_line_number_table.resize(jmethod.line_number_size);
reinterpret_cast<LineNumberInfo*>( jmethod.line_number_table = jmethod_line_number_table.data();
malloc(sizeof(LineNumberInfo)*jmethod.line_number_size));
std::list<JITCodeLineInfo::LineNumInfo>::iterator Iter; std::list<JITCodeLineInfo::LineNumInfo>::iterator Iter;
int index = 0; int index = 0;
...@@ -213,14 +211,33 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) { ...@@ -213,14 +211,33 @@ void VTUNEJITInterface::event_handler(const v8::JitCodeEvent* event) {
} }
GetEntries()->erase(event->code_start); 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, iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
reinterpret_cast<void*>(&jmethod)); reinterpret_cast<void*>(&jmethod));
if (temp_method_name)
delete []temp_method_name;
if (temp_file_name)
delete []temp_file_name;
break; break;
} }
// TODO(chunyang.dai@intel.com): code_move will be supported. // TODO(chunyang.dai@intel.com): code_move will be supported.
......
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