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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 // constant values, we pack _all_ partitionAllocGeneric() sizes perfectly up | 134 // constant values, we pack _all_ partitionAllocGeneric() sizes perfectly up |
135 // against the end of a system page. | 135 // against the end of a system page. |
136 static const size_t kPartitionPageShift = 14; // 16KB | 136 static const size_t kPartitionPageShift = 14; // 16KB |
137 static const size_t kPartitionPageSize = 1 << kPartitionPageShift; | 137 static const size_t kPartitionPageSize = 1 << kPartitionPageShift; |
138 static const size_t kPartitionPageOffsetMask = kPartitionPageSize - 1; | 138 static const size_t kPartitionPageOffsetMask = kPartitionPageSize - 1; |
139 static const size_t kPartitionPageBaseMask = ~kPartitionPageOffsetMask; | 139 static const size_t kPartitionPageBaseMask = ~kPartitionPageOffsetMask; |
140 static const size_t kMaxPartitionPagesPerSlotSpan = 4; | 140 static const size_t kMaxPartitionPagesPerSlotSpan = 4; |
141 | 141 |
142 // To avoid fragmentation via never-used freelist entries, we hand out partition | 142 // To avoid fragmentation via never-used freelist entries, we hand out partition |
143 // freelist sections gradually, in units of the dominant system page size. | 143 // freelist sections gradually, in units of the dominant system page size. |
144 // What we're actually doing is avoiding filling the full partition page | 144 // What we're actually doing is avoiding filling the full partition page (16 KB) |
145 // (typically 16KB) will freelist pointers right away. Writing freelist | 145 // with freelist pointers right away. Writing freelist pointers will fault and |
146 // pointers will fault and dirty a private page, which is very wasteful if we | 146 // dirty a private page, which is very wasteful if we never actually store |
147 // never actually store objects there. | 147 // objects there. |
148 static const size_t kNumSystemPagesPerPartitionPage = kPartitionPageSize / kSyst
emPageSize; | 148 static const size_t kNumSystemPagesPerPartitionPage = kPartitionPageSize / kSyst
emPageSize; |
149 static const size_t kMaxSystemPagesPerSlotSpan = kNumSystemPagesPerPartitionPage
* kMaxPartitionPagesPerSlotSpan; | 149 static const size_t kMaxSystemPagesPerSlotSpan = kNumSystemPagesPerPartitionPage
* kMaxPartitionPagesPerSlotSpan; |
150 | 150 |
151 // We reserve virtual address space in 2MB chunks (aligned to 2MB as well). | 151 // We reserve virtual address space in 2MB chunks (aligned to 2MB as well). |
152 // These chunks are called "super pages". We do this so that we can store | 152 // These chunks are called "super pages". We do this so that we can store |
153 // metadata in the first few pages of each 2MB aligned section. This leads to | 153 // metadata in the first few pages of each 2MB aligned section. This leads to |
154 // a very fast free(). We specifically choose 2MB because this virtual address | 154 // a very fast free(). We specifically choose 2MB because this virtual address |
155 // block represents a full but single PTE allocation on ARM, ia32 and x64. | 155 // block represents a full but single PTE allocation on ARM, ia32 and x64. |
156 // | 156 // |
157 // The layout of the super page is as follows. The sizes below are the same | 157 // The layout of the super page is as follows. The sizes below are the same |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 | 719 |
720 ptr = partitionCookieFreePointerAdjust(ptr); | 720 ptr = partitionCookieFreePointerAdjust(ptr); |
721 ASSERT(partitionPointerIsValid(ptr)); | 721 ASSERT(partitionPointerIsValid(ptr)); |
722 PartitionPage* page = partitionPointerToPage(ptr); | 722 PartitionPage* page = partitionPointerToPage(ptr); |
723 spinLockLock(&root->lock); | 723 spinLockLock(&root->lock); |
724 partitionFreeWithPage(ptr, page); | 724 partitionFreeWithPage(ptr, page); |
725 spinLockUnlock(&root->lock); | 725 spinLockUnlock(&root->lock); |
726 #endif | 726 #endif |
727 } | 727 } |
728 | 728 |
729 ALWAYS_INLINE size_t partitionDirectMapSize(size_t size) | 729 ALWAYS_INLINE size_t partitionRoundUpToSystemPage(size_t size) |
730 { | 730 { |
731 // Caller must check that the size is not above the kGenericMaxDirectMapped | 731 // Caller must check that the size is not above the kGenericMaxDirectMapped |
732 // limit before calling. This also guards against integer overflow in the | 732 // limit before calling. This also guards against integer overflow in the |
733 // calculation here. | 733 // calculation here. |
734 ASSERT(size <= kGenericMaxDirectMapped); | 734 ASSERT(size <= kGenericMaxDirectMapped); |
735 return (size + kSystemPageOffsetMask) & kSystemPageBaseMask; | 735 return (size + kSystemPageOffsetMask) & kSystemPageBaseMask; |
736 } | 736 } |
737 | 737 |
738 ALWAYS_INLINE size_t partitionAllocActualSize(PartitionRootGeneric* root, size_t
size) | 738 ALWAYS_INLINE size_t partitionAllocActualSize(PartitionRootGeneric* root, size_t
size) |
739 { | 739 { |
740 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 740 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
741 return size; | 741 return size; |
742 #else | 742 #else |
743 ASSERT(root->initialized); | 743 ASSERT(root->initialized); |
744 size = partitionCookieSizeAdjustAdd(size); | 744 size = partitionCookieSizeAdjustAdd(size); |
745 PartitionBucket* bucket = partitionGenericSizeToBucket(root, size); | 745 PartitionBucket* bucket = partitionGenericSizeToBucket(root, size); |
746 if (LIKELY(!partitionBucketIsDirectMapped(bucket))) { | 746 if (LIKELY(!partitionBucketIsDirectMapped(bucket))) { |
747 size = bucket->slotSize; | 747 size = bucket->slotSize; |
748 } else if (size > kGenericMaxDirectMapped) { | 748 } else if (size > kGenericMaxDirectMapped) { |
749 // Too large to allocate => return the size unchanged. | 749 // Too large to allocate => return the size unchanged. |
750 } else { | 750 } else { |
751 ASSERT(bucket == &PartitionRootBase::gPagedBucket); | 751 ASSERT(bucket == &PartitionRootBase::gPagedBucket); |
752 size = partitionDirectMapSize(size); | 752 size = partitionRoundUpToSystemPage(size); |
753 } | 753 } |
754 return partitionCookieSizeAdjustSubtract(size); | 754 return partitionCookieSizeAdjustSubtract(size); |
755 #endif | 755 #endif |
756 } | 756 } |
757 | 757 |
758 ALWAYS_INLINE bool partitionAllocSupportsGetSize() | 758 ALWAYS_INLINE bool partitionAllocSupportsGetSize() |
759 { | 759 { |
760 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 760 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
761 return false; | 761 return false; |
762 #else | 762 #else |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 using WTF::partitionAlloc; | 811 using WTF::partitionAlloc; |
812 using WTF::partitionFree; | 812 using WTF::partitionFree; |
813 using WTF::partitionAllocGeneric; | 813 using WTF::partitionAllocGeneric; |
814 using WTF::partitionFreeGeneric; | 814 using WTF::partitionFreeGeneric; |
815 using WTF::partitionReallocGeneric; | 815 using WTF::partitionReallocGeneric; |
816 using WTF::partitionAllocActualSize; | 816 using WTF::partitionAllocActualSize; |
817 using WTF::partitionAllocSupportsGetSize; | 817 using WTF::partitionAllocSupportsGetSize; |
818 using WTF::partitionAllocGetSize; | 818 using WTF::partitionAllocGetSize; |
819 | 819 |
820 #endif // WTF_PartitionAlloc_h | 820 #endif // WTF_PartitionAlloc_h |
OLD | NEW |