Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(498)

Unified Diff: runtime/vm/profiler.cc

Issue 227433004: Add runtime and native entry tags (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/profiler.cc
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 24d3da973f44574fe46971f0885cf3350147fb1e..b10396e9c0f9be3af6aa2661ab5c294f76576333 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -35,6 +35,8 @@ DEFINE_FLAG(int, profile_depth, 8,
"Maximum number stack frames walked. Minimum 1. Maximum 255.");
DEFINE_FLAG(bool, profile_verify_stack_walk, false,
"Verify instruction addresses while walking the stack.");
+DEFINE_FLAG(bool, profile_native_stack, true,
+ "Use native stack in profiler.");
bool Profiler::initialized_ = false;
SampleBuffer* Profiler::sample_buffer_ = NULL;
@@ -926,6 +928,11 @@ class CodeRegionTableBuilder : public SampleVisitor {
min_time_ = timestamp;
}
// Make sure VM tag is created.
+ if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
+ CreateTag(VMTag::kNativeTagId);
+ } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+ CreateTag(VMTag::kRuntimeTagId);
+ }
CreateTag(sample->vm_tag());
// Exclusive tick for bottom frame.
Tick(sample->At(0), true, timestamp);
@@ -1101,6 +1108,19 @@ class CodeRegionExclusiveTrieBuilder : public SampleVisitor {
root_->Tick();
CodeRegionTrieNode* current = root_;
if (use_tags()) {
+ if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
+ // Insert a dummy kNativeTagId node.
+ intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId);
+ current = current->GetChild(tag_index);
+ // Give the tag a tick.
+ current->Tick();
+ } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+ // Insert a dummy kRuntimeTagId node.
+ intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId);
+ current = current->GetChild(tag_index);
+ // Give the tag a tick.
+ current->Tick();
+ }
intptr_t tag_index = FindTagIndex(sample->vm_tag());
current = current->GetChild(tag_index);
// Give the tag a tick.
@@ -1406,6 +1426,45 @@ Sample* SampleBuffer::ReserveSample() {
return At(cursor);
}
+class ProfilerDartStackWalker : public ValueObject {
+ public:
+ explicit ProfilerDartStackWalker(Sample* sample)
+ : sample_(sample),
+ frame_iterator_() {
+ ASSERT(sample_ != NULL);
+ }
+
+ ProfilerDartStackWalker(Sample* sample, uword pc, uword fp, uword sp)
+ : sample_(sample),
+ frame_iterator_(fp, sp, pc) {
+ ASSERT(sample_ != NULL);
+ }
+
+ ProfilerDartStackWalker(Sample* sample, uword fp)
+ : sample_(sample),
+ frame_iterator_(fp) {
+ ASSERT(sample_ != NULL);
+ }
+
+ int walk() {
+ intptr_t frame_index = 0;
+ StackFrame* frame = frame_iterator_.NextFrame();
+ while (frame != NULL) {
+ sample_->SetAt(frame_index, frame->pc());
+ frame_index++;
+ if (frame_index >= FLAG_profile_depth) {
+ break;
+ }
+ frame = frame_iterator_.NextFrame();
+ }
+ return frame_index;
+ }
+
+ private:
+ Sample* sample_;
+ DartFrameIterator frame_iterator_;
+};
+
// Notes on stack frame walking:
//
// The sampling profiler will collect up to Sample::kNumStackFrames stack frames
@@ -1414,9 +1473,9 @@ Sample* SampleBuffer::ReserveSample() {
// recent GCC versions with optimizing enabled) the stack walking code may
// fail (sometimes leading to a crash).
//
-class ProfilerSampleStackWalker : public ValueObject {
+class ProfilerNativeStackWalker : public ValueObject {
public:
- ProfilerSampleStackWalker(Sample* sample,
+ ProfilerNativeStackWalker(Sample* sample,
uword stack_lower,
uword stack_upper,
uword pc,
@@ -1431,13 +1490,11 @@ class ProfilerSampleStackWalker : public ValueObject {
ASSERT(sample_ != NULL);
}
- int walk(Heap* heap, uword vm_tag) {
+ int walk(Heap* heap) {
const intptr_t kMaxStep = 0x1000; // 4K.
const bool kWalkStack = true; // Walk the stack.
// Always store the exclusive PC.
sample_->SetAt(0, original_pc_);
- // Always store the vm tag.
- sample_->set_vm_tag(vm_tag);
if (!kWalkStack) {
// Not walking the stack, only took exclusive sample.
return 1;
@@ -1534,7 +1591,15 @@ void Profiler::RecordSampleInterruptCallback(
const InterruptedThreadState& state,
void* data) {
Isolate* isolate = reinterpret_cast<Isolate*>(data);
- if (isolate == NULL) {
+ if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) {
+ return;
+ }
+ if (isolate == Dart::vm_isolate()) {
+ // Never sample the vm_isolate.
+ return;
+ }
siva 2014/04/08 16:27:54 Does it make sense to start the profiler before th
Cutch 2014/04/09 17:40:59 Isolate::SetCurrent expects the profiler to have b
siva 2014/04/09 23:28:11 I agree we don't want to make Isolate::SetCurrent
Cutch 2014/04/10 15:30:27 Done.
+ if (!FLAG_profile_native_stack && (isolate->stub_code() == NULL)) {
+ // ProfilerDartStackWalker requires stub code setup to be completed.
return;
}
siva 2014/04/08 16:27:54 Instead of checking like this wouldn't it be more
Cutch 2014/04/09 17:40:59 See above.
VMTagCounters* counters = isolate->vm_tag_counters();
@@ -1550,16 +1615,28 @@ void Profiler::RecordSampleInterruptCallback(
}
Sample* sample = sample_buffer->ReserveSample();
sample->Init(isolate, OS::GetCurrentTimeMicros(), state.tid);
- uword stack_lower = 0;
- uword stack_upper = 0;
- isolate->GetStackBounds(&stack_lower, &stack_upper);
- if ((stack_lower == 0) || (stack_upper == 0)) {
- stack_lower = 0;
- stack_upper = 0;
- }
- ProfilerSampleStackWalker stackWalker(sample, stack_lower, stack_upper,
- state.pc, state.fp, state.sp);
- stackWalker.walk(isolate->heap(), isolate->vm_tag());
+ sample->set_vm_tag(isolate->vm_tag());
+ if (FLAG_profile_native_stack) {
+ // Collect native and Dart frames.
+ uword stack_lower = 0;
+ uword stack_upper = 0;
+ isolate->GetStackBounds(&stack_lower, &stack_upper);
+ if ((stack_lower == 0) || (stack_upper == 0)) {
+ stack_lower = 0;
+ stack_upper = 0;
+ }
+ ProfilerNativeStackWalker stackWalker(sample, stack_lower, stack_upper,
+ state.pc, state.fp, state.sp);
+ stackWalker.walk(isolate->heap());
+ } else {
+ if (isolate->top_exit_frame_info() != 0) {
+ ProfilerDartStackWalker stackWalker(sample);
+ stackWalker.walk();
+ } else {
+ // TODO(johnmccutchan): StackFrameIterator that is resilient to native
+ // frames.
siva 2014/04/08 16:27:54 what does this TODO mean (for pure Dart frame walk
Cutch 2014/04/09 17:40:59 Slightly misworded but I want to support only coll
+ }
+ }
}
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698