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 <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 // are part of a linked list via the |next| member. This list is either the | 94 // are part of a linked list via the |next| member. This list is either the |
95 // list for a particular hash, or the free list. All cells are contiguous in | 95 // list for a particular hash, or the free list. All cells are contiguous in |
96 // memory in one big array. Therefore, on 64-bit systems, space can be saved | 96 // memory in one big array. Therefore, on 64-bit systems, space can be saved |
97 // by storing 32-bit indices instead of pointers as links. Index 0 is used as | 97 // by storing 32-bit indices instead of pointers as links. Index 0 is used as |
98 // the list terminator. | 98 // the list terminator. |
99 struct Cell { | 99 struct Cell { |
100 CellIndex next; | 100 CellIndex next; |
101 Allocation allocation; | 101 Allocation allocation; |
102 }; | 102 }; |
103 | 103 |
104 // The number of buckets, 2^18, approximately 260 000, has been tuned for | 104 // The number of buckets, 2^17, approximately 130 000, has been tuned for |
105 // Chrome's typical number of outstanding allocations. (This number varies | 105 // Chrome's typical number of outstanding allocations. (This number varies |
106 // between processes. Most processes have a sustained load of ~30k unfreed | 106 // between processes. Most processes have a sustained load of ~30k unfreed |
107 // allocations, but some processes have peeks around 100k-400k allocations.) | 107 // allocations, but some processes have peeks around 100k-400k allocations.) |
108 // Because of the size of the table, it is likely that every |buckets_| | 108 // Because of the size of the table, it is likely that every |buckets_| |
109 // access and every |cells_| access will incur a cache miss. Microbenchmarks | 109 // access and every |cells_| access will incur a cache miss. Microbenchmarks |
110 // suggest that it is worthwile to use more memory for the table to avoid | 110 // suggest that it is worthwile to use more memory for the table to avoid |
111 // chasing down the linked list, until the size is 2^18. The number of buckets | 111 // chasing down the linked list, until the size is 2^18. The number of buckets |
112 // is a power of two so modular indexing can be done with bitwise and. | 112 // is a power of two so modular indexing can be done with bitwise and. |
113 static const uint32_t kNumBuckets = 0x40000; | 113 static const uint32_t kNumBuckets = 0x20000; |
114 static const uint32_t kNumBucketsMask = kNumBuckets - 1; | 114 static const uint32_t kNumBucketsMask = kNumBuckets - 1; |
115 | 115 |
116 // Reserve address space to store at most this number of entries. High | 116 // Reserve address space to store at most this number of entries. High |
117 // capacity does not imply high memory usage due to the access pattern. The | 117 // capacity does not imply high memory usage due to the access pattern. The |
118 // only constraint on the number of cells is that on 32-bit systems address | 118 // only constraint on the number of cells is that on 32-bit systems address |
119 // space is scarce (i.e. reserving 2GiB of address space for the entries is | 119 // space is scarce (i.e. reserving 2GiB of address space for the entries is |
120 // not an option). A value of ~3M entries is large enough to handle spikes in | 120 // not an option). A value of ~3M entries is large enough to handle spikes in |
121 // the number of allocations, and modest enough to require no more than a few | 121 // the number of allocations, and modest enough to require no more than a few |
122 // dozens of MiB of address space. | 122 // dozens of MiB of address space. |
123 static const uint32_t kNumCellsPerBucket = 10; | 123 static const uint32_t kNumCellsPerBucket = 10; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 // is used. This is the high water mark for the number of entries stored. | 167 // is used. This is the high water mark for the number of entries stored. |
168 CellIndex next_unused_cell_; | 168 CellIndex next_unused_cell_; |
169 | 169 |
170 DISALLOW_COPY_AND_ASSIGN(AllocationRegister); | 170 DISALLOW_COPY_AND_ASSIGN(AllocationRegister); |
171 }; | 171 }; |
172 | 172 |
173 } // namespace trace_event | 173 } // namespace trace_event |
174 } // namespace base | 174 } // namespace base |
175 | 175 |
176 #endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ | 176 #endif // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_REGISTER_H_ |
OLD | NEW |