Commit d0cd940f authored by Danylo Boiko's avatar Danylo Boiko Committed by V8 LUCI CQ

[turbofan] Print bytecode sources in --trace-turbo output

Bug: v8:7327
Change-Id: Ia0b768fe6a08c6e628fb91ac489556ddedf120ad
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3805662Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Commit-Queue: Danylo Boiko <danielboyko02@gmail.com>
Cr-Commit-Position: refs/heads/main@{#82496}
parent e8b62d50
...@@ -86,6 +86,17 @@ class JSONEscaped { ...@@ -86,6 +86,17 @@ class JSONEscaped {
const std::string str_; const std::string str_;
}; };
void JsonPrintBytecodeSource(std::ostream& os, int source_id,
std::unique_ptr<char[]> function_name,
Handle<BytecodeArray> bytecode_array) {
os << "\"" << source_id << "\" : {";
os << "\"sourceId\": " << source_id;
os << ", \"functionName\": \"" << function_name.get() << "\"";
os << ", \"bytecodeSource\": ";
bytecode_array->PrintJson(os);
os << "}";
}
void JsonPrintFunctionSource(std::ostream& os, int source_id, void JsonPrintFunctionSource(std::ostream& os, int source_id,
std::unique_ptr<char[]> function_name, std::unique_ptr<char[]> function_name,
Handle<Script> script, Isolate* isolate, Handle<Script> script, Isolate* isolate,
...@@ -158,6 +169,27 @@ void JsonPrintInlinedFunctionInfo( ...@@ -158,6 +169,27 @@ void JsonPrintInlinedFunctionInfo(
} // namespace } // namespace
void JsonPrintAllBytecodeSources(std::ostream& os,
OptimizedCompilationInfo* info) {
os << "\"bytecodeSources\" : {";
JsonPrintBytecodeSource(os, -1, info->shared_info()->DebugNameCStr(),
info->bytecode_array());
const auto& inlined = info->inlined_functions();
SourceIdAssigner id_assigner(info->inlined_functions().size());
for (unsigned id = 0; id < inlined.size(); id++) {
os << ", ";
Handle<SharedFunctionInfo> shared_info = inlined[id].shared_info;
const int source_id = id_assigner.GetIdFor(shared_info);
JsonPrintBytecodeSource(os, source_id, shared_info->DebugNameCStr(),
inlined[id].bytecode_array);
}
os << "}";
}
void JsonPrintAllSourceWithPositions(std::ostream& os, void JsonPrintAllSourceWithPositions(std::ostream& os,
OptimizedCompilationInfo* info, OptimizedCompilationInfo* info,
Isolate* isolate) { Isolate* isolate) {
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "src/objects/code.h"
#include "src/base/optional.h" #include "src/base/optional.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
...@@ -86,6 +87,13 @@ class V8_EXPORT_PRIVATE SourceIdAssigner { ...@@ -86,6 +87,13 @@ class V8_EXPORT_PRIVATE SourceIdAssigner {
std::vector<int> source_ids_; std::vector<int> source_ids_;
}; };
void JsonPrintAllBytecodeSources(std::ostream& os,
OptimizedCompilationInfo* info);
void JsonPrintBytecodeSource(std::ostream& os, int source_id,
std::unique_ptr<char[]> function_name,
Handle<BytecodeArray> bytecode_array);
void JsonPrintAllSourceWithPositions(std::ostream& os, void JsonPrintAllSourceWithPositions(std::ostream& os,
OptimizedCompilationInfo* info, OptimizedCompilationInfo* info,
Isolate* isolate); Isolate* isolate);
......
...@@ -3858,6 +3858,8 @@ MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) { ...@@ -3858,6 +3858,8 @@ MaybeHandle<Code> PipelineImpl::FinalizeCode(bool retire_broker) {
json_of << "\"nodePositions\":"; json_of << "\"nodePositions\":";
json_of << data->source_position_output() << ",\n"; json_of << data->source_position_output() << ",\n";
JsonPrintAllSourceWithPositions(json_of, data->info(), isolate()); JsonPrintAllSourceWithPositions(json_of, data->info(), isolate());
json_of << ",\n";
JsonPrintAllBytecodeSources(json_of, data->info());
json_of << "\n}"; json_of << "\n}";
} }
if (info()->trace_turbo_json() || info()->trace_turbo_graph()) { if (info()->trace_turbo_json() || info()->trace_turbo_graph()) {
......
...@@ -93,7 +93,8 @@ const char* NameForNativeContextIndex(uint32_t idx) { ...@@ -93,7 +93,8 @@ const char* NameForNativeContextIndex(uint32_t idx) {
// static // static
std::ostream& BytecodeDecoder::Decode(std::ostream& os, std::ostream& BytecodeDecoder::Decode(std::ostream& os,
const uint8_t* bytecode_start) { const uint8_t* bytecode_start,
bool with_hex) {
Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]);
int prefix_offset = 0; int prefix_offset = 0;
OperandScale operand_scale = OperandScale::kSingle; OperandScale operand_scale = OperandScale::kSingle;
...@@ -104,28 +105,31 @@ std::ostream& BytecodeDecoder::Decode(std::ostream& os, ...@@ -104,28 +105,31 @@ std::ostream& BytecodeDecoder::Decode(std::ostream& os,
} }
// Prepare to print bytecode and operands as hex digits. // Prepare to print bytecode and operands as hex digits.
std::ios saved_format(nullptr); if (with_hex) {
saved_format.copyfmt(saved_format); std::ios saved_format(nullptr);
os.fill('0'); saved_format.copyfmt(saved_format);
os.flags(std::ios::hex); os.fill('0');
os.flags(std::ios::hex);
int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
for (int i = 0; i < prefix_offset + bytecode_size; i++) { int bytecode_size = Bytecodes::Size(bytecode, operand_scale);
os << std::setw(2) << static_cast<uint32_t>(bytecode_start[i]) << ' '; for (int i = 0; i < prefix_offset + bytecode_size; i++) {
} os << std::setw(2) << static_cast<uint32_t>(bytecode_start[i]) << ' ';
os.copyfmt(saved_format); }
os.copyfmt(saved_format);
const int kBytecodeColumnSize = 6; const int kBytecodeColumnSize = 6;
for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) { for (int i = prefix_offset + bytecode_size; i < kBytecodeColumnSize; i++) {
os << " "; os << " ";
}
} }
os << Bytecodes::ToString(bytecode, operand_scale) << " "; os << Bytecodes::ToString(bytecode, operand_scale);
// Operands for the debug break are from the original instruction. // Operands for the debug break are from the original instruction.
if (Bytecodes::IsDebugBreak(bytecode)) return os; if (Bytecodes::IsDebugBreak(bytecode)) return os;
int number_of_operands = Bytecodes::NumberOfOperands(bytecode); int number_of_operands = Bytecodes::NumberOfOperands(bytecode);
if (number_of_operands > 0) os << " ";
for (int i = 0; i < number_of_operands; i++) { for (int i = 0; i < number_of_operands; i++) {
OperandType op_type = Bytecodes::GetOperandType(bytecode, i); OperandType op_type = Bytecodes::GetOperandType(bytecode, i);
int operand_offset = int operand_offset =
......
...@@ -37,7 +37,8 @@ class V8_EXPORT_PRIVATE BytecodeDecoder final { ...@@ -37,7 +37,8 @@ class V8_EXPORT_PRIVATE BytecodeDecoder final {
OperandScale operand_scale); OperandScale operand_scale);
// Decode a single bytecode and operands to |os|. // Decode a single bytecode and operands to |os|.
static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start); static std::ostream& Decode(std::ostream& os, const uint8_t* bytecode_start,
bool with_hex = true);
}; };
} // namespace interpreter } // namespace interpreter
......
...@@ -685,6 +685,64 @@ void CodeDataContainer::Disassemble(const char* name, std::ostream& os, ...@@ -685,6 +685,64 @@ void CodeDataContainer::Disassemble(const char* name, std::ostream& os,
#endif // ENABLE_DISASSEMBLER #endif // ENABLE_DISASSEMBLER
void BytecodeArray::PrintJson(std::ostream& os) {
DisallowGarbageCollection no_gc;
Address base_address = GetFirstBytecodeAddress();
BytecodeArray handle_storage = *this;
Handle<BytecodeArray> handle(reinterpret_cast<Address*>(&handle_storage));
interpreter::BytecodeArrayIterator iterator(handle);
bool first_data = true;
os << "{\"data\": [";
while (!iterator.done()) {
if (!first_data) os << ", ";
Address current_address = base_address + iterator.current_offset();
first_data = false;
os << "{\"offset\":" << iterator.current_offset() << ", \"disassembly\":\"";
interpreter::BytecodeDecoder::Decode(
os, reinterpret_cast<byte*>(current_address), false);
if (interpreter::Bytecodes::IsJump(iterator.current_bytecode())) {
os << " (" << iterator.GetJumpTargetOffset() << ")";
}
if (interpreter::Bytecodes::IsSwitch(iterator.current_bytecode())) {
os << " {";
bool first_entry = true;
for (interpreter::JumpTableTargetOffset entry :
iterator.GetJumpTableTargetOffsets()) {
if (!first_entry) os << ", ";
first_entry = false;
os << entry.target_offset;
}
os << "}";
}
os << "\"}";
iterator.Advance();
}
os << "]";
int constant_pool_lenght = constant_pool().length();
if (constant_pool_lenght > 0) {
os << ", \"constantPool\": [";
for (int i = 0; i < constant_pool_lenght; i++) {
HeapObject heapObject = HeapObject::cast(constant_pool().get(i));
if (i > 0) os << ", ";
os << "\"";
heapObject.HeapObjectShortPrint(os);
os << "\"";
}
os << "]";
}
os << "}";
}
void BytecodeArray::Disassemble(std::ostream& os) { void BytecodeArray::Disassemble(std::ostream& os) {
DisallowGarbageCollection no_gc; DisallowGarbageCollection no_gc;
......
...@@ -1264,6 +1264,7 @@ class BytecodeArray ...@@ -1264,6 +1264,7 @@ class BytecodeArray
DECL_PRINTER(BytecodeArray) DECL_PRINTER(BytecodeArray)
DECL_VERIFIER(BytecodeArray) DECL_VERIFIER(BytecodeArray)
V8_EXPORT_PRIVATE void PrintJson(std::ostream& os);
V8_EXPORT_PRIVATE void Disassemble(std::ostream& os); V8_EXPORT_PRIVATE void Disassemble(std::ostream& os);
void CopyBytecodesTo(BytecodeArray to); void CopyBytecodesTo(BytecodeArray to);
......
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