Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Back porting Denis Pravdin changes to CPU Profiling code. #58

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 49 additions & 25 deletions src/cpu-profiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@ namespace internal {
static const int kProfilerStackSize = 64 * KB;


ProfilerEventsProcessor::ProfilerEventsProcessor(
ProfileGenerator* generator,
Sampler* sampler,
base::TimeDelta period)
ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator,
Sampler* sampler,
base::TimeDelta period)
: Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
generator_(generator),
sampler_(sampler),
running_(true),
running_(1),
period_(period),
last_code_event_id_(0), last_processed_code_event_id_(0) {
}
last_code_event_id_(0),
last_processed_code_event_id_(0) {}


void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) {
Expand All @@ -55,8 +54,7 @@ void ProfilerEventsProcessor::AddCurrentStack(Isolate* isolate) {


void ProfilerEventsProcessor::StopSynchronously() {
if (!running_) return;
running_ = false;
if (!base::NoBarrier_AtomicExchange(&running_, 0)) return;
Join();
}

Expand Down Expand Up @@ -107,7 +105,7 @@ ProfilerEventsProcessor::SampleProcessingResult


void ProfilerEventsProcessor::Run() {
while (running_) {
while (!!base::NoBarrier_Load(&running_)) {
base::ElapsedTimer timer;
timer.Start();
// Keep processing existing events until we need to do next sample.
Expand Down Expand Up @@ -201,7 +199,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
rec->entry = profiles_->NewCodeEntry(
tag,
profiles_->GetFunctionName(name),
CodeEntry::kEmptyNamePrefix,
CodeEntry::kEmptyResourceName,
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo,
NULL,
code->instruction_start());
rec->size = code->ExecutableSize();
rec->shared = NULL;
processor_->Enqueue(evt_rec);
Expand All @@ -215,7 +221,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
rec->entry = profiles_->NewCodeEntry(
tag,
profiles_->GetFunctionName(name),
CodeEntry::kEmptyNamePrefix,
CodeEntry::kEmptyResourceName,
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo,
NULL,
code->instruction_start());
rec->size = code->ExecutableSize();
rec->shared = NULL;
processor_->Enqueue(evt_rec);
Expand All @@ -231,7 +245,11 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
rec->start = code->address();
rec->entry = profiles_->NewCodeEntry(
tag, profiles_->GetFunctionName(shared->DebugName()),
CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name));
CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name),
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo,
NULL,
code->instruction_start());
if (info) {
rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
}
Expand All @@ -256,11 +274,9 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
rec->start = code->address();
Script* script = NULL;
Script* script = Script::cast(shared->script());
JITLineInfoTable* line_table = NULL;
if (shared->script()->IsScript()) {
DCHECK(Script::cast(shared->script()));
script = Script::cast(shared->script());
if (script) {
line_table = new JITLineInfoTable();
for (RelocIterator it(code); !it.done(); it.next()) {
RelocInfo::Mode mode = it.rinfo()->rmode();
Expand All @@ -277,17 +293,15 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
rec->entry = profiles_->NewCodeEntry(
tag, profiles_->GetFunctionName(shared->DebugName()),
CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line,
column, line_table);
column, line_table, code->instruction_start());
if (info) {
rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
}
if (script) {
rec->entry->set_script_id(script->id()->value());
}
rec->entry->set_bailout_reason(
GetBailoutReason(shared->DisableOptimizationReason()));
rec->entry->set_script_id(script->id()->value());
rec->size = code->ExecutableSize();
rec->shared = shared->address();
rec->entry->set_bailout_reason(
GetBailoutReason(shared->DisableOptimizationReason()));
processor_->Enqueue(evt_rec);
}

Expand All @@ -302,7 +316,12 @@ void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
rec->entry = profiles_->NewCodeEntry(
tag,
profiles_->GetName(args_count),
"args_count: ");
"args_count: ",
CodeEntry::kEmptyResourceName,
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo,
NULL,
code->instruction_start());
rec->size = code->ExecutableSize();
rec->shared = NULL;
processor_->Enqueue(evt_rec);
Expand Down Expand Up @@ -364,7 +383,12 @@ void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
rec->entry = profiles_->NewCodeEntry(
Logger::REG_EXP_TAG,
profiles_->GetName(source),
"RegExp: ");
"RegExp: ",
CodeEntry::kEmptyResourceName,
CpuProfileNode::kNoLineNumberInfo,
CpuProfileNode::kNoColumnNumberInfo,
NULL,
code->instruction_start());
rec->size = code->ExecutableSize();
processor_->Enqueue(evt_rec);
}
Expand Down
4 changes: 2 additions & 2 deletions src/cpu-profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class ProfilerEventsProcessor : public base::Thread {
// Thread control.
virtual void Run();
void StopSynchronously();
INLINE(bool running()) { return running_; }
INLINE(bool running()) { return !!base::NoBarrier_Load(&running_); }
void Enqueue(const CodeEventsContainer& event);

// Puts current stack into tick sample events buffer.
Expand Down Expand Up @@ -163,7 +163,7 @@ class ProfilerEventsProcessor : public base::Thread {

ProfileGenerator* generator_;
Sampler* sampler_;
bool running_;
base::Atomic32 running_;
// Sampling period in microseconds.
const base::TimeDelta period_;
UnboundQueue<CodeEventsContainer> events_buffer_;
Expand Down
6 changes: 4 additions & 2 deletions src/profile-generator-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
const char* resource_name,
int line_number,
int column_number,
JITLineInfoTable* line_info)
JITLineInfoTable* line_info,
Address instruction_start)
: tag_(tag),
builtin_id_(Builtins::builtin_count),
name_prefix_(name_prefix),
Expand All @@ -28,7 +29,8 @@ CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
script_id_(v8::UnboundScript::kNoScriptId),
no_frame_ranges_(NULL),
bailout_reason_(kEmptyBailoutReason),
line_info_(line_info) { }
line_info_(line_info),
instruction_start_(instruction_start) { }


bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) {
Expand Down
57 changes: 43 additions & 14 deletions src/profile-generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,31 @@ HashMap::Entry* StringsStorage::GetEntry(const char* str, int len) {
}


JITLineInfoTable::JITLineInfoTable() {}


JITLineInfoTable::~JITLineInfoTable() {}


void JITLineInfoTable::SetPosition(int pc_offset, int line) {
DCHECK(pc_offset >= 0);
DCHECK(line > 0); // The 1-based number of the source line.
if (GetSourceLineNumber(pc_offset) != line) {
pc_offset_map_.insert(std::make_pair(pc_offset, line));
}
}


int JITLineInfoTable::GetSourceLineNumber(int pc_offset) const {
PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset);
if (it == pc_offset_map_.end()) {
if (pc_offset_map_.empty()) return v8::CpuProfileNode::kNoLineNumberInfo;
return (--pc_offset_map_.end())->second;
}
return it->second;
}


const char* const CodeEntry::kEmptyNamePrefix = "";
const char* const CodeEntry::kEmptyResourceName = "";
const char* const CodeEntry::kEmptyBailoutReason = "";
Expand Down Expand Up @@ -183,7 +208,7 @@ void CodeEntry::SetBuiltinId(Builtins::Name id) {


int CodeEntry::GetSourceLine(int pc_offset) const {
if (line_info_ && !line_info_->Empty()) {
if (line_info_ && !line_info_->empty()) {
return line_info_->GetSourceLineNumber(pc_offset);
}
return v8::CpuProfileNode::kNoLineNumberInfo;
Expand Down Expand Up @@ -216,7 +241,7 @@ void ProfileNode::IncrementLineTicks(int src_line) {
// Increment a hit counter of a certain source line.
// Add a new source line if not found.
HashMap::Entry* e =
line_ticks_.Lookup(reinterpret_cast<void*>(src_line), src_line, true);
line_ticks_.Lookup(reinterpret_cast<void*>(src_line), src_line, true);
DCHECK(e);
e->value = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(e->value) + 1);
}
Expand All @@ -228,7 +253,7 @@ bool ProfileNode::GetLineTicks(v8::CpuProfileNode::LineTick* entries,

unsigned line_count = line_ticks_.occupancy();

if (line_count == 0) return false;
if (line_count == 0) return true;
if (length < line_count) return false;

v8::CpuProfileNode::LineTick* entry = entries;
Expand Down Expand Up @@ -591,14 +616,16 @@ CodeEntry* CpuProfilesCollection::NewCodeEntry(
const char* resource_name,
int line_number,
int column_number,
JITLineInfoTable* line_info) {
JITLineInfoTable* line_info,
Address instruction_start) {
CodeEntry* code_entry = new CodeEntry(tag,
name,
name_prefix,
resource_name,
line_number,
column_number,
line_info);
line_info,
instruction_start);
code_entries_.Add(code_entry);
return code_entry;
}
Expand Down Expand Up @@ -641,8 +668,9 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
// the same JS function. The line number information associated with
// the latest version of generated code is used to find a source line number
// for a JS function. Then, the detected source line is passed to
// ProfileNode to accumulate the samples.
// ProfileNode to increase the tick count for this source line.
int src_line = v8::CpuProfileNode::kNoLineNumberInfo;
bool src_line_not_found = true;

if (sample.pc != NULL) {
if (sample.has_external_callback && sample.state == EXTERNAL &&
Expand All @@ -660,9 +688,8 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
// frame. Check for this case and just skip such samples.
if (pc_entry) {
List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
Code* code = Code::cast(HeapObject::FromAddress(start));
int pc_offset = static_cast<int>(sample.pc - code->instruction_start());
src_line = pc_entry->GetSourceLine(pc_offset);
int pc_offset =
static_cast<int>(sample.pc - pc_entry->instruction_start());
if (ranges) {
for (int i = 0; i < ranges->length(); i++) {
OffsetRange& range = ranges->at(i);
Expand All @@ -671,6 +698,11 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
}
}
}
src_line = pc_entry->GetSourceLine(pc_offset);
if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) {
src_line = pc_entry->line_number();
}
src_line_not_found = false;
*entry++ = pc_entry;

if (pc_entry->builtin_id() == Builtins::kFunctionCall ||
Expand All @@ -687,8 +719,6 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
}
}

bool src_line_not_found = src_line == v8::CpuProfileNode::kNoLineNumberInfo;

for (const Address* stack_pos = sample.stack,
*stack_end = stack_pos + sample.frames_count;
stack_pos != stack_end;
Expand All @@ -697,11 +727,10 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
*entry = code_map_.FindEntry(*stack_pos, &start);

// Skip unresolved frames (e.g. internal frame) and get source line of
// the JS caller.
// the first JS caller.
if (src_line_not_found && *entry) {
Code* code = Code::cast(HeapObject::FromAddress(start));
int pc_offset =
static_cast<int>(*stack_pos - code->instruction_start());
static_cast<int>(*stack_pos - (*entry)->instruction_start());
src_line = (*entry)->GetSourceLine(pc_offset);
if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) {
src_line = (*entry)->line_number();
Expand Down
30 changes: 12 additions & 18 deletions src/profile-generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,13 @@ class StringsStorage {
// the source line.
class JITLineInfoTable : public Malloced {
public:
JITLineInfoTable() {}
~JITLineInfoTable() {}
JITLineInfoTable();
~JITLineInfoTable();

void SetPosition(int pc_offset, int line) {
DCHECK(pc_offset >= 0);
DCHECK(line > 0); // The 1-based number of the source line.
pc_offset_map_.insert(std::make_pair(pc_offset, line));
}
void SetPosition(int pc_offset, int line);
int GetSourceLineNumber(int pc_offset) const;

int GetSourceLineNumber(int pc_offset) const {
PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset);
if (it == pc_offset_map_.end()) {
return v8::CpuProfileNode::kNoLineNumberInfo;
}
return it->second;
}

bool Empty() const { return pc_offset_map_.empty(); }
bool empty() const { return pc_offset_map_.empty(); }

private:
// pc_offset -> source line
Expand All @@ -84,7 +73,8 @@ class CodeEntry {
const char* resource_name = CodeEntry::kEmptyResourceName,
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
JITLineInfoTable* line_info = NULL);
JITLineInfoTable* line_info = NULL,
Address instruction_start = NULL);
~CodeEntry();

bool is_js_function() const { return is_js_function_tag(tag_); }
Expand Down Expand Up @@ -118,6 +108,8 @@ class CodeEntry {

int GetSourceLine(int pc_offset) const;

Address instruction_start() const { return instruction_start_; }

static const char* const kEmptyNamePrefix;
static const char* const kEmptyResourceName;
static const char* const kEmptyBailoutReason;
Expand All @@ -135,6 +127,7 @@ class CodeEntry {
List<OffsetRange>* no_frame_ranges_;
const char* bailout_reason_;
JITLineInfoTable* line_info_;
Address instruction_start_;

DISALLOW_COPY_AND_ASSIGN(CodeEntry);
};
Expand Down Expand Up @@ -329,7 +322,8 @@ class CpuProfilesCollection {
const char* resource_name = CodeEntry::kEmptyResourceName,
int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
JITLineInfoTable* line_info = NULL);
JITLineInfoTable* line_info = NULL,
Address instruction_start = NULL);

// Called from profile generator thread.
void AddPathToCurrentProfiles(base::TimeTicks timestamp,
Expand Down
Loading