| 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 #ifndef BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ | 5 #ifndef BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ |
| 6 #define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ | 6 #define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 friend class AllocationRegister; | 53 friend class AllocationRegister; |
| 54 using CellIndex = uint32_t; | 54 using CellIndex = uint32_t; |
| 55 | 55 |
| 56 ConstIterator(const AllocationRegister& alloc_register, CellIndex index); | 56 ConstIterator(const AllocationRegister& alloc_register, CellIndex index); |
| 57 | 57 |
| 58 const AllocationRegister& register_; | 58 const AllocationRegister& register_; |
| 59 CellIndex index_; | 59 CellIndex index_; |
| 60 }; | 60 }; |
| 61 | 61 |
| 62 AllocationRegister(); | 62 AllocationRegister(); |
| 63 explicit AllocationRegister(uint32_t num_cells); | |
| 64 | |
| 65 ~AllocationRegister(); | 63 ~AllocationRegister(); |
| 66 | 64 |
| 67 // Inserts allocation details into the table. If the address was present | 65 // Inserts allocation details into the table. If the address was present |
| 68 // already, its details are updated. |address| must not be null. (This is | 66 // already, its details are updated. |address| must not be null. (This is |
| 69 // because null is used to mark free cells, to allow efficient iteration of | 67 // because null is used to mark free cells, to allow efficient iteration of |
| 70 // the hash table.) | 68 // the hash table.) |
| 71 void Insert(void* address, size_t size, AllocationContext context); | 69 void Insert(void* address, size_t size, AllocationContext context); |
| 72 | 70 |
| 73 // Removes the address from the table if it is present. It is ok to call this | 71 // Removes the address from the table if it is present. It is ok to call this |
| 74 // with a null pointer. | 72 // with a null pointer. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 static const uint32_t kNumBuckets = 0x40000; | 105 static const uint32_t kNumBuckets = 0x40000; |
| 108 static const uint32_t kNumBucketsMask = kNumBuckets - 1; | 106 static const uint32_t kNumBucketsMask = kNumBuckets - 1; |
| 109 | 107 |
| 110 // Reserve address space to store at most this number of entries. High | 108 // Reserve address space to store at most this number of entries. High |
| 111 // capacity does not imply high memory usage due to the access pattern. The | 109 // capacity does not imply high memory usage due to the access pattern. The |
| 112 // only constraint on the number of cells is that on 32-bit systems address | 110 // only constraint on the number of cells is that on 32-bit systems address |
| 113 // space is scarce (i.e. reserving 2GiB of address space for the entries is | 111 // space is scarce (i.e. reserving 2GiB of address space for the entries is |
| 114 // not an option). A value of ~3M entries is large enough to handle spikes in | 112 // not an option). A value of ~3M entries is large enough to handle spikes in |
| 115 // the number of allocations, and modest enough to require no more than a few | 113 // the number of allocations, and modest enough to require no more than a few |
| 116 // dozens of MiB of address space. | 114 // dozens of MiB of address space. |
| 117 static const uint32_t kNumCellsPerBucket = 10; | 115 static const uint32_t kNumCells = kNumBuckets * 10; |
| 118 | 116 |
| 119 // Returns a value in the range [0, kNumBuckets - 1] (inclusive). | 117 // Returns a value in the range [0, kNumBuckets - 1] (inclusive). |
| 120 static uint32_t Hash(void* address); | 118 static uint32_t Hash(void* address); |
| 121 | 119 |
| 122 // Allocates a region of virtual address space of |size| rounded up to the | 120 // Allocates a region of virtual address space of |size| rounded up to the |
| 123 // system page size. The memory is zeroed by the system. A guard page is | 121 // system page size. The memory is zeroed by the system. A guard page is |
| 124 // added after the end. | 122 // added after the end. |
| 125 static void* AllocateVirtualMemory(size_t size); | 123 static void* AllocateVirtualMemory(size_t size); |
| 126 | 124 |
| 127 // Frees a region of virtual address space allocated by a call to | 125 // Frees a region of virtual address space allocated by a call to |
| 128 // |AllocateVirtualMemory|. | 126 // |AllocateVirtualMemory|. |
| 129 static void FreeVirtualMemory(void* address, size_t allocated_size); | 127 static void FreeVirtualMemory(void* address, size_t allocated_size); |
| 130 | 128 |
| 131 // Returns a pointer to the variable that contains or should contain the | 129 // Returns a pointer to the variable that contains or should contain the |
| 132 // index of the cell that stores the entry for |address|. The pointer may | 130 // index of the cell that stores the entry for |address|. The pointer may |
| 133 // point at an element of |buckets_| or at the |next| member of an element of | 131 // point at an element of |buckets_| or at the |next| member of an element of |
| 134 // |cells_|. If the value pointed at is 0, |address| is not in the table. | 132 // |cells_|. If the value pointed at is 0, |address| is not in the table. |
| 135 CellIndex* Lookup(void* address); | 133 CellIndex* Lookup(void* address); |
| 136 | 134 |
| 137 // Takes a cell that is not being used to store an entry (either by recycling | 135 // Takes a cell that is not being used to store an entry (either by recycling |
| 138 // from the free list or by taking a fresh cell) and returns its index. | 136 // from the free list or by taking a fresh cell) and returns its index. |
| 139 CellIndex GetFreeCell(); | 137 CellIndex GetFreeCell(); |
| 140 | 138 |
| 141 // The maximum number of cells which can be allocated. | |
| 142 uint32_t const num_cells_; | |
| 143 | |
| 144 // The array of cells. This array is backed by mmapped memory. Lower indices | 139 // The array of cells. This array is backed by mmapped memory. Lower indices |
| 145 // are accessed first, higher indices are only accessed when required. In | 140 // are accessed first, higher indices are only accessed when required. In |
| 146 // this way, even if a huge amount of address space has been mmapped, only | 141 // this way, even if a huge amount of address space has been mmapped, only |
| 147 // the cells that are actually used will be backed by physical memory. | 142 // the cells that are actually used will be backed by physical memory. |
| 148 Cell* const cells_; | 143 Cell* const cells_; |
| 149 | 144 |
| 150 // The array of indices into |cells_|. |buckets_[Hash(address)]| will contain | 145 // The array of indices into |cells_|. |buckets_[Hash(address)]| will contain |
| 151 // the index of the head of the linked list for |Hash(address)|. A value of 0 | 146 // the index of the head of the linked list for |Hash(address)|. A value of 0 |
| 152 // indicates an empty list. This array is backed by mmapped memory. | 147 // indicates an empty list. This array is backed by mmapped memory. |
| 153 CellIndex* const buckets_; | 148 CellIndex* const buckets_; |
| 154 | 149 |
| 155 // The head of the free list. This is the index of the cell. A value of 0 | 150 // The head of the free list. This is the index of the cell. A value of 0 |
| 156 // means that the free list is empty. | 151 // means that the free list is empty. |
| 157 CellIndex free_list_; | 152 CellIndex free_list_; |
| 158 | 153 |
| 159 // The index of the first element of |cells_| that has not been used before. | 154 // The index of the first element of |cells_| that has not been used before. |
| 160 // If the free list is empty and a new cell is needed, the cell at this index | 155 // If the free list is empty and a new cell is needed, the cell at this index |
| 161 // is used. This is the high water mark for the number of entries stored. | 156 // is used. This is the high water mark for the number of entries stored. |
| 162 CellIndex next_unused_cell_; | 157 CellIndex next_unused_cell_; |
| 163 | 158 |
| 164 DISALLOW_COPY_AND_ASSIGN(AllocationRegister); | 159 DISALLOW_COPY_AND_ASSIGN(AllocationRegister); |
| 165 }; | 160 }; |
| 166 | 161 |
| 167 } // namespace trace_event | 162 } // namespace trace_event |
| 168 } // namespace base | 163 } // namespace base |
| 169 | 164 |
| 170 #endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ | 165 #endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ |
| OLD | NEW |