Index: runtime/vm/profiler.cc |
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc |
index 7110d082ae276e80ebd9b09549448502da39d0ee..e637be31f49fc63d700f020c35a524eaef302379 100644 |
--- a/runtime/vm/profiler.cc |
+++ b/runtime/vm/profiler.cc |
@@ -168,7 +168,7 @@ Sample* SampleBuffer::ReserveSampleAndLink(Sample* previous) { |
ASSERT(previous != NULL); |
intptr_t next_index = ReserveSampleSlot(); |
Sample* next = At(next_index); |
- next->Init(previous->port(), previous->timestamp(), previous->tid()); |
+ next->Init(previous->isolate(), previous->timestamp(), previous->tid()); |
next->set_head_sample(false); |
// Mark that previous continues at next. |
previous->SetContinuationIndex(next_index); |
@@ -321,7 +321,7 @@ bool SampleFilter::TaskFilterSample(Sample* sample) { |
ClearProfileVisitor::ClearProfileVisitor(Isolate* isolate) |
- : SampleVisitor(isolate->main_port()) {} |
+ : SampleVisitor(isolate) {} |
void ClearProfileVisitor::VisitSample(Sample* sample) { |
@@ -357,17 +357,15 @@ static void DumpStackFrame(intptr_t frame_index, uword pc) { |
class ProfilerStackWalker : public ValueObject { |
public: |
- ProfilerStackWalker(Dart_Port port_id, |
+ ProfilerStackWalker(Isolate* isolate, |
Sample* head_sample, |
- SampleBuffer* sample_buffer, |
- intptr_t skip_count = 0) |
- : port_id_(port_id), |
+ SampleBuffer* sample_buffer) |
+ : isolate_(isolate), |
sample_(head_sample), |
sample_buffer_(sample_buffer), |
- skip_count_(skip_count), |
- frames_skipped_(0), |
frame_index_(0), |
total_frames_(0) { |
+ ASSERT(isolate_ != NULL); |
if (sample_ == NULL) { |
ASSERT(sample_buffer_ == NULL); |
} else { |
@@ -377,11 +375,6 @@ class ProfilerStackWalker : public ValueObject { |
} |
bool Append(uword pc) { |
- if (frames_skipped_ < skip_count_) { |
- frames_skipped_++; |
- return true; |
- } |
- |
if (sample_ == NULL) { |
DumpStackFrame(frame_index_, pc); |
frame_index_++; |
@@ -411,11 +404,9 @@ class ProfilerStackWalker : public ValueObject { |
} |
protected: |
- Dart_Port port_id_; |
+ Isolate* isolate_; |
Sample* sample_; |
SampleBuffer* sample_buffer_; |
- intptr_t skip_count_; |
- intptr_t frames_skipped_; |
intptr_t frame_index_; |
intptr_t total_frames_; |
}; |
@@ -433,14 +424,8 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { |
uword fp, |
uword sp, |
bool exited_dart_code, |
- bool allocation_sample, |
- intptr_t skip_count = 0) |
- : ProfilerStackWalker((thread->isolate() != NULL) |
- ? thread->isolate()->main_port() |
- : ILLEGAL_PORT, |
- sample, |
- sample_buffer, |
- skip_count), |
+ bool allocation_sample) |
+ : ProfilerStackWalker(thread->isolate(), sample, sample_buffer), |
pc_(reinterpret_cast<uword*>(pc)), |
fp_(reinterpret_cast<uword*>(fp)), |
sp_(reinterpret_cast<uword*>(sp)), |
@@ -612,16 +597,15 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { |
// |
class ProfilerNativeStackWalker : public ProfilerStackWalker { |
public: |
- ProfilerNativeStackWalker(Dart_Port port_id, |
+ ProfilerNativeStackWalker(Isolate* isolate, |
Sample* sample, |
SampleBuffer* sample_buffer, |
uword stack_lower, |
uword stack_upper, |
uword pc, |
uword fp, |
- uword sp, |
- intptr_t skip_count = 0) |
- : ProfilerStackWalker(port_id, sample, sample_buffer, skip_count), |
+ uword sp) |
+ : ProfilerStackWalker(isolate, sample, sample_buffer), |
stack_upper_(stack_upper), |
original_pc_(pc), |
original_fp_(fp), |
@@ -630,7 +614,6 @@ class ProfilerNativeStackWalker : public ProfilerStackWalker { |
void walk() { |
const uword kMaxStep = VirtualMemory::PageSize(); |
- |
Append(original_pc_); |
uword* pc = reinterpret_cast<uword*>(original_pc_); |
@@ -813,29 +796,6 @@ static void CollectSample(Isolate* isolate, |
} |
-static bool ValidateThreadStackBounds(uintptr_t fp, |
- uintptr_t sp, |
- uword stack_lower, |
- uword stack_upper) { |
- if (stack_lower >= stack_upper) { |
- // Stack boundary is invalid. |
- return false; |
- } |
- |
- if ((sp < stack_lower) || (sp >= stack_upper)) { |
- // Stack pointer is outside thread's stack boundary. |
- return false; |
- } |
- |
- if ((fp < stack_lower) || (fp >= stack_upper)) { |
- // Frame pointer is outside threads's stack boundary. |
- return false; |
- } |
- |
- return true; |
-} |
- |
- |
// Get |isolate|'s stack boundary and verify that |sp| and |fp| are within |
// it. If |get_os_thread_bounds| is true then if |isolate| stackbounds are |
// not available we fallback to using underlying OS thread bounds. This only |
@@ -847,12 +807,8 @@ static bool GetAndValidateThreadStackBounds(Thread* thread, |
uword* stack_lower, |
uword* stack_upper, |
bool get_os_thread_bounds = false) { |
- OSThread* os_thread = NULL; |
- if (thread != NULL) { |
- os_thread = thread->os_thread(); |
- } else { |
- os_thread = OSThread::Current(); |
- } |
+ ASSERT(thread != NULL); |
+ OSThread* os_thread = thread->os_thread(); |
ASSERT(os_thread != NULL); |
ASSERT(stack_lower != NULL); |
ASSERT(stack_upper != NULL); |
@@ -888,7 +844,22 @@ static bool GetAndValidateThreadStackBounds(Thread* thread, |
*stack_lower = sp; |
} |
- return ValidateThreadStackBounds(fp, sp, *stack_lower, *stack_upper); |
+ if (*stack_lower >= *stack_upper) { |
+ // Stack boundary is invalid. |
+ return false; |
+ } |
+ |
+ if ((sp < *stack_lower) || (sp >= *stack_upper)) { |
+ // Stack pointer is outside thread's stack boundary. |
+ return false; |
+ } |
+ |
+ if ((fp < *stack_lower) || (fp >= *stack_upper)) { |
+ // Frame pointer is outside threads's stack boundary. |
+ return false; |
+ } |
+ |
+ return true; |
} |
@@ -916,7 +887,7 @@ static Sample* SetupSample(Thread* thread, |
Isolate* isolate = thread->isolate(); |
ASSERT(sample_buffer != NULL); |
Sample* sample = sample_buffer->ReserveSample(); |
- sample->Init(isolate->main_port(), OS::GetCurrentMonotonicMicros(), tid); |
+ sample->Init(isolate, OS::GetCurrentMonotonicMicros(), tid); |
uword vm_tag = thread->vm_tag(); |
#if defined(USING_SIMULATOR) && !defined(TARGET_ARCH_DBC) |
// When running in the simulator, the runtime entry function address |
@@ -934,23 +905,6 @@ static Sample* SetupSample(Thread* thread, |
} |
-static Sample* SetupSampleNative(SampleBuffer* sample_buffer, ThreadId tid) { |
- Sample* sample = sample_buffer->ReserveSample(); |
- sample->Init(ILLEGAL_PORT, OS::GetCurrentMonotonicMicros(), tid); |
- sample->set_is_native_allocation_sample(true); |
- |
- Thread* thread = Thread::Current(); |
- |
- // TODO(bkonyi) Any samples created while a current thread doesn't exist are |
- // ignored by the NativeAllocationSampleFilter since the default task is |
- // kUnknownTask. Is this what we want to do? |
- if (thread != NULL) { |
- sample->set_thread_task(thread->task_kind()); |
- } |
- return sample; |
-} |
- |
- |
static bool CheckIsolate(Isolate* isolate) { |
if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
// No isolate. |
@@ -960,6 +914,18 @@ static bool CheckIsolate(Isolate* isolate) { |
} |
+#if defined(TARGET_OS_WINDOWS) |
+__declspec(noinline) static uintptr_t GetProgramCounter() { |
+ return reinterpret_cast<uintptr_t>(_ReturnAddress()); |
+} |
+#else |
+static uintptr_t __attribute__((noinline)) GetProgramCounter() { |
+ return reinterpret_cast<uintptr_t>( |
+ __builtin_extract_return_addr(__builtin_return_address(0))); |
+} |
+#endif |
+ |
+ |
void Profiler::DumpStackTrace(void* context) { |
#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_MACOS) |
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
@@ -978,7 +944,7 @@ void Profiler::DumpStackTrace(void* context) { |
void Profiler::DumpStackTrace() { |
uintptr_t sp = Thread::GetCurrentStackPointer(); |
uintptr_t fp = 0; |
- uintptr_t pc = OS::GetProgramCounter(); |
+ uintptr_t pc = GetProgramCounter(); |
COPY_FP_REGISTER(fp); |
@@ -1026,8 +992,7 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) { |
} |
ProfilerNativeStackWalker native_stack_walker( |
- (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, NULL, NULL, |
- stack_lower, stack_upper, pc, fp, sp); |
+ isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); |
native_stack_walker.walk(); |
OS::PrintErr("-- End of DumpStackTrace\n"); |
} |
@@ -1052,7 +1017,7 @@ void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
uintptr_t sp = Thread::GetCurrentStackPointer(); |
uintptr_t fp = 0; |
- uintptr_t pc = OS::GetProgramCounter(); |
+ uintptr_t pc = GetProgramCounter(); |
COPY_FP_REGISTER(fp); |
@@ -1074,8 +1039,7 @@ void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
if (FLAG_profile_vm) { |
ProfilerNativeStackWalker native_stack_walker( |
- (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample, |
- sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
+ isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
native_stack_walker.walk(); |
} else if (exited_dart_code) { |
ProfilerDartStackWalker dart_exit_stack_walker( |
@@ -1084,7 +1048,7 @@ void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
dart_exit_stack_walker.walk(); |
} else { |
// Fall back. |
- uintptr_t pc = OS::GetProgramCounter(); |
+ uintptr_t pc = GetProgramCounter(); |
Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id()); |
sample->SetAllocationCid(cid); |
sample->SetAt(0, pc); |
@@ -1092,44 +1056,6 @@ void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
} |
-Sample* Profiler::SampleNativeAllocation(intptr_t skip_count) { |
- SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
- if (sample_buffer == NULL) { |
- return NULL; |
- } |
- |
- uintptr_t sp = Thread::GetCurrentStackPointer(); |
- uintptr_t fp = 0; |
- uintptr_t pc = OS::GetProgramCounter(); |
- |
- COPY_FP_REGISTER(fp); |
- |
- uword stack_lower = 0; |
- uword stack_upper = 0; |
- if (!InitialRegisterCheck(pc, fp, sp)) { |
- AtomicOperations::IncrementInt64By( |
- &counters_.failure_native_allocation_sample, 1); |
- return NULL; |
- } |
- |
- if (!(OSThread::GetCurrentStackBounds(&stack_lower, &stack_upper) && |
- ValidateThreadStackBounds(fp, sp, stack_lower, stack_upper))) { |
- // Could not get stack boundary. |
- AtomicOperations::IncrementInt64By( |
- &counters_.failure_native_allocation_sample, 1); |
- return NULL; |
- } |
- |
- OSThread* os_thread = OSThread::Current(); |
- Sample* sample = SetupSampleNative(sample_buffer, os_thread->trace_id()); |
- ProfilerNativeStackWalker native_stack_walker( |
- ILLEGAL_PORT, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp, |
- skip_count); |
- native_stack_walker.walk(); |
- return sample; |
-} |
- |
- |
void Profiler::SampleThreadSingleFrame(Thread* thread, uintptr_t pc) { |
ASSERT(thread != NULL); |
OSThread* os_thread = thread->os_thread(); |
@@ -1255,8 +1181,7 @@ void Profiler::SampleThread(Thread* thread, |
} |
ProfilerNativeStackWalker native_stack_walker( |
- (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample, |
- sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
+ isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
const bool exited_dart_code = thread->HasExitedDartCode(); |
ProfilerDartStackWalker dart_stack_walker(thread, sample, sample_buffer, |
stack_lower, stack_upper, pc, fp, |
@@ -1416,9 +1341,7 @@ ProcessedSampleBuffer* SampleBuffer::BuildProcessedSampleBuffer( |
// An inner sample in a chain of samples. |
continue; |
} |
- // If we're requesting all the native allocation samples, we don't care |
- // whether or not we're in the same isolate as the sample. |
- if (sample->port() != filter->port()) { |
+ if (sample->isolate() != filter->isolate()) { |
// Another isolate. |
continue; |
} |
@@ -1497,7 +1420,7 @@ Sample* SampleBuffer::Next(Sample* sample) { |
// Sanity check. |
ASSERT(sample != next_sample); |
// Detect invalid chaining. |
- if (sample->port() != next_sample->port()) { |
+ if (sample->isolate() != next_sample->isolate()) { |
return NULL; |
} |
if (sample->timestamp() != next_sample->timestamp()) { |