OLD | NEW |
1 // Copyright (c) 2008, Google Inc. | 1 // Copyright (c) 2008, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 16 matching lines...) Expand all Loading... |
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | 29 |
30 // --- | 30 // --- |
31 // Author: Sanjay Ghemawat <opensource@google.com> | 31 // Author: Sanjay Ghemawat <opensource@google.com> |
32 | 32 |
33 #ifndef TCMALLOC_PAGE_HEAP_H_ | 33 #ifndef TCMALLOC_PAGE_HEAP_H_ |
34 #define TCMALLOC_PAGE_HEAP_H_ | 34 #define TCMALLOC_PAGE_HEAP_H_ |
35 | 35 |
36 #include <config.h> | 36 #include <config.h> |
| 37 #include <stddef.h> // for size_t |
| 38 #ifdef HAVE_STDINT_H |
| 39 #include <stdint.h> // for uint64_t, int64_t, uint16_t |
| 40 #endif |
37 #include <google/malloc_extension.h> | 41 #include <google/malloc_extension.h> |
| 42 #include "base/basictypes.h" |
38 #include "common.h" | 43 #include "common.h" |
39 #include "packed-cache-inl.h" | 44 #include "packed-cache-inl.h" |
40 #include "pagemap.h" | 45 #include "pagemap.h" |
41 #include "span.h" | 46 #include "span.h" |
42 | 47 |
43 // We need to dllexport PageHeap just for the unittest. MSVC complains | 48 // We need to dllexport PageHeap just for the unittest. MSVC complains |
44 // that we don't dllexport the PageHeap members, but we don't need to | 49 // that we don't dllexport the PageHeap members, but we don't need to |
45 // test those, so I just suppress this warning. | 50 // test those, so I just suppress this warning. |
46 #ifdef _MSC_VER | 51 #ifdef _MSC_VER |
47 #pragma warning(push) | 52 #pragma warning(push) |
48 #pragma warning(disable:4251) | 53 #pragma warning(disable:4251) |
49 #endif | 54 #endif |
50 | 55 |
51 // This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if | 56 // This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if |
52 // you're porting to a system where you really can't get a stacktrace. | 57 // you're porting to a system where you really can't get a stacktrace. |
| 58 // Because we control the definition of GetStackTrace, all clients of |
| 59 // GetStackTrace should #include us rather than stacktrace.h. |
53 #ifdef NO_TCMALLOC_SAMPLES | 60 #ifdef NO_TCMALLOC_SAMPLES |
54 // We use #define so code compiles even if you #include stacktrace.h somehow. | 61 // We use #define so code compiles even if you #include stacktrace.h somehow. |
55 # define GetStackTrace(stack, depth, skip) (0) | 62 # define GetStackTrace(stack, depth, skip) (0) |
56 #else | 63 #else |
57 # include <google/stacktrace.h> | 64 # include <google/stacktrace.h> |
58 #endif | 65 #endif |
59 | 66 |
| 67 class TCMalloc_Printer; |
| 68 namespace base { |
| 69 struct MallocRange; |
| 70 } |
| 71 |
60 namespace tcmalloc { | 72 namespace tcmalloc { |
61 | 73 |
62 // ------------------------------------------------------------------------- | 74 // ------------------------------------------------------------------------- |
63 // Map from page-id to per-page data | 75 // Map from page-id to per-page data |
64 // ------------------------------------------------------------------------- | 76 // ------------------------------------------------------------------------- |
65 | 77 |
66 // We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines. | 78 // We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines. |
67 // ...except... | 79 // ...except... |
68 // On Windows, we use TCMalloc_PageMap1_LazyCommit<> for 32-bit machines. | 80 // On Windows, we use TCMalloc_PageMap1_LazyCommit<> for 32-bit machines. |
69 // We also use a simple one-level cache for hot PageID-to-sizeclass mappings, | 81 // We also use a simple one-level cache for hot PageID-to-sizeclass mappings, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 // Page heap statistics | 155 // Page heap statistics |
144 struct Stats { | 156 struct Stats { |
145 Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0) {} | 157 Stats() : system_bytes(0), free_bytes(0), unmapped_bytes(0) {} |
146 uint64_t system_bytes; // Total bytes allocated from system | 158 uint64_t system_bytes; // Total bytes allocated from system |
147 uint64_t free_bytes; // Total bytes on normal freelists | 159 uint64_t free_bytes; // Total bytes on normal freelists |
148 uint64_t unmapped_bytes; // Total bytes on returned freelists | 160 uint64_t unmapped_bytes; // Total bytes on returned freelists |
149 uint64_t committed_bytes; // Bytes committed, always <= system_bytes_. | 161 uint64_t committed_bytes; // Bytes committed, always <= system_bytes_. |
150 | 162 |
151 }; | 163 }; |
152 inline Stats stats() const { return stats_; } | 164 inline Stats stats() const { return stats_; } |
| 165 void GetClassSizes(int64 class_sizes_normal[kMaxPages], |
| 166 int64 class_sizes_returned[kMaxPages], |
| 167 int64* normal_pages_in_spans, |
| 168 int64* returned_pages_in_spans); |
153 | 169 |
154 bool Check(); | 170 bool Check(); |
155 // Like Check() but does some more comprehensive checking. | 171 // Like Check() but does some more comprehensive checking. |
156 bool CheckExpensive(); | 172 bool CheckExpensive(); |
157 bool CheckList(Span* list, Length min_pages, Length max_pages, | 173 bool CheckList(Span* list, Length min_pages, Length max_pages, |
158 int freelist); // ON_NORMAL_FREELIST or ON_RETURNED_FREELIST | 174 int freelist); // ON_NORMAL_FREELIST or ON_RETURNED_FREELIST |
159 | 175 |
160 // Try to release at least num_pages for reuse by the OS. Returns | 176 // Try to release at least num_pages for reuse by the OS. Returns |
161 // the actual number of pages released, which may be less than | 177 // the actual number of pages released, which may be less than |
162 // num_pages if there weren't enough pages to release. The result | 178 // num_pages if there weren't enough pages to release. The result |
(...skipping 16 matching lines...) Expand all Loading... |
179 // Allocates a big block of memory for the pagemap once we reach more than | 195 // Allocates a big block of memory for the pagemap once we reach more than |
180 // 128MB | 196 // 128MB |
181 static const size_t kPageMapBigAllocationThreshold = 128 << 20; | 197 static const size_t kPageMapBigAllocationThreshold = 128 << 20; |
182 | 198 |
183 // Minimum number of pages to fetch from system at a time. Must be | 199 // Minimum number of pages to fetch from system at a time. Must be |
184 // significantly bigger than kBlockSize to amortize system-call | 200 // significantly bigger than kBlockSize to amortize system-call |
185 // overhead, and also to reduce external fragementation. Also, we | 201 // overhead, and also to reduce external fragementation. Also, we |
186 // should keep this value big because various incarnations of Linux | 202 // should keep this value big because various incarnations of Linux |
187 // have small limits on the number of mmap() regions per | 203 // have small limits on the number of mmap() regions per |
188 // address-space. | 204 // address-space. |
189 static const int kMinSystemAlloc = 1 << (20 - kPageShift); | 205 // REQUIRED: kMinSystemAlloc <= kMaxPages; |
190 | 206 static const int kMinSystemAlloc = kMaxPages; |
191 // For all span-lengths < kMaxPages we keep an exact-size list. | |
192 // REQUIRED: kMaxPages >= kMinSystemAlloc; | |
193 static const size_t kMaxPages = kMinSystemAlloc; | |
194 | 207 |
195 // Never delay scavenging for more than the following number of | 208 // Never delay scavenging for more than the following number of |
196 // deallocated pages. With 4K pages, this comes to 4GB of | 209 // deallocated pages. With 4K pages, this comes to 4GB of |
197 // deallocation. | 210 // deallocation. |
198 // Chrome: Changed to 64MB | 211 // Chrome: Changed to 64MB |
199 static const int kMaxReleaseDelay = 1 << 14; | 212 static const int kMaxReleaseDelay = 1 << 14; |
200 | 213 |
201 // If there is nothing to release, wait for so many pages before | 214 // If there is nothing to release, wait for so many pages before |
202 // scavenging again. With 4K pages, this comes to 1GB of memory. | 215 // scavenging again. With 4K pages, this comes to 1GB of memory. |
203 // Chrome: Changed to 16MB | 216 // Chrome: Changed to 16MB |
204 static const int kDefaultReleaseDelay = 1 << 12; | 217 static const int kDefaultReleaseDelay = 1 << 12; |
205 | 218 |
206 // Pick the appropriate map and cache types based on pointer size | 219 // Pick the appropriate map and cache types based on pointer size |
207 typedef MapSelector<8*sizeof(uintptr_t)>::Type PageMap; | 220 typedef MapSelector<kAddressBits>::Type PageMap; |
208 typedef MapSelector<8*sizeof(uintptr_t)>::CacheType PageMapCache; | 221 typedef MapSelector<kAddressBits>::CacheType PageMapCache; |
209 PageMap pagemap_; | 222 PageMap pagemap_; |
210 mutable PageMapCache pagemap_cache_; | 223 mutable PageMapCache pagemap_cache_; |
211 | 224 |
212 // We segregate spans of a given size into two circular linked | 225 // We segregate spans of a given size into two circular linked |
213 // lists: one for normal spans, and one for spans whose memory | 226 // lists: one for normal spans, and one for spans whose memory |
214 // has been returned to the system. | 227 // has been returned to the system. |
215 struct SpanList { | 228 struct SpanList { |
216 Span normal; | 229 Span normal; |
217 Span returned; | 230 Span returned; |
218 }; | 231 }; |
219 | 232 |
220 // List of free spans of length >= kMaxPages | 233 // List of free spans of length >= kMaxPages |
221 SpanList large_; | 234 SpanList large_; |
222 | 235 |
223 // Array mapping from span length to a doubly linked list of free spans | 236 // Array mapping from span length to a doubly linked list of free spans |
224 SpanList free_[kMaxPages]; | 237 SpanList free_[kMaxPages]; |
225 | 238 |
226 // Statistics on system, free, and unmapped bytes | 239 // Statistics on system, free, and unmapped bytes |
227 Stats stats_; | 240 Stats stats_; |
| 241 Span* SearchFreeAndLargeLists(Length n); |
| 242 |
228 bool GrowHeap(Length n); | 243 bool GrowHeap(Length n); |
229 | 244 |
230 // REQUIRES: span->length >= n | 245 // REQUIRES: span->length >= n |
231 // REQUIRES: span->location != IN_USE | 246 // REQUIRES: span->location != IN_USE |
232 // Remove span from its free list, and move any leftover part of | 247 // Remove span from its free list, and move any leftover part of |
233 // span into appropriate free lists. Also update "span" to have | 248 // span into appropriate free lists. Also update "span" to have |
234 // length exactly "n" and mark it as non-free so it can be returned | 249 // length exactly "n" and mark it as non-free so it can be returned |
235 // to the client. After all that, decrease free_pages_ by n and | 250 // to the client. After all that, decrease free_pages_ by n and |
236 // return span. | 251 // return span. |
237 Span* Carve(Span* span, Length n); | 252 Span* Carve(Span* span, Length n); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 int release_index_; | 294 int release_index_; |
280 }; | 295 }; |
281 | 296 |
282 } // namespace tcmalloc | 297 } // namespace tcmalloc |
283 | 298 |
284 #ifdef _MSC_VER | 299 #ifdef _MSC_VER |
285 #pragma warning(pop) | 300 #pragma warning(pop) |
286 #endif | 301 #endif |
287 | 302 |
288 #endif // TCMALLOC_PAGE_HEAP_H_ | 303 #endif // TCMALLOC_PAGE_HEAP_H_ |
OLD | NEW |