| 871 | } |
| 872 | |
| 873 | void BFCAllocator::DumpMemoryLog(size_t num_bytes) { |
| 874 | const std::array<BinDebugInfo, kNumBins> bin_infos = get_bin_debug_info(); |
| 875 | for (BinNum bin_num = 0; bin_num < kNumBins; bin_num++) { |
| 876 | Bin* b = BinFromIndex(bin_num); |
| 877 | const BinDebugInfo& bin_info = bin_infos[bin_num]; |
| 878 | CHECK_EQ(b->free_chunks.size(), |
| 879 | bin_info.total_chunks_in_bin - bin_info.total_chunks_in_use); |
| 880 | |
| 881 | LOG(INFO) << "Bin (" << b->bin_size |
| 882 | << "): \tTotal Chunks: " << bin_info.total_chunks_in_bin |
| 883 | << ", Chunks in use: " << bin_info.total_chunks_in_use << ". " |
| 884 | << strings::HumanReadableNumBytes(bin_info.total_bytes_in_bin) |
| 885 | << " allocated for chunks. " |
| 886 | << strings::HumanReadableNumBytes(bin_info.total_bytes_in_use) |
| 887 | << " in use in bin. " |
| 888 | << strings::HumanReadableNumBytes( |
| 889 | bin_info.total_requested_bytes_in_use) |
| 890 | << " client-requested in use in bin."; |
| 891 | } |
| 892 | |
| 893 | // Find the bin that we would have liked to allocate in, so we |
| 894 | // can get some further analysis about fragmentation. |
| 895 | Bin* b = BinForSize(num_bytes); |
| 896 | |
| 897 | LOG(INFO) << "Bin for " << strings::HumanReadableNumBytes(num_bytes) |
| 898 | << " was " << strings::HumanReadableNumBytes(b->bin_size) |
| 899 | << ", Chunk State: "; |
| 900 | |
| 901 | for (ChunkHandle h : b->free_chunks) { |
| 902 | Chunk* c = ChunkFromHandle(h); |
| 903 | LOG(INFO) << c->DebugString(this, true); |
| 904 | } |
| 905 | |
| 906 | // Next show the chunks that are in use, and also summarize their |
| 907 | // number by size. |
| 908 | std::map<size_t, int> in_use_by_size; |
| 909 | for (const auto& region : region_manager_.regions()) { |
| 910 | LOG(INFO) << "Next region of size " << region.memory_size(); |
| 911 | ChunkHandle h = region_manager_.get_handle(region.ptr()); |
| 912 | while (h != kInvalidChunkHandle) { |
| 913 | const Chunk* c = ChunkFromHandle(h); |
| 914 | if (c->in_use()) { |
| 915 | in_use_by_size[c->size]++; |
| 916 | } |
| 917 | LOG(INFO) << (c->in_use() ? "InUse" : "Free ") << " at " << c->ptr |
| 918 | << " next " << c->next << " of size " << c->size |
| 919 | << (timing_counter_ |
| 920 | ? strings::StrCat(" freed_at_count ", c->freed_at_count) |
| 921 | : ""); |
| 922 | h = c->next; |
| 923 | } |
| 924 | } |
| 925 | |
| 926 | LOG(INFO) << " Summary of in-use Chunks by size: "; |
| 927 | size_t total_bytes = 0; |
| 928 | for (auto& it : in_use_by_size) { |
| 929 | LOG(INFO) << it.second << " Chunks of size " << it.first << " totalling " |
| 930 | << strings::HumanReadableNumBytes(it.first * it.second); |
nothing calls this directly
no test coverage detected