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 30 matching lines...) Expand all Loading... |
41 | 41 |
42 // This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if | 42 // This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if |
43 // you're porting to a system where you really can't get a stacktrace. | 43 // you're porting to a system where you really can't get a stacktrace. |
44 #ifdef NO_TCMALLOC_SAMPLES | 44 #ifdef NO_TCMALLOC_SAMPLES |
45 // We use #define so code compiles even if you #include stacktrace.h somehow. | 45 // We use #define so code compiles even if you #include stacktrace.h somehow. |
46 # define GetStackTrace(stack, depth, skip) (0) | 46 # define GetStackTrace(stack, depth, skip) (0) |
47 #else | 47 #else |
48 # include <google/stacktrace.h> | 48 # include <google/stacktrace.h> |
49 #endif | 49 #endif |
50 | 50 |
51 | |
52 namespace tcmalloc { | 51 namespace tcmalloc { |
53 | 52 |
54 // ------------------------------------------------------------------------- | 53 // ------------------------------------------------------------------------- |
55 // Map from page-id to per-page data | 54 // Map from page-id to per-page data |
56 // ------------------------------------------------------------------------- | 55 // ------------------------------------------------------------------------- |
57 | 56 |
58 // We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines. | 57 // We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines. |
59 // We also use a simple one-level cache for hot PageID-to-sizeclass mappings, | 58 // We also use a simple one-level cache for hot PageID-to-sizeclass mappings, |
60 // because sometimes the sizeclass is all the information we need. | 59 // because sometimes the sizeclass is all the information we need. |
61 | 60 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 // Return 0 if we have no information, or else the correct sizeclass for p. | 138 // Return 0 if we have no information, or else the correct sizeclass for p. |
140 // Reads and writes to pagemap_cache_ do not require locking. | 139 // Reads and writes to pagemap_cache_ do not require locking. |
141 // The entries are 64 bits on 64-bit hardware and 16 bits on | 140 // The entries are 64 bits on 64-bit hardware and 16 bits on |
142 // 32-bit hardware, and we don't mind raciness as long as each read of | 141 // 32-bit hardware, and we don't mind raciness as long as each read of |
143 // an entry yields a valid entry, not a partially updated entry. | 142 // an entry yields a valid entry, not a partially updated entry. |
144 size_t GetSizeClassIfCached(PageID p) const { | 143 size_t GetSizeClassIfCached(PageID p) const { |
145 return pagemap_cache_.GetOrDefault(p, 0); | 144 return pagemap_cache_.GetOrDefault(p, 0); |
146 } | 145 } |
147 void CacheSizeClass(PageID p, size_t cl) const { pagemap_cache_.Put(p, cl); } | 146 void CacheSizeClass(PageID p, size_t cl) const { pagemap_cache_.Put(p, cl); } |
148 | 147 |
149 // Attempt to free some free pages currently not used. | |
150 void Scavenge(); | |
151 | |
152 private: | 148 private: |
153 // Allocates a big block of memory for the pagemap once we reach more than | 149 // Allocates a big block of memory for the pagemap once we reach more than |
154 // 128MB | 150 // 128MB |
155 static const size_t kPageMapBigAllocationThreshold = 128 << 20; | 151 static const size_t kPageMapBigAllocationThreshold = 128 << 20; |
156 | 152 |
157 // Minimum number of pages to fetch from system at a time. Must be | 153 // Minimum number of pages to fetch from system at a time. Must be |
158 // significantly bigger than kBlockSize to amortize system-call | 154 // significantly bigger than kBlockSize to amortize system-call |
159 // overhead, and also to reduce external fragementation. Also, we | 155 // overhead, and also to reduce external fragementation. Also, we |
160 // should keep this value big because various incarnations of Linux | 156 // should keep this value big because various incarnations of Linux |
161 // have small limits on the number of mmap() regions per | 157 // have small limits on the number of mmap() regions per |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 pagemap_.set(span->start, span); | 203 pagemap_.set(span->start, span); |
208 if (span->length > 1) { | 204 if (span->length > 1) { |
209 pagemap_.set(span->start + span->length - 1, span); | 205 pagemap_.set(span->start + span->length - 1, span); |
210 } | 206 } |
211 } | 207 } |
212 | 208 |
213 // Allocate a large span of length == n. If successful, returns a | 209 // Allocate a large span of length == n. If successful, returns a |
214 // span of exactly the specified length. Else, returns NULL. | 210 // span of exactly the specified length. Else, returns NULL. |
215 Span* AllocLarge(Length n); | 211 Span* AllocLarge(Length n); |
216 | 212 |
217 // Commits the span. | 213 // Commit the span. |
218 void CommitSpan(Span* span); | 214 void CommitSpan(Span* span); |
219 | 215 |
220 #if DEFER_DECOMMIT | |
221 // Number of free committed pages that we want to keep around. | |
222 static const size_t kMinimumFreeCommittedPageCount = 512; // 2M (2 ** 21) for
4K pages | |
223 | |
224 // During a scavenge, we'll release up to a fraction of the free committed pag
es. | |
225 #ifdef _WIN32 | |
226 // We are slightly less aggressive in releasing memory on Windows due to perfo
rmance reasons. | |
227 static const int kMaxScavengeAmountFactor = 3; | |
228 #else | |
229 static const int kMaxScavengeAmountFactor = 2; | |
230 #endif | |
231 | |
232 // Decommits some parts from SpanList. | |
233 uint64_t DecommitFromSpanList(SpanList* span_list, uint64_t to_decommit); | |
234 | |
235 // Decommits some parts from SpanList. | |
236 Length DecommitLastSpan(SpanList* span_list, Span* span); | |
237 | |
238 // Number of pages kept in free lists that are still committed a.k.a. total | |
239 // number of pages in "normal" lists. | |
240 uint64_t free_committed_pages_; | |
241 | |
242 // Number of pages that we commited in the last scavenge wait interval. | |
243 uint64_t pages_committed_since_last_scavenge_; | |
244 #else | |
245 // Incrementally release some memory to the system. | 216 // Incrementally release some memory to the system. |
246 // IncrementalScavenge(n) is called whenever n pages are freed. | 217 // IncrementalScavenge(n) is called whenever n pages are freed. |
247 void IncrementalScavenge(Length n); | 218 void IncrementalScavenge(Length n); |
248 | 219 |
249 // Number of pages to deallocate before doing more scavenging | 220 // Number of pages to deallocate before doing more scavenging |
250 int64_t scavenge_counter_; | 221 int64_t scavenge_counter_; |
251 #endif | |
252 | 222 |
253 // Index of last free list we scavenged | 223 // Index of last free list we scavenged |
254 int scavenge_index_; | 224 int scavenge_index_; |
255 }; | 225 }; |
256 | 226 |
257 } // namespace tcmalloc | 227 } // namespace tcmalloc |
258 | 228 |
259 #endif // TCMALLOC_PAGE_HEAP_H_ | 229 #endif // TCMALLOC_PAGE_HEAP_H_ |
OLD | NEW |