| 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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 // the allocation. More precisely, the order is the bit index of the | 189 // the allocation. More precisely, the order is the bit index of the |
| 190 // most-significant-bit in the allocation size, where the bit numbers starts | 190 // most-significant-bit in the allocation size, where the bit numbers starts |
| 191 // at index 1 for the least-significant-bit. | 191 // at index 1 for the least-significant-bit. |
| 192 // In terms of allocation sizes, order 0 covers 0, order 1 covers 1, order 2 | 192 // In terms of allocation sizes, order 0 covers 0, order 1 covers 1, order 2 |
| 193 // covers 2->3, order 3 covers 4->7, order 4 covers 8->15. | 193 // covers 2->3, order 3 covers 4->7, order 4 covers 8->15. |
| 194 static const size_t kGenericMinBucketedOrder = 4; // 8 bytes. | 194 static const size_t kGenericMinBucketedOrder = 4; // 8 bytes. |
| 195 static const size_t kGenericMaxBucketedOrder = 20; // Largest bucketed order is
1<<(20-1) (storing 512KB -> almost 1MB) | 195 static const size_t kGenericMaxBucketedOrder = 20; // Largest bucketed order is
1<<(20-1) (storing 512KB -> almost 1MB) |
| 196 static const size_t kGenericNumBucketedOrders = (kGenericMaxBucketedOrder - kGen
ericMinBucketedOrder) + 1; | 196 static const size_t kGenericNumBucketedOrders = (kGenericMaxBucketedOrder - kGen
ericMinBucketedOrder) + 1; |
| 197 static const size_t kGenericNumBucketsPerOrderBits = 3; // Eight buckets per ord
er (for the higher orders), e.g. order 8 is 128, 144, 160, ..., 240 | 197 static const size_t kGenericNumBucketsPerOrderBits = 3; // Eight buckets per ord
er (for the higher orders), e.g. order 8 is 128, 144, 160, ..., 240 |
| 198 static const size_t kGenericNumBucketsPerOrder = 1 << kGenericNumBucketsPerOrder
Bits; | 198 static const size_t kGenericNumBucketsPerOrder = 1 << kGenericNumBucketsPerOrder
Bits; |
| 199 static const size_t kGenericNumBuckets = kGenericNumBucketedOrders * kGenericNum
BucketsPerOrder; |
| 199 static const size_t kGenericSmallestBucket = 1 << (kGenericMinBucketedOrder - 1)
; | 200 static const size_t kGenericSmallestBucket = 1 << (kGenericMinBucketedOrder - 1)
; |
| 200 static const size_t kGenericMaxBucketSpacing = 1 << ((kGenericMaxBucketedOrder -
1) - kGenericNumBucketsPerOrderBits); | 201 static const size_t kGenericMaxBucketSpacing = 1 << ((kGenericMaxBucketedOrder -
1) - kGenericNumBucketsPerOrderBits); |
| 201 static const size_t kGenericMaxBucketed = (1 << (kGenericMaxBucketedOrder - 1))
+ ((kGenericNumBucketsPerOrder - 1) * kGenericMaxBucketSpacing); | 202 static const size_t kGenericMaxBucketed = (1 << (kGenericMaxBucketedOrder - 1))
+ ((kGenericNumBucketsPerOrder - 1) * kGenericMaxBucketSpacing); |
| 202 static const size_t kGenericMinDirectMappedDownsize = kGenericMaxBucketed + 1; /
/ Limit when downsizing a direct mapping using realloc(). | 203 static const size_t kGenericMinDirectMappedDownsize = kGenericMaxBucketed + 1; /
/ Limit when downsizing a direct mapping using realloc(). |
| 203 static const size_t kGenericMaxDirectMapped = INT_MAX - kSystemPageSize; | 204 static const size_t kGenericMaxDirectMapped = INT_MAX - kSystemPageSize; |
| 204 static const size_t kBitsPerSizet = sizeof(void*) * CHAR_BIT; | 205 static const size_t kBitsPerSizet = sizeof(void*) * CHAR_BIT; |
| 205 | 206 |
| 206 // Constants for the memory reclaim logic. | 207 // Constants for the memory reclaim logic. |
| 207 static const size_t kMaxFreeableSpans = 16; | 208 static const size_t kMaxFreeableSpans = 16; |
| 208 | 209 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 struct PartitionRootGeneric : public PartitionRootBase { | 328 struct PartitionRootGeneric : public PartitionRootBase { |
| 328 int lock; | 329 int lock; |
| 329 // Some pre-computed constants. | 330 // Some pre-computed constants. |
| 330 size_t orderIndexShifts[kBitsPerSizet + 1]; | 331 size_t orderIndexShifts[kBitsPerSizet + 1]; |
| 331 size_t orderSubIndexMasks[kBitsPerSizet + 1]; | 332 size_t orderSubIndexMasks[kBitsPerSizet + 1]; |
| 332 // The bucket lookup table lets us map a size_t to a bucket quickly. | 333 // The bucket lookup table lets us map a size_t to a bucket quickly. |
| 333 // The trailing +1 caters for the overflow case for very large allocation si
zes. | 334 // The trailing +1 caters for the overflow case for very large allocation si
zes. |
| 334 // It is one flat array instead of a 2D array because in the 2D world, we'd | 335 // It is one flat array instead of a 2D array because in the 2D world, we'd |
| 335 // need to index array[blah][max+1] which risks undefined behavior. | 336 // need to index array[blah][max+1] which risks undefined behavior. |
| 336 PartitionBucket* bucketLookups[((kBitsPerSizet + 1) * kGenericNumBucketsPerO
rder) + 1]; | 337 PartitionBucket* bucketLookups[((kBitsPerSizet + 1) * kGenericNumBucketsPerO
rder) + 1]; |
| 337 PartitionBucket buckets[kGenericNumBucketedOrders * kGenericNumBucketsPerOrd
er]; | 338 PartitionBucket buckets[kGenericNumBuckets]; |
| 338 }; | 339 }; |
| 339 | 340 |
| 340 // Flags for partitionAllocGenericFlags. | 341 // Flags for partitionAllocGenericFlags. |
| 341 enum PartitionAllocFlags { | 342 enum PartitionAllocFlags { |
| 342 PartitionAllocReturnNull = 1 << 0, | 343 PartitionAllocReturnNull = 1 << 0, |
| 343 }; | 344 }; |
| 344 | 345 |
| 345 // Struct used to retrieve memory statistics about a partition bucket. Used by | 346 // Struct used to retrieve memory statistics about a partition bucket. Used by |
| 346 // PartitionStatsDumper implementation. | 347 // PartitionStatsDumper implementation. |
| 347 struct PartitionBucketMemoryStats { | 348 struct PartitionBucketMemoryStats { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 { | 510 { |
| 510 PartitionPage* page = bucket->activePagesHead; | 511 PartitionPage* page = bucket->activePagesHead; |
| 511 // Check that this page is neither full nor freed. | 512 // Check that this page is neither full nor freed. |
| 512 ASSERT(page->numAllocatedSlots >= 0); | 513 ASSERT(page->numAllocatedSlots >= 0); |
| 513 void* ret = page->freelistHead; | 514 void* ret = page->freelistHead; |
| 514 if (LIKELY(ret != 0)) { | 515 if (LIKELY(ret != 0)) { |
| 515 // If these asserts fire, you probably corrupted memory. | 516 // If these asserts fire, you probably corrupted memory. |
| 516 ASSERT(partitionPointerIsValid(ret)); | 517 ASSERT(partitionPointerIsValid(ret)); |
| 517 PartitionFreelistEntry* newHead = partitionFreelistMask(static_cast<Part
itionFreelistEntry*>(ret)->next); | 518 PartitionFreelistEntry* newHead = partitionFreelistMask(static_cast<Part
itionFreelistEntry*>(ret)->next); |
| 518 page->freelistHead = newHead; | 519 page->freelistHead = newHead; |
| 519 ASSERT(!ret || partitionPointerIsValid(ret)); | |
| 520 page->numAllocatedSlots++; | 520 page->numAllocatedSlots++; |
| 521 } else { | 521 } else { |
| 522 ret = partitionAllocSlowPath(root, flags, size, bucket); | 522 ret = partitionAllocSlowPath(root, flags, size, bucket); |
| 523 ASSERT(!ret || partitionPointerIsValid(ret)); |
| 523 } | 524 } |
| 524 #if ENABLE(ASSERT) | 525 #if ENABLE(ASSERT) |
| 525 if (!ret) | 526 if (!ret) |
| 526 return 0; | 527 return 0; |
| 527 // Fill the uninitialized pattern. and write the cookies. | 528 // Fill the uninitialized pattern. and write the cookies. |
| 528 page = partitionPointerToPage(ret); | 529 page = partitionPointerToPage(ret); |
| 529 size_t bucketSize = page->bucket->slotSize; | 530 size_t bucketSize = page->bucket->slotSize; |
| 530 memset(ret, kUninitializedByte, bucketSize); | 531 memset(ret, kUninitializedByte, bucketSize); |
| 531 partitionCookieWriteValue(ret); | 532 partitionCookieWriteValue(ret); |
| 532 partitionCookieWriteValue(reinterpret_cast<char*>(ret) + bucketSize - kCooki
eSize); | 533 partitionCookieWriteValue(reinterpret_cast<char*>(ret) + bucketSize - kCooki
eSize); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 using WTF::partitionAlloc; | 732 using WTF::partitionAlloc; |
| 732 using WTF::partitionFree; | 733 using WTF::partitionFree; |
| 733 using WTF::partitionAllocGeneric; | 734 using WTF::partitionAllocGeneric; |
| 734 using WTF::partitionFreeGeneric; | 735 using WTF::partitionFreeGeneric; |
| 735 using WTF::partitionReallocGeneric; | 736 using WTF::partitionReallocGeneric; |
| 736 using WTF::partitionAllocActualSize; | 737 using WTF::partitionAllocActualSize; |
| 737 using WTF::partitionAllocSupportsGetSize; | 738 using WTF::partitionAllocSupportsGetSize; |
| 738 using WTF::partitionAllocGetSize; | 739 using WTF::partitionAllocGetSize; |
| 739 | 740 |
| 740 #endif // WTF_PartitionAlloc_h | 741 #endif // WTF_PartitionAlloc_h |
| OLD | NEW |