Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // --- | 5 // --- |
| 6 // Author: Sainbayar Sukhbaatar | 6 // Author: Sainbayar Sukhbaatar |
| 7 // Dai Mikurube | 7 // Dai Mikurube |
| 8 // | 8 // |
| 9 | 9 |
| 10 #include "deep-heap-profile.h" | 10 #include "deep-heap-profile.h" |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 *hash_value += add; | 428 *hash_value += add; |
| 429 *hash_value += *hash_value << 10; | 429 *hash_value += *hash_value << 10; |
| 430 *hash_value ^= *hash_value >> 6; | 430 *hash_value ^= *hash_value >> 6; |
| 431 } | 431 } |
| 432 | 432 |
| 433 // GetDeepBucket is implemented as almost copy of heap-profile-table:GetBucket. | 433 // GetDeepBucket is implemented as almost copy of heap-profile-table:GetBucket. |
| 434 // It's to avoid modifying heap-profile-table. Performance issues can be | 434 // It's to avoid modifying heap-profile-table. Performance issues can be |
| 435 // ignored in usual Chromium runs. Another hash function can be tried in an | 435 // ignored in usual Chromium runs. Another hash function can be tried in an |
| 436 // easy way in future. | 436 // easy way in future. |
| 437 DeepHeapProfile::DeepBucket* DeepHeapProfile::GetDeepBucket( | 437 DeepHeapProfile::DeepBucket* DeepHeapProfile::GetDeepBucket( |
| 438 Bucket* bucket, bool is_mmap, DeepBucket **table) { | 438 Bucket* bucket, bool is_mmap, |
| 439 #if defined(PROFILING_ALLOCATED_TYPE) | |
| 440 const std::type_info* type, | |
| 441 #endif | |
| 442 DeepBucket **table) { | |
| 439 // Make hash-value | 443 // Make hash-value |
| 440 uintptr_t h = 0; | 444 uintptr_t h = 0; |
| 441 | 445 |
| 442 AddIntegerToHashValue(reinterpret_cast<uintptr_t>(bucket), &h); | 446 AddIntegerToHashValue(reinterpret_cast<uintptr_t>(bucket), &h); |
| 443 if (is_mmap) | 447 if (is_mmap) |
| 444 AddIntegerToHashValue(1, &h); | 448 AddIntegerToHashValue(1, &h); |
| 445 else | 449 else |
| 446 AddIntegerToHashValue(0, &h); | 450 AddIntegerToHashValue(0, &h); |
| 451 #if defined(PROFILING_ALLOCATED_TYPE) | |
| 452 if (type == NULL) | |
|
M-A Ruel
2012/08/19 02:40:00
Mixing #if and conditions without bracket is a rec
Dai Mikurube (NOT FULLTIME)
2012/08/20 10:35:27
Done.
| |
| 453 AddIntegerToHashValue(0, &h); | |
| 454 else | |
| 455 AddIntegerToHashValue(reinterpret_cast<uintptr_t>(type->name()), &h); | |
| 456 #endif | |
| 447 | 457 |
| 448 h += h << 3; | 458 h += h << 3; |
| 449 h ^= h >> 11; | 459 h ^= h >> 11; |
| 450 | 460 |
| 451 // Lookup stack trace in table | 461 // Lookup stack trace in table |
| 452 unsigned int buck = ((unsigned int) h) % kHashTableSize; | 462 unsigned int buck = ((unsigned int) h) % kHashTableSize; |
| 453 for (DeepBucket* db = table[buck]; db != 0; db = db->next) { | 463 for (DeepBucket* db = table[buck]; db != 0; db = db->next) { |
| 454 if (db->bucket == bucket) { | 464 if (db->bucket == bucket) { |
| 455 return db; | 465 return db; |
| 456 } | 466 } |
| 457 } | 467 } |
| 458 | 468 |
| 459 // Create new bucket | 469 // Create new bucket |
| 460 DeepBucket* db = | 470 DeepBucket* db = |
| 461 reinterpret_cast<DeepBucket*>(heap_profile_->alloc_(sizeof(DeepBucket))); | 471 reinterpret_cast<DeepBucket*>(heap_profile_->alloc_(sizeof(DeepBucket))); |
| 462 memset(db, 0, sizeof(*db)); | 472 memset(db, 0, sizeof(*db)); |
| 463 db->bucket = bucket; | 473 db->bucket = bucket; |
| 474 #if defined(PROFILING_ALLOCATED_TYPE) | |
| 475 db->type = type; | |
| 476 #endif | |
| 464 db->committed_size = 0; | 477 db->committed_size = 0; |
| 465 db->is_mmap = is_mmap; | 478 db->is_mmap = is_mmap; |
| 466 db->id = (bucket_id_++); | 479 db->id = (bucket_id_++); |
| 467 db->is_logged = false; | 480 db->is_logged = false; |
| 468 db->next = table[buck]; | 481 db->next = table[buck]; |
| 469 table[buck] = db; | 482 table[buck] = db; |
| 470 return db; | 483 return db; |
| 471 } | 484 } |
| 472 | 485 |
| 473 void DeepHeapProfile::ResetCommittedSize(DeepBucket** deep_table) { | 486 void DeepHeapProfile::ResetCommittedSize(DeepBucket** deep_table) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 514 } | 527 } |
| 515 | 528 |
| 516 void DeepHeapProfile::RecordAlloc(const void* pointer, | 529 void DeepHeapProfile::RecordAlloc(const void* pointer, |
| 517 AllocValue* alloc_value, | 530 AllocValue* alloc_value, |
| 518 DeepHeapProfile* deep_profile) { | 531 DeepHeapProfile* deep_profile) { |
| 519 uint64 address = reinterpret_cast<uintptr_t>(pointer); | 532 uint64 address = reinterpret_cast<uintptr_t>(pointer); |
| 520 size_t committed = GetCommittedSize(deep_profile->pagemap_fd_, | 533 size_t committed = GetCommittedSize(deep_profile->pagemap_fd_, |
| 521 address, address + alloc_value->bytes - 1); | 534 address, address + alloc_value->bytes - 1); |
| 522 | 535 |
| 523 DeepBucket* deep_bucket = deep_profile->GetDeepBucket( | 536 DeepBucket* deep_bucket = deep_profile->GetDeepBucket( |
| 524 alloc_value->bucket(), /* is_mmap */ false, deep_profile->deep_table_); | 537 alloc_value->bucket(), /* is_mmap */ false, |
| 538 #if defined(PROFILING_ALLOCATED_TYPE) | |
| 539 LookupAllocatedType(pointer), | |
| 540 #endif | |
| 541 deep_profile->deep_table_); | |
| 525 deep_bucket->committed_size += committed; | 542 deep_bucket->committed_size += committed; |
| 526 deep_profile->stats_.profiled_malloc.AddToVirtualBytes(alloc_value->bytes); | 543 deep_profile->stats_.profiled_malloc.AddToVirtualBytes(alloc_value->bytes); |
| 527 deep_profile->stats_.profiled_malloc.AddToCommittedBytes(committed); | 544 deep_profile->stats_.profiled_malloc.AddToCommittedBytes(committed); |
| 528 } | 545 } |
| 529 | 546 |
| 530 void DeepHeapProfile::RecordMMap(const void* pointer, | 547 void DeepHeapProfile::RecordMMap(const void* pointer, |
| 531 AllocValue* alloc_value, | 548 AllocValue* alloc_value, |
| 532 DeepHeapProfile* deep_profile) { | 549 DeepHeapProfile* deep_profile) { |
| 533 uint64 address = reinterpret_cast<uintptr_t>(pointer); | 550 uint64 address = reinterpret_cast<uintptr_t>(pointer); |
| 534 size_t committed = GetCommittedSize(deep_profile->pagemap_fd_, | 551 size_t committed = GetCommittedSize(deep_profile->pagemap_fd_, |
| 535 address, address + alloc_value->bytes - 1); | 552 address, address + alloc_value->bytes - 1); |
| 536 | 553 |
| 537 DeepBucket* deep_bucket = deep_profile->GetDeepBucket( | 554 DeepBucket* deep_bucket = deep_profile->GetDeepBucket( |
| 538 alloc_value->bucket(), /* is_mmap */ true, deep_profile->deep_table_); | 555 alloc_value->bucket(), /* is_mmap */ true, |
| 556 #if defined(PROFILING_ALLOCATED_TYPE) | |
| 557 NULL, | |
| 558 #endif | |
| 559 deep_profile->deep_table_); | |
| 539 deep_bucket->committed_size += committed; | 560 deep_bucket->committed_size += committed; |
| 540 deep_profile->stats_.profiled_mmap.AddToVirtualBytes(alloc_value->bytes); | 561 deep_profile->stats_.profiled_mmap.AddToVirtualBytes(alloc_value->bytes); |
| 541 deep_profile->stats_.profiled_mmap.AddToCommittedBytes(committed); | 562 deep_profile->stats_.profiled_mmap.AddToCommittedBytes(committed); |
| 542 | 563 |
| 543 if (deep_profile->mmap_list_length_ < deep_profile->num_mmap_allocations_) { | 564 if (deep_profile->mmap_list_length_ < deep_profile->num_mmap_allocations_) { |
| 544 deep_profile->mmap_list_[deep_profile->mmap_list_length_].first_address = | 565 deep_profile->mmap_list_[deep_profile->mmap_list_length_].first_address = |
| 545 address; | 566 address; |
| 546 deep_profile->mmap_list_[deep_profile->mmap_list_length_].last_address = | 567 deep_profile->mmap_list_[deep_profile->mmap_list_length_].last_address = |
| 547 address - 1 + alloc_value->bytes; | 568 address - 1 + alloc_value->bytes; |
| 548 deep_profile->mmap_list_[deep_profile->mmap_list_length_].type = ABSENT; | 569 deep_profile->mmap_list_[deep_profile->mmap_list_length_].type = ABSENT; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 576 } | 597 } |
| 577 int used_in_buffer = printed; | 598 int used_in_buffer = printed; |
| 578 | 599 |
| 579 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, | 600 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, |
| 580 " %s", deep_bucket->is_mmap ? "mmap" : "malloc"); | 601 " %s", deep_bucket->is_mmap ? "mmap" : "malloc"); |
| 581 if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { | 602 if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { |
| 582 return used_in_buffer; | 603 return used_in_buffer; |
| 583 } | 604 } |
| 584 used_in_buffer += printed; | 605 used_in_buffer += printed; |
| 585 | 606 |
| 607 #if defined(PROFILING_ALLOCATED_TYPE) | |
| 608 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, | |
| 609 " t0x%" PRIxPTR, | |
| 610 reinterpret_cast<uintptr_t>(deep_bucket->type)); | |
| 611 if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { | |
| 612 return used_in_buffer; | |
| 613 } | |
| 614 used_in_buffer += printed; | |
| 615 | |
| 616 if (deep_bucket->type == NULL) { | |
| 617 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, | |
| 618 " nno_typeinfo"); | |
| 619 } else { | |
| 620 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, | |
| 621 " n%s", deep_bucket->type->name()); | |
| 622 } | |
| 623 if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { | |
| 624 return used_in_buffer; | |
| 625 } | |
| 626 used_in_buffer += printed; | |
| 627 #endif | |
| 628 | |
| 586 for (int depth = 0; depth < bucket->depth; depth++) { | 629 for (int depth = 0; depth < bucket->depth; depth++) { |
| 587 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, | 630 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, |
| 588 " 0x%08" PRIxPTR, | 631 " 0x%08" PRIxPTR, |
| 589 reinterpret_cast<uintptr_t>(bucket->stack[depth])); | 632 reinterpret_cast<uintptr_t>(bucket->stack[depth])); |
| 590 if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { | 633 if (IsPrintedStringValid(printed, buffer_size, used_in_buffer)) { |
| 591 return used_in_buffer; | 634 return used_in_buffer; |
| 592 } | 635 } |
| 593 used_in_buffer += printed; | 636 used_in_buffer += printed; |
| 594 } | 637 } |
| 595 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, | 638 printed = snprintf(buffer + used_in_buffer, buffer_size - used_in_buffer, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 764 } | 807 } |
| 765 | 808 |
| 766 DeepHeapProfile::~DeepHeapProfile() { | 809 DeepHeapProfile::~DeepHeapProfile() { |
| 767 } | 810 } |
| 768 | 811 |
| 769 int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) { | 812 int DeepHeapProfile::FillOrderedProfile(char buffer[], int buffer_size) { |
| 770 return heap_profile_->FillOrderedProfile(buffer, buffer_size); | 813 return heap_profile_->FillOrderedProfile(buffer, buffer_size); |
| 771 } | 814 } |
| 772 | 815 |
| 773 #endif // DEEP_HEAP_PROFILE | 816 #endif // DEEP_HEAP_PROFILE |
| OLD | NEW |