Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: runtime/vm/profiler_service.h

Issue 1210333002: Make CPU profile models public and refactor model building code (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/profiler_service.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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_SERVICE_H_ 5 #ifndef VM_PROFILER_SERVICE_H_
6 #define VM_PROFILER_SERVICE_H_ 6 #define VM_PROFILER_SERVICE_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/growable_array.h"
12 #include "vm/object.h"
11 #include "vm/tags.h" 13 #include "vm/tags.h"
12 #include "vm/thread_interrupter.h" 14 #include "vm/thread_interrupter.h"
13 15
14 // Profile VM Service. 16 // CPU Profile model and service protocol bits.
15 // NOTE: For sampling and stack walking related code, see profiler.h. 17 // NOTE: For sampling and stack walking related code, see profiler.h.
16 18
17 namespace dart { 19 namespace dart {
18 20
19 // Forward declarations. 21 // Forward declarations.
22 class Code;
23 class Function;
20 class JSONArray; 24 class JSONArray;
21 class JSONStream; 25 class JSONStream;
22 class ProfilerCodeRegionTable; 26 class ProfileFunctionTable;
23 27 class ProfileCodeTable;
24 class ProfilerService : public AllStatic { 28 class RawCode;
29 class RawFunction;
30 class SampleFilter;
31
32 // Profile data related to a |Function|.
33 class ProfileFunction : public ZoneAllocated {
34 public:
35 enum Kind {
36 kDartFunction, // Dart function.
37 kNativeFunction, // Synthetic function for Native (C/C++).
38 kTagFunction, // Synthetic function for a VM or User tag.
39 kStubFunction, // Synthetic function for stub code.
40 kUnknownFunction, // A singleton function for unknown objects.
41 };
42
43 ProfileFunction(Kind kind,
44 const char* name,
45 const Function& function,
46 const intptr_t table_index);
47
48 const char* name() const {
49 ASSERT(name_ != NULL);
50 return name_;
51 }
52
53 RawFunction* function() const {
54 return function_.raw();
55 }
56
57 intptr_t table_index() const {
58 return table_index_;
59 }
60
61 Kind kind() const {
62 return kind_;
63 }
64
65 intptr_t exclusive_ticks() const { return exclusive_ticks_; }
66 intptr_t inclusive_ticks() const { return inclusive_ticks_; }
67
68 void IncInclusiveTicks() {
69 inclusive_ticks_++;
70 }
71
72 void Tick(bool exclusive, intptr_t inclusive_serial);
73
74 static const char* KindToCString(Kind kind);
75
76 void PrintToJSONArray(JSONArray* functions);
77
78 private:
79 const Kind kind_;
80 const char* name_;
81 const Function& function_;
82 const intptr_t table_index_;
83 ZoneGrowableArray<intptr_t> profile_codes_;
84
85 intptr_t exclusive_ticks_;
86 intptr_t inclusive_ticks_;
87 intptr_t inclusive_serial_;
88
89 void PrintToJSONObject(JSONObject* func);
90 // A |ProfileCode| that contains this function.
91 void AddProfileCode(intptr_t code_table_index);
92
93 friend class ProfileCode;
94 friend class ProfileBuilder;
95 };
96
97
98 class ProfileCodeAddress {
99 public:
100 explicit ProfileCodeAddress(uword pc);
101
102 void Tick(bool exclusive);
103
104 uword pc() const { return pc_; }
105 intptr_t exclusive_ticks() const { return exclusive_ticks_; }
106 intptr_t inclusive_ticks() const { return inclusive_ticks_; }
107
108 private:
109 uword pc_;
110 intptr_t exclusive_ticks_;
111 intptr_t inclusive_ticks_;
112 };
113
114
115 // Profile data related to a |Code|.
116 class ProfileCode : public ZoneAllocated {
117 public:
118 enum Kind {
119 kDartCode, // Live Dart code.
120 kCollectedCode, // Dead Dart code.
121 kNativeCode, // Native code.
122 kReusedCode, // Dead Dart code that has been reused by new kDartCode.
123 kTagCode, // A special kind of code representing a tag.
124 };
125
126 ProfileCode(Kind kind,
127 uword start,
128 uword end,
129 int64_t timestamp,
130 const Code& code);
131
132 Kind kind() const { return kind_; }
133
134 uword start() const { return start_; }
135 void set_start(uword start) { start_ = start; }
136
137 uword end() const { return end_; }
138 void set_end(uword end) { end_ = end; }
139
140 void AdjustExtent(uword start, uword end);
141
142 bool Contains(uword pc) const {
143 return (pc >= start_) && (pc < end_);
144 }
145
146 bool Overlaps(const ProfileCode* other) const;
147
148 int64_t compile_timestamp() const { return compile_timestamp_; }
149 void set_compile_timestamp(int64_t timestamp) {
150 compile_timestamp_ = timestamp;
151 }
152
153 intptr_t exclusive_ticks() const { return exclusive_ticks_; }
154 void set_exclusive_ticks(intptr_t exclusive_ticks) {
155 exclusive_ticks_ = exclusive_ticks;
156 }
157 void IncExclusiveTicks() {
158 exclusive_ticks_++;
159 }
160
161 intptr_t inclusive_ticks() const { return inclusive_ticks_; }
162 void set_inclusive_ticks(intptr_t inclusive_ticks) {
163 inclusive_ticks_ = inclusive_ticks;
164 }
165 void IncInclusiveTicks() {
166 inclusive_ticks_++;
167 }
168
169 bool IsOptimizedDart() const;
170 RawCode* code() const {
171 return code_.raw();
172 }
173
174 const char* name() const { return name_; }
175 void SetName(const char* name);
176 void GenerateAndSetSymbolName(const char* prefix);
177
178 static const char* KindToCString(Kind kind);
179
180 void PrintToJSONArray(JSONArray* codes);
181
182 private:
183 void Tick(uword pc, bool exclusive, intptr_t serial);
184 void TickAddress(uword pc, bool exclusive);
185
186 ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table);
187
188 ProfileFunction* function() const {
189 return function_;
190 }
191
192 void PrintNativeCode(JSONObject* profile_code_obj);
193 void PrintCollectedCode(JSONObject* profile_code_obj);
194 void PrintOverwrittenCode(JSONObject* profile_code_obj);
195 void PrintTagCode(JSONObject* profile_code_obj);
196
197 void set_code_table_index(intptr_t index) { code_table_index_ = index; }
198 intptr_t code_table_index() const { return code_table_index_; }
199
200 const Kind kind_;
201 uword start_;
202 uword end_;
203 intptr_t exclusive_ticks_;
204 intptr_t inclusive_ticks_;
205 intptr_t inclusive_serial_;
206
207 const Code& code_;
208 const char* name_;
209 int64_t compile_timestamp_;
210 ProfileFunction* function_;
211 intptr_t code_table_index_;
212 ZoneGrowableArray<ProfileCodeAddress> address_ticks_;
213
214 friend class ProfileBuilder;
215 };
216
217
218 // Stack traces are organized in a trie. This holds information about one node
219 // in the trie. A node in a tree represents a stack frame and a path in the tree
220 // represents a stack trace. Each unique stack trace appears in the tree once
221 // and each node has a count indicating how many times this has been observed.
222 // The index can be used to look up a |ProfileFunction| or |ProfileCode|.
223 // A node can have zero or more children. Depending on the kind of trie the
224 // children are callers or callees of the current node.
225 class ProfileTrieNode : public ZoneAllocated {
226 public:
227 explicit ProfileTrieNode(intptr_t index);
228 virtual ~ProfileTrieNode();
229
230 virtual void PrintToJSONArray(JSONArray* array) const = 0;
231
232 // Index into function or code tables.
233 intptr_t table_index() const { return table_index_; }
234
235 intptr_t count() const { return count_; }
236
237 void Tick() {
238 count_++;
239 }
240
241 intptr_t NumChildren() const {
242 return children_.length();
243 }
244
245 ProfileTrieNode* At(intptr_t i) {
246 return children_.At(i);
247 }
248
249 protected:
250 void SortChildren();
251
252 static int ProfileTrieNodeCompare(ProfileTrieNode* const* a,
253 ProfileTrieNode* const* b) {
254 ASSERT(a != NULL);
255 ASSERT(b != NULL);
256 return (*b)->count() - (*a)->count();
257 }
258
259
260 intptr_t table_index_;
261 intptr_t count_;
262 ZoneGrowableArray<ProfileTrieNode*> children_;
263
264 friend class ProfileBuilder;
265 };
266
267
268 // The model for a profile. Most of the model is zone allocated, therefore
269 // a zone must be created that lives longer than this object.
270 class Profile : public ValueObject {
25 public: 271 public:
26 enum TagOrder { 272 enum TagOrder {
27 kNoTags, 273 kNoTags,
28 kUser, 274 kUser,
29 kUserVM, 275 kUserVM,
30 kVM, 276 kVM,
31 kVMUser 277 kVMUser
32 }; 278 };
33 279
280 enum TrieKind {
281 kExclusiveCode,
282 kExclusiveFunction,
283 kInclusiveCode,
284 kInclusiveFunction,
285 kNumTrieKinds,
286 };
287
288 explicit Profile(Isolate* isolate);
289
290 // Build a filtered model using |filter| with the specified |tag_order|.
291 void Build(SampleFilter* filter, TagOrder tag_order);
292
293 // After building:
294 int64_t min_time() const { return min_time_; }
295 int64_t max_time() const { return max_time_; }
296 int64_t GetTimeSpan() const {
297 return max_time() - min_time();
298 }
299 intptr_t sample_count() const { return sample_count_; }
300
301 ProfileFunction* GetFunction(intptr_t index);
302 ProfileCode* GetCode(intptr_t index);
303 ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);
304
305 void PrintJSON(JSONStream* stream);
306
307 private:
308 Isolate* isolate_;
309 ProfileCodeTable* live_code_;
310 ProfileCodeTable* dead_code_;
311 ProfileCodeTable* tag_code_;
312 ProfileFunctionTable* functions_;
313 intptr_t dead_code_index_offset_;
314 intptr_t tag_code_index_offset_;
315
316 ProfileTrieNode* roots_[kNumTrieKinds];
317
318 int64_t min_time_;
319 int64_t max_time_;
320
321 intptr_t sample_count_;
322
323 friend class ProfileBuilder;
324 };
325
326
327 class ProfilerService : public AllStatic {
328 public:
34 static void PrintJSON(JSONStream* stream, 329 static void PrintJSON(JSONStream* stream,
35 TagOrder tag_order); 330 Profile::TagOrder tag_order);
36 331
37 static void ClearSamples(); 332 static void ClearSamples();
38 }; 333 };
39 334
40 } // namespace dart 335 } // namespace dart
41 336
42 #endif // VM_PROFILER_SERVICE_H_ 337 #endif // VM_PROFILER_SERVICE_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/profiler_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698