| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 | 122 |
| 123 // Check every page on which the allocation resides. | 123 // Check every page on which the allocation resides. |
| 124 while (page_address <= last_address) { | 124 while (page_address <= last_address) { |
| 125 // Read corresponding physical page. | 125 // Read corresponding physical page. |
| 126 State state; | 126 State state; |
| 127 // TODO(dmikurube): Read pagemap in bulk for speed. | 127 // TODO(dmikurube): Read pagemap in bulk for speed. |
| 128 // TODO(dmikurube): Consider using mincore(2). | 128 // TODO(dmikurube): Consider using mincore(2). |
| 129 if (Read(&state, pageframe_type_ != DUMP_NO_PAGEFRAME) == false) { | 129 if (Read(&state, pageframe_type_ != DUMP_NO_PAGEFRAME) == false) { |
| 130 // We can't read the last region (e.g vsyscall). | 130 // We can't read the last region (e.g vsyscall). |
| 131 #ifndef NDEBUG | 131 #ifndef NDEBUG |
| 132 RAW_LOG(0, "pagemap read failed @ %#llx %"PRId64" bytes", | 132 RAW_LOG(0, "pagemap read failed @ %#llx %" PRId64 " bytes", |
| 133 first_address, last_address - first_address + 1); | 133 first_address, last_address - first_address + 1); |
| 134 #endif | 134 #endif |
| 135 return 0; | 135 return 0; |
| 136 } | 136 } |
| 137 | 137 |
| 138 // Dump pageframes of resident pages. Non-resident pages are just skipped. | 138 // Dump pageframes of resident pages. Non-resident pages are just skipped. |
| 139 if (pageframe_type_ != DUMP_NO_PAGEFRAME && | 139 if (pageframe_type_ != DUMP_NO_PAGEFRAME && |
| 140 buffer != NULL && state.pfn != 0) { | 140 buffer != NULL && state.pfn != 0) { |
| 141 if (pageframe_list_length == 0) { | 141 if (pageframe_list_length == 0) { |
| 142 buffer->AppendString(" PF:", 0); | 142 buffer->AppendString(" PF:", 0); |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 else | 488 else |
| 489 appended = snprintf(position, available, "%*lu", width, value); | 489 appended = snprintf(position, available, "%*lu", width, value); |
| 490 return ForwardCursor(appended); | 490 return ForwardCursor(appended); |
| 491 } | 491 } |
| 492 | 492 |
| 493 bool DeepHeapProfile::TextBuffer::AppendInt64(int64 value, int width) { | 493 bool DeepHeapProfile::TextBuffer::AppendInt64(int64 value, int width) { |
| 494 char* position = buffer_ + cursor_; | 494 char* position = buffer_ + cursor_; |
| 495 int available = size_ - cursor_; | 495 int available = size_ - cursor_; |
| 496 int appended; | 496 int appended; |
| 497 if (width == 0) | 497 if (width == 0) |
| 498 appended = snprintf(position, available, "%"PRId64, value); | 498 appended = snprintf(position, available, "%" PRId64, value); |
| 499 else | 499 else |
| 500 appended = snprintf(position, available, "%*"PRId64, width, value); | 500 appended = snprintf(position, available, "%*" PRId64, width, value); |
| 501 return ForwardCursor(appended); | 501 return ForwardCursor(appended); |
| 502 } | 502 } |
| 503 | 503 |
| 504 bool DeepHeapProfile::TextBuffer::AppendPtr(uint64 value, int width) { | 504 bool DeepHeapProfile::TextBuffer::AppendPtr(uint64 value, int width) { |
| 505 char* position = buffer_ + cursor_; | 505 char* position = buffer_ + cursor_; |
| 506 int available = size_ - cursor_; | 506 int available = size_ - cursor_; |
| 507 int appended; | 507 int appended; |
| 508 if (width == 0) | 508 if (width == 0) |
| 509 appended = snprintf(position, available, "%"PRIx64, value); | 509 appended = snprintf(position, available, "%" PRIx64, value); |
| 510 else | 510 else |
| 511 appended = snprintf(position, available, "%0*"PRIx64, width, value); | 511 appended = snprintf(position, available, "%0*" PRIx64, width, value); |
| 512 return ForwardCursor(appended); | 512 return ForwardCursor(appended); |
| 513 } | 513 } |
| 514 | 514 |
| 515 bool DeepHeapProfile::TextBuffer::AppendBase64(uint64 value, int width) { | 515 bool DeepHeapProfile::TextBuffer::AppendBase64(uint64 value, int width) { |
| 516 static const char base64[65] = | 516 static const char base64[65] = |
| 517 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | 517 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 518 #if defined(__BIG_ENDIAN__) | 518 #if defined(__BIG_ENDIAN__) |
| 519 value = bswap_64(value); | 519 value = bswap_64(value); |
| 520 #endif | 520 #endif |
| 521 for (int shift = (width - 1) * 6; shift >= 0; shift -= 6) { | 521 for (int shift = (width - 1) * 6; shift >= 0; shift -= 6) { |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 } | 940 } |
| 941 } while (mmap_iter != MemoryRegionMap::EndRegionLocked() && | 941 } while (mmap_iter != MemoryRegionMap::EndRegionLocked() && |
| 942 mmap_iter->end_addr - 1 <= vma_last_addr); | 942 mmap_iter->end_addr - 1 <= vma_last_addr); |
| 943 } | 943 } |
| 944 | 944 |
| 945 if (vma_total != vma_subtotal) { | 945 if (vma_total != vma_subtotal) { |
| 946 char buffer[1024]; | 946 char buffer[1024]; |
| 947 int written = procmaps_iter.FormatLine(buffer, sizeof(buffer), | 947 int written = procmaps_iter.FormatLine(buffer, sizeof(buffer), |
| 948 vma_start_addr, vma_last_addr, | 948 vma_start_addr, vma_last_addr, |
| 949 flags, offset, inode, filename, 0); | 949 flags, offset, inode, filename, 0); |
| 950 RAW_LOG(0, "[%d] Mismatched total in VMA %"PRId64":%"PRId64" (%"PRId64")", | 950 RAW_LOG(0, "[%d] Mismatched total in VMA %" PRId64 ":" |
| 951 "%" PRId64 " (%" PRId64 ")", |
| 951 getpid(), vma_total, vma_subtotal, vma_total - vma_subtotal); | 952 getpid(), vma_total, vma_subtotal, vma_total - vma_subtotal); |
| 952 RAW_LOG(0, "[%d] in %s", getpid(), buffer); | 953 RAW_LOG(0, "[%d] in %s", getpid(), buffer); |
| 953 } | 954 } |
| 954 } | 955 } |
| 955 | 956 |
| 956 // TODO(dmikurube): Investigate and fix http://crbug.com/189114. | 957 // TODO(dmikurube): Investigate and fix http://crbug.com/189114. |
| 957 // | 958 // |
| 958 // The total committed memory usage in all_ (from /proc/<pid>/maps) is | 959 // The total committed memory usage in all_ (from /proc/<pid>/maps) is |
| 959 // sometimes smaller than the sum of the committed mmap'ed addresses and | 960 // sometimes smaller than the sum of the committed mmap'ed addresses and |
| 960 // unhooked regions. Within our observation, the difference was only 4KB | 961 // unhooked regions. Within our observation, the difference was only 4KB |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 DeepHeapProfile::~DeepHeapProfile() { | 1119 DeepHeapProfile::~DeepHeapProfile() { |
| 1119 } | 1120 } |
| 1120 | 1121 |
| 1121 int DeepHeapProfile::DumpOrderedProfile(const char* reason, | 1122 int DeepHeapProfile::DumpOrderedProfile(const char* reason, |
| 1122 char raw_buffer[], | 1123 char raw_buffer[], |
| 1123 int buffer_size, | 1124 int buffer_size, |
| 1124 RawFD fd) { | 1125 RawFD fd) { |
| 1125 } | 1126 } |
| 1126 | 1127 |
| 1127 #endif // USE_DEEP_HEAP_PROFILE | 1128 #endif // USE_DEEP_HEAP_PROFILE |
| OLD | NEW |