Index: runtime/vm/profiler.cc |
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc |
index 1515eed45563e78c82a360e9283be5a103d0b259..3ab3207d4db2c0f4c65fbf5b9c7c9f04a636ae2a 100644 |
--- a/runtime/vm/profiler.cc |
+++ b/runtime/vm/profiler.cc |
@@ -9,10 +9,12 @@ |
#include "vm/allocation.h" |
#include "vm/atomic.h" |
#include "vm/code_patcher.h" |
+#include "vm/debugger.h" |
#include "vm/instructions.h" |
#include "vm/isolate.h" |
#include "vm/json_stream.h" |
#include "vm/lockers.h" |
+#include "vm/message_handler.h" |
#include "vm/native_symbol.h" |
#include "vm/object.h" |
#include "vm/os.h" |
@@ -104,54 +106,6 @@ void Profiler::SetSamplePeriod(intptr_t period) { |
} |
-void Profiler::InitProfilingForIsolate(Isolate* isolate, bool shared_buffer) { |
- if (!FLAG_profile) { |
- return; |
- } |
- ASSERT(isolate == Isolate::Current()); |
- ASSERT(isolate != NULL); |
- ASSERT(sample_buffer_ != NULL); |
- { |
- MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); |
- SampleBuffer* sample_buffer = sample_buffer_; |
- if (!shared_buffer) { |
- sample_buffer = new SampleBuffer(); |
- } |
- IsolateProfilerData* profiler_data = |
- new IsolateProfilerData(sample_buffer, !shared_buffer); |
- ASSERT(profiler_data != NULL); |
- isolate->set_profiler_data(profiler_data); |
- if (FLAG_trace_profiled_isolates) { |
- OS::Print("Profiler Setup %p %s\n", isolate, isolate->name()); |
- } |
- } |
- BeginExecution(isolate); |
-} |
- |
- |
-void Profiler::ShutdownProfilingForIsolate(Isolate* isolate) { |
- ASSERT(isolate != NULL); |
- if (!FLAG_profile) { |
- return; |
- } |
- // We do not have a current isolate. |
- ASSERT(Isolate::Current() == NULL); |
- { |
- MutexLocker profiler_data_lock(isolate->profiler_data_mutex()); |
- IsolateProfilerData* profiler_data = isolate->profiler_data(); |
- if (profiler_data == NULL) { |
- // Already freed. |
- return; |
- } |
- isolate->set_profiler_data(NULL); |
- delete profiler_data; |
- if (FLAG_trace_profiled_isolates) { |
- OS::Print("Profiler Shutdown %p %s\n", isolate, isolate->name()); |
- } |
- } |
-} |
- |
- |
void Profiler::BeginExecution(Isolate* isolate) { |
Ivan Posva
2015/10/28 06:45:16
Is this API even needed given that we are profilin
|
if (isolate == NULL) { |
return; |
@@ -160,13 +114,8 @@ void Profiler::BeginExecution(Isolate* isolate) { |
return; |
} |
ASSERT(initialized_); |
- IsolateProfilerData* profiler_data = isolate->profiler_data(); |
- if (profiler_data == NULL) { |
- return; |
- } |
Thread* thread = Thread::Current(); |
thread->SetThreadInterrupter(RecordSampleInterruptCallback, thread); |
- ThreadInterrupter::WakeUp(); |
} |
@@ -183,41 +132,6 @@ void Profiler::EndExecution(Isolate* isolate) { |
} |
-IsolateProfilerData::IsolateProfilerData(SampleBuffer* sample_buffer, |
- bool own_sample_buffer) { |
- ASSERT(sample_buffer != NULL); |
- sample_buffer_ = sample_buffer; |
- own_sample_buffer_ = own_sample_buffer; |
- block_count_ = 0; |
-} |
- |
- |
-IsolateProfilerData::~IsolateProfilerData() { |
- if (own_sample_buffer_) { |
- delete sample_buffer_; |
- sample_buffer_ = NULL; |
- own_sample_buffer_ = false; |
- } |
-} |
- |
- |
-void IsolateProfilerData::Block() { |
- block_count_++; |
-} |
- |
- |
-void IsolateProfilerData::Unblock() { |
- block_count_--; |
- if (block_count_ < 0) { |
- FATAL("Too many calls to Dart_IsolateUnblocked."); |
- } |
- if (!blocked()) { |
- // We just unblocked this isolate, wake up the thread interrupter. |
- ThreadInterrupter::WakeUp(); |
- } |
-} |
- |
- |
intptr_t Sample::pcs_length_ = 0; |
intptr_t Sample::instance_size_ = 0; |
@@ -868,8 +782,8 @@ static bool ExitedDart(Thread* thread) { |
// Get |isolate|'s stack boundary and verify that |sp| and |fp| are within |
// it. Return |false| if anything looks suspicious. |
static bool GetAndValidateIsolateStackBounds(Thread* thread, |
- uintptr_t sp, |
uintptr_t fp, |
+ uintptr_t sp, |
uword* stack_lower, |
uword* stack_upper) { |
ASSERT(thread != NULL); |
@@ -921,8 +835,8 @@ static bool GetAndValidateIsolateStackBounds(Thread* thread, |
} |
-// Some simple sanity checking of |pc|, |sp|, and |fp|. |
-static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) { |
+// Some simple sanity checking of |pc|, |fp|, and |sp|. |
+static bool InitialRegisterCheck(uintptr_t pc, uintptr_t fp, uintptr_t sp) { |
if ((sp == 0) || (fp == 0) || (pc == 0)) { |
// None of these registers should be zero. |
return false; |
@@ -938,18 +852,6 @@ static bool InitialRegisterCheck(uintptr_t pc, uintptr_t sp, uintptr_t fp) { |
} |
-// Return |isolate|'s sample buffer. |
-static SampleBuffer* GetSampleBuffer(Isolate* isolate) { |
- IsolateProfilerData* profiler_data = isolate->profiler_data(); |
- if (profiler_data == NULL) { |
- // Profiler not initialized. |
- return NULL; |
- } |
- SampleBuffer* sample_buffer = profiler_data->sample_buffer(); |
- return sample_buffer; |
-} |
- |
- |
static Sample* SetupSample(Thread* thread, |
SampleBuffer* sample_buffer, |
ThreadId tid) { |
@@ -979,8 +881,7 @@ static bool CheckIsolate(Isolate* isolate) { |
// No isolate. |
return false; |
} |
- ASSERT(isolate != Dart::vm_isolate()); |
- return true; |
+ return isolate != Dart::vm_isolate(); |
} |
@@ -996,7 +897,7 @@ static uintptr_t __attribute__((noinline)) GetProgramCounter() { |
} |
#endif |
-void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { |
+void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
ASSERT(thread != NULL); |
Isolate* isolate = thread->isolate(); |
if (!CheckIsolate(isolate)) { |
@@ -1005,7 +906,7 @@ void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { |
const bool exited_dart_code = ExitedDart(thread); |
- SampleBuffer* sample_buffer = GetSampleBuffer(isolate); |
+ SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
if (sample_buffer == NULL) { |
// Profiler not initialized. |
return; |
@@ -1021,13 +922,13 @@ void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { |
uword stack_lower = 0; |
uword stack_upper = 0; |
- if (!InitialRegisterCheck(pc, sp, fp)) { |
+ if (!InitialRegisterCheck(pc, fp, sp)) { |
return; |
} |
if (!GetAndValidateIsolateStackBounds(thread, |
- sp, |
fp, |
+ sp, |
&stack_lower, |
&stack_upper)) { |
// Could not get stack boundary. |
@@ -1069,64 +970,45 @@ void Profiler::RecordAllocation(Thread* thread, intptr_t cid) { |
} |
-void Profiler::RecordSampleInterruptCallback( |
- const InterruptedThreadState& state, |
- void* data) { |
- Thread* thread = reinterpret_cast<Thread*>(data); |
+void Profiler::SampleMutator(Thread* thread, |
Ivan Posva
2015/10/28 06:45:16
Not only mutator, right?
|
+ uintptr_t pc, |
+ uintptr_t fp, |
+ uintptr_t sp) { |
+ ASSERT(thread != NULL); |
Isolate* isolate = thread->isolate(); |
- if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
- // No isolate. |
+ if (!CheckIsolate(isolate)) { |
return; |
} |
- ASSERT(isolate != Dart::vm_isolate()); |
- SampleBuffer* sample_buffer = GetSampleBuffer(isolate); |
- if (sample_buffer == NULL) { |
- // Profiler not initialized. |
+ if (!isolate->IsMutatorThread(thread)) { |
+ // Not the mutator thread. |
return; |
} |
- const bool exited_dart_code = ExitedDart(thread); |
- const bool in_dart_code = ExecutingDart(thread); |
- |
- uintptr_t sp = 0; |
- uintptr_t fp = state.fp; |
- uintptr_t pc = state.pc; |
-#if defined(USING_SIMULATOR) |
- Simulator* simulator = NULL; |
-#endif |
- |
- if (in_dart_code) { |
- // If we're in Dart code, use the Dart stack pointer. |
-#if defined(USING_SIMULATOR) |
- simulator = isolate->simulator(); |
- sp = simulator->get_register(SPREG); |
- fp = simulator->get_register(FPREG); |
- pc = simulator->get_pc(); |
-#else |
- sp = state.dsp; |
-#endif |
- } else { |
- // If we're in runtime code, use the C stack pointer. |
- sp = state.csp; |
+ if (isolate->HasDebugger()) { |
+ Debugger* debugger = isolate->debugger(); |
+ if (debugger->IsPaused()) { |
+ // Mutator is paused at breakpoint. |
+ return; |
+ } |
} |
- if (!InitialRegisterCheck(pc, sp, fp)) { |
+ MessageHandler* msg_handler = isolate->message_handler(); |
+ if ((msg_handler != NULL) && |
+ (msg_handler->paused_on_start() || |
+ msg_handler->paused_on_exit())) { |
+ // Isolate is paused at start / exit. |
return; |
} |
- if (StubCode::InJumpToExceptionHandlerStub(pc)) { |
- // The JumpToExceptionHandler stub manually adjusts the stack pointer, |
- // frame pointer, and some isolate state before jumping to a catch entry. |
- // It is not safe to walk the stack when executing this stub. |
- return; |
- } |
+ const bool exited_dart_code = ExitedDart(thread); |
+ const bool in_dart_code = ExecutingDart(thread); |
uword stack_lower = 0; |
uword stack_upper = 0; |
if (!GetAndValidateIsolateStackBounds(thread, |
- sp, |
fp, |
+ sp, |
&stack_lower, |
&stack_upper)) { |
// Could not get stack boundary. |
@@ -1135,6 +1017,11 @@ void Profiler::RecordSampleInterruptCallback( |
// At this point we have a valid stack boundary for this isolate and |
// know that our initial stack and frame pointers are within the boundary. |
+ SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
+ if (sample_buffer == NULL) { |
+ // Profiler not initialized. |
+ return; |
+ } |
// Setup sample. |
Sample* sample = SetupSample(thread, |
@@ -1181,6 +1068,49 @@ void Profiler::RecordSampleInterruptCallback( |
} |
+void Profiler::RecordSampleInterruptCallback( |
+ const InterruptedThreadState& state, |
+ void* data) { |
+ Thread* thread = reinterpret_cast<Thread*>(data); |
siva
2015/10/26 23:45:26
ASSERT this is a valid thread in the thread list?
|
+ const bool in_dart_code = ExecutingDart(thread); |
siva
2015/10/26 23:45:26
ExecutingDart should be in class Thread now?
thre
Cutch
2015/10/27 22:36:24
Done.
|
+ |
+ uintptr_t sp = 0; |
+ uintptr_t fp = state.fp; |
+ uintptr_t pc = state.pc; |
+#if defined(USING_SIMULATOR) |
+ Simulator* simulator = NULL; |
+#endif |
+ |
+ if (StubCode::InJumpToExceptionHandlerStub(pc)) { |
+ // The JumpToExceptionHandler stub manually adjusts the stack pointer, |
+ // frame pointer, and some isolate state before jumping to a catch entry. |
+ // It is not safe to walk the stack when executing this stub. |
+ return; |
+ } |
+ |
+ if (in_dart_code) { |
+ // If we're in Dart code, use the Dart stack pointer. |
+#if defined(USING_SIMULATOR) |
+ simulator = isolate->simulator(); |
+ sp = simulator->get_register(SPREG); |
+ fp = simulator->get_register(FPREG); |
+ pc = simulator->get_pc(); |
+#else |
+ sp = state.dsp; |
+#endif |
+ } else { |
+ // If we're in runtime code, use the C stack pointer. |
+ sp = state.csp; |
+ } |
+ |
+ if (!InitialRegisterCheck(pc, fp, sp)) { |
+ return; |
+ } |
+ |
+ SampleMutator(thread, pc, fp, sp); |
siva
2015/10/26 23:45:26
So we will not be profiling the background compila
Cutch
2015/10/27 22:36:24
This is intentional and temporary.
|
+} |
+ |
+ |
ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer( |
SampleFilter* filter) { |
ASSERT(filter != NULL); |