| 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 |