OLD | NEW |
---|---|
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 RUNTIME_VM_PROFILER_SERVICE_H_ | 5 #ifndef RUNTIME_VM_PROFILER_SERVICE_H_ |
6 #define RUNTIME_VM_PROFILER_SERVICE_H_ | 6 #define RUNTIME_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" | 11 #include "vm/growable_array.h" |
12 #include "vm/hash_map.h" | |
12 #include "vm/object.h" | 13 #include "vm/object.h" |
13 #include "vm/tags.h" | 14 #include "vm/tags.h" |
14 #include "vm/thread_interrupter.h" | 15 #include "vm/thread_interrupter.h" |
15 #include "vm/token_position.h" | 16 #include "vm/token_position.h" |
16 | 17 |
17 // CPU Profile model and service protocol bits. | 18 // CPU Profile model and service protocol bits. |
18 // NOTE: For sampling and stack walking related code, see profiler.h. | 19 // NOTE: For sampling and stack walking related code, see profiler.h. |
19 | 20 |
20 namespace dart { | 21 namespace dart { |
21 | 22 |
22 // Forward declarations. | 23 // Forward declarations. |
23 class Code; | 24 class Code; |
24 class Function; | 25 class Function; |
25 class JSONArray; | 26 class JSONArray; |
26 class JSONStream; | 27 class JSONStream; |
27 class ProfileFunctionTable; | 28 class ProfileFunctionTable; |
28 class ProfileCodeTable; | 29 class ProfileCodeTable; |
29 class RawCode; | 30 class RawCode; |
30 class RawFunction; | 31 class RawFunction; |
31 class SampleFilter; | 32 class SampleFilter; |
33 class ProcessedSample; | |
32 class ProcessedSampleBuffer; | 34 class ProcessedSampleBuffer; |
33 | 35 |
36 class AllocationKeyValueTrait { | |
37 public: | |
38 typedef intptr_t Key; | |
Cutch
2017/03/16 20:38:16
what is the key?
bkonyi
2017/03/16 20:48:40
Size of the allocation. Will add comment/better na
bkonyi
2017/03/21 01:53:24
Removed.
| |
39 typedef intptr_t Value; | |
Cutch
2017/03/16 20:38:16
what is the value?
bkonyi
2017/03/16 20:48:40
The number of allocations of the size represented
bkonyi
2017/03/21 01:53:24
Removed.
| |
40 | |
41 struct Pair { | |
42 Key key; | |
43 Value value; | |
44 Pair() : key(), value(-1) {} | |
45 Pair(const Key key, const Value value) : key(key), value(value) {} | |
46 Pair(const Pair& other) : key(other.key), value(other.value) {} | |
47 }; | |
48 | |
49 static Key KeyOf(Pair kv) { return kv.key; } | |
50 static Value ValueOf(Pair kv) { return kv.value; } | |
51 static uintptr_t Hashcode(Key key) { return key; } | |
52 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; } | |
53 }; | |
54 | |
55 typedef DirectChainedHashMap<AllocationKeyValueTrait> AllocationHashMap; | |
56 | |
34 class ProfileFunctionSourcePosition { | 57 class ProfileFunctionSourcePosition { |
35 public: | 58 public: |
36 explicit ProfileFunctionSourcePosition(TokenPosition token_pos); | 59 explicit ProfileFunctionSourcePosition(TokenPosition token_pos); |
37 | 60 |
38 void Tick(bool exclusive); | 61 void Tick(bool exclusive); |
39 | 62 |
40 TokenPosition token_pos() const { return token_pos_; } | 63 TokenPosition token_pos() const { return token_pos_; } |
41 intptr_t exclusive_ticks() const { return exclusive_ticks_; } | 64 intptr_t exclusive_ticks() const { return exclusive_ticks_; } |
42 intptr_t inclusive_ticks() const { return inclusive_ticks_; } | 65 intptr_t inclusive_ticks() const { return inclusive_ticks_; } |
43 | 66 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 const Function* function() const { return &function_; } | 99 const Function* function() const { return &function_; } |
77 | 100 |
78 bool is_visible() const; | 101 bool is_visible() const; |
79 | 102 |
80 intptr_t table_index() const { return table_index_; } | 103 intptr_t table_index() const { return table_index_; } |
81 | 104 |
82 Kind kind() const { return kind_; } | 105 Kind kind() const { return kind_; } |
83 | 106 |
84 intptr_t exclusive_ticks() const { return exclusive_ticks_; } | 107 intptr_t exclusive_ticks() const { return exclusive_ticks_; } |
85 intptr_t inclusive_ticks() const { return inclusive_ticks_; } | 108 intptr_t inclusive_ticks() const { return inclusive_ticks_; } |
86 | |
87 void IncInclusiveTicks() { inclusive_ticks_++; } | 109 void IncInclusiveTicks() { inclusive_ticks_++; } |
88 | |
89 void Tick(bool exclusive, | 110 void Tick(bool exclusive, |
90 intptr_t inclusive_serial, | 111 intptr_t inclusive_serial, |
91 TokenPosition token_position); | 112 TokenPosition token_position, |
113 ProcessedSample* sample); | |
114 | |
115 bool contains_native_allocation() const { | |
116 return contains_native_allocation_; | |
117 } | |
92 | 118 |
93 static const char* KindToCString(Kind kind); | 119 static const char* KindToCString(Kind kind); |
94 | 120 |
95 void PrintToJSONArray(JSONArray* functions); | 121 void PrintToJSONArray(JSONArray* functions); |
96 | 122 |
97 // Returns true if the call was successful and |pfsp| is set. | 123 // Returns true if the call was successful and |pfsp| is set. |
98 bool GetSinglePosition(ProfileFunctionSourcePosition* pfsp); | 124 bool GetSinglePosition(ProfileFunctionSourcePosition* pfsp); |
99 | 125 |
100 void TickSourcePosition(TokenPosition token_position, bool exclusive); | 126 void TickSourcePosition(TokenPosition token_position, bool exclusive); |
101 | 127 |
(...skipping 10 matching lines...) Expand all Loading... | |
112 const char* name_; | 138 const char* name_; |
113 const Function& function_; | 139 const Function& function_; |
114 const intptr_t table_index_; | 140 const intptr_t table_index_; |
115 ZoneGrowableArray<intptr_t> profile_codes_; | 141 ZoneGrowableArray<intptr_t> profile_codes_; |
116 ZoneGrowableArray<ProfileFunctionSourcePosition> source_position_ticks_; | 142 ZoneGrowableArray<ProfileFunctionSourcePosition> source_position_ticks_; |
117 | 143 |
118 intptr_t exclusive_ticks_; | 144 intptr_t exclusive_ticks_; |
119 intptr_t inclusive_ticks_; | 145 intptr_t inclusive_ticks_; |
120 intptr_t inclusive_serial_; | 146 intptr_t inclusive_serial_; |
121 | 147 |
148 void AccumulateAllocation(intptr_t allocation_size, bool exclusive); | |
149 bool contains_native_allocation_; | |
150 AllocationHashMap exclusive_native_allocations_; | |
151 AllocationHashMap inclusive_native_allocations_; | |
152 | |
122 void PrintToJSONObject(JSONObject* func); | 153 void PrintToJSONObject(JSONObject* func); |
123 // A |ProfileCode| that contains this function. | 154 // A |ProfileCode| that contains this function. |
124 void AddProfileCode(intptr_t code_table_index); | 155 void AddProfileCode(intptr_t code_table_index); |
125 | 156 |
126 friend class ProfileCode; | 157 friend class ProfileCode; |
127 friend class ProfileBuilder; | 158 friend class ProfileBuilder; |
128 }; | 159 }; |
129 | 160 |
130 | 161 |
131 class ProfileCodeAddress { | 162 class ProfileCodeAddress { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 exclusive_ticks_ = exclusive_ticks; | 217 exclusive_ticks_ = exclusive_ticks; |
187 } | 218 } |
188 void IncExclusiveTicks() { exclusive_ticks_++; } | 219 void IncExclusiveTicks() { exclusive_ticks_++; } |
189 | 220 |
190 intptr_t inclusive_ticks() const { return inclusive_ticks_; } | 221 intptr_t inclusive_ticks() const { return inclusive_ticks_; } |
191 void set_inclusive_ticks(intptr_t inclusive_ticks) { | 222 void set_inclusive_ticks(intptr_t inclusive_ticks) { |
192 inclusive_ticks_ = inclusive_ticks; | 223 inclusive_ticks_ = inclusive_ticks; |
193 } | 224 } |
194 void IncInclusiveTicks() { inclusive_ticks_++; } | 225 void IncInclusiveTicks() { inclusive_ticks_++; } |
195 | 226 |
227 bool contains_native_allocation() const { | |
228 return contains_native_allocation_; | |
229 } | |
230 | |
196 bool IsOptimizedDart() const; | 231 bool IsOptimizedDart() const; |
197 RawCode* code() const { return code_.raw(); } | 232 RawCode* code() const { return code_.raw(); } |
198 | 233 |
199 const char* name() const { return name_; } | 234 const char* name() const { return name_; } |
200 void SetName(const char* name); | 235 void SetName(const char* name); |
201 void GenerateAndSetSymbolName(const char* prefix); | 236 void GenerateAndSetSymbolName(const char* prefix); |
202 | 237 |
203 static const char* KindToCString(Kind kind); | 238 static const char* KindToCString(Kind kind); |
204 | 239 |
205 void PrintToJSONArray(JSONArray* codes); | 240 void PrintToJSONArray(JSONArray* codes); |
206 | 241 |
207 private: | 242 private: |
208 void Tick(uword pc, bool exclusive, intptr_t serial); | 243 void Tick(uword pc, bool exclusive, intptr_t serial, ProcessedSample* sample); |
209 void TickAddress(uword pc, bool exclusive); | 244 void TickAddress(uword pc, bool exclusive); |
245 void AccumulateAllocation(intptr_t allocation_size, bool exclusive); | |
210 | 246 |
211 ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table); | 247 ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table); |
212 | 248 |
213 ProfileFunction* function() const { return function_; } | 249 ProfileFunction* function() const { return function_; } |
214 | 250 |
215 void PrintNativeCode(JSONObject* profile_code_obj); | 251 void PrintNativeCode(JSONObject* profile_code_obj); |
216 void PrintCollectedCode(JSONObject* profile_code_obj); | 252 void PrintCollectedCode(JSONObject* profile_code_obj); |
217 void PrintOverwrittenCode(JSONObject* profile_code_obj); | 253 void PrintOverwrittenCode(JSONObject* profile_code_obj); |
218 void PrintTagCode(JSONObject* profile_code_obj); | 254 void PrintTagCode(JSONObject* profile_code_obj); |
219 | 255 |
220 void set_code_table_index(intptr_t index) { code_table_index_ = index; } | 256 void set_code_table_index(intptr_t index) { code_table_index_ = index; } |
221 intptr_t code_table_index() const { return code_table_index_; } | 257 intptr_t code_table_index() const { return code_table_index_; } |
222 | 258 |
223 const Kind kind_; | 259 const Kind kind_; |
224 uword start_; | 260 uword start_; |
225 uword end_; | 261 uword end_; |
226 intptr_t exclusive_ticks_; | 262 intptr_t exclusive_ticks_; |
227 intptr_t inclusive_ticks_; | 263 intptr_t inclusive_ticks_; |
228 intptr_t inclusive_serial_; | 264 intptr_t inclusive_serial_; |
229 | 265 |
266 AllocationHashMap exclusive_native_allocations_; | |
267 AllocationHashMap inclusive_native_allocations_; | |
268 bool contains_native_allocation_; | |
269 | |
230 const Code& code_; | 270 const Code& code_; |
231 char* name_; | 271 char* name_; |
232 int64_t compile_timestamp_; | 272 int64_t compile_timestamp_; |
233 ProfileFunction* function_; | 273 ProfileFunction* function_; |
234 intptr_t code_table_index_; | 274 intptr_t code_table_index_; |
235 ZoneGrowableArray<ProfileCodeAddress> address_ticks_; | 275 ZoneGrowableArray<ProfileCodeAddress> address_ticks_; |
236 | 276 |
237 friend class ProfileBuilder; | 277 friend class ProfileBuilder; |
238 }; | 278 }; |
239 | 279 |
(...skipping 11 matching lines...) Expand all Loading... | |
251 virtual ~ProfileTrieNode(); | 291 virtual ~ProfileTrieNode(); |
252 | 292 |
253 virtual void PrintToJSONArray(JSONArray* array) const = 0; | 293 virtual void PrintToJSONArray(JSONArray* array) const = 0; |
254 | 294 |
255 // Index into function or code tables. | 295 // Index into function or code tables. |
256 intptr_t table_index() const { return table_index_; } | 296 intptr_t table_index() const { return table_index_; } |
257 | 297 |
258 intptr_t count() const { return count_; } | 298 intptr_t count() const { return count_; } |
259 | 299 |
260 void Tick() { count_++; } | 300 void Tick() { count_++; } |
301 void IncrementAllocation(intptr_t allocation, bool exclusive) { | |
302 ASSERT(allocation >= 0); | |
303 if (exclusive) { | |
304 exclusive_allocations_ += allocation; | |
305 } | |
306 inclusive_allocations_ += allocation; | |
307 } | |
261 | 308 |
262 intptr_t NumChildren() const { return children_.length(); } | 309 intptr_t NumChildren() const { return children_.length(); } |
263 | 310 |
264 ProfileTrieNode* At(intptr_t i) { return children_.At(i); } | 311 ProfileTrieNode* At(intptr_t i) { return children_.At(i); } |
265 | 312 |
266 intptr_t IndexOf(ProfileTrieNode* node); | 313 intptr_t IndexOf(ProfileTrieNode* node); |
267 | 314 |
268 intptr_t frame_id() const { return frame_id_; } | 315 intptr_t frame_id() const { return frame_id_; } |
269 void set_frame_id(intptr_t id) { | 316 void set_frame_id(intptr_t id) { |
270 ASSERT(frame_id_ == -1); | 317 ASSERT(frame_id_ == -1); |
271 frame_id_ = id; | 318 frame_id_ = id; |
272 } | 319 } |
273 | 320 |
274 protected: | 321 protected: |
275 void SortChildren(); | 322 void SortChildren(); |
276 | 323 |
277 static int ProfileTrieNodeCompare(ProfileTrieNode* const* a, | 324 static int ProfileTrieNodeCompare(ProfileTrieNode* const* a, |
278 ProfileTrieNode* const* b) { | 325 ProfileTrieNode* const* b) { |
279 ASSERT(a != NULL); | 326 ASSERT(a != NULL); |
280 ASSERT(b != NULL); | 327 ASSERT(b != NULL); |
281 return (*b)->count() - (*a)->count(); | 328 return (*b)->count() - (*a)->count(); |
282 } | 329 } |
283 | 330 |
284 | 331 |
285 intptr_t table_index_; | 332 intptr_t table_index_; |
286 intptr_t count_; | 333 intptr_t count_; |
334 intptr_t exclusive_allocations_; | |
335 intptr_t inclusive_allocations_; | |
287 ZoneGrowableArray<ProfileTrieNode*> children_; | 336 ZoneGrowableArray<ProfileTrieNode*> children_; |
288 intptr_t frame_id_; | 337 intptr_t frame_id_; |
289 | 338 |
290 friend class ProfileBuilder; | 339 friend class ProfileBuilder; |
291 }; | 340 }; |
292 | 341 |
293 | 342 |
294 // The model for a profile. Most of the model is zone allocated, therefore | 343 // The model for a profile. Most of the model is zone allocated, therefore |
295 // a zone must be created that lives longer than this object. | 344 // a zone must be created that lives longer than this object. |
296 class Profile : public ValueObject { | 345 class Profile : public ValueObject { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
436 JSONStream* stream, | 485 JSONStream* stream, |
437 Profile::TagOrder tag_order, | 486 Profile::TagOrder tag_order, |
438 intptr_t extra_tags, | 487 intptr_t extra_tags, |
439 SampleFilter* filter, | 488 SampleFilter* filter, |
440 bool as_timline); | 489 bool as_timline); |
441 }; | 490 }; |
442 | 491 |
443 } // namespace dart | 492 } // namespace dart |
444 | 493 |
445 #endif // RUNTIME_VM_PROFILER_SERVICE_H_ | 494 #endif // RUNTIME_VM_PROFILER_SERVICE_H_ |
OLD | NEW |