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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 PartitionPageHeader seedPage; | 129 PartitionPageHeader seedPage; |
130 PartitionBucket seedBucket; | 130 PartitionBucket seedBucket; |
131 PartitionBucket buckets[kNumBuckets]; | 131 PartitionBucket buckets[kNumBuckets]; |
132 char* nextSuperPage; | 132 char* nextSuperPage; |
133 char* nextPartitionPage; | 133 char* nextPartitionPage; |
134 char* nextPartitionPageEnd; | 134 char* nextPartitionPageEnd; |
135 bool initialized; | 135 bool initialized; |
136 }; | 136 }; |
137 | 137 |
138 WTF_EXPORT void partitionAllocInit(PartitionRoot*); | 138 WTF_EXPORT void partitionAllocInit(PartitionRoot*); |
139 WTF_EXPORT void partitionAllocShutdown(PartitionRoot*); | 139 WTF_EXPORT bool partitionAllocShutdown(PartitionRoot*); |
140 | 140 |
141 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionBucket*); | 141 WTF_EXPORT NEVER_INLINE void* partitionAllocSlowPath(PartitionBucket*); |
142 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPageHeader*); | 142 WTF_EXPORT NEVER_INLINE void partitionFreeSlowPath(PartitionPageHeader*); |
143 | 143 |
144 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEnt
ry* ptr) | 144 ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEnt
ry* ptr) |
145 { | 145 { |
146 // For now, use a simple / fast mask that guarantees an invalid pointer in | 146 // For now, use a simple / fast mask that guarantees an invalid pointer in |
147 // case it gets used as a vtable pointer. | 147 // case it gets used as a vtable pointer. |
148 // The one attack we're fully mitigating is where an object is freed and its | 148 // The one attack we're fully mitigating is where an object is freed and its |
149 // vtable used where the attacker doesn't get the chance to run allocations | 149 // vtable used where the attacker doesn't get the chance to run allocations |
(...skipping 27 matching lines...) Expand all Loading... |
177 return partitionAllocSlowPath(bucket); | 177 return partitionAllocSlowPath(bucket); |
178 } | 178 } |
179 | 179 |
180 ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) | 180 ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) |
181 { | 181 { |
182 ASSERT(isMainThread()); | 182 ASSERT(isMainThread()); |
183 ASSERT(size); | 183 ASSERT(size); |
184 size_t index = size >> kBucketShift; | 184 size_t index = size >> kBucketShift; |
185 ASSERT(index < kNumBuckets); | 185 ASSERT(index < kNumBuckets); |
186 ASSERT(size == index << kBucketShift); | 186 ASSERT(size == index << kBucketShift); |
187 #if defined(ADDRESS_SANITIZER) || (!defined(NDEBUG) && !defined(DEBUG_PARTITION_
ALLOC)) | 187 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
188 return malloc(size); | 188 return malloc(size); |
189 #else | 189 #else |
190 PartitionBucket* bucket = &root->buckets[index]; | 190 PartitionBucket* bucket = &root->buckets[index]; |
191 return partitionBucketAlloc(bucket); | 191 return partitionBucketAlloc(bucket); |
192 #endif | 192 #endif |
193 } | 193 } |
194 | 194 |
195 ALWAYS_INLINE void partitionFree(void* ptr) | 195 ALWAYS_INLINE void partitionFree(void* ptr) |
196 { | 196 { |
197 ASSERT(isMainThread()); | 197 ASSERT(isMainThread()); |
198 #if defined(ADDRESS_SANITIZER) || (!defined(NDEBUG) && !defined(DEBUG_PARTITION_
ALLOC)) | 198 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
199 free(ptr); | 199 free(ptr); |
200 #else | 200 #else |
201 uintptr_t pointerAsUint = reinterpret_cast<uintptr_t>(ptr); | 201 uintptr_t pointerAsUint = reinterpret_cast<uintptr_t>(ptr); |
202 // Checks that the pointer is after the page header. You can't free the | 202 // Checks that the pointer is after the page header. You can't free the |
203 // page header! | 203 // page header! |
204 ASSERT((pointerAsUint & kPartitionPageOffsetMask) >= sizeof(PartitionPageHea
der)); | 204 ASSERT((pointerAsUint & kPartitionPageOffsetMask) >= sizeof(PartitionPageHea
der)); |
205 PartitionPageHeader* page = reinterpret_cast<PartitionPageHeader*>(pointerAs
Uint & kPartitionPageBaseMask); | 205 PartitionPageHeader* page = reinterpret_cast<PartitionPageHeader*>(pointerAs
Uint & kPartitionPageBaseMask); |
206 // Checks that the pointer is a multiple of bucket size. | 206 // Checks that the pointer is a multiple of bucket size. |
207 ASSERT(!(((pointerAsUint & kPartitionPageOffsetMask) - sizeof(PartitionPageH
eader)) % partitionBucketSize(page->bucket))); | 207 ASSERT(!(((pointerAsUint & kPartitionPageOffsetMask) - sizeof(PartitionPageH
eader)) % partitionBucketSize(page->bucket))); |
208 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); | 208 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); |
209 entry->next = partitionFreelistMask(page->freelistHead); | 209 entry->next = partitionFreelistMask(page->freelistHead); |
210 page->freelistHead = entry; | 210 page->freelistHead = entry; |
211 --page->numAllocatedSlots; | 211 --page->numAllocatedSlots; |
212 if (UNLIKELY(page->numAllocatedSlots <= 0)) | 212 if (UNLIKELY(page->numAllocatedSlots <= 0)) |
213 partitionFreeSlowPath(page); | 213 partitionFreeSlowPath(page); |
214 #endif | 214 #endif |
215 } | 215 } |
216 | 216 |
217 } // namespace WTF | 217 } // namespace WTF |
218 | 218 |
219 using WTF::PartitionRoot; | 219 using WTF::PartitionRoot; |
220 using WTF::partitionAllocInit; | 220 using WTF::partitionAllocInit; |
221 using WTF::partitionAllocShutdown; | 221 using WTF::partitionAllocShutdown; |
222 using WTF::partitionAlloc; | 222 using WTF::partitionAlloc; |
223 using WTF::partitionFree; | 223 using WTF::partitionFree; |
224 | 224 |
225 #endif // WTF_PartitionAlloc_h | 225 #endif // WTF_PartitionAlloc_h |
OLD | NEW |