Commit cfd3cd6b authored by jarin's avatar jarin Committed by Commit bot

Ensure synchronized access to the perf dump file.

This CL introduces static variables and global lock for writing to the
dump files, so that multiple web workers do not run into trouble.

Review URL: https://codereview.chromium.org/1839133002

Cr-Commit-Position: refs/heads/master@{#35123}
parent 48561ef6
......@@ -90,6 +90,13 @@ const char PerfJitLogger::kFilenameFormatString[] = "./jit-%d.dump";
// Extra padding for the PID in the filename
const int PerfJitLogger::kFilenameBufferPadding = 16;
base::LazyRecursiveMutex PerfJitLogger::file_mutex_;
// The following static variables are protected by PerfJitLogger::file_mutex_.
uint64_t PerfJitLogger::reference_count_ = 0;
void* PerfJitLogger::marker_address_ = nullptr;
uint64_t PerfJitLogger::code_index_ = 0;
FILE* PerfJitLogger::perf_output_handle_ = nullptr;
void PerfJitLogger::OpenJitDumpFile() {
// Open the perf JIT dump file.
perf_output_handle_ = nullptr;
......@@ -137,14 +144,27 @@ void PerfJitLogger::CloseMarkerFile(void* marker_address) {
munmap(marker_address, page_size);
}
PerfJitLogger::PerfJitLogger()
: perf_output_handle_(nullptr), code_index_(0), marker_address_(nullptr) {
OpenJitDumpFile();
if (perf_output_handle_ == nullptr) return;
LogWriteHeader();
PerfJitLogger::PerfJitLogger() {
base::LockGuard<base::RecursiveMutex> guard_file(file_mutex_.Pointer());
reference_count_++;
// If this is the first logger, open the file and write the header.
if (reference_count_ == 1) {
OpenJitDumpFile();
if (perf_output_handle_ == nullptr) return;
LogWriteHeader();
}
}
PerfJitLogger::~PerfJitLogger() { CloseJitDumpFile(); }
PerfJitLogger::~PerfJitLogger() {
base::LockGuard<base::RecursiveMutex> guard_file(file_mutex_.Pointer());
reference_count_--;
// If this was the last logger, close the file.
if (reference_count_ == 0) {
CloseJitDumpFile();
}
}
uint64_t PerfJitLogger::GetTimestamp() {
struct timespec ts;
......@@ -158,7 +178,6 @@ uint64_t PerfJitLogger::GetTimestamp() {
void PerfJitLogger::LogRecordedBuffer(AbstractCode* abstract_code,
SharedFunctionInfo* shared,
const char* name, int length) {
if (perf_output_handle_ == nullptr) return;
if (FLAG_perf_basic_prof_only_functions &&
(abstract_code->kind() != AbstractCode::FUNCTION &&
abstract_code->kind() != AbstractCode::INTERPRETED_FUNCTION &&
......@@ -166,13 +185,17 @@ void PerfJitLogger::LogRecordedBuffer(AbstractCode* abstract_code,
return;
}
base::LockGuard<base::RecursiveMutex> guard_file(file_mutex_.Pointer());
if (perf_output_handle_ == nullptr) return;
// We only support non-interpreted functions.
if (!abstract_code->IsCode()) return;
Code* code = abstract_code->GetCode();
DCHECK(code->instruction_start() == code->address() + Code::kHeaderSize);
// Debug info has to be emitted first.
if (FLAG_perf_prof_debug_info) {
if (FLAG_perf_prof_debug_info && shared != nullptr) {
LogWriteDebugInfo(code, shared);
}
......
......@@ -87,9 +87,13 @@ class PerfJitLogger : public CodeEventLogger {
#endif
}
FILE* perf_output_handle_;
uint64_t code_index_;
void* marker_address_;
// Per-process singleton file. We assume that there is one main isolate;
// to determine when it goes away, we keep reference count.
static base::LazyRecursiveMutex file_mutex_;
static FILE* perf_output_handle_;
static uint64_t reference_count_;
static void* marker_address_;
static uint64_t code_index_;
};
#else
......
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