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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 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 | « runtime/vm/profiler_service.h ('k') | runtime/vm/profiler_test.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 #include "vm/profiler_service.h" 5 #include "vm/profiler_service.h"
6 6
7 #include "vm/growable_array.h" 7 #include "vm/growable_array.h"
8 #include "vm/hash_map.h" 8 #include "vm/hash_map.h"
9 #include "vm/log.h" 9 #include "vm/log.h"
10 #include "vm/malloc_hooks.h" 10 #include "vm/malloc_hooks.h"
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 } 84 }
85 return size; 85 return size;
86 } 86 }
87 87
88 // Array holding code that is being kept around only for the profiler. 88 // Array holding code that is being kept around only for the profiler.
89 const GrowableObjectArray& previous_; 89 const GrowableObjectArray& previous_;
90 // Array holding code that should continue to be kept around for the profiler. 90 // Array holding code that should continue to be kept around for the profiler.
91 const GrowableObjectArray& current_; 91 const GrowableObjectArray& current_;
92 }; 92 };
93 93
94
95 ProfileFunctionSourcePosition::ProfileFunctionSourcePosition( 94 ProfileFunctionSourcePosition::ProfileFunctionSourcePosition(
96 TokenPosition token_pos) 95 TokenPosition token_pos)
97 : token_pos_(token_pos), exclusive_ticks_(0), inclusive_ticks_(0) {} 96 : token_pos_(token_pos), exclusive_ticks_(0), inclusive_ticks_(0) {}
98 97
99
100 void ProfileFunctionSourcePosition::Tick(bool exclusive) { 98 void ProfileFunctionSourcePosition::Tick(bool exclusive) {
101 if (exclusive) { 99 if (exclusive) {
102 exclusive_ticks_++; 100 exclusive_ticks_++;
103 } else { 101 } else {
104 inclusive_ticks_++; 102 inclusive_ticks_++;
105 } 103 }
106 } 104 }
107 105
108
109 ProfileFunction::ProfileFunction(Kind kind, 106 ProfileFunction::ProfileFunction(Kind kind,
110 const char* name, 107 const char* name,
111 const Function& function, 108 const Function& function,
112 const intptr_t table_index) 109 const intptr_t table_index)
113 : kind_(kind), 110 : kind_(kind),
114 name_(name), 111 name_(name),
115 function_(Function::ZoneHandle(function.raw())), 112 function_(Function::ZoneHandle(function.raw())),
116 table_index_(table_index), 113 table_index_(table_index),
117 profile_codes_(0), 114 profile_codes_(0),
118 source_position_ticks_(0), 115 source_position_ticks_(0),
119 exclusive_ticks_(0), 116 exclusive_ticks_(0),
120 inclusive_ticks_(0), 117 inclusive_ticks_(0),
121 inclusive_serial_(-1) { 118 inclusive_serial_(-1) {
122 ASSERT((kind_ != kDartFunction) || !function_.IsNull()); 119 ASSERT((kind_ != kDartFunction) || !function_.IsNull());
123 ASSERT((kind_ != kDartFunction) || (table_index_ >= 0)); 120 ASSERT((kind_ != kDartFunction) || (table_index_ >= 0));
124 ASSERT(profile_codes_.length() == 0); 121 ASSERT(profile_codes_.length() == 0);
125 } 122 }
126 123
127
128 const char* ProfileFunction::Name() const { 124 const char* ProfileFunction::Name() const {
129 if (name_ != NULL) { 125 if (name_ != NULL) {
130 return name_; 126 return name_;
131 } 127 }
132 ASSERT(!function_.IsNull()); 128 ASSERT(!function_.IsNull());
133 const String& func_name = 129 const String& func_name =
134 String::Handle(function_.QualifiedUserVisibleName()); 130 String::Handle(function_.QualifiedUserVisibleName());
135 return func_name.ToCString(); 131 return func_name.ToCString();
136 } 132 }
137 133
138
139 bool ProfileFunction::is_visible() const { 134 bool ProfileFunction::is_visible() const {
140 if (function_.IsNull()) { 135 if (function_.IsNull()) {
141 // Some synthetic function. 136 // Some synthetic function.
142 return true; 137 return true;
143 } 138 }
144 return FLAG_show_invisible_frames || function_.is_visible(); 139 return FLAG_show_invisible_frames || function_.is_visible();
145 } 140 }
146 141
147
148 void ProfileFunction::Tick(bool exclusive, 142 void ProfileFunction::Tick(bool exclusive,
149 intptr_t inclusive_serial, 143 intptr_t inclusive_serial,
150 TokenPosition token_position) { 144 TokenPosition token_position) {
151 if (exclusive) { 145 if (exclusive) {
152 exclusive_ticks_++; 146 exclusive_ticks_++;
153 TickSourcePosition(token_position, exclusive); 147 TickSourcePosition(token_position, exclusive);
154 } 148 }
155 // Fall through and tick inclusive count too. 149 // Fall through and tick inclusive count too.
156 if (inclusive_serial_ == inclusive_serial) { 150 if (inclusive_serial_ == inclusive_serial) {
157 // Already ticked. 151 // Already ticked.
158 return; 152 return;
159 } 153 }
160 inclusive_serial_ = inclusive_serial; 154 inclusive_serial_ = inclusive_serial;
161 inclusive_ticks_++; 155 inclusive_ticks_++;
162 TickSourcePosition(token_position, false); 156 TickSourcePosition(token_position, false);
163 } 157 }
164 158
165
166 void ProfileFunction::TickSourcePosition(TokenPosition token_position, 159 void ProfileFunction::TickSourcePosition(TokenPosition token_position,
167 bool exclusive) { 160 bool exclusive) {
168 intptr_t i = 0; 161 intptr_t i = 0;
169 for (; i < source_position_ticks_.length(); i++) { 162 for (; i < source_position_ticks_.length(); i++) {
170 ProfileFunctionSourcePosition& position = source_position_ticks_[i]; 163 ProfileFunctionSourcePosition& position = source_position_ticks_[i];
171 if (position.token_pos().value() == token_position.value()) { 164 if (position.token_pos().value() == token_position.value()) {
172 if (FLAG_trace_profiler_verbose) { 165 if (FLAG_trace_profiler_verbose) {
173 OS::Print("Ticking source position %s %s\n", 166 OS::Print("Ticking source position %s %s\n",
174 exclusive ? "exclusive" : "inclusive", 167 exclusive ? "exclusive" : "inclusive",
175 token_position.ToCString()); 168 token_position.ToCString());
(...skipping 16 matching lines...) Expand all
192 } 185 }
193 pfsp.Tick(exclusive); 186 pfsp.Tick(exclusive);
194 187
195 if (i < source_position_ticks_.length()) { 188 if (i < source_position_ticks_.length()) {
196 source_position_ticks_.InsertAt(i, pfsp); 189 source_position_ticks_.InsertAt(i, pfsp);
197 } else { 190 } else {
198 source_position_ticks_.Add(pfsp); 191 source_position_ticks_.Add(pfsp);
199 } 192 }
200 } 193 }
201 194
202
203 const char* ProfileFunction::KindToCString(Kind kind) { 195 const char* ProfileFunction::KindToCString(Kind kind) {
204 switch (kind) { 196 switch (kind) {
205 case kDartFunction: 197 case kDartFunction:
206 return "Dart"; 198 return "Dart";
207 case kNativeFunction: 199 case kNativeFunction:
208 return "Native"; 200 return "Native";
209 case kTagFunction: 201 case kTagFunction:
210 return "Tag"; 202 return "Tag";
211 case kStubFunction: 203 case kStubFunction:
212 return "Stub"; 204 return "Stub";
213 case kUnknownFunction: 205 case kUnknownFunction:
214 return "Collected"; 206 return "Collected";
215 default: 207 default:
216 UNIMPLEMENTED(); 208 UNIMPLEMENTED();
217 return ""; 209 return "";
218 } 210 }
219 } 211 }
220 212
221
222 void ProfileFunction::PrintToJSONObject(JSONObject* func) { 213 void ProfileFunction::PrintToJSONObject(JSONObject* func) {
223 func->AddProperty("type", "@Function"); 214 func->AddProperty("type", "@Function");
224 func->AddProperty("name", name()); 215 func->AddProperty("name", name());
225 func->AddProperty("_kind", KindToCString(kind())); 216 func->AddProperty("_kind", KindToCString(kind()));
226 } 217 }
227 218
228
229 void ProfileFunction::PrintToJSONArray(JSONArray* functions) { 219 void ProfileFunction::PrintToJSONArray(JSONArray* functions) {
230 JSONObject obj(functions); 220 JSONObject obj(functions);
231 obj.AddProperty("kind", KindToCString(kind())); 221 obj.AddProperty("kind", KindToCString(kind()));
232 obj.AddProperty("inclusiveTicks", inclusive_ticks()); 222 obj.AddProperty("inclusiveTicks", inclusive_ticks());
233 obj.AddProperty("exclusiveTicks", exclusive_ticks()); 223 obj.AddProperty("exclusiveTicks", exclusive_ticks());
234 if (kind() == kDartFunction) { 224 if (kind() == kDartFunction) {
235 ASSERT(!function_.IsNull()); 225 ASSERT(!function_.IsNull());
236 obj.AddProperty("function", function_); 226 obj.AddProperty("function", function_);
237 } else { 227 } else {
238 JSONObject func(&obj, "function"); 228 JSONObject func(&obj, "function");
239 PrintToJSONObject(&func); 229 PrintToJSONObject(&func);
240 } 230 }
241 { 231 {
242 JSONArray codes(&obj, "codes"); 232 JSONArray codes(&obj, "codes");
243 for (intptr_t i = 0; i < profile_codes_.length(); i++) { 233 for (intptr_t i = 0; i < profile_codes_.length(); i++) {
244 intptr_t code_index = profile_codes_[i]; 234 intptr_t code_index = profile_codes_[i];
245 codes.AddValue(code_index); 235 codes.AddValue(code_index);
246 } 236 }
247 } 237 }
248 } 238 }
249 239
250
251 void ProfileFunction::AddProfileCode(intptr_t code_table_index) { 240 void ProfileFunction::AddProfileCode(intptr_t code_table_index) {
252 for (intptr_t i = 0; i < profile_codes_.length(); i++) { 241 for (intptr_t i = 0; i < profile_codes_.length(); i++) {
253 if (profile_codes_[i] == code_table_index) { 242 if (profile_codes_[i] == code_table_index) {
254 return; 243 return;
255 } 244 }
256 } 245 }
257 profile_codes_.Add(code_table_index); 246 profile_codes_.Add(code_table_index);
258 } 247 }
259 248
260
261 bool ProfileFunction::GetSinglePosition(ProfileFunctionSourcePosition* pfsp) { 249 bool ProfileFunction::GetSinglePosition(ProfileFunctionSourcePosition* pfsp) {
262 if (pfsp == NULL) { 250 if (pfsp == NULL) {
263 return false; 251 return false;
264 } 252 }
265 if (source_position_ticks_.length() != 1) { 253 if (source_position_ticks_.length() != 1) {
266 return false; 254 return false;
267 } 255 }
268 *pfsp = source_position_ticks_[0]; 256 *pfsp = source_position_ticks_[0];
269 return true; 257 return true;
270 } 258 }
271 259
272
273 ProfileCodeAddress::ProfileCodeAddress(uword pc) 260 ProfileCodeAddress::ProfileCodeAddress(uword pc)
274 : pc_(pc), exclusive_ticks_(0), inclusive_ticks_(0) {} 261 : pc_(pc), exclusive_ticks_(0), inclusive_ticks_(0) {}
275 262
276
277 void ProfileCodeAddress::Tick(bool exclusive) { 263 void ProfileCodeAddress::Tick(bool exclusive) {
278 if (exclusive) { 264 if (exclusive) {
279 exclusive_ticks_++; 265 exclusive_ticks_++;
280 } else { 266 } else {
281 inclusive_ticks_++; 267 inclusive_ticks_++;
282 } 268 }
283 } 269 }
284 270
285
286 ProfileCode::ProfileCode(Kind kind, 271 ProfileCode::ProfileCode(Kind kind,
287 uword start, 272 uword start,
288 uword end, 273 uword end,
289 int64_t timestamp, 274 int64_t timestamp,
290 const Code& code) 275 const Code& code)
291 : kind_(kind), 276 : kind_(kind),
292 start_(start), 277 start_(start),
293 end_(end), 278 end_(end),
294 exclusive_ticks_(0), 279 exclusive_ticks_(0),
295 inclusive_ticks_(0), 280 inclusive_ticks_(0),
296 inclusive_serial_(-1), 281 inclusive_serial_(-1),
297 code_(code), 282 code_(code),
298 name_(NULL), 283 name_(NULL),
299 compile_timestamp_(0), 284 compile_timestamp_(0),
300 function_(NULL), 285 function_(NULL),
301 code_table_index_(-1), 286 code_table_index_(-1),
302 address_ticks_(0) {} 287 address_ticks_(0) {}
303 288
304
305 void ProfileCode::TruncateLower(uword start) { 289 void ProfileCode::TruncateLower(uword start) {
306 if (start > start_) { 290 if (start > start_) {
307 start_ = start; 291 start_ = start;
308 } 292 }
309 ASSERT(start_ < end_); 293 ASSERT(start_ < end_);
310 } 294 }
311 295
312
313 void ProfileCode::TruncateUpper(uword end) { 296 void ProfileCode::TruncateUpper(uword end) {
314 if (end < end_) { 297 if (end < end_) {
315 end_ = end; 298 end_ = end;
316 } 299 }
317 ASSERT(start_ < end_); 300 ASSERT(start_ < end_);
318 } 301 }
319 302
320
321 void ProfileCode::ExpandLower(uword start) { 303 void ProfileCode::ExpandLower(uword start) {
322 if (start < start_) { 304 if (start < start_) {
323 start_ = start; 305 start_ = start;
324 } 306 }
325 ASSERT(start_ < end_); 307 ASSERT(start_ < end_);
326 } 308 }
327 309
328
329 void ProfileCode::ExpandUpper(uword end) { 310 void ProfileCode::ExpandUpper(uword end) {
330 if (end > end_) { 311 if (end > end_) {
331 end_ = end; 312 end_ = end;
332 } 313 }
333 ASSERT(start_ < end_); 314 ASSERT(start_ < end_);
334 } 315 }
335 316
336
337 bool ProfileCode::Overlaps(const ProfileCode* other) const { 317 bool ProfileCode::Overlaps(const ProfileCode* other) const {
338 ASSERT(other != NULL); 318 ASSERT(other != NULL);
339 return other->Contains(start_) || other->Contains(end_ - 1) || 319 return other->Contains(start_) || other->Contains(end_ - 1) ||
340 Contains(other->start()) || Contains(other->end() - 1); 320 Contains(other->start()) || Contains(other->end() - 1);
341 } 321 }
342 322
343
344 bool ProfileCode::IsOptimizedDart() const { 323 bool ProfileCode::IsOptimizedDart() const {
345 return !code_.IsNull() && code_.is_optimized(); 324 return !code_.IsNull() && code_.is_optimized();
346 } 325 }
347 326
348
349 void ProfileCode::SetName(const char* name) { 327 void ProfileCode::SetName(const char* name) {
350 if (name == NULL) { 328 if (name == NULL) {
351 name_ = NULL; 329 name_ = NULL;
352 } 330 }
353 intptr_t len = strlen(name); 331 intptr_t len = strlen(name);
354 name_ = Thread::Current()->zone()->Alloc<char>(len + 1); 332 name_ = Thread::Current()->zone()->Alloc<char>(len + 1);
355 strncpy(name_, name, len); 333 strncpy(name_, name, len);
356 name_[len] = '\0'; 334 name_[len] = '\0';
357 } 335 }
358 336
359
360 void ProfileCode::GenerateAndSetSymbolName(const char* prefix) { 337 void ProfileCode::GenerateAndSetSymbolName(const char* prefix) {
361 const intptr_t kBuffSize = 512; 338 const intptr_t kBuffSize = 512;
362 char buff[kBuffSize]; 339 char buff[kBuffSize];
363 OS::SNPrint(&buff[0], kBuffSize - 1, "%s [%" Px ", %" Px ")", prefix, start(), 340 OS::SNPrint(&buff[0], kBuffSize - 1, "%s [%" Px ", %" Px ")", prefix, start(),
364 end()); 341 end());
365 SetName(buff); 342 SetName(buff);
366 } 343 }
367 344
368
369 void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) { 345 void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) {
370 // If exclusive is set, tick it. 346 // If exclusive is set, tick it.
371 if (exclusive) { 347 if (exclusive) {
372 exclusive_ticks_++; 348 exclusive_ticks_++;
373 TickAddress(pc, true); 349 TickAddress(pc, true);
374 } 350 }
375 // Fall through and tick inclusive count too. 351 // Fall through and tick inclusive count too.
376 if (inclusive_serial_ == serial) { 352 if (inclusive_serial_ == serial) {
377 // Already gave inclusive tick for this sample. 353 // Already gave inclusive tick for this sample.
378 return; 354 return;
379 } 355 }
380 inclusive_serial_ = serial; 356 inclusive_serial_ = serial;
381 inclusive_ticks_++; 357 inclusive_ticks_++;
382 TickAddress(pc, false); 358 TickAddress(pc, false);
383 } 359 }
384 360
385
386 void ProfileCode::TickAddress(uword pc, bool exclusive) { 361 void ProfileCode::TickAddress(uword pc, bool exclusive) {
387 const intptr_t length = address_ticks_.length(); 362 const intptr_t length = address_ticks_.length();
388 363
389 intptr_t i = 0; 364 intptr_t i = 0;
390 for (; i < length; i++) { 365 for (; i < length; i++) {
391 ProfileCodeAddress& entry = address_ticks_[i]; 366 ProfileCodeAddress& entry = address_ticks_[i];
392 if (entry.pc() == pc) { 367 if (entry.pc() == pc) {
393 // Tick the address entry. 368 // Tick the address entry.
394 entry.Tick(exclusive); 369 entry.Tick(exclusive);
395 return; 370 return;
(...skipping 10 matching lines...) Expand all
406 381
407 if (i < length) { 382 if (i < length) {
408 // Insert at i. 383 // Insert at i.
409 address_ticks_.InsertAt(i, entry); 384 address_ticks_.InsertAt(i, entry);
410 } else { 385 } else {
411 // Add to end. 386 // Add to end.
412 address_ticks_.Add(entry); 387 address_ticks_.Add(entry);
413 } 388 }
414 } 389 }
415 390
416
417 void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) { 391 void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) {
418 ASSERT(kind() == kNativeCode); 392 ASSERT(kind() == kNativeCode);
419 JSONObject obj(profile_code_obj, "code"); 393 JSONObject obj(profile_code_obj, "code");
420 obj.AddProperty("type", "@Code"); 394 obj.AddProperty("type", "@Code");
421 obj.AddProperty("kind", "Native"); 395 obj.AddProperty("kind", "Native");
422 obj.AddProperty("name", name()); 396 obj.AddProperty("name", name());
423 obj.AddProperty("_optimized", false); 397 obj.AddProperty("_optimized", false);
424 obj.AddPropertyF("start", "%" Px "", start()); 398 obj.AddPropertyF("start", "%" Px "", start());
425 obj.AddPropertyF("end", "%" Px "", end()); 399 obj.AddPropertyF("end", "%" Px "", end());
426 { 400 {
427 // Generate a fake function entry. 401 // Generate a fake function entry.
428 JSONObject func(&obj, "function"); 402 JSONObject func(&obj, "function");
429 ASSERT(function_ != NULL); 403 ASSERT(function_ != NULL);
430 function_->PrintToJSONObject(&func); 404 function_->PrintToJSONObject(&func);
431 } 405 }
432 } 406 }
433 407
434
435 void ProfileCode::PrintCollectedCode(JSONObject* profile_code_obj) { 408 void ProfileCode::PrintCollectedCode(JSONObject* profile_code_obj) {
436 ASSERT(kind() == kCollectedCode); 409 ASSERT(kind() == kCollectedCode);
437 JSONObject obj(profile_code_obj, "code"); 410 JSONObject obj(profile_code_obj, "code");
438 obj.AddProperty("type", "@Code"); 411 obj.AddProperty("type", "@Code");
439 obj.AddProperty("kind", "Collected"); 412 obj.AddProperty("kind", "Collected");
440 obj.AddProperty("name", name()); 413 obj.AddProperty("name", name());
441 obj.AddProperty("_optimized", false); 414 obj.AddProperty("_optimized", false);
442 obj.AddPropertyF("start", "%" Px "", start()); 415 obj.AddPropertyF("start", "%" Px "", start());
443 obj.AddPropertyF("end", "%" Px "", end()); 416 obj.AddPropertyF("end", "%" Px "", end());
444 { 417 {
445 // Generate a fake function entry. 418 // Generate a fake function entry.
446 JSONObject func(&obj, "function"); 419 JSONObject func(&obj, "function");
447 ASSERT(function_ != NULL); 420 ASSERT(function_ != NULL);
448 function_->PrintToJSONObject(&func); 421 function_->PrintToJSONObject(&func);
449 } 422 }
450 } 423 }
451 424
452
453 void ProfileCode::PrintOverwrittenCode(JSONObject* profile_code_obj) { 425 void ProfileCode::PrintOverwrittenCode(JSONObject* profile_code_obj) {
454 ASSERT(kind() == kReusedCode); 426 ASSERT(kind() == kReusedCode);
455 JSONObject obj(profile_code_obj, "code"); 427 JSONObject obj(profile_code_obj, "code");
456 obj.AddProperty("type", "@Code"); 428 obj.AddProperty("type", "@Code");
457 obj.AddProperty("kind", "Collected"); 429 obj.AddProperty("kind", "Collected");
458 obj.AddProperty("name", name()); 430 obj.AddProperty("name", name());
459 obj.AddProperty("_optimized", false); 431 obj.AddProperty("_optimized", false);
460 obj.AddPropertyF("start", "%" Px "", start()); 432 obj.AddPropertyF("start", "%" Px "", start());
461 obj.AddPropertyF("end", "%" Px "", end()); 433 obj.AddPropertyF("end", "%" Px "", end());
462 { 434 {
463 // Generate a fake function entry. 435 // Generate a fake function entry.
464 JSONObject func(&obj, "function"); 436 JSONObject func(&obj, "function");
465 ASSERT(function_ != NULL); 437 ASSERT(function_ != NULL);
466 function_->PrintToJSONObject(&func); 438 function_->PrintToJSONObject(&func);
467 } 439 }
468 } 440 }
469 441
470
471 void ProfileCode::PrintTagCode(JSONObject* profile_code_obj) { 442 void ProfileCode::PrintTagCode(JSONObject* profile_code_obj) {
472 ASSERT(kind() == kTagCode); 443 ASSERT(kind() == kTagCode);
473 JSONObject obj(profile_code_obj, "code"); 444 JSONObject obj(profile_code_obj, "code");
474 obj.AddProperty("type", "@Code"); 445 obj.AddProperty("type", "@Code");
475 obj.AddProperty("kind", "Tag"); 446 obj.AddProperty("kind", "Tag");
476 obj.AddProperty("name", name()); 447 obj.AddProperty("name", name());
477 obj.AddPropertyF("start", "%" Px "", start()); 448 obj.AddPropertyF("start", "%" Px "", start());
478 obj.AddPropertyF("end", "%" Px "", end()); 449 obj.AddPropertyF("end", "%" Px "", end());
479 obj.AddProperty("_optimized", false); 450 obj.AddProperty("_optimized", false);
480 { 451 {
481 // Generate a fake function entry. 452 // Generate a fake function entry.
482 JSONObject func(&obj, "function"); 453 JSONObject func(&obj, "function");
483 ASSERT(function_ != NULL); 454 ASSERT(function_ != NULL);
484 function_->PrintToJSONObject(&func); 455 function_->PrintToJSONObject(&func);
485 } 456 }
486 } 457 }
487 458
488
489 const char* ProfileCode::KindToCString(Kind kind) { 459 const char* ProfileCode::KindToCString(Kind kind) {
490 switch (kind) { 460 switch (kind) {
491 case kDartCode: 461 case kDartCode:
492 return "Dart"; 462 return "Dart";
493 case kCollectedCode: 463 case kCollectedCode:
494 return "Collected"; 464 return "Collected";
495 case kNativeCode: 465 case kNativeCode:
496 return "Native"; 466 return "Native";
497 case kReusedCode: 467 case kReusedCode:
498 return "Overwritten"; 468 return "Overwritten";
499 case kTagCode: 469 case kTagCode:
500 return "Tag"; 470 return "Tag";
501 } 471 }
502 UNREACHABLE(); 472 UNREACHABLE();
503 return NULL; 473 return NULL;
504 } 474 }
505 475
506
507 void ProfileCode::PrintToJSONArray(JSONArray* codes) { 476 void ProfileCode::PrintToJSONArray(JSONArray* codes) {
508 JSONObject obj(codes); 477 JSONObject obj(codes);
509 obj.AddProperty("kind", ProfileCode::KindToCString(kind())); 478 obj.AddProperty("kind", ProfileCode::KindToCString(kind()));
510 obj.AddProperty("inclusiveTicks", inclusive_ticks()); 479 obj.AddProperty("inclusiveTicks", inclusive_ticks());
511 obj.AddProperty("exclusiveTicks", exclusive_ticks()); 480 obj.AddProperty("exclusiveTicks", exclusive_ticks());
512 if (kind() == kDartCode) { 481 if (kind() == kDartCode) {
513 ASSERT(!code_.IsNull()); 482 ASSERT(!code_.IsNull());
514 obj.AddProperty("code", code_); 483 obj.AddProperty("code", code_);
515 } else if (kind() == kCollectedCode) { 484 } else if (kind() == kCollectedCode) {
516 PrintCollectedCode(&obj); 485 PrintCollectedCode(&obj);
517 } else if (kind() == kReusedCode) { 486 } else if (kind() == kReusedCode) {
518 PrintOverwrittenCode(&obj); 487 PrintOverwrittenCode(&obj);
519 } else if (kind() == kTagCode) { 488 } else if (kind() == kTagCode) {
520 PrintTagCode(&obj); 489 PrintTagCode(&obj);
521 } else { 490 } else {
522 ASSERT(kind() == kNativeCode); 491 ASSERT(kind() == kNativeCode);
523 PrintNativeCode(&obj); 492 PrintNativeCode(&obj);
524 } 493 }
525 { 494 {
526 JSONArray ticks(&obj, "ticks"); 495 JSONArray ticks(&obj, "ticks");
527 for (intptr_t i = 0; i < address_ticks_.length(); i++) { 496 for (intptr_t i = 0; i < address_ticks_.length(); i++) {
528 const ProfileCodeAddress& entry = address_ticks_[i]; 497 const ProfileCodeAddress& entry = address_ticks_[i];
529 ticks.AddValueF("%" Px "", entry.pc()); 498 ticks.AddValueF("%" Px "", entry.pc());
530 ticks.AddValue(entry.exclusive_ticks()); 499 ticks.AddValue(entry.exclusive_ticks());
531 ticks.AddValue(entry.inclusive_ticks()); 500 ticks.AddValue(entry.inclusive_ticks());
532 } 501 }
533 } 502 }
534 } 503 }
535 504
536
537 class ProfileFunctionTable : public ZoneAllocated { 505 class ProfileFunctionTable : public ZoneAllocated {
538 public: 506 public:
539 ProfileFunctionTable() 507 ProfileFunctionTable()
540 : null_function_(Function::ZoneHandle()), 508 : null_function_(Function::ZoneHandle()),
541 unknown_function_(NULL), 509 unknown_function_(NULL),
542 table_(8) { 510 table_(8) {
543 unknown_function_ = 511 unknown_function_ =
544 Add(ProfileFunction::kUnknownFunction, "<unknown Dart function>"); 512 Add(ProfileFunction::kUnknownFunction, "<unknown Dart function>");
545 } 513 }
546 514
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 return kv->function()->raw() == key->raw(); 592 return kv->function()->raw() == key->raw();
625 } 593 }
626 }; 594 };
627 595
628 const Function& null_function_; 596 const Function& null_function_;
629 ProfileFunction* unknown_function_; 597 ProfileFunction* unknown_function_;
630 ZoneGrowableArray<ProfileFunction*> table_; 598 ZoneGrowableArray<ProfileFunction*> table_;
631 DirectChainedHashMap<ProfileFunctionTableTrait> function_hash_; 599 DirectChainedHashMap<ProfileFunctionTableTrait> function_hash_;
632 }; 600 };
633 601
634
635 ProfileFunction* ProfileCode::SetFunctionAndName(ProfileFunctionTable* table) { 602 ProfileFunction* ProfileCode::SetFunctionAndName(ProfileFunctionTable* table) {
636 ASSERT(function_ == NULL); 603 ASSERT(function_ == NULL);
637 604
638 ProfileFunction* function = NULL; 605 ProfileFunction* function = NULL;
639 if ((kind() == kReusedCode) || (kind() == kCollectedCode)) { 606 if ((kind() == kReusedCode) || (kind() == kCollectedCode)) {
640 if (name() == NULL) { 607 if (name() == NULL) {
641 // Lazily set generated name. 608 // Lazily set generated name.
642 GenerateAndSetSymbolName("[Collected]"); 609 GenerateAndSetSymbolName("[Collected]");
643 } 610 }
644 // Map these to a canonical unknown function. 611 // Map these to a canonical unknown function.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 UNREACHABLE(); 675 UNREACHABLE();
709 } 676 }
710 ASSERT(function != NULL); 677 ASSERT(function != NULL);
711 678
712 function->AddProfileCode(code_table_index()); 679 function->AddProfileCode(code_table_index());
713 680
714 function_ = function; 681 function_ = function;
715 return function_; 682 return function_;
716 } 683 }
717 684
718
719 intptr_t ProfileCodeTable::FindCodeIndexForPC(uword pc) const { 685 intptr_t ProfileCodeTable::FindCodeIndexForPC(uword pc) const {
720 intptr_t length = table_.length(); 686 intptr_t length = table_.length();
721 if (length == 0) { 687 if (length == 0) {
722 return -1; // Not found. 688 return -1; // Not found.
723 } 689 }
724 intptr_t lo = 0; 690 intptr_t lo = 0;
725 intptr_t hi = length - 1; 691 intptr_t hi = length - 1;
726 while (lo <= hi) { 692 while (lo <= hi) {
727 intptr_t mid = (hi - lo + 1) / 2 + lo; 693 intptr_t mid = (hi - lo + 1) / 2 + lo;
728 ASSERT(mid >= lo); 694 ASSERT(mid >= lo);
729 ASSERT(mid <= hi); 695 ASSERT(mid <= hi);
730 ProfileCode* code = At(mid); 696 ProfileCode* code = At(mid);
731 if (code->Contains(pc)) { 697 if (code->Contains(pc)) {
732 return mid; 698 return mid;
733 } else if (pc < code->start()) { 699 } else if (pc < code->start()) {
734 hi = mid - 1; 700 hi = mid - 1;
735 } else { 701 } else {
736 lo = mid + 1; 702 lo = mid + 1;
737 } 703 }
738 } 704 }
739 return -1; 705 return -1;
740 } 706 }
741 707
742
743 intptr_t ProfileCodeTable::InsertCode(ProfileCode* new_code) { 708 intptr_t ProfileCodeTable::InsertCode(ProfileCode* new_code) {
744 const intptr_t length = table_.length(); 709 const intptr_t length = table_.length();
745 if (length == 0) { 710 if (length == 0) {
746 table_.Add(new_code); 711 table_.Add(new_code);
747 return length; 712 return length;
748 } 713 }
749 714
750 // Determine the correct place to insert or merge |new_code| into table. 715 // Determine the correct place to insert or merge |new_code| into table.
751 intptr_t lo = -1; 716 intptr_t lo = -1;
752 intptr_t hi = -1; 717 intptr_t hi = -1;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 insert = 0; 757 insert = 0;
793 } else if (hi == -1) { 758 } else if (hi == -1) {
794 insert = length; 759 insert = length;
795 } else { 760 } else {
796 insert = lo + 1; 761 insert = lo + 1;
797 } 762 }
798 table_.InsertAt(insert, new_code); 763 table_.InsertAt(insert, new_code);
799 return insert; 764 return insert;
800 } 765 }
801 766
802
803 void ProfileCodeTable::FindNeighbors(uword pc, 767 void ProfileCodeTable::FindNeighbors(uword pc,
804 intptr_t* lo, 768 intptr_t* lo,
805 intptr_t* hi, 769 intptr_t* hi,
806 ProfileCode** lo_code, 770 ProfileCode** lo_code,
807 ProfileCode** hi_code) const { 771 ProfileCode** hi_code) const {
808 ASSERT(table_.length() >= 1); 772 ASSERT(table_.length() >= 1);
809 773
810 intptr_t length = table_.length(); 774 intptr_t length = table_.length();
811 775
812 if (pc < At(0)->start()) { 776 if (pc < At(0)->start()) {
(...skipping 28 matching lines...) Expand all
841 *lo = mid; 805 *lo = mid;
842 *lo_code = code; 806 *lo_code = code;
843 } 807 }
844 if (pc < code->end()) { 808 if (pc < code->end()) {
845 *hi = mid; 809 *hi = mid;
846 *hi_code = code; 810 *hi_code = code;
847 } 811 }
848 } 812 }
849 } 813 }
850 814
851
852 void ProfileCodeTable::VerifyOrder() { 815 void ProfileCodeTable::VerifyOrder() {
853 const intptr_t length = table_.length(); 816 const intptr_t length = table_.length();
854 if (length == 0) { 817 if (length == 0) {
855 return; 818 return;
856 } 819 }
857 uword last = table_[0]->end(); 820 uword last = table_[0]->end();
858 for (intptr_t i = 1; i < length; i++) { 821 for (intptr_t i = 1; i < length; i++) {
859 ProfileCode* a = table_[i]; 822 ProfileCode* a = table_[i];
860 ASSERT(last <= a->start()); 823 ASSERT(last <= a->start());
861 last = a->end(); 824 last = a->end();
862 } 825 }
863 } 826 }
864 827
865 void ProfileCodeTable::VerifyOverlap() { 828 void ProfileCodeTable::VerifyOverlap() {
866 const intptr_t length = table_.length(); 829 const intptr_t length = table_.length();
867 for (intptr_t i = 0; i < length; i++) { 830 for (intptr_t i = 0; i < length; i++) {
868 ProfileCode* a = table_[i]; 831 ProfileCode* a = table_[i];
869 for (intptr_t j = i + 1; j < length; j++) { 832 for (intptr_t j = i + 1; j < length; j++) {
870 ProfileCode* b = table_[j]; 833 ProfileCode* b = table_[j];
871 ASSERT(!a->Contains(b->start()) && !a->Contains(b->end() - 1) && 834 ASSERT(!a->Contains(b->start()) && !a->Contains(b->end() - 1) &&
872 !b->Contains(a->start()) && !b->Contains(a->end() - 1)); 835 !b->Contains(a->start()) && !b->Contains(a->end() - 1));
873 } 836 }
874 } 837 }
875 } 838 }
876 839
877
878 ProfileTrieNode::ProfileTrieNode(intptr_t table_index) 840 ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
879 : table_index_(table_index), 841 : table_index_(table_index),
880 count_(0), 842 count_(0),
881 exclusive_allocations_(0), 843 exclusive_allocations_(0),
882 inclusive_allocations_(0), 844 inclusive_allocations_(0),
883 children_(0), 845 children_(0),
884 frame_id_(-1) { 846 frame_id_(-1) {
885 ASSERT(table_index_ >= 0); 847 ASSERT(table_index_ >= 0);
886 } 848 }
887 849
888
889 ProfileTrieNode::~ProfileTrieNode() {} 850 ProfileTrieNode::~ProfileTrieNode() {}
890 851
891
892 void ProfileTrieNode::Tick(ProcessedSample* sample, bool exclusive) { 852 void ProfileTrieNode::Tick(ProcessedSample* sample, bool exclusive) {
893 count_++; 853 count_++;
894 IncrementAllocation(sample->native_allocation_size_bytes(), exclusive); 854 IncrementAllocation(sample->native_allocation_size_bytes(), exclusive);
895 } 855 }
896 856
897
898 void ProfileTrieNode::SortChildren() { 857 void ProfileTrieNode::SortChildren() {
899 children_.Sort(ProfileTrieNodeCompare); 858 children_.Sort(ProfileTrieNodeCompare);
900 // Recurse. 859 // Recurse.
901 for (intptr_t i = 0; i < children_.length(); i++) { 860 for (intptr_t i = 0; i < children_.length(); i++) {
902 children_[i]->SortChildren(); 861 children_[i]->SortChildren();
903 } 862 }
904 } 863 }
905 864
906
907 intptr_t ProfileTrieNode::IndexOf(ProfileTrieNode* node) { 865 intptr_t ProfileTrieNode::IndexOf(ProfileTrieNode* node) {
908 for (intptr_t i = 0; i < children_.length(); i++) { 866 for (intptr_t i = 0; i < children_.length(); i++) {
909 if (children_[i] == node) { 867 if (children_[i] == node) {
910 return i; 868 return i;
911 } 869 }
912 } 870 }
913 return -1; 871 return -1;
914 } 872 }
915 873
916
917 class ProfileCodeTrieNode : public ProfileTrieNode { 874 class ProfileCodeTrieNode : public ProfileTrieNode {
918 public: 875 public:
919 explicit ProfileCodeTrieNode(intptr_t table_index) 876 explicit ProfileCodeTrieNode(intptr_t table_index)
920 : ProfileTrieNode(table_index) {} 877 : ProfileTrieNode(table_index) {}
921 878
922 void PrintToJSONArray(JSONArray* array) const { 879 void PrintToJSONArray(JSONArray* array) const {
923 ASSERT(array != NULL); 880 ASSERT(array != NULL);
924 // Write CodeRegion index. 881 // Write CodeRegion index.
925 array->AddValue(table_index()); 882 array->AddValue(table_index());
926 // Write count. 883 // Write count.
(...skipping 30 matching lines...) Expand all
957 // Insert at i. 914 // Insert at i.
958 children_.InsertAt(i, reinterpret_cast<ProfileTrieNode*>(child)); 915 children_.InsertAt(i, reinterpret_cast<ProfileTrieNode*>(child));
959 } else { 916 } else {
960 // Add to end. 917 // Add to end.
961 children_.Add(reinterpret_cast<ProfileTrieNode*>(child)); 918 children_.Add(reinterpret_cast<ProfileTrieNode*>(child));
962 } 919 }
963 return child; 920 return child;
964 } 921 }
965 }; 922 };
966 923
967
968 class ProfileFunctionTrieNodeCode { 924 class ProfileFunctionTrieNodeCode {
969 public: 925 public:
970 explicit ProfileFunctionTrieNodeCode(intptr_t index) 926 explicit ProfileFunctionTrieNodeCode(intptr_t index)
971 : code_index_(index), ticks_(0) {} 927 : code_index_(index), ticks_(0) {}
972 928
973 intptr_t index() const { return code_index_; } 929 intptr_t index() const { return code_index_; }
974 930
975 void Tick() { ticks_++; } 931 void Tick() { ticks_++; }
976 932
977 intptr_t ticks() const { return ticks_; } 933 intptr_t ticks() const { return ticks_; }
978 934
979 private: 935 private:
980 intptr_t code_index_; 936 intptr_t code_index_;
981 intptr_t ticks_; 937 intptr_t ticks_;
982 }; 938 };
983 939
984
985 class ProfileFunctionTrieNode : public ProfileTrieNode { 940 class ProfileFunctionTrieNode : public ProfileTrieNode {
986 public: 941 public:
987 explicit ProfileFunctionTrieNode(intptr_t table_index) 942 explicit ProfileFunctionTrieNode(intptr_t table_index)
988 : ProfileTrieNode(table_index), code_objects_(1) {} 943 : ProfileTrieNode(table_index), code_objects_(1) {}
989 944
990 void PrintToJSONArray(JSONArray* array) const { 945 void PrintToJSONArray(JSONArray* array) const {
991 ASSERT(array != NULL); 946 ASSERT(array != NULL);
992 // Write CodeRegion index. 947 // Write CodeRegion index.
993 array->AddValue(table_index()); 948 array->AddValue(table_index());
994 // Write count. 949 // Write count.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 } 1005 }
1051 ProfileFunctionTrieNodeCode code_object(index); 1006 ProfileFunctionTrieNodeCode code_object(index);
1052 code_object.Tick(); 1007 code_object.Tick();
1053 code_objects_.Add(code_object); 1008 code_objects_.Add(code_object);
1054 } 1009 }
1055 1010
1056 private: 1011 private:
1057 ZoneGrowableArray<ProfileFunctionTrieNodeCode> code_objects_; 1012 ZoneGrowableArray<ProfileFunctionTrieNodeCode> code_objects_;
1058 }; 1013 };
1059 1014
1060
1061 class ProfileCodeInlinedFunctionsCache : public ValueObject { 1015 class ProfileCodeInlinedFunctionsCache : public ValueObject {
1062 public: 1016 public:
1063 ProfileCodeInlinedFunctionsCache() : cache_cursor_(0), last_hit_(0) { 1017 ProfileCodeInlinedFunctionsCache() : cache_cursor_(0), last_hit_(0) {
1064 for (intptr_t i = 0; i < kCacheSize; i++) { 1018 for (intptr_t i = 0; i < kCacheSize; i++) {
1065 cache_[i].Reset(); 1019 cache_[i].Reset();
1066 } 1020 }
1067 cache_hit_ = 0; 1021 cache_hit_ = 0;
1068 cache_miss_ = 0; 1022 cache_miss_ = 0;
1069 } 1023 }
1070 1024
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 }; 1149 };
1196 1150
1197 static const intptr_t kCacheSize = 128; 1151 static const intptr_t kCacheSize = 128;
1198 intptr_t cache_cursor_; 1152 intptr_t cache_cursor_;
1199 intptr_t last_hit_; 1153 intptr_t last_hit_;
1200 CacheEntry cache_[kCacheSize]; 1154 CacheEntry cache_[kCacheSize];
1201 intptr_t cache_miss_; 1155 intptr_t cache_miss_;
1202 intptr_t cache_hit_; 1156 intptr_t cache_hit_;
1203 }; 1157 };
1204 1158
1205
1206 class ProfileBuilder : public ValueObject { 1159 class ProfileBuilder : public ValueObject {
1207 public: 1160 public:
1208 enum ProfileInfoKind { 1161 enum ProfileInfoKind {
1209 kNone, 1162 kNone,
1210 kOptimized, 1163 kOptimized,
1211 kUnoptimized, 1164 kUnoptimized,
1212 kNative, 1165 kNative,
1213 kInlineStart, 1166 kInlineStart,
1214 kInlineFinish, 1167 kInlineFinish,
1215 kNumProfileInfoKind, 1168 kNumProfileInfoKind,
(...skipping 555 matching lines...) Expand 10 before | Expand all | Expand 10 after
1771 ProfileCodeTable* tag_table = profile_->tag_code_; 1724 ProfileCodeTable* tag_table = profile_->tag_code_;
1772 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId); 1725 intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId);
1773 ASSERT(index >= 0); 1726 ASSERT(index >= 0);
1774 ProfileCode* code = tag_table->At(index); 1727 ProfileCode* code = tag_table->At(index);
1775 code->IncInclusiveTicks(); 1728 code->IncInclusiveTicks();
1776 ASSERT(code != NULL); 1729 ASSERT(code != NULL);
1777 ProfileFunction* function = code->function(); 1730 ProfileFunction* function = code->function();
1778 function->IncInclusiveTicks(); 1731 function->IncInclusiveTicks();
1779 } 1732 }
1780 1733
1781
1782 // Tag append functions are overloaded for |ProfileCodeTrieNode| and 1734 // Tag append functions are overloaded for |ProfileCodeTrieNode| and
1783 // |ProfileFunctionTrieNode| types. 1735 // |ProfileFunctionTrieNode| types.
1784 1736
1785 // ProfileCodeTrieNode 1737 // ProfileCodeTrieNode
1786 ProfileCodeTrieNode* AppendUserTag(uword user_tag, 1738 ProfileCodeTrieNode* AppendUserTag(uword user_tag,
1787 ProfileCodeTrieNode* current, 1739 ProfileCodeTrieNode* current,
1788 ProcessedSample* sample) { 1740 ProcessedSample* sample) {
1789 intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag); 1741 intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag);
1790 if (user_tag_index >= 0) { 1742 if (user_tag_index >= 0) {
1791 current = current->GetChild(user_tag_index); 1743 current = current->GetChild(user_tag_index);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 ProfileCode* code = 2170 ProfileCode* code =
2219 new ProfileCode(ProfileCode::kReusedCode, pc, pc + 1, 0, null_code_); 2171 new ProfileCode(ProfileCode::kReusedCode, pc, pc + 1, 0, null_code_);
2220 return code; 2172 return code;
2221 } 2173 }
2222 2174
2223 bool IsPCInDartHeap(uword pc) { 2175 bool IsPCInDartHeap(uword pc) {
2224 return vm_isolate_->heap()->CodeContains(pc) || 2176 return vm_isolate_->heap()->CodeContains(pc) ||
2225 thread_->isolate()->heap()->CodeContains(pc); 2177 thread_->isolate()->heap()->CodeContains(pc);
2226 } 2178 }
2227 2179
2228
2229 ProfileCode* FindOrRegisterNativeProfileCode(uword pc) { 2180 ProfileCode* FindOrRegisterNativeProfileCode(uword pc) {
2230 // Check if |pc| is already known in the live code table. 2181 // Check if |pc| is already known in the live code table.
2231 ProfileCodeTable* live_table = profile_->live_code_; 2182 ProfileCodeTable* live_table = profile_->live_code_;
2232 ProfileCode* profile_code = live_table->FindCodeForPC(pc); 2183 ProfileCode* profile_code = live_table->FindCodeForPC(pc);
2233 if (profile_code != NULL) { 2184 if (profile_code != NULL) {
2234 return profile_code; 2185 return profile_code;
2235 } 2186 }
2236 2187
2237 // We haven't seen this pc yet. 2188 // We haven't seen this pc yet.
2238 Code& code = Code::Handle(thread_->zone()); 2189 Code& code = Code::Handle(thread_->zone());
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 DeoptimizedCodeSet* deoptimized_code_; 2289 DeoptimizedCodeSet* deoptimized_code_;
2339 const Code& null_code_; 2290 const Code& null_code_;
2340 const Function& null_function_; 2291 const Function& null_function_;
2341 bool tick_functions_; 2292 bool tick_functions_;
2342 bool inclusive_tree_; 2293 bool inclusive_tree_;
2343 ProfileCodeInlinedFunctionsCache inlined_functions_cache_; 2294 ProfileCodeInlinedFunctionsCache inlined_functions_cache_;
2344 ProcessedSampleBuffer* samples_; 2295 ProcessedSampleBuffer* samples_;
2345 ProfileInfoKind info_kind_; 2296 ProfileInfoKind info_kind_;
2346 }; // ProfileBuilder. 2297 }; // ProfileBuilder.
2347 2298
2348
2349 Profile::Profile(Isolate* isolate) 2299 Profile::Profile(Isolate* isolate)
2350 : isolate_(isolate), 2300 : isolate_(isolate),
2351 zone_(Thread::Current()->zone()), 2301 zone_(Thread::Current()->zone()),
2352 samples_(NULL), 2302 samples_(NULL),
2353 live_code_(NULL), 2303 live_code_(NULL),
2354 dead_code_(NULL), 2304 dead_code_(NULL),
2355 tag_code_(NULL), 2305 tag_code_(NULL),
2356 functions_(NULL), 2306 functions_(NULL),
2357 dead_code_index_offset_(-1), 2307 dead_code_index_offset_(-1),
2358 tag_code_index_offset_(-1), 2308 tag_code_index_offset_(-1),
2359 min_time_(kMaxInt64), 2309 min_time_(kMaxInt64),
2360 max_time_(0) { 2310 max_time_(0) {
2361 ASSERT(isolate_ != NULL); 2311 ASSERT(isolate_ != NULL);
2362 for (intptr_t i = 0; i < kNumTrieKinds; i++) { 2312 for (intptr_t i = 0; i < kNumTrieKinds; i++) {
2363 roots_[i] = NULL; 2313 roots_[i] = NULL;
2364 } 2314 }
2365 } 2315 }
2366 2316
2367
2368 void Profile::Build(Thread* thread, 2317 void Profile::Build(Thread* thread,
2369 SampleFilter* filter, 2318 SampleFilter* filter,
2370 SampleBuffer* sample_buffer, 2319 SampleBuffer* sample_buffer,
2371 TagOrder tag_order, 2320 TagOrder tag_order,
2372 intptr_t extra_tags) { 2321 intptr_t extra_tags) {
2373 ProfileBuilder builder(thread, filter, sample_buffer, tag_order, extra_tags, 2322 ProfileBuilder builder(thread, filter, sample_buffer, tag_order, extra_tags,
2374 this); 2323 this);
2375 builder.Build(); 2324 builder.Build();
2376 } 2325 }
2377 2326
2378
2379 intptr_t Profile::NumFunctions() const { 2327 intptr_t Profile::NumFunctions() const {
2380 return functions_->length(); 2328 return functions_->length();
2381 } 2329 }
2382 2330
2383 ProfileFunction* Profile::GetFunction(intptr_t index) { 2331 ProfileFunction* Profile::GetFunction(intptr_t index) {
2384 ASSERT(functions_ != NULL); 2332 ASSERT(functions_ != NULL);
2385 return functions_->At(index); 2333 return functions_->At(index);
2386 } 2334 }
2387 2335
2388
2389 ProfileCode* Profile::GetCode(intptr_t index) { 2336 ProfileCode* Profile::GetCode(intptr_t index) {
2390 ASSERT(live_code_ != NULL); 2337 ASSERT(live_code_ != NULL);
2391 ASSERT(dead_code_ != NULL); 2338 ASSERT(dead_code_ != NULL);
2392 ASSERT(tag_code_ != NULL); 2339 ASSERT(tag_code_ != NULL);
2393 ASSERT(dead_code_index_offset_ >= 0); 2340 ASSERT(dead_code_index_offset_ >= 0);
2394 ASSERT(tag_code_index_offset_ >= 0); 2341 ASSERT(tag_code_index_offset_ >= 0);
2395 2342
2396 // Code indexes span three arrays. 2343 // Code indexes span three arrays.
2397 // 0 ... |live_code| 2344 // 0 ... |live_code|
2398 // |live_code| ... |dead_code| 2345 // |live_code| ... |dead_code|
2399 // |dead_code| ... |tag_code| 2346 // |dead_code| ... |tag_code|
2400 2347
2401 if (index < dead_code_index_offset_) { 2348 if (index < dead_code_index_offset_) {
2402 return live_code_->At(index); 2349 return live_code_->At(index);
2403 } 2350 }
2404 2351
2405 if (index < tag_code_index_offset_) { 2352 if (index < tag_code_index_offset_) {
2406 index -= dead_code_index_offset_; 2353 index -= dead_code_index_offset_;
2407 return dead_code_->At(index); 2354 return dead_code_->At(index);
2408 } 2355 }
2409 2356
2410 index -= tag_code_index_offset_; 2357 index -= tag_code_index_offset_;
2411 return tag_code_->At(index); 2358 return tag_code_->At(index);
2412 } 2359 }
2413 2360
2414
2415 ProfileTrieNode* Profile::GetTrieRoot(TrieKind trie_kind) { 2361 ProfileTrieNode* Profile::GetTrieRoot(TrieKind trie_kind) {
2416 return roots_[static_cast<intptr_t>(trie_kind)]; 2362 return roots_[static_cast<intptr_t>(trie_kind)];
2417 } 2363 }
2418 2364
2419
2420 void Profile::PrintHeaderJSON(JSONObject* obj) { 2365 void Profile::PrintHeaderJSON(JSONObject* obj) {
2421 obj->AddProperty("samplePeriod", static_cast<intptr_t>(FLAG_profile_period)); 2366 obj->AddProperty("samplePeriod", static_cast<intptr_t>(FLAG_profile_period));
2422 obj->AddProperty("stackDepth", static_cast<intptr_t>(FLAG_max_profile_depth)); 2367 obj->AddProperty("stackDepth", static_cast<intptr_t>(FLAG_max_profile_depth));
2423 obj->AddProperty("sampleCount", sample_count()); 2368 obj->AddProperty("sampleCount", sample_count());
2424 obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan())); 2369 obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
2425 obj->AddPropertyTimeMicros("timeOriginMicros", min_time()); 2370 obj->AddPropertyTimeMicros("timeOriginMicros", min_time());
2426 obj->AddPropertyTimeMicros("timeExtentMicros", GetTimeSpan()); 2371 obj->AddPropertyTimeMicros("timeExtentMicros", GetTimeSpan());
2427 2372
2428 ProfilerCounters counters = Profiler::counters(); 2373 ProfilerCounters counters = Profiler::counters();
2429 { 2374 {
(...skipping 12 matching lines...) Expand all
2442 "single_frame_sample_get_and_validate_stack_bounds", 2387 "single_frame_sample_get_and_validate_stack_bounds",
2443 counters.single_frame_sample_get_and_validate_stack_bounds); 2388 counters.single_frame_sample_get_and_validate_stack_bounds);
2444 counts.AddProperty64("stack_walker_native", counters.stack_walker_native); 2389 counts.AddProperty64("stack_walker_native", counters.stack_walker_native);
2445 counts.AddProperty64("stack_walker_dart_exit", 2390 counts.AddProperty64("stack_walker_dart_exit",
2446 counters.stack_walker_dart_exit); 2391 counters.stack_walker_dart_exit);
2447 counts.AddProperty64("stack_walker_dart", counters.stack_walker_dart); 2392 counts.AddProperty64("stack_walker_dart", counters.stack_walker_dart);
2448 counts.AddProperty64("stack_walker_none", counters.stack_walker_none); 2393 counts.AddProperty64("stack_walker_none", counters.stack_walker_none);
2449 } 2394 }
2450 } 2395 }
2451 2396
2452
2453 void Profile::PrintTimelineFrameJSON(JSONObject* frames, 2397 void Profile::PrintTimelineFrameJSON(JSONObject* frames,
2454 ProfileTrieNode* current, 2398 ProfileTrieNode* current,
2455 ProfileTrieNode* parent, 2399 ProfileTrieNode* parent,
2456 intptr_t* next_id) { 2400 intptr_t* next_id) {
2457 ASSERT(current->frame_id() == -1); 2401 ASSERT(current->frame_id() == -1);
2458 const intptr_t id = *next_id; 2402 const intptr_t id = *next_id;
2459 *next_id = id + 1; 2403 *next_id = id + 1;
2460 current->set_frame_id(id); 2404 current->set_frame_id(id);
2461 ASSERT(current->frame_id() != -1); 2405 ASSERT(current->frame_id() != -1);
2462 2406
(...skipping 13 matching lines...) Expand all
2476 parent->frame_id()); 2420 parent->frame_id());
2477 } 2421 }
2478 } 2422 }
2479 2423
2480 for (intptr_t i = 0; i < current->NumChildren(); i++) { 2424 for (intptr_t i = 0; i < current->NumChildren(); i++) {
2481 ProfileTrieNode* child = current->At(i); 2425 ProfileTrieNode* child = current->At(i);
2482 PrintTimelineFrameJSON(frames, child, current, next_id); 2426 PrintTimelineFrameJSON(frames, child, current, next_id);
2483 } 2427 }
2484 } 2428 }
2485 2429
2486
2487 void Profile::PrintTimelineJSON(JSONStream* stream) { 2430 void Profile::PrintTimelineJSON(JSONStream* stream) {
2488 ScopeTimer sw("Profile::PrintTimelineJSON", FLAG_trace_profiler); 2431 ScopeTimer sw("Profile::PrintTimelineJSON", FLAG_trace_profiler);
2489 JSONObject obj(stream); 2432 JSONObject obj(stream);
2490 obj.AddProperty("type", "_CpuProfileTimeline"); 2433 obj.AddProperty("type", "_CpuProfileTimeline");
2491 PrintHeaderJSON(&obj); 2434 PrintHeaderJSON(&obj);
2492 { 2435 {
2493 JSONObject frames(&obj, "stackFrames"); 2436 JSONObject frames(&obj, "stackFrames");
2494 ProfileTrieNode* root = GetTrieRoot(kInclusiveFunction); 2437 ProfileTrieNode* root = GetTrieRoot(kInclusiveFunction);
2495 intptr_t next_id = 0; 2438 intptr_t next_id = 0;
2496 PrintTimelineFrameJSON(&frames, root, NULL, &next_id); 2439 PrintTimelineFrameJSON(&frames, root, NULL, &next_id);
(...skipping 14 matching lines...) Expand all
2511 event.AddPropertyTimeMicros("ts", sample->timestamp()); 2454 event.AddPropertyTimeMicros("ts", sample->timestamp());
2512 event.AddProperty("cat", "Dart"); 2455 event.AddProperty("cat", "Dart");
2513 2456
2514 ProfileTrieNode* trie = sample->timeline_trie(); 2457 ProfileTrieNode* trie = sample->timeline_trie();
2515 ASSERT(trie->frame_id() != -1); 2458 ASSERT(trie->frame_id() != -1);
2516 event.AddPropertyF("sf", "%" Pd "-%" Pd, isolate_id, trie->frame_id()); 2459 event.AddPropertyF("sf", "%" Pd "-%" Pd, isolate_id, trie->frame_id());
2517 } 2460 }
2518 } 2461 }
2519 } 2462 }
2520 2463
2521
2522 ProfileFunction* Profile::FindFunction(const Function& function) { 2464 ProfileFunction* Profile::FindFunction(const Function& function) {
2523 return (functions_ != NULL) ? functions_->Lookup(function) : NULL; 2465 return (functions_ != NULL) ? functions_->Lookup(function) : NULL;
2524 } 2466 }
2525 2467
2526
2527 void Profile::PrintProfileJSON(JSONStream* stream) { 2468 void Profile::PrintProfileJSON(JSONStream* stream) {
2528 ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler); 2469 ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler);
2529 JSONObject obj(stream); 2470 JSONObject obj(stream);
2530 obj.AddProperty("type", "_CpuProfile"); 2471 obj.AddProperty("type", "_CpuProfile");
2531 PrintHeaderJSON(&obj); 2472 PrintHeaderJSON(&obj);
2532 { 2473 {
2533 JSONArray codes(&obj, "codes"); 2474 JSONArray codes(&obj, "codes");
2534 for (intptr_t i = 0; i < live_code_->length(); i++) { 2475 for (intptr_t i = 0; i < live_code_->length(); i++) {
2535 ProfileCode* code = live_code_->At(i); 2476 ProfileCode* code = live_code_->At(i);
2536 ASSERT(code != NULL); 2477 ASSERT(code != NULL);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2575 root->PrintToJSONArray(&function_trie); 2516 root->PrintToJSONArray(&function_trie);
2576 } 2517 }
2577 { 2518 {
2578 JSONArray function_trie(&obj, "inclusiveFunctionTrie"); 2519 JSONArray function_trie(&obj, "inclusiveFunctionTrie");
2579 ProfileTrieNode* root = roots_[static_cast<intptr_t>(kInclusiveFunction)]; 2520 ProfileTrieNode* root = roots_[static_cast<intptr_t>(kInclusiveFunction)];
2580 ASSERT(root != NULL); 2521 ASSERT(root != NULL);
2581 root->PrintToJSONArray(&function_trie); 2522 root->PrintToJSONArray(&function_trie);
2582 } 2523 }
2583 } 2524 }
2584 2525
2585
2586 void ProfileTrieWalker::Reset(Profile::TrieKind trie_kind) { 2526 void ProfileTrieWalker::Reset(Profile::TrieKind trie_kind) {
2587 code_trie_ = Profile::IsCodeTrie(trie_kind); 2527 code_trie_ = Profile::IsCodeTrie(trie_kind);
2588 parent_ = NULL; 2528 parent_ = NULL;
2589 current_ = profile_->GetTrieRoot(trie_kind); 2529 current_ = profile_->GetTrieRoot(trie_kind);
2590 ASSERT(current_ != NULL); 2530 ASSERT(current_ != NULL);
2591 } 2531 }
2592 2532
2593
2594 const char* ProfileTrieWalker::CurrentName() { 2533 const char* ProfileTrieWalker::CurrentName() {
2595 if (current_ == NULL) { 2534 if (current_ == NULL) {
2596 return NULL; 2535 return NULL;
2597 } 2536 }
2598 if (code_trie_) { 2537 if (code_trie_) {
2599 ProfileCode* code = profile_->GetCode(current_->table_index()); 2538 ProfileCode* code = profile_->GetCode(current_->table_index());
2600 return code->name(); 2539 return code->name();
2601 } else { 2540 } else {
2602 ProfileFunction* func = profile_->GetFunction(current_->table_index()); 2541 ProfileFunction* func = profile_->GetFunction(current_->table_index());
2603 return func->Name(); 2542 return func->Name();
2604 } 2543 }
2605 UNREACHABLE(); 2544 UNREACHABLE();
2606 return NULL; 2545 return NULL;
2607 } 2546 }
2608 2547
2609
2610 intptr_t ProfileTrieWalker::CurrentNodeTickCount() { 2548 intptr_t ProfileTrieWalker::CurrentNodeTickCount() {
2611 if (current_ == NULL) { 2549 if (current_ == NULL) {
2612 return -1; 2550 return -1;
2613 } 2551 }
2614 return current_->count(); 2552 return current_->count();
2615 } 2553 }
2616 2554
2617
2618 intptr_t ProfileTrieWalker::CurrentInclusiveTicks() { 2555 intptr_t ProfileTrieWalker::CurrentInclusiveTicks() {
2619 if (current_ == NULL) { 2556 if (current_ == NULL) {
2620 return -1; 2557 return -1;
2621 } 2558 }
2622 if (code_trie_) { 2559 if (code_trie_) {
2623 ProfileCode* code = profile_->GetCode(current_->table_index()); 2560 ProfileCode* code = profile_->GetCode(current_->table_index());
2624 return code->inclusive_ticks(); 2561 return code->inclusive_ticks();
2625 } else { 2562 } else {
2626 ProfileFunction* func = profile_->GetFunction(current_->table_index()); 2563 ProfileFunction* func = profile_->GetFunction(current_->table_index());
2627 return func->inclusive_ticks(); 2564 return func->inclusive_ticks();
2628 } 2565 }
2629 UNREACHABLE(); 2566 UNREACHABLE();
2630 return -1; 2567 return -1;
2631 } 2568 }
2632 2569
2633
2634 intptr_t ProfileTrieWalker::CurrentExclusiveTicks() { 2570 intptr_t ProfileTrieWalker::CurrentExclusiveTicks() {
2635 if (current_ == NULL) { 2571 if (current_ == NULL) {
2636 return -1; 2572 return -1;
2637 } 2573 }
2638 if (code_trie_) { 2574 if (code_trie_) {
2639 ProfileCode* code = profile_->GetCode(current_->table_index()); 2575 ProfileCode* code = profile_->GetCode(current_->table_index());
2640 return code->exclusive_ticks(); 2576 return code->exclusive_ticks();
2641 } else { 2577 } else {
2642 ProfileFunction* func = profile_->GetFunction(current_->table_index()); 2578 ProfileFunction* func = profile_->GetFunction(current_->table_index());
2643 return func->exclusive_ticks(); 2579 return func->exclusive_ticks();
2644 } 2580 }
2645 UNREACHABLE(); 2581 UNREACHABLE();
2646 return -1; 2582 return -1;
2647 } 2583 }
2648 2584
2649
2650 intptr_t ProfileTrieWalker::CurrentInclusiveAllocations() { 2585 intptr_t ProfileTrieWalker::CurrentInclusiveAllocations() {
2651 if (current_ == NULL) { 2586 if (current_ == NULL) {
2652 return -1; 2587 return -1;
2653 } 2588 }
2654 return current_->inclusive_allocations(); 2589 return current_->inclusive_allocations();
2655 } 2590 }
2656 2591
2657
2658 intptr_t ProfileTrieWalker::CurrentExclusiveAllocations() { 2592 intptr_t ProfileTrieWalker::CurrentExclusiveAllocations() {
2659 if (current_ == NULL) { 2593 if (current_ == NULL) {
2660 return -1; 2594 return -1;
2661 } 2595 }
2662 return current_->exclusive_allocations(); 2596 return current_->exclusive_allocations();
2663 } 2597 }
2664 2598
2665
2666 const char* ProfileTrieWalker::CurrentToken() { 2599 const char* ProfileTrieWalker::CurrentToken() {
2667 if (current_ == NULL) { 2600 if (current_ == NULL) {
2668 return NULL; 2601 return NULL;
2669 } 2602 }
2670 if (code_trie_) { 2603 if (code_trie_) {
2671 return NULL; 2604 return NULL;
2672 } 2605 }
2673 ProfileFunction* func = profile_->GetFunction(current_->table_index()); 2606 ProfileFunction* func = profile_->GetFunction(current_->table_index());
2674 const Function& function = *(func->function()); 2607 const Function& function = *(func->function());
2675 if (function.IsNull()) { 2608 if (function.IsNull()) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 2649
2717 bool ProfileTrieWalker::Down() { 2650 bool ProfileTrieWalker::Down() {
2718 if ((current_ == NULL) || (current_->NumChildren() == 0)) { 2651 if ((current_ == NULL) || (current_->NumChildren() == 0)) {
2719 return false; 2652 return false;
2720 } 2653 }
2721 parent_ = current_; 2654 parent_ = current_;
2722 current_ = current_->At(0); 2655 current_ = current_->At(0);
2723 return true; 2656 return true;
2724 } 2657 }
2725 2658
2726
2727 bool ProfileTrieWalker::NextSibling() { 2659 bool ProfileTrieWalker::NextSibling() {
2728 if (parent_ == NULL) { 2660 if (parent_ == NULL) {
2729 return false; 2661 return false;
2730 } 2662 }
2731 intptr_t current_index = parent_->IndexOf(current_); 2663 intptr_t current_index = parent_->IndexOf(current_);
2732 if (current_index < 0) { 2664 if (current_index < 0) {
2733 return false; 2665 return false;
2734 } 2666 }
2735 current_index++; 2667 current_index++;
2736 if (current_index >= parent_->NumChildren()) { 2668 if (current_index >= parent_->NumChildren()) {
2737 return false; 2669 return false;
2738 } 2670 }
2739 current_ = parent_->At(current_index); 2671 current_ = parent_->At(current_index);
2740 return true; 2672 return true;
2741 } 2673 }
2742 2674
2743
2744 intptr_t ProfileTrieWalker::SiblingCount() { 2675 intptr_t ProfileTrieWalker::SiblingCount() {
2745 ASSERT(parent_ != NULL); 2676 ASSERT(parent_ != NULL);
2746 return parent_->NumChildren(); 2677 return parent_->NumChildren();
2747 } 2678 }
2748 2679
2749
2750 void ProfilerService::PrintJSONImpl(Thread* thread, 2680 void ProfilerService::PrintJSONImpl(Thread* thread,
2751 JSONStream* stream, 2681 JSONStream* stream,
2752 Profile::TagOrder tag_order, 2682 Profile::TagOrder tag_order,
2753 intptr_t extra_tags, 2683 intptr_t extra_tags,
2754 SampleFilter* filter, 2684 SampleFilter* filter,
2755 SampleBuffer* sample_buffer, 2685 SampleBuffer* sample_buffer,
2756 bool as_timeline) { 2686 bool as_timeline) {
2757 Isolate* isolate = thread->isolate(); 2687 Isolate* isolate = thread->isolate();
2758 // Disable thread interrupts while processing the buffer. 2688 // Disable thread interrupts while processing the buffer.
2759 DisableThreadInterruptsScope dtis(thread); 2689 DisableThreadInterruptsScope dtis(thread);
2760 2690
2761 if (sample_buffer == NULL) { 2691 if (sample_buffer == NULL) {
2762 stream->PrintError(kFeatureDisabled, NULL); 2692 stream->PrintError(kFeatureDisabled, NULL);
2763 return; 2693 return;
2764 } 2694 }
2765 2695
2766 { 2696 {
2767 StackZone zone(thread); 2697 StackZone zone(thread);
2768 HANDLESCOPE(thread); 2698 HANDLESCOPE(thread);
2769 Profile profile(isolate); 2699 Profile profile(isolate);
2770 profile.Build(thread, filter, sample_buffer, tag_order, extra_tags); 2700 profile.Build(thread, filter, sample_buffer, tag_order, extra_tags);
2771 if (as_timeline) { 2701 if (as_timeline) {
2772 profile.PrintTimelineJSON(stream); 2702 profile.PrintTimelineJSON(stream);
2773 } else { 2703 } else {
2774 profile.PrintProfileJSON(stream); 2704 profile.PrintProfileJSON(stream);
2775 } 2705 }
2776 } 2706 }
2777 } 2707 }
2778 2708
2779
2780 class NoAllocationSampleFilter : public SampleFilter { 2709 class NoAllocationSampleFilter : public SampleFilter {
2781 public: 2710 public:
2782 NoAllocationSampleFilter(Dart_Port port, 2711 NoAllocationSampleFilter(Dart_Port port,
2783 intptr_t thread_task_mask, 2712 intptr_t thread_task_mask,
2784 int64_t time_origin_micros, 2713 int64_t time_origin_micros,
2785 int64_t time_extent_micros) 2714 int64_t time_extent_micros)
2786 : SampleFilter(port, 2715 : SampleFilter(port,
2787 thread_task_mask, 2716 thread_task_mask,
2788 time_origin_micros, 2717 time_origin_micros,
2789 time_extent_micros) {} 2718 time_extent_micros) {}
2790 2719
2791 bool FilterSample(Sample* sample) { return !sample->is_allocation_sample(); } 2720 bool FilterSample(Sample* sample) { return !sample->is_allocation_sample(); }
2792 }; 2721 };
2793 2722
2794
2795 void ProfilerService::PrintJSON(JSONStream* stream, 2723 void ProfilerService::PrintJSON(JSONStream* stream,
2796 Profile::TagOrder tag_order, 2724 Profile::TagOrder tag_order,
2797 intptr_t extra_tags, 2725 intptr_t extra_tags,
2798 int64_t time_origin_micros, 2726 int64_t time_origin_micros,
2799 int64_t time_extent_micros) { 2727 int64_t time_extent_micros) {
2800 Thread* thread = Thread::Current(); 2728 Thread* thread = Thread::Current();
2801 Isolate* isolate = thread->isolate(); 2729 Isolate* isolate = thread->isolate();
2802 NoAllocationSampleFilter filter(isolate->main_port(), Thread::kMutatorTask, 2730 NoAllocationSampleFilter filter(isolate->main_port(), Thread::kMutatorTask,
2803 time_origin_micros, time_extent_micros); 2731 time_origin_micros, time_extent_micros);
2804 const bool as_timeline = false; 2732 const bool as_timeline = false;
2805 PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter, 2733 PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter,
2806 Profiler::sample_buffer(), as_timeline); 2734 Profiler::sample_buffer(), as_timeline);
2807 } 2735 }
2808 2736
2809
2810 class ClassAllocationSampleFilter : public SampleFilter { 2737 class ClassAllocationSampleFilter : public SampleFilter {
2811 public: 2738 public:
2812 ClassAllocationSampleFilter(Dart_Port port, 2739 ClassAllocationSampleFilter(Dart_Port port,
2813 const Class& cls, 2740 const Class& cls,
2814 intptr_t thread_task_mask, 2741 intptr_t thread_task_mask,
2815 int64_t time_origin_micros, 2742 int64_t time_origin_micros,
2816 int64_t time_extent_micros) 2743 int64_t time_extent_micros)
2817 : SampleFilter(port, 2744 : SampleFilter(port,
2818 thread_task_mask, 2745 thread_task_mask,
2819 time_origin_micros, 2746 time_origin_micros,
2820 time_extent_micros), 2747 time_extent_micros),
2821 cls_(Class::Handle(cls.raw())) { 2748 cls_(Class::Handle(cls.raw())) {
2822 ASSERT(!cls_.IsNull()); 2749 ASSERT(!cls_.IsNull());
2823 } 2750 }
2824 2751
2825 bool FilterSample(Sample* sample) { 2752 bool FilterSample(Sample* sample) {
2826 return sample->is_allocation_sample() && 2753 return sample->is_allocation_sample() &&
2827 (sample->allocation_cid() == cls_.id()); 2754 (sample->allocation_cid() == cls_.id());
2828 } 2755 }
2829 2756
2830 private: 2757 private:
2831 const Class& cls_; 2758 const Class& cls_;
2832 }; 2759 };
2833 2760
2834
2835 void ProfilerService::PrintAllocationJSON(JSONStream* stream, 2761 void ProfilerService::PrintAllocationJSON(JSONStream* stream,
2836 Profile::TagOrder tag_order, 2762 Profile::TagOrder tag_order,
2837 const Class& cls, 2763 const Class& cls,
2838 int64_t time_origin_micros, 2764 int64_t time_origin_micros,
2839 int64_t time_extent_micros) { 2765 int64_t time_extent_micros) {
2840 Thread* thread = Thread::Current(); 2766 Thread* thread = Thread::Current();
2841 Isolate* isolate = thread->isolate(); 2767 Isolate* isolate = thread->isolate();
2842 ClassAllocationSampleFilter filter(isolate->main_port(), cls, 2768 ClassAllocationSampleFilter filter(isolate->main_port(), cls,
2843 Thread::kMutatorTask, time_origin_micros, 2769 Thread::kMutatorTask, time_origin_micros,
2844 time_extent_micros); 2770 time_extent_micros);
2845 const bool as_timeline = false; 2771 const bool as_timeline = false;
2846 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, 2772 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter,
2847 Profiler::sample_buffer(), as_timeline); 2773 Profiler::sample_buffer(), as_timeline);
2848 } 2774 }
2849 2775
2850
2851 void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream, 2776 void ProfilerService::PrintNativeAllocationJSON(JSONStream* stream,
2852 Profile::TagOrder tag_order, 2777 Profile::TagOrder tag_order,
2853 int64_t time_origin_micros, 2778 int64_t time_origin_micros,
2854 int64_t time_extent_micros) { 2779 int64_t time_extent_micros) {
2855 Thread* thread = Thread::Current(); 2780 Thread* thread = Thread::Current();
2856 NativeAllocationSampleFilter filter(time_origin_micros, time_extent_micros); 2781 NativeAllocationSampleFilter filter(time_origin_micros, time_extent_micros);
2857 const bool as_timeline = false; 2782 const bool as_timeline = false;
2858 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, 2783 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter,
2859 Profiler::allocation_sample_buffer(), as_timeline); 2784 Profiler::allocation_sample_buffer(), as_timeline);
2860 } 2785 }
2861 2786
2862
2863 void ProfilerService::PrintTimelineJSON(JSONStream* stream, 2787 void ProfilerService::PrintTimelineJSON(JSONStream* stream,
2864 Profile::TagOrder tag_order, 2788 Profile::TagOrder tag_order,
2865 int64_t time_origin_micros, 2789 int64_t time_origin_micros,
2866 int64_t time_extent_micros) { 2790 int64_t time_extent_micros) {
2867 Thread* thread = Thread::Current(); 2791 Thread* thread = Thread::Current();
2868 Isolate* isolate = thread->isolate(); 2792 Isolate* isolate = thread->isolate();
2869 const intptr_t thread_task_mask = Thread::kMutatorTask | 2793 const intptr_t thread_task_mask = Thread::kMutatorTask |
2870 Thread::kCompilerTask | 2794 Thread::kCompilerTask |
2871 Thread::kSweeperTask | Thread::kMarkerTask; 2795 Thread::kSweeperTask | Thread::kMarkerTask;
2872 NoAllocationSampleFilter filter(isolate->main_port(), thread_task_mask, 2796 NoAllocationSampleFilter filter(isolate->main_port(), thread_task_mask,
2873 time_origin_micros, time_extent_micros); 2797 time_origin_micros, time_extent_micros);
2874 const bool as_timeline = true; 2798 const bool as_timeline = true;
2875 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, 2799 PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter,
2876 Profiler::sample_buffer(), as_timeline); 2800 Profiler::sample_buffer(), as_timeline);
2877 } 2801 }
2878 2802
2879
2880 void ProfilerService::ClearSamples() { 2803 void ProfilerService::ClearSamples() {
2881 SampleBuffer* sample_buffer = Profiler::sample_buffer(); 2804 SampleBuffer* sample_buffer = Profiler::sample_buffer();
2882 if (sample_buffer == NULL) { 2805 if (sample_buffer == NULL) {
2883 return; 2806 return;
2884 } 2807 }
2885 2808
2886 Thread* thread = Thread::Current(); 2809 Thread* thread = Thread::Current();
2887 Isolate* isolate = thread->isolate(); 2810 Isolate* isolate = thread->isolate();
2888 2811
2889 // Disable thread interrupts while processing the buffer. 2812 // Disable thread interrupts while processing the buffer.
2890 DisableThreadInterruptsScope dtis(thread); 2813 DisableThreadInterruptsScope dtis(thread);
2891 2814
2892 ClearProfileVisitor clear_profile(isolate); 2815 ClearProfileVisitor clear_profile(isolate);
2893 sample_buffer->VisitSamples(&clear_profile); 2816 sample_buffer->VisitSamples(&clear_profile);
2894 } 2817 }
2895 2818
2896 #endif // !PRODUCT 2819 #endif // !PRODUCT
2897 2820
2898 } // namespace dart 2821 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/profiler_service.h ('k') | runtime/vm/profiler_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698