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:
Zhou, Zhiguo 2019-10-15 22:47:45 +08:00 committed by Commit Bot
parent 282766c26d
commit ec5807099f
5 changed files with 95 additions and 24 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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.