Index: src/perf-jit.cc |
diff --git a/src/perf-jit.cc b/src/perf-jit.cc |
index 6f3551468abb48088e752014512889845533ab41..b72b21c9e39f95d6d064f8bafd5049c7cb3dc24d 100644 |
--- a/src/perf-jit.cc |
+++ b/src/perf-jit.cc |
@@ -29,6 +29,7 @@ |
#include "src/assembler.h" |
#include "src/objects-inl.h" |
+#include "src/unwinding-info.h" |
#if V8_OS_LINUX |
#include <fcntl.h> |
@@ -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) LogWriteUnwindingInfo(code); |
+ |
static const char string_terminator[] = "\0"; |
PerfJitCodeLoad code_load; |
@@ -303,6 +320,48 @@ 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; |
+ |
+ int unwinding_info_size; |
rmcilroy
2016/06/21 13:47:44
nit - just use the field rather than having an ext
Stefano Sanfilippo
2016/06/23 15:23:44
Done.
|
+ if (code->has_unwinding_info()) { |
+ unwinding_info_size = code->unwinding_info_size(); |
+ unwinding_info_header.mapped_size_ = unwinding_info_size; |
+ } else { |
+ unwinding_info_size = EhFrameHdr::kRecordSize; |
+ unwinding_info_header.mapped_size_ = 0; |
+ } |
+ unwinding_info_header.unwinding_size_ = unwinding_info_size; |
+ |
+ int content_size = sizeof(unwinding_info_header) + unwinding_info_size; |
+ int padding_size = ((content_size + 7) & (~7)) - content_size; |
rmcilroy
2016/06/21 13:47:44
Don't use literals for '7'. Can you use RoundUp he
Stefano Sanfilippo
2016/06/23 15:23:44
Done.
|
+ 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()) { |
+ PatchProcedureBoundariesInEhFrame(code); |
rmcilroy
2016/06/21 13:47:44
You don't have any code which actually writes to t
Stefano Sanfilippo
2016/06/23 15:23:44
Agreed. Done.
|
+ |
+ // 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"; |
+ LogWriteBytes(padding_bytes, padding_size); |
+} |
+ |
void PerfJitLogger::CodeMoveEvent(AbstractCode* from, Address to) { |
// Code relocation not supported. |
UNREACHABLE(); |