Chromium Code Reviews| Index: runtime/vm/profiler.h |
| diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h |
| index f8107e49d2999e312e3e08ec9340fcb14b137dc1..9de8f700dbfe853c7eb4dd429875dd3e9af0123e 100644 |
| --- a/runtime/vm/profiler.h |
| +++ b/runtime/vm/profiler.h |
| @@ -26,6 +26,7 @@ class ProcessedSample; |
| class ProcessedSampleBuffer; |
| class Sample; |
| +class AllocationSampleBuffer; |
| class SampleBuffer; |
| class ProfileTrieNode; |
| @@ -51,12 +52,16 @@ struct ProfilerCounters { |
| class Profiler : public AllStatic { |
| public: |
| static void InitOnce(); |
| + static void InitAllocationSampleBuffer(); |
| static void Shutdown(); |
| static void SetSampleDepth(intptr_t depth); |
| static void SetSamplePeriod(intptr_t period); |
| static SampleBuffer* sample_buffer() { return sample_buffer_; } |
| + static AllocationSampleBuffer* allocation_sample_buffer() { |
| + return allocation_sample_buffer_; |
| + } |
| static void DumpStackTrace(void* context); |
| static void DumpStackTrace(bool for_crash = true); |
| @@ -89,6 +94,7 @@ class Profiler : public AllStatic { |
| static bool initialized_; |
| static SampleBuffer* sample_buffer_; |
| + static AllocationSampleBuffer* allocation_sample_buffer_; |
| static ProfilerCounters counters_; |
| @@ -192,6 +198,7 @@ class Sample { |
| native_allocation_address_ = 0; |
| native_allocation_size_bytes_ = 0; |
| continuation_index_ = -1; |
| + next_free_ = NULL; |
| uword* pcs = GetPCArray(); |
| for (intptr_t i = 0; i < pcs_length_; i++) { |
| pcs[i] = 0; |
| @@ -293,21 +300,12 @@ class Sample { |
| state_ = ClassAllocationSampleBit::update(allocation_sample, state_); |
| } |
| - bool is_native_allocation_sample() const { |
| - return NativeAllocationSampleBit::decode(state_); |
| - } |
| - |
| - void set_is_native_allocation_sample(bool native_allocation_sample) { |
| - state_ = |
| - NativeAllocationSampleBit::update(native_allocation_sample, state_); |
| - } |
| + uword native_allocation_address() const { return native_allocation_address_; } |
| void set_native_allocation_address(uword address) { |
| native_allocation_address_ = address; |
| } |
| - uword native_allocation_address() const { return native_allocation_address_; } |
| - |
| uintptr_t native_allocation_size_bytes() const { |
| return native_allocation_size_bytes_; |
| } |
| @@ -316,6 +314,9 @@ class Sample { |
| native_allocation_size_bytes_ = size; |
| } |
| + Sample* next_free() const { return next_free_; } |
| + void set_next_free(Sample* next_free) { next_free_ = next_free; } |
| + |
| Thread::TaskKind thread_task() const { return ThreadTaskBit::decode(state_); } |
| void set_thread_task(Thread::TaskKind task) { |
| @@ -357,6 +358,7 @@ class Sample { |
| set_metadata(cid); |
| } |
| + |
|
zra
2017/06/30 18:49:17
rm extra newline
bkonyi
2017/07/05 18:20:52
Done.
|
| static void InitOnce(); |
| static intptr_t instance_size() { return instance_size_; } |
| @@ -366,7 +368,7 @@ class Sample { |
| static const int kStackBufferSizeInWords = 2; |
| uword* GetStackBuffer() { return &stack_buffer_[0]; } |
| - private: |
| + protected: |
|
zra
2017/06/30 18:49:17
I'm having trouble finding why this needs to be pr
bkonyi
2017/07/05 18:20:52
This is just something I forgot to change back sin
|
| static intptr_t instance_size_; |
| static intptr_t pcs_length_; |
| enum StateBits { |
| @@ -379,8 +381,7 @@ class Sample { |
| kClassAllocationSampleBit = 6, |
| kContinuationSampleBit = 7, |
| kThreadTaskBit = 8, // 5 bits. |
| - kNativeAllocationSampleBit = 13, |
| - kNextFreeBit = 14, |
| + kNextFreeBit = 13, |
| }; |
| class HeadSampleBit : public BitField<uword, bool, kHeadSampleBit, 1> {}; |
| class LeafFrameIsDart : public BitField<uword, bool, kLeafFrameIsDartBit, 1> { |
| @@ -397,8 +398,6 @@ class Sample { |
| : public BitField<uword, bool, kContinuationSampleBit, 1> {}; |
| class ThreadTaskBit |
| : public BitField<uword, Thread::TaskKind, kThreadTaskBit, 5> {}; |
| - class NativeAllocationSampleBit |
| - : public BitField<uword, bool, kNativeAllocationSampleBit, 1> {}; |
| int64_t timestamp_; |
| ThreadId tid_; |
| @@ -413,10 +412,11 @@ class Sample { |
| uword native_allocation_address_; |
| uintptr_t native_allocation_size_bytes_; |
| intptr_t continuation_index_; |
| + Sample* next_free_; |
| /* There are a variable number of words that follow, the words hold the |
| * sampled pc values. Access via GetPCArray() */ |
| - |
| + private: |
| DISALLOW_COPY_AND_ASSIGN(Sample); |
| }; |
| @@ -431,9 +431,6 @@ class NativeAllocationSampleFilter : public SampleFilter { |
| time_extent_micros) {} |
| bool FilterSample(Sample* sample) { |
| - if (!sample->is_native_allocation_sample()) { |
| - return false; |
| - } |
| // If the sample is an allocation sample, we need to check that the |
|
zra
2017/06/30 18:49:17
Maybe assert that the sample is an allocation samp
bkonyi
2017/07/05 18:20:52
I'll assert that the sample has a valid allocation
|
| // memory at the address hasn't been freed, and if the address associated |
| // with the allocation has been freed and then reissued. |
| @@ -521,14 +518,14 @@ class SampleBuffer { |
| static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. |
| explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); |
| - ~SampleBuffer(); |
| + virtual ~SampleBuffer(); |
| intptr_t capacity() const { return capacity_; } |
| Sample* At(intptr_t idx) const; |
| - intptr_t ReserveSampleSlot(); |
| - Sample* ReserveSample(); |
| - Sample* ReserveSampleAndLink(Sample* previous); |
| + virtual intptr_t ReserveSampleSlot(); |
| + virtual Sample* ReserveSample(); |
| + virtual Sample* ReserveSampleAndLink(Sample* previous); |
| void VisitSamples(SampleVisitor* visitor) { |
| ASSERT(visitor != NULL); |
| @@ -562,7 +559,7 @@ class SampleBuffer { |
| ProcessedSampleBuffer* BuildProcessedSampleBuffer(SampleFilter* filter); |
| - private: |
| + protected: |
| ProcessedSample* BuildProcessedSample(Sample* sample, |
| const CodeLookupTable& clt); |
| Sample* Next(Sample* sample); |
| @@ -572,10 +569,29 @@ class SampleBuffer { |
| intptr_t capacity_; |
| uintptr_t cursor_; |
| + private: |
| DISALLOW_COPY_AND_ASSIGN(SampleBuffer); |
| }; |
| +class AllocationSampleBuffer : public SampleBuffer { |
| + public: |
| + explicit AllocationSampleBuffer(intptr_t capacity = kDefaultBufferCapacity); |
| + virtual ~AllocationSampleBuffer(); |
| + |
| + virtual intptr_t ReserveSampleSlot(); |
| + virtual Sample* ReserveSample(); |
| + virtual Sample* ReserveSampleAndLink(Sample* previous); |
| + void FreeAllocationSample(Sample* sample); |
| + |
| + private: |
| + Mutex* mutex_; |
| + Sample* free_sample_list_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(AllocationSampleBuffer); |
| +}; |
| + |
| + |
| // A |ProcessedSample| is a combination of 1 (or more) |Sample|(s) that have |
| // been merged into a logical sample. The raw data may have been processed to |
| // improve the quality of the stack trace. |