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

Side by Side Diff: third_party/tcmalloc/chromium/src/heap-profile-table.cc

Issue 15418002: Record Chrome trace events in tcmalloc heap profiles (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase, cleanup Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006, Google Inc. 1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 reinterpret_cast<uintptr_t>(b.stack[d])); 321 reinterpret_cast<uintptr_t>(b.stack[d]));
322 if (printed < 0 || printed >= bufsize - buflen) return buflen; 322 if (printed < 0 || printed >= bufsize - buflen) return buflen;
323 buflen += printed; 323 buflen += printed;
324 } 324 }
325 printed = snprintf(buf + buflen, bufsize - buflen, "\n"); 325 printed = snprintf(buf + buflen, bufsize - buflen, "\n");
326 if (printed < 0 || printed >= bufsize - buflen) return buflen; 326 if (printed < 0 || printed >= bufsize - buflen) return buflen;
327 buflen += printed; 327 buflen += printed;
328 return buflen; 328 return buflen;
329 } 329 }
330 330
331 int HeapProfileTable::UnparsePseudoStackBucket(
332 const Bucket& bucket,
333 char* buffer, int written, int buffer_size,
334 Stats* profile_stats) {
335 if (profile_stats != NULL) {
336 profile_stats->allocs += bucket.allocs;
337 profile_stats->alloc_size += bucket.alloc_size;
338 profile_stats->frees += bucket.frees;
339 profile_stats->free_size += bucket.free_size;
340 }
341 int printed = snprintf(buffer + written,
dsinclair 2013/06/18 15:30:15 Would it be possible, instead of converting to JSO
Dai Mikurube (NOT FULLTIME) 2013/06/19 04:34:03 Agreed with dsinclair. Would it be possible to ke
342 buffer_size - written,
343 "{"
344 "\"trace\": \"");
345 written += printed;
346 RAW_DCHECK(bucket.depth <= HeapProfileBucket::kMaxStackDepth,
347 "stack depth too deep");
348 for (int d = 0; d < bucket.depth; d++) {
349 printed = snprintf(buffer + written, buffer_size - written, "%s ",
350 reinterpret_cast<const char*>(bucket.stack[d]));
351 // Brute-force replace any " with ' to keep the JSON correct.
352 for (int i = 0; i < printed; ++i) {
353 char* c = buffer + written + i;
354 if (*c == '"')
355 *c = '\'';
356 }
357 if (printed < 0 || printed >= buffer_size - written) return written;
358 written += printed;
359 }
360 printed = snprintf(buffer + written,
361 buffer_size - written,
362 "\", "
363 "\"current_allocs\": %d, "
364 "\"current_bytes\": %" PRId64 ", "
365 "\"total_allocs\": %d, "
366 "\"total_bytes\": %" PRId64
367 "}",
368 bucket.allocs - bucket.frees,
369 bucket.alloc_size - bucket.free_size,
370 bucket.allocs,
371 bucket.alloc_size);
372 // If it looks like the snprintf failed, ignore the fact we printed anything
373 if (printed < 0 || printed >= buffer_size - written) return written;
374 written += printed;
375 return written;
376 }
377
331 HeapProfileTable::Bucket** 378 HeapProfileTable::Bucket**
332 HeapProfileTable::MakeSortedBucketList() const { 379 HeapProfileTable::MakeSortedBucketList() const {
333 Bucket** list = static_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_)); 380 Bucket** list = static_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_));
334 381
335 int bucket_count = 0; 382 int bucket_count = 0;
336 for (int i = 0; i < kHashTableSize; i++) { 383 for (int i = 0; i < kHashTableSize; i++) {
337 for (Bucket* curr = bucket_table_[i]; curr != 0; curr = curr->next) { 384 for (Bucket* curr = bucket_table_[i]; curr != 0; curr = curr->next) {
338 list[bucket_count++] = curr; 385 list[bucket_count++] = curr;
339 } 386 }
340 } 387 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 RAW_DCHECK(bucket_length < size, ""); 480 RAW_DCHECK(bucket_length < size, "");
434 481
435 dealloc_(list); 482 dealloc_(list);
436 483
437 RAW_DCHECK(buf + bucket_length <= map_start, ""); 484 RAW_DCHECK(buf + bucket_length <= map_start, "");
438 memmove(buf + bucket_length, map_start, map_length); // close the gap 485 memmove(buf + bucket_length, map_start, map_length); // close the gap
439 486
440 return bucket_length + map_length; 487 return bucket_length + map_length;
441 } 488 }
442 489
490 int HeapProfileTable::FillPseudoStackProfile(char buffer[],
491 int buffer_size) const {
492 Bucket** list = MakeSortedBucketList();
493
494 Stats stats;
495 memset(&stats, 0, sizeof(stats));
496 int written = snprintf(buffer, buffer_size, "[\n");
497 written = UnparsePseudoStackBucket(
498 total_, buffer, written, buffer_size, &stats);
499
500 for (int i = 0; i < num_buckets_; i++) {
501 written += snprintf(buffer + written, buffer_size - written, ",\n");
502 written = UnparsePseudoStackBucket(
503 *list[i], buffer, written, buffer_size, &stats);
504 }
505 RAW_DCHECK(written < buffer_size, "");
506
507 written += snprintf(buffer + written, buffer_size - written, "\n]\n");
508
509 dealloc_(list);
510
511 return written;
512 }
513
443 // static 514 // static
444 void HeapProfileTable::DumpBucketIterator(const Bucket* bucket, 515 void HeapProfileTable::DumpBucketIterator(const Bucket* bucket,
445 BufferArgs* args) { 516 BufferArgs* args) {
446 args->buflen = UnparseBucket(*bucket, args->buf, args->buflen, args->bufsize, 517 args->buflen = UnparseBucket(*bucket, args->buf, args->buflen, args->bufsize,
447 "", NULL); 518 "", NULL);
448 } 519 }
449 520
450 #if defined(TYPE_PROFILING) 521 #if defined(TYPE_PROFILING)
451 // static 522 // static
452 void HeapProfileTable::TallyTypesItererator( 523 void HeapProfileTable::TallyTypesItererator(
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 char* unused) { 812 char* unused) {
742 // Perhaps also log the allocation stack trace (unsymbolized) 813 // Perhaps also log the allocation stack trace (unsymbolized)
743 // on this line in case somebody finds it useful. 814 // on this line in case somebody finds it useful.
744 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr); 815 RAW_LOG(ERROR, "leaked %"PRIuS" byte object %p", v->bytes, ptr);
745 } 816 }
746 817
747 void HeapProfileTable::Snapshot::ReportIndividualObjects() { 818 void HeapProfileTable::Snapshot::ReportIndividualObjects() {
748 char unused; 819 char unused;
749 map_.Iterate(ReportObject, &unused); 820 map_.Iterate(ReportObject, &unused);
750 } 821 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698