OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 static const size_t kGenericMaxBucketedOrder = 15; // Largest bucketed order is
1<<(15-1) (storing 16KB -> almost 32KB)) | 176 static const size_t kGenericMaxBucketedOrder = 15; // Largest bucketed order is
1<<(15-1) (storing 16KB -> almost 32KB)) |
177 static const size_t kGenericMinBucketedOrder = 4; // 8 bytes. | 177 static const size_t kGenericMinBucketedOrder = 4; // 8 bytes. |
178 static const size_t kGenericNumBucketedOrders = (kGenericMaxBucketedOrder - kGen
ericMinBucketedOrder) + 1; | 178 static const size_t kGenericNumBucketedOrders = (kGenericMaxBucketedOrder - kGen
ericMinBucketedOrder) + 1; |
179 static const size_t kGenericNumBucketsPerOrderBits = 3; // Eight buckets per ord
er (for the higher orders), e.g. order 8 is 128, 144, 160, ..., 240 | 179 static const size_t kGenericNumBucketsPerOrderBits = 3; // Eight buckets per ord
er (for the higher orders), e.g. order 8 is 128, 144, 160, ..., 240 |
180 static const size_t kGenericNumBucketsPerOrder = 1 << kGenericNumBucketsPerOrder
Bits; | 180 static const size_t kGenericNumBucketsPerOrder = 1 << kGenericNumBucketsPerOrder
Bits; |
181 static const size_t kGenericSmallestBucket = 1 << (kGenericMinBucketedOrder - 1)
; | 181 static const size_t kGenericSmallestBucket = 1 << (kGenericMinBucketedOrder - 1)
; |
182 static const size_t kGenericMaxBucketSpacing = 1 << ((kGenericMaxBucketedOrder -
1) - kGenericNumBucketsPerOrderBits); | 182 static const size_t kGenericMaxBucketSpacing = 1 << ((kGenericMaxBucketedOrder -
1) - kGenericNumBucketsPerOrderBits); |
183 static const size_t kGenericMaxBucketed = (1 << (kGenericMaxBucketedOrder - 1))
+ ((kGenericNumBucketsPerOrder - 1) * kGenericMaxBucketSpacing); | 183 static const size_t kGenericMaxBucketed = (1 << (kGenericMaxBucketedOrder - 1))
+ ((kGenericNumBucketsPerOrder - 1) * kGenericMaxBucketSpacing); |
184 static const size_t kBitsPerSizet = sizeof(void*) * CHAR_BIT; | 184 static const size_t kBitsPerSizet = sizeof(void*) * CHAR_BIT; |
185 | 185 |
| 186 // Constants for the memory reclaim logic. |
| 187 static const size_t kMaxFreeableSpans = 16; |
186 | 188 |
187 #ifndef NDEBUG | 189 #ifndef NDEBUG |
188 // These two byte values match tcmalloc. | 190 // These two byte values match tcmalloc. |
189 static const unsigned char kUninitializedByte = 0xAB; | 191 static const unsigned char kUninitializedByte = 0xAB; |
190 static const unsigned char kFreedByte = 0xCD; | 192 static const unsigned char kFreedByte = 0xCD; |
191 #if CPU(64BIT) | 193 #if CPU(64BIT) |
192 static const uintptr_t kCookieValue = 0xDEADBEEFDEADBEEFul; | 194 static const uintptr_t kCookieValue = 0xDEADBEEFDEADBEEFul; |
193 #else | 195 #else |
194 static const uintptr_t kCookieValue = 0xDEADBEEFu; | 196 static const uintptr_t kCookieValue = 0xDEADBEEFu; |
195 #endif | 197 #endif |
196 #endif | 198 #endif |
197 | 199 |
| 200 struct PartitionBucket; |
198 struct PartitionRootBase; | 201 struct PartitionRootBase; |
199 struct PartitionBucket; | |
200 | 202 |
201 struct PartitionFreelistEntry { | 203 struct PartitionFreelistEntry { |
202 PartitionFreelistEntry* next; | 204 PartitionFreelistEntry* next; |
203 }; | 205 }; |
204 | 206 |
205 // Some notes on page states. A page can be in one of three major states: | 207 // Some notes on page states. A page can be in one of three major states: |
206 // 1) Active. | 208 // 1) Active. |
207 // 2) Full. | 209 // 2) Full. |
208 // 3) Free. | 210 // 3) Free. |
209 // An active page has available free slots. A full page has no free slots. A | 211 // An active page has available free slots. A full page has no free slots. A |
(...skipping 12 matching lines...) Expand all Loading... |
222 // If it does this, full and free pages encountered will be booted out of the | 224 // If it does this, full and free pages encountered will be booted out of the |
223 // active list. If there are no suitable active pages found, a free page (if one | 225 // active list. If there are no suitable active pages found, a free page (if one |
224 // exists) will be pulled from the free list on to the active list. | 226 // exists) will be pulled from the free list on to the active list. |
225 struct PartitionPage { | 227 struct PartitionPage { |
226 PartitionFreelistEntry* freelistHead; | 228 PartitionFreelistEntry* freelistHead; |
227 PartitionPage* nextPage; | 229 PartitionPage* nextPage; |
228 PartitionBucket* bucket; | 230 PartitionBucket* bucket; |
229 int16_t numAllocatedSlots; // Deliberately signed, -1 for free page, -n for
full pages. | 231 int16_t numAllocatedSlots; // Deliberately signed, -1 for free page, -n for
full pages. |
230 uint16_t numUnprovisionedSlots; | 232 uint16_t numUnprovisionedSlots; |
231 uint16_t pageOffset; | 233 uint16_t pageOffset; |
| 234 int16_t freeCacheIndex; // -1 if not in the free cache. |
232 }; | 235 }; |
233 | 236 |
234 struct PartitionBucket { | 237 struct PartitionBucket { |
235 PartitionPage* activePagesHead; // Accessed most in hot path => goes first. | 238 PartitionPage* activePagesHead; // Accessed most in hot path => goes first. |
236 PartitionPage* freePagesHead; | 239 PartitionPage* freePagesHead; |
237 uint16_t slotSize; | 240 uint16_t slotSize; |
238 uint16_t numSystemPagesPerSlotSpan; | 241 uint16_t numSystemPagesPerSlotSpan; |
239 uint32_t numFullPages; | 242 uint32_t numFullPages; |
240 }; | 243 }; |
241 | 244 |
(...skipping 10 matching lines...) Expand all Loading... |
252 struct WTF_EXPORT PartitionRootBase { | 255 struct WTF_EXPORT PartitionRootBase { |
253 size_t totalSizeOfSuperPages; | 256 size_t totalSizeOfSuperPages; |
254 unsigned numBuckets; | 257 unsigned numBuckets; |
255 unsigned maxAllocation; | 258 unsigned maxAllocation; |
256 bool initialized; | 259 bool initialized; |
257 char* nextSuperPage; | 260 char* nextSuperPage; |
258 char* nextPartitionPage; | 261 char* nextPartitionPage; |
259 char* nextPartitionPageEnd; | 262 char* nextPartitionPageEnd; |
260 PartitionSuperPageExtentEntry* currentExtent; | 263 PartitionSuperPageExtentEntry* currentExtent; |
261 PartitionSuperPageExtentEntry* firstExtent; | 264 PartitionSuperPageExtentEntry* firstExtent; |
| 265 PartitionPage* globalEmptyPageRing[kMaxFreeableSpans]; |
| 266 size_t globalEmptyPageRingIndex; |
262 uintptr_t invertedSelf; | 267 uintptr_t invertedSelf; |
263 | 268 |
264 static int gInitializedLock; | 269 static int gInitializedLock; |
265 static bool gInitialized; | 270 static bool gInitialized; |
266 static PartitionPage gSeedPage; | 271 static PartitionPage gSeedPage; |
267 static PartitionBucket gPagedBucket; | 272 static PartitionBucket gPagedBucket; |
268 }; | 273 }; |
269 | 274 |
270 // Never instantiate a PartitionRoot directly, instead use PartitionAlloc. | 275 // Never instantiate a PartitionRoot directly, instead use PartitionAlloc. |
271 struct PartitionRoot : public PartitionRootBase { | 276 struct PartitionRoot : public PartitionRootBase { |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 using WTF::PartitionRoot; | 647 using WTF::PartitionRoot; |
643 using WTF::partitionAllocInit; | 648 using WTF::partitionAllocInit; |
644 using WTF::partitionAllocShutdown; | 649 using WTF::partitionAllocShutdown; |
645 using WTF::partitionAlloc; | 650 using WTF::partitionAlloc; |
646 using WTF::partitionFree; | 651 using WTF::partitionFree; |
647 using WTF::partitionAllocGeneric; | 652 using WTF::partitionAllocGeneric; |
648 using WTF::partitionFreeGeneric; | 653 using WTF::partitionFreeGeneric; |
649 using WTF::partitionReallocGeneric; | 654 using WTF::partitionReallocGeneric; |
650 | 655 |
651 #endif // WTF_PartitionAlloc_h | 656 #endif // WTF_PartitionAlloc_h |
OLD | NEW |