Chromium Code Reviews| 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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 // An "extent" is a span of consecutive superpages. We link to the partition's | 269 // An "extent" is a span of consecutive superpages. We link to the partition's |
| 270 // next extent (if there is one) at the very start of a superpage's metadata | 270 // next extent (if there is one) at the very start of a superpage's metadata |
| 271 // area. | 271 // area. |
| 272 struct PartitionSuperPageExtentEntry { | 272 struct PartitionSuperPageExtentEntry { |
| 273 PartitionRootBase* root; | 273 PartitionRootBase* root; |
| 274 char* superPageBase; | 274 char* superPageBase; |
| 275 char* superPagesEnd; | 275 char* superPagesEnd; |
| 276 PartitionSuperPageExtentEntry* next; | 276 PartitionSuperPageExtentEntry* next; |
| 277 }; | 277 }; |
| 278 | 278 |
| 279 // This callback can be called on any thread. | |
|
Chris Evans
2015/04/06 04:39:53
Nit: also document that it's illegal to re-enter P
haraken
2015/04/06 06:14:14
Done.
| |
| 280 typedef void (*NotifyCommittedMemoryChangedFunction)(); | |
| 281 | |
| 279 struct WTF_EXPORT PartitionRootBase { | 282 struct WTF_EXPORT PartitionRootBase { |
| 280 size_t totalSizeOfCommittedPages; | 283 size_t totalSizeOfCommittedPages; |
| 281 size_t totalSizeOfSuperPages; | 284 size_t totalSizeOfSuperPages; |
| 282 size_t totalSizeOfDirectMappedPages; | 285 size_t totalSizeOfDirectMappedPages; |
| 283 // Invariant: totalSizeOfCommittedPages <= totalSizeOfSuperPages + totalSize OfDirectMappedPages. | 286 // Invariant: totalSizeOfCommittedPages <= totalSizeOfSuperPages + totalSize OfDirectMappedPages. |
| 284 unsigned numBuckets; | 287 unsigned numBuckets; |
| 285 unsigned maxAllocation; | 288 unsigned maxAllocation; |
| 286 bool initialized; | 289 bool initialized; |
| 287 char* nextSuperPage; | 290 char* nextSuperPage; |
| 288 char* nextPartitionPage; | 291 char* nextPartitionPage; |
| 289 char* nextPartitionPageEnd; | 292 char* nextPartitionPageEnd; |
| 290 PartitionSuperPageExtentEntry* currentExtent; | 293 PartitionSuperPageExtentEntry* currentExtent; |
| 291 PartitionSuperPageExtentEntry* firstExtent; | 294 PartitionSuperPageExtentEntry* firstExtent; |
| 292 PartitionPage* globalEmptyPageRing[kMaxFreeableSpans]; | 295 PartitionPage* globalEmptyPageRing[kMaxFreeableSpans]; |
| 293 int16_t globalEmptyPageRingIndex; | 296 int16_t globalEmptyPageRingIndex; |
| 294 uintptr_t invertedSelf; | 297 uintptr_t invertedSelf; |
| 298 NotifyCommittedMemoryChangedFunction notifyCommittedMemoryChangedFunction; | |
| 295 | 299 |
| 296 static int gInitializedLock; | 300 static int gInitializedLock; |
| 297 static bool gInitialized; | 301 static bool gInitialized; |
| 298 // gSeedPage is used as a sentinel to indicate that there is no page | 302 // gSeedPage is used as a sentinel to indicate that there is no page |
| 299 // in the active page list. We can use nullptr, but in that case we need | 303 // in the active page list. We can use nullptr, but in that case we need |
| 300 // to add a null-check branch to the hot allocation path. We want to avoid | 304 // to add a null-check branch to the hot allocation path. We want to avoid |
| 301 // that. | 305 // that. |
| 302 static PartitionPage gSeedPage; | 306 static PartitionPage gSeedPage; |
| 303 static PartitionBucket gPagedBucket; | 307 static PartitionBucket gPagedBucket; |
| 304 }; | 308 }; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 322 // need to index array[blah][max+1] which risks undefined behavior. | 326 // need to index array[blah][max+1] which risks undefined behavior. |
| 323 PartitionBucket* bucketLookups[((kBitsPerSizet + 1) * kGenericNumBucketsPerO rder) + 1]; | 327 PartitionBucket* bucketLookups[((kBitsPerSizet + 1) * kGenericNumBucketsPerO rder) + 1]; |
| 324 PartitionBucket buckets[kGenericNumBucketedOrders * kGenericNumBucketsPerOrd er]; | 328 PartitionBucket buckets[kGenericNumBucketedOrders * kGenericNumBucketsPerOrd er]; |
| 325 }; | 329 }; |
| 326 | 330 |
| 327 // Flags for partitionAllocGenericFlags. | 331 // Flags for partitionAllocGenericFlags. |
| 328 enum PartitionAllocFlags { | 332 enum PartitionAllocFlags { |
| 329 PartitionAllocReturnNull = 1 << 0, | 333 PartitionAllocReturnNull = 1 << 0, |
| 330 }; | 334 }; |
| 331 | 335 |
| 332 WTF_EXPORT void partitionAllocInit(PartitionRoot*, size_t numBuckets, size_t max Allocation); | 336 WTF_EXPORT void partitionAllocInit(PartitionRoot*, size_t numBuckets, size_t max Allocation, NotifyCommittedMemoryChangedFunction); |
| 333 WTF_EXPORT bool partitionAllocShutdown(PartitionRoot*); | 337 WTF_EXPORT bool partitionAllocShutdown(PartitionRoot*); |
| 334 WTF_EXPORT void partitionAllocGenericInit(PartitionRootGeneric*); | 338 WTF_EXPORT void partitionAllocGenericInit(PartitionRootGeneric*, NotifyCommitted MemoryChangedFunction); |
| 335 WTF_EXPORT bool partitionAllocGenericShutdown(PartitionRootGeneric*); | 339 WTF_EXPORT bool partitionAllocGenericShutdown(PartitionRootGeneric*); |
| 336 | 340 |
| 337 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*, int, si ze_t, PartitionBucket*); | 341 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionRootBase*, int, si ze_t, PartitionBucket*); |
| 338 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*); | 342 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPage*); |
| 339 WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi d*, size_t); | 343 WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi d*, size_t); |
| 340 | 344 |
| 341 #ifndef NDEBUG | 345 #ifndef NDEBUG |
| 342 WTF_EXPORT void partitionDumpStats(const PartitionRoot&); | 346 WTF_EXPORT void partitionDumpStats(const PartitionRoot&); |
| 343 #endif | 347 #endif |
| 344 | 348 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 } | 664 } |
| 661 | 665 |
| 662 // N (or more accurately, N - sizeof(void*)) represents the largest size in | 666 // N (or more accurately, N - sizeof(void*)) represents the largest size in |
| 663 // bytes that will be handled by a SizeSpecificPartitionAllocator. | 667 // bytes that will be handled by a SizeSpecificPartitionAllocator. |
| 664 // Attempts to partitionAlloc() more than this amount will fail. | 668 // Attempts to partitionAlloc() more than this amount will fail. |
| 665 template <size_t N> | 669 template <size_t N> |
| 666 class SizeSpecificPartitionAllocator { | 670 class SizeSpecificPartitionAllocator { |
| 667 public: | 671 public: |
| 668 static const size_t kMaxAllocation = N - kAllocationGranularity; | 672 static const size_t kMaxAllocation = N - kAllocationGranularity; |
| 669 static const size_t kNumBuckets = N / kAllocationGranularity; | 673 static const size_t kNumBuckets = N / kAllocationGranularity; |
| 670 void init() { partitionAllocInit(&m_partitionRoot, kNumBuckets, kMaxAllocati on); } | 674 void init(NotifyCommittedMemoryChangedFunction notifyCommittedMemoryChangedF unction = nullptr) |
| 675 { | |
| 676 partitionAllocInit(&m_partitionRoot, kNumBuckets, kMaxAllocation, notify CommittedMemoryChangedFunction); | |
| 677 } | |
| 671 bool shutdown() { return partitionAllocShutdown(&m_partitionRoot); } | 678 bool shutdown() { return partitionAllocShutdown(&m_partitionRoot); } |
| 672 ALWAYS_INLINE PartitionRoot* root() { return &m_partitionRoot; } | 679 ALWAYS_INLINE PartitionRoot* root() { return &m_partitionRoot; } |
| 673 private: | 680 private: |
| 674 PartitionRoot m_partitionRoot; | 681 PartitionRoot m_partitionRoot; |
| 675 PartitionBucket m_actualBuckets[kNumBuckets]; | 682 PartitionBucket m_actualBuckets[kNumBuckets]; |
| 676 }; | 683 }; |
| 677 | 684 |
| 678 class PartitionAllocatorGeneric { | 685 class PartitionAllocatorGeneric { |
| 679 public: | 686 public: |
| 680 void init() { partitionAllocGenericInit(&m_partitionRoot); } | 687 void init(NotifyCommittedMemoryChangedFunction notifyCommittedMemoryChangedF unction = nullptr) |
| 688 { | |
| 689 partitionAllocGenericInit(&m_partitionRoot, notifyCommittedMemoryChanged Function); | |
| 690 } | |
| 681 bool shutdown() { return partitionAllocGenericShutdown(&m_partitionRoot); } | 691 bool shutdown() { return partitionAllocGenericShutdown(&m_partitionRoot); } |
| 682 ALWAYS_INLINE PartitionRootGeneric* root() { return &m_partitionRoot; } | 692 ALWAYS_INLINE PartitionRootGeneric* root() { return &m_partitionRoot; } |
| 683 private: | 693 private: |
| 684 PartitionRootGeneric m_partitionRoot; | 694 PartitionRootGeneric m_partitionRoot; |
| 685 }; | 695 }; |
| 686 | 696 |
| 687 } // namespace WTF | 697 } // namespace WTF |
| 688 | 698 |
| 689 using WTF::SizeSpecificPartitionAllocator; | 699 using WTF::SizeSpecificPartitionAllocator; |
| 690 using WTF::PartitionAllocatorGeneric; | 700 using WTF::PartitionAllocatorGeneric; |
| 691 using WTF::PartitionRoot; | 701 using WTF::PartitionRoot; |
| 692 using WTF::partitionAllocInit; | 702 using WTF::partitionAllocInit; |
| 693 using WTF::partitionAllocShutdown; | 703 using WTF::partitionAllocShutdown; |
| 694 using WTF::partitionAlloc; | 704 using WTF::partitionAlloc; |
| 695 using WTF::partitionFree; | 705 using WTF::partitionFree; |
| 696 using WTF::partitionAllocGeneric; | 706 using WTF::partitionAllocGeneric; |
| 697 using WTF::partitionFreeGeneric; | 707 using WTF::partitionFreeGeneric; |
| 698 using WTF::partitionReallocGeneric; | 708 using WTF::partitionReallocGeneric; |
| 699 using WTF::partitionAllocActualSize; | 709 using WTF::partitionAllocActualSize; |
| 700 using WTF::partitionAllocSupportsGetSize; | 710 using WTF::partitionAllocSupportsGetSize; |
| 701 using WTF::partitionAllocGetSize; | 711 using WTF::partitionAllocGetSize; |
| 702 | 712 |
| 703 #endif // WTF_PartitionAlloc_h | 713 #endif // WTF_PartitionAlloc_h |
| OLD | NEW |