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}
This commit is contained in:
jarin 2016-03-29 22:13:50 -07:00 committed by Commit bot
parent 48561ef6ad
commit cfd3cd6b00
2 changed files with 38 additions and 11 deletions

View File

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

View File

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