Chromium Code Reviews| Index: runtime/vm/profiler.cc |
| diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc |
| index 2e99b34d7ee646d2eb9d364f4c66f09feb469a78..59ac669803de2ae7af2d1e6a9b3b4a761a06b125 100644 |
| --- a/runtime/vm/profiler.cc |
| +++ b/runtime/vm/profiler.cc |
| @@ -357,15 +357,14 @@ static void DumpStackFrame(intptr_t frame_index, uword pc) { |
| class ProfilerStackWalker : public ValueObject { |
| public: |
| - ProfilerStackWalker(Isolate* isolate, |
| + ProfilerStackWalker(Dart_Port port_id, |
| Sample* head_sample, |
| SampleBuffer* sample_buffer) |
| - : isolate_(isolate), |
| + : port_id_(port_id), |
| sample_(head_sample), |
| sample_buffer_(sample_buffer), |
| frame_index_(0), |
| total_frames_(0) { |
| - ASSERT(isolate_ != NULL); |
| if (sample_ == NULL) { |
| ASSERT(sample_buffer_ == NULL); |
| } else { |
| @@ -404,7 +403,7 @@ class ProfilerStackWalker : public ValueObject { |
| } |
| protected: |
| - Isolate* isolate_; |
| + Dart_Port port_id_; |
| Sample* sample_; |
| SampleBuffer* sample_buffer_; |
| intptr_t frame_index_; |
| @@ -425,7 +424,11 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { |
| uword sp, |
| bool exited_dart_code, |
| bool allocation_sample) |
| - : ProfilerStackWalker(thread->isolate(), sample, sample_buffer), |
| + : ProfilerStackWalker(thread->isolate() != NULL |
|
Cutch
2017/02/08 00:28:54
Wrap comparison in parens:
(thread->isolate() !=
bkonyi
2017/02/08 01:37:05
Done.
|
| + ? thread->isolate()->main_port() |
| + : ILLEGAL_PORT, |
| + sample, |
| + sample_buffer), |
| pc_(reinterpret_cast<uword*>(pc)), |
| fp_(reinterpret_cast<uword*>(fp)), |
| sp_(reinterpret_cast<uword*>(sp)), |
| @@ -597,7 +600,7 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { |
| // |
| class ProfilerNativeStackWalker : public ProfilerStackWalker { |
| public: |
| - ProfilerNativeStackWalker(Isolate* isolate, |
| + ProfilerNativeStackWalker(Dart_Port port_id, |
| Sample* sample, |
| SampleBuffer* sample_buffer, |
| uword stack_lower, |
| @@ -605,7 +608,7 @@ class ProfilerNativeStackWalker : public ProfilerStackWalker { |
| uword pc, |
| uword fp, |
| uword sp) |
| - : ProfilerStackWalker(isolate, sample, sample_buffer), |
| + : ProfilerStackWalker(port_id, sample, sample_buffer), |
| stack_upper_(stack_upper), |
| original_pc_(pc), |
| original_fp_(fp), |
| @@ -862,6 +865,43 @@ static bool GetAndValidateIsolateStackBounds(Thread* thread, |
| } |
| +static bool GetAndValidateThreadStackBounds(OSThread* os_thread, |
|
Cutch
2017/02/08 00:28:54
please find a way to merge this function with the
bkonyi
2017/02/08 01:37:05
Acknowledged. Will do this for patch 3.
bkonyi
2017/02/09 21:22:46
Done.
|
| + uintptr_t fp, |
| + uintptr_t sp, |
| + uword* stack_lower, |
| + uword* stack_upper) { |
| + ASSERT(os_thread != NULL); |
| + ASSERT(stack_lower != NULL); |
| + ASSERT(stack_upper != NULL); |
| + if (!os_thread->GetProfilerStackBounds(stack_lower, stack_upper) || |
| + (*stack_lower == 0) || (*stack_upper == 0)) { |
| + // Could not get stack boundary. |
| + } |
| + |
| + if (sp > *stack_lower) { |
| + // The stack pointer gives us a tighter lower bound. |
| + *stack_lower = sp; |
| + } |
| + |
| + 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; |
| +} |
| + |
| + |
| // 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)) { |
| @@ -904,6 +944,14 @@ static Sample* SetupSample(Thread* thread, |
| } |
| +static Sample* SetupNativeSample(SampleBuffer* sample_buffer, ThreadId tid) { |
| + Sample* sample = sample_buffer->ReserveSample(); |
| + sample->Init(NULL, OS::GetCurrentMonotonicMicros(), tid); |
|
Cutch
2017/02/08 00:28:54
You should be passing in ILLEGAL_PORT_ID and not N
bkonyi
2017/02/08 01:37:05
Done.
|
| + sample->set_is_native_allocation_sample(true); |
| + return sample; |
| +} |
| + |
| + |
| static bool CheckIsolate(Isolate* isolate) { |
| if ((isolate == NULL) || (Dart::vm_isolate() == NULL)) { |
| // No isolate. |
| @@ -990,7 +1038,8 @@ void Profiler::DumpStackTrace(uword sp, uword fp, uword pc) { |
| } |
| ProfilerNativeStackWalker native_stack_walker( |
| - isolate, NULL, NULL, stack_lower, stack_upper, pc, fp, sp); |
| + (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, NULL, NULL, |
| + stack_lower, stack_upper, pc, fp, sp); |
| native_stack_walker.walk(); |
| OS::PrintErr("-- End of DumpStackTrace\n"); |
| } |
| @@ -1037,7 +1086,8 @@ void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
| if (FLAG_profile_vm) { |
| ProfilerNativeStackWalker native_stack_walker( |
| - isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| + (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, sample, |
| + sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| native_stack_walker.walk(); |
| } else if (exited_dart_code) { |
| ProfilerDartStackWalker dart_exit_stack_walker( |
| @@ -1054,6 +1104,44 @@ void Profiler::SampleAllocation(Thread* thread, intptr_t cid) { |
| } |
| +Sample* Profiler::NativeSampleAllocation() { |
| + SampleBuffer* sample_buffer = Profiler::sample_buffer(); |
| + if (sample_buffer == NULL) { |
| + return NULL; |
| + } |
| + |
| + uintptr_t sp = Thread::GetCurrentStackPointer(); |
| + uintptr_t fp = 0; |
| + uintptr_t pc = GetProgramCounter(); |
| + |
| + COPY_FP_REGISTER(fp); |
| + |
| + uword stack_lower = 0; |
| + uword stack_upper = 0; |
| + if (!InitialRegisterCheck(pc, fp, sp)) { |
| + return NULL; |
| + } |
| + |
| + OSThread* os_thread = OSThread::Current(); |
| + if (os_thread->stack_base() == 0) { |
| + stack_lower = sp; |
| + stack_upper = ~static_cast<uintptr_t>(0x0); |
| + } else { |
| + if (!GetAndValidateThreadStackBounds(os_thread, fp, sp, &stack_lower, |
| + &stack_upper)) { |
| + // Could not get stack boundary. |
| + return NULL; |
| + } |
| + } |
| + Sample* sample = SetupNativeSample(sample_buffer, os_thread->trace_id()); |
| + ProfilerNativeStackWalker native_stack_walker(ILLEGAL_PORT, sample, |
| + sample_buffer, stack_lower, |
| + stack_upper, pc, fp, sp); |
| + native_stack_walker.walk(); |
| + return sample; |
| +} |
| + |
| + |
| void Profiler::SampleThreadSingleFrame(Thread* thread, uintptr_t pc) { |
| ASSERT(thread != NULL); |
| OSThread* os_thread = thread->os_thread(); |
| @@ -1179,7 +1267,8 @@ void Profiler::SampleThread(Thread* thread, |
| } |
| ProfilerNativeStackWalker native_stack_walker( |
| - isolate, sample, sample_buffer, stack_lower, stack_upper, pc, fp, sp); |
| + (isolate != NULL) ? isolate->main_port() : ILLEGAL_PORT, 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, |