 Chromium Code Reviews
 Chromium Code Reviews Issue 174213002:
  Rework Sample class  (Closed) 
  Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
    
  
    Issue 174213002:
  Rework Sample class  (Closed) 
  Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a | 
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 #ifndef VM_PROFILER_H_ | 5 #ifndef VM_PROFILER_H_ | 
| 6 #define VM_PROFILER_H_ | 6 #define VM_PROFILER_H_ | 
| 7 | 7 | 
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" | 
| 9 #include "vm/code_observers.h" | 9 #include "vm/code_observers.h" | 
| 10 #include "vm/globals.h" | 10 #include "vm/globals.h" | 
| 11 #include "vm/thread.h" | 11 #include "vm/thread.h" | 
| 12 #include "vm/thread_interrupter.h" | 12 #include "vm/thread_interrupter.h" | 
| 13 | 13 | 
| 14 namespace dart { | 14 namespace dart { | 
| 15 | 15 | 
| 16 // Forward declarations. | 16 // Forward declarations. | 
| 17 class JSONArray; | 17 class JSONArray; | 
| 18 class JSONStream; | 18 class JSONStream; | 
| 19 class ProfilerCodeRegionTable; | 19 class ProfilerCodeRegionTable; | 
| 20 class Sample; | 20 class Sample; | 
| 21 class SampleBuffer; | 21 class SampleBuffer; | 
| 22 | 22 | 
| 23 // Profiler | 23 // Profiler | 
| 24 class Profiler : public AllStatic { | 24 class Profiler : public AllStatic { | 
| 25 public: | 25 public: | 
| 26 static void InitOnce(); | 26 static void InitOnce(); | 
| 27 static void Shutdown(); | 27 static void Shutdown(); | 
| 28 | 28 | 
| 29 static void SetSampleDepth(intptr_t depth); | |
| 30 static void SetSamplePeriod(intptr_t period); | |
| 31 | |
| 29 static void InitProfilingForIsolate(Isolate* isolate, | 32 static void InitProfilingForIsolate(Isolate* isolate, | 
| 30 bool shared_buffer = true); | 33 bool shared_buffer = true); | 
| 31 static void ShutdownProfilingForIsolate(Isolate* isolate); | 34 static void ShutdownProfilingForIsolate(Isolate* isolate); | 
| 32 | 35 | 
| 33 static void BeginExecution(Isolate* isolate); | 36 static void BeginExecution(Isolate* isolate); | 
| 34 static void EndExecution(Isolate* isolate); | 37 static void EndExecution(Isolate* isolate); | 
| 35 | 38 | 
| 36 static void PrintToJSONStream(Isolate* isolate, JSONStream* stream, | 39 static void PrintToJSONStream(Isolate* isolate, JSONStream* stream, | 
| 37 bool full); | 40 bool full); | 
| 38 static void WriteProfile(Isolate* isolate); | 41 static void WriteProfile(Isolate* isolate); | 
| (...skipping 24 matching lines...) Expand all Loading... | |
| 63 sample_buffer_ = sample_buffer; | 66 sample_buffer_ = sample_buffer; | 
| 64 } | 67 } | 
| 65 | 68 | 
| 66 private: | 69 private: | 
| 67 SampleBuffer* sample_buffer_; | 70 SampleBuffer* sample_buffer_; | 
| 68 bool own_sample_buffer_; | 71 bool own_sample_buffer_; | 
| 69 DISALLOW_COPY_AND_ASSIGN(IsolateProfilerData); | 72 DISALLOW_COPY_AND_ASSIGN(IsolateProfilerData); | 
| 70 }; | 73 }; | 
| 71 | 74 | 
| 72 | 75 | 
| 73 // Profile sample. | |
| 74 class Sample { | |
| 75 public: | |
| 76 enum SampleType { | |
| 77 kIsolateSample, | |
| 78 }; | |
| 79 | |
| 80 static void InitOnce(); | |
| 81 | |
| 82 uword At(intptr_t i) const; | |
| 83 void SetAt(intptr_t i, uword pc); | |
| 84 void Init(SampleType type, Isolate* isolate, int64_t timestamp, ThreadId tid); | |
| 85 void CopyInto(Sample* dst) const; | |
| 86 | |
| 87 static Sample* Allocate(); | |
| 88 static intptr_t instance_size() { | |
| 89 return instance_size_; | |
| 90 } | |
| 91 | |
| 92 SampleType type() const { | |
| 93 return type_; | |
| 94 } | |
| 95 | |
| 96 Isolate* isolate() const { | |
| 97 return isolate_; | |
| 98 } | |
| 99 | |
| 100 int64_t timestamp() const { | |
| 101 return timestamp_; | |
| 102 } | |
| 103 | |
| 104 private: | |
| 105 static intptr_t instance_size_; | |
| 106 int64_t timestamp_; | |
| 107 ThreadId tid_; | |
| 108 Isolate* isolate_; | |
| 109 SampleType type_; | |
| 110 // Note: This class has a size determined at run-time. The pcs_ array | |
| 111 // must be the final field. | |
| 112 uword pcs_[0]; | |
| 113 | |
| 114 DISALLOW_COPY_AND_ASSIGN(Sample); | |
| 115 }; | |
| 116 | |
| 117 | |
| 118 class SampleVisitor { | 76 class SampleVisitor { | 
| 119 public: | 77 public: | 
| 120 explicit SampleVisitor(Isolate* isolate) : isolate_(isolate), visited_(0) { } | 78 explicit SampleVisitor(Isolate* isolate) : isolate_(isolate), visited_(0) { } | 
| 121 virtual ~SampleVisitor() {} | 79 virtual ~SampleVisitor() {} | 
| 122 | 80 | 
| 123 virtual void VisitSample(Sample* sample) = 0; | 81 virtual void VisitSample(Sample* sample) = 0; | 
| 124 | 82 | 
| 125 intptr_t visited() const { | 83 intptr_t visited() const { | 
| 126 return visited_; | 84 return visited_; | 
| 127 } | 85 } | 
| 128 | 86 | 
| 129 void IncrementVisited() { | 87 void IncrementVisited() { | 
| 130 visited_++; | 88 visited_++; | 
| 131 } | 89 } | 
| 132 | 90 | 
| 133 Isolate* isolate() const { | 91 Isolate* isolate() const { | 
| 134 return isolate_; | 92 return isolate_; | 
| 135 } | 93 } | 
| 136 | 94 | 
| 137 private: | 95 private: | 
| 138 Isolate* isolate_; | 96 Isolate* isolate_; | 
| 139 intptr_t visited_; | 97 intptr_t visited_; | 
| 140 | 98 | 
| 141 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); | 99 DISALLOW_IMPLICIT_CONSTRUCTORS(SampleVisitor); | 
| 142 }; | 100 }; | 
| 143 | 101 | 
| 102 // The maximum number of stack frames a sample can hold. | |
| 103 #define kSampleFramesSize 256 | |
| 144 | 104 | 
| 145 // Ring buffer of samples. | 105 // Each Sample holds a stack trace from an isolate. | 
| 106 class Sample { | |
| 107 public: | |
| 108 void Init(Isolate* isolate, int64_t timestamp, ThreadId tid) { | |
| 109 timestamp_ = timestamp; | |
| 110 tid_ = tid; | |
| 111 isolate_ = isolate; | |
| 112 for (intptr_t i = 0; i < kSampleFramesSize; i++) { | |
| 113 pcs_[i] = 0; | |
| 
siva
2014/02/20 21:07:38
I am wondering if we should initialize it to kZapU
 | |
| 114 } | |
| 115 } | |
| 116 | |
| 117 // Isolate sample was taken from. | |
| 118 Isolate* isolate() const { | |
| 119 return isolate_; | |
| 120 } | |
| 121 | |
| 122 // Timestamp sample was taken at. | |
| 123 int64_t timestamp() const { | |
| 124 return timestamp_; | |
| 125 } | |
| 126 | |
| 127 // Get stack trace entry. | |
| 128 uword At(intptr_t i) const { | |
| 129 ASSERT(i >= 0); | |
| 130 ASSERT(i < kSampleFramesSize); | |
| 131 return pcs_[i]; | |
| 132 } | |
| 133 | |
| 134 // Set stack trace entry. | |
| 135 void SetAt(intptr_t i, uword pc) { | |
| 136 ASSERT(i >= 0); | |
| 137 ASSERT(i < kSampleFramesSize); | |
| 138 pcs_[i] = pc; | |
| 139 } | |
| 140 | |
| 141 private: | |
| 142 int64_t timestamp_; | |
| 143 ThreadId tid_; | |
| 144 Isolate* isolate_; | |
| 145 uword pcs_[kSampleFramesSize]; | |
| 146 }; | |
| 147 | |
| 148 | |
| 149 // Ring buffer of Samples that is (usually) shared by many isolates. | |
| 146 class SampleBuffer { | 150 class SampleBuffer { | 
| 147 public: | 151 public: | 
| 148 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. | 152 static const intptr_t kDefaultBufferCapacity = 120000; // 2 minutes @ 1000hz. | 
| 149 | 153 | 
| 150 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity); | 154 explicit SampleBuffer(intptr_t capacity = kDefaultBufferCapacity) { | 
| 151 ~SampleBuffer(); | 155 samples_ = reinterpret_cast<Sample*>(calloc(capacity, sizeof(*samples_))); | 
| 156 capacity_ = capacity; | |
| 157 cursor_ = 0; | |
| 158 } | |
| 159 | |
| 160 ~SampleBuffer() { | |
| 161 if (samples_ != NULL) { | |
| 162 free(samples_); | |
| 163 samples_ = NULL; | |
| 164 cursor_ = 0; | |
| 165 capacity_ = 0; | |
| 166 } | |
| 167 } | |
| 152 | 168 | 
| 153 intptr_t capacity() const { return capacity_; } | 169 intptr_t capacity() const { return capacity_; } | 
| 170 | |
| 154 Sample* ReserveSample(); | 171 Sample* ReserveSample(); | 
| 155 void CopySample(intptr_t i, Sample* sample) const; | |
| 156 Sample* At(intptr_t idx) const; | |
| 157 | 172 | 
| 158 void VisitSamples(SampleVisitor* visitor); | 173 Sample* At(intptr_t idx) const { | 
| 174 ASSERT(idx >= 0); | |
| 175 ASSERT(idx < capacity_); | |
| 176 return &samples_[idx]; | |
| 177 } | |
| 178 | |
| 179 void VisitSamples(SampleVisitor* visitor) { | |
| 180 ASSERT(visitor != NULL); | |
| 181 Sample sample; | |
| 182 const intptr_t length = capacity(); | |
| 183 for (intptr_t i = 0; i < length; i++) { | |
| 184 // Copy the sample. | |
| 185 sample = *At(i); | |
| 186 if (sample.isolate() != visitor->isolate()) { | |
| 187 // Another isolate. | |
| 188 continue; | |
| 189 } | |
| 190 if (sample.timestamp() == 0) { | |
| 191 // Empty. | |
| 192 continue; | |
| 193 } | |
| 194 if (sample.At(0) == 0) { | |
| 195 // No frames. | |
| 196 continue; | |
| 197 } | |
| 198 visitor->IncrementVisited(); | |
| 199 visitor->VisitSample(&sample); | |
| 200 } | |
| 201 } | |
| 159 | 202 | 
| 160 private: | 203 private: | 
| 161 Sample* samples_; | 204 Sample* samples_; | 
| 162 intptr_t capacity_; | 205 intptr_t capacity_; | 
| 163 uintptr_t cursor_; | 206 uintptr_t cursor_; | 
| 164 | 207 | 
| 165 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 208 DISALLOW_COPY_AND_ASSIGN(SampleBuffer); | 
| 166 }; | 209 }; | 
| 167 | 210 | 
| 168 | 211 | 
| 169 } // namespace dart | 212 } // namespace dart | 
| 170 | 213 | 
| 171 #endif // VM_PROFILER_H_ | 214 #endif // VM_PROFILER_H_ | 
| OLD | NEW |