OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include "base/trace_event/heap_profiler_allocation_register.h" | 5 #include "base/trace_event/heap_profiler_allocation_register.h" |
6 | 6 |
7 #include "base/trace_event/trace_event_memory_overhead.h" | 7 #include "base/trace_event/trace_event_memory_overhead.h" |
8 | 8 |
9 namespace base { | 9 namespace base { |
10 namespace trace_event { | 10 namespace trace_event { |
(...skipping 25 matching lines...) Expand all Loading... |
36 size_t size, | 36 size_t size, |
37 AllocationContext context) { | 37 AllocationContext context) { |
38 DCHECK(address != nullptr); | 38 DCHECK(address != nullptr); |
39 | 39 |
40 CellIndex* idx_ptr = Lookup(address); | 40 CellIndex* idx_ptr = Lookup(address); |
41 | 41 |
42 // If the index is 0, the address is not yet present, so insert it. | 42 // If the index is 0, the address is not yet present, so insert it. |
43 if (*idx_ptr == 0) { | 43 if (*idx_ptr == 0) { |
44 *idx_ptr = GetFreeCell(); | 44 *idx_ptr = GetFreeCell(); |
45 | 45 |
46 cells_[*idx_ptr].allocation.address = address; | 46 // The address stored in a cell is const as long as it is exposed (via the |
| 47 // iterators or |Get|), but because cells are re-used, a const cast is |
| 48 // required to set it on insert and remove. |
| 49 void* const& allocation_address = cells_[*idx_ptr].allocation.address; |
| 50 const_cast<void*&>(allocation_address) = address; |
47 cells_[*idx_ptr].next = 0; | 51 cells_[*idx_ptr].next = 0; |
48 } | 52 } |
49 | 53 |
50 cells_[*idx_ptr].allocation.size = size; | 54 cells_[*idx_ptr].allocation.size = size; |
51 cells_[*idx_ptr].allocation.context = context; | 55 cells_[*idx_ptr].allocation.context = context; |
52 } | 56 } |
53 | 57 |
54 void AllocationRegister::Remove(void* address) { | 58 void AllocationRegister::Remove(void* address) { |
55 // Get a pointer to the index of the cell that stores |address|. The index can | 59 // Get a pointer to the index of the cell that stores |address|. The index can |
56 // be an element of |buckets_| or the |next| member of a cell. | 60 // be an element of |buckets_| or the |next| member of a cell. |
57 CellIndex* idx_ptr = Lookup(address); | 61 CellIndex* idx_ptr = Lookup(address); |
58 CellIndex freed_idx = *idx_ptr; | 62 CellIndex freed_idx = *idx_ptr; |
59 | 63 |
60 // If the index is 0, the address was not there in the first place. | 64 // If the index is 0, the address was not there in the first place. |
61 if (freed_idx == 0) | 65 if (freed_idx == 0) |
62 return; | 66 return; |
63 | 67 |
64 // The cell at the index is now free, remove it from the linked list for | 68 // The cell at the index is now free, remove it from the linked list for |
65 // |Hash(address)|. | 69 // |Hash(address)|. |
66 Cell* freed_cell = &cells_[freed_idx]; | 70 Cell* freed_cell = &cells_[freed_idx]; |
67 *idx_ptr = freed_cell->next; | 71 *idx_ptr = freed_cell->next; |
68 | 72 |
69 // Put the free cell at the front of the free list. | 73 // Put the free cell at the front of the free list. |
70 freed_cell->next = free_list_; | 74 freed_cell->next = free_list_; |
71 free_list_ = freed_idx; | 75 free_list_ = freed_idx; |
72 | 76 |
73 // Reset the address, so that on iteration the free cell is ignored. | 77 // Reset the address, so that on iteration the free cell is ignored. |
74 freed_cell->allocation.address = nullptr; | 78 const_cast<void*&>(freed_cell->allocation.address) = nullptr; |
| 79 } |
| 80 |
| 81 AllocationRegister::Allocation* AllocationRegister::Get(void* address) { |
| 82 CellIndex* idx_ptr = Lookup(address); |
| 83 |
| 84 // If the index is 0, the address is not present in the table. |
| 85 return *idx_ptr == 0 ? nullptr : &cells_[*idx_ptr].allocation; |
75 } | 86 } |
76 | 87 |
77 AllocationRegister::ConstIterator AllocationRegister::begin() const { | 88 AllocationRegister::ConstIterator AllocationRegister::begin() const { |
78 // Initialize the iterator's index to 0. Cell 0 never stores an entry. | 89 // Initialize the iterator's index to 0. Cell 0 never stores an entry. |
79 ConstIterator iterator(*this, 0); | 90 ConstIterator iterator(*this, 0); |
80 // Incrementing will advance the iterator to the first used cell. | 91 // Incrementing will advance the iterator to the first used cell. |
81 ++iterator; | 92 ++iterator; |
82 return iterator; | 93 return iterator; |
83 } | 94 } |
84 | 95 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 size_t resident = sizeof(AllocationRegister) | 188 size_t resident = sizeof(AllocationRegister) |
178 // Include size of touched cells (size of |*cells_|). | 189 // Include size of touched cells (size of |*cells_|). |
179 + sizeof(Cell) * next_unused_cell_ | 190 + sizeof(Cell) * next_unused_cell_ |
180 // Size of |*buckets_|. | 191 // Size of |*buckets_|. |
181 + sizeof(CellIndex) * kNumBuckets; | 192 + sizeof(CellIndex) * kNumBuckets; |
182 overhead->Add("AllocationRegister", allocated, resident); | 193 overhead->Add("AllocationRegister", allocated, resident); |
183 } | 194 } |
184 | 195 |
185 } // namespace trace_event | 196 } // namespace trace_event |
186 } // namespace base | 197 } // namespace base |
OLD | NEW |