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