| Index: src/perf-jit.cc
|
| diff --git a/src/perf-jit.cc b/src/perf-jit.cc
|
| index 6f3551468abb48088e752014512889845533ab41..df251fde6e10685944c3a45e5113c56fc23cb40b 100644
|
| --- a/src/perf-jit.cc
|
| +++ b/src/perf-jit.cc
|
| @@ -28,6 +28,7 @@
|
| #include "src/perf-jit.h"
|
|
|
| #include "src/assembler.h"
|
| +#include "src/eh-frame.h"
|
| #include "src/objects-inl.h"
|
|
|
| #if V8_OS_LINUX
|
| @@ -56,7 +57,13 @@ struct PerfJitHeader {
|
| };
|
|
|
| struct PerfJitBase {
|
| - enum PerfJitEvent { kLoad = 0, kMove = 1, kDebugInfo = 2, kClose = 3 };
|
| + enum PerfJitEvent {
|
| + kLoad = 0,
|
| + kMove = 1,
|
| + kDebugInfo = 2,
|
| + kClose = 3,
|
| + kUnwindingInfo = 4
|
| + };
|
|
|
| uint32_t event_;
|
| uint32_t size_;
|
| @@ -85,6 +92,13 @@ struct PerfJitCodeDebugInfo : PerfJitBase {
|
| // Followed by entry_count_ instances of PerfJitDebugEntry.
|
| };
|
|
|
| +struct PerfJitCodeUnwindingInfo : PerfJitBase {
|
| + uint64_t unwinding_size_;
|
| + uint64_t eh_frame_hdr_size_;
|
| + uint64_t mapped_size_;
|
| + // Followed by size_ - sizeof(PerfJitCodeUnwindingInfo) bytes of data.
|
| +};
|
| +
|
| const char PerfJitLogger::kFilenameFormatString[] = "./jit-%d.dump";
|
|
|
| // Extra padding for the PID in the filename
|
| @@ -204,6 +218,9 @@ void PerfJitLogger::LogRecordedBuffer(AbstractCode* abstract_code,
|
| uint32_t code_size = code->is_crankshafted() ? code->safepoint_table_offset()
|
| : code->instruction_size();
|
|
|
| + // Unwinding info comes right after debug info.
|
| + if (FLAG_perf_prof_unwinding_info) LogWriteUnwindingInfo(code);
|
| +
|
| static const char string_terminator[] = "\0";
|
|
|
| PerfJitCodeLoad code_load;
|
| @@ -303,6 +320,46 @@ void PerfJitLogger::LogWriteDebugInfo(Code* code, SharedFunctionInfo* shared) {
|
| LogWriteBytes(padding_bytes, padding);
|
| }
|
|
|
| +void PerfJitLogger::LogWriteUnwindingInfo(Code* code) {
|
| + EhFrameHdr eh_frame_hdr(code);
|
| +
|
| + PerfJitCodeUnwindingInfo unwinding_info_header;
|
| + unwinding_info_header.event_ = PerfJitCodeLoad::kUnwindingInfo;
|
| + unwinding_info_header.time_stamp_ = GetTimestamp();
|
| + unwinding_info_header.eh_frame_hdr_size_ = EhFrameHdr::kRecordSize;
|
| +
|
| + if (code->has_unwinding_info()) {
|
| + unwinding_info_header.unwinding_size_ = code->unwinding_info_size();
|
| + unwinding_info_header.mapped_size_ = unwinding_info_header.unwinding_size_;
|
| + } else {
|
| + unwinding_info_header.unwinding_size_ = EhFrameHdr::kRecordSize;
|
| + unwinding_info_header.mapped_size_ = 0;
|
| + }
|
| +
|
| + int content_size = static_cast<int>(sizeof(unwinding_info_header) +
|
| + unwinding_info_header.unwinding_size_);
|
| + int padding_size = RoundUp(content_size, 8) - content_size;
|
| + unwinding_info_header.size_ = content_size + padding_size;
|
| +
|
| + LogWriteBytes(reinterpret_cast<const char*>(&unwinding_info_header),
|
| + sizeof(unwinding_info_header));
|
| +
|
| + if (code->has_unwinding_info()) {
|
| + // The last EhFrameHdr::kRecordSize bytes were a placeholder for the header.
|
| + // Discard them and write the actual eh_frame_hdr (below).
|
| + DCHECK_GE(code->unwinding_info_size(), EhFrameHdr::kRecordSize);
|
| + LogWriteBytes(reinterpret_cast<const char*>(code->unwinding_info_start()),
|
| + code->unwinding_info_size() - EhFrameHdr::kRecordSize);
|
| + }
|
| +
|
| + LogWriteBytes(reinterpret_cast<const char*>(&eh_frame_hdr),
|
| + EhFrameHdr::kRecordSize);
|
| +
|
| + char padding_bytes[] = "\0\0\0\0\0\0\0\0";
|
| + DCHECK_LT(padding_size, sizeof(padding_bytes));
|
| + LogWriteBytes(padding_bytes, padding_size);
|
| +}
|
| +
|
| void PerfJitLogger::CodeMoveEvent(AbstractCode* from, Address to) {
|
| // Code relocation not supported.
|
| UNREACHABLE();
|
|
|