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 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
247 // next extent (if there is one) at the very start of a superpage's metadata | 247 // next extent (if there is one) at the very start of a superpage's metadata |
248 // area. | 248 // area. |
249 struct PartitionSuperPageExtentEntry { | 249 struct PartitionSuperPageExtentEntry { |
250 PartitionRootBase* root; | 250 PartitionRootBase* root; |
251 char* superPageBase; | 251 char* superPageBase; |
252 char* superPagesEnd; | 252 char* superPagesEnd; |
253 PartitionSuperPageExtentEntry* next; | 253 PartitionSuperPageExtentEntry* next; |
254 }; | 254 }; |
255 | 255 |
256 struct WTF_EXPORT PartitionRootBase { | 256 struct WTF_EXPORT PartitionRootBase { |
257 size_t totalAllocationSize; | |
257 size_t totalSizeOfSuperPages; | 258 size_t totalSizeOfSuperPages; |
258 unsigned numBuckets; | 259 unsigned numBuckets; |
259 unsigned maxAllocation; | 260 unsigned maxAllocation; |
260 bool initialized; | 261 bool initialized; |
261 char* nextSuperPage; | 262 char* nextSuperPage; |
262 char* nextPartitionPage; | 263 char* nextPartitionPage; |
263 char* nextPartitionPageEnd; | 264 char* nextPartitionPageEnd; |
264 PartitionSuperPageExtentEntry* currentExtent; | 265 PartitionSuperPageExtentEntry* currentExtent; |
265 PartitionSuperPageExtentEntry* firstExtent; | 266 PartitionSuperPageExtentEntry* firstExtent; |
266 PartitionPage* globalEmptyPageRing[kMaxFreeableSpans]; | 267 PartitionPage* globalEmptyPageRing[kMaxFreeableSpans]; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 return 0; | 458 return 0; |
458 // Fill the uninitialized pattern. and write the cookies. | 459 // Fill the uninitialized pattern. and write the cookies. |
459 page = partitionPointerToPage(ret); | 460 page = partitionPointerToPage(ret); |
460 size_t bucketSize = page->bucket->slotSize; | 461 size_t bucketSize = page->bucket->slotSize; |
461 memset(ret, kUninitializedByte, bucketSize); | 462 memset(ret, kUninitializedByte, bucketSize); |
462 partitionCookieWriteValue(ret); | 463 partitionCookieWriteValue(ret); |
463 partitionCookieWriteValue(reinterpret_cast<char*>(ret) + bucketSize - kCooki eSize); | 464 partitionCookieWriteValue(reinterpret_cast<char*>(ret) + bucketSize - kCooki eSize); |
464 // The value given to the application is actually just after the cookie. | 465 // The value given to the application is actually just after the cookie. |
465 ret = static_cast<char*>(ret) + kCookieSize; | 466 ret = static_cast<char*>(ret) + kCookieSize; |
466 #endif | 467 #endif |
468 root->totalAllocationSize += bucket->slotSize; | |
Chris Evans
2014/06/05 18:00:26
My gut reaction is I don't like this. It adds over
| |
467 return ret; | 469 return ret; |
468 } | 470 } |
469 | 471 |
470 ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) | 472 ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) |
471 { | 473 { |
472 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 474 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
473 void* result = malloc(size); | 475 void* result = malloc(size); |
474 RELEASE_ASSERT(result); | 476 RELEASE_ASSERT(result); |
475 return result; | 477 return result; |
476 #else | 478 #else |
477 size = partitionCookieSizeAdjustAdd(size); | 479 size = partitionCookieSizeAdjustAdd(size); |
478 ASSERT(root->initialized); | 480 ASSERT(root->initialized); |
479 size_t index = size >> kBucketShift; | 481 size_t index = size >> kBucketShift; |
480 ASSERT(index < root->numBuckets); | 482 ASSERT(index < root->numBuckets); |
481 ASSERT(size == index << kBucketShift); | 483 ASSERT(size == index << kBucketShift); |
482 PartitionBucket* bucket = &root->buckets()[index]; | 484 PartitionBucket* bucket = &root->buckets()[index]; |
483 return partitionBucketAlloc(root, 0, size, bucket); | 485 return partitionBucketAlloc(root, 0, size, bucket); |
484 #endif // defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 486 #endif // defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
485 } | 487 } |
486 | 488 |
487 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page) | 489 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page) |
488 { | 490 { |
489 // If these asserts fire, you probably corrupted memory. | 491 // If these asserts fire, you probably corrupted memory. |
492 size_t bucketSize = page->bucket->slotSize; | |
490 #ifndef NDEBUG | 493 #ifndef NDEBUG |
491 size_t bucketSize = page->bucket->slotSize; | |
492 partitionCookieCheckValue(ptr); | 494 partitionCookieCheckValue(ptr); |
493 partitionCookieCheckValue(reinterpret_cast<char*>(ptr) + bucketSize - kCooki eSize); | 495 partitionCookieCheckValue(reinterpret_cast<char*>(ptr) + bucketSize - kCooki eSize); |
494 memset(ptr, kFreedByte, bucketSize); | 496 memset(ptr, kFreedByte, bucketSize); |
495 #endif | 497 #endif |
496 ASSERT(page->numAllocatedSlots); | 498 ASSERT(page->numAllocatedSlots); |
497 PartitionFreelistEntry* freelistHead = page->freelistHead; | 499 PartitionFreelistEntry* freelistHead = page->freelistHead; |
498 ASSERT(!freelistHead || partitionPointerIsValid(freelistHead)); | 500 ASSERT(!freelistHead || partitionPointerIsValid(freelistHead)); |
499 RELEASE_ASSERT(ptr != freelistHead); // Catches an immediate double free. | 501 RELEASE_ASSERT(ptr != freelistHead); // Catches an immediate double free. |
500 ASSERT(!freelistHead || ptr != partitionFreelistMask(freelistHead->next)); / / Look for double free one level deeper in debug. | 502 ASSERT(!freelistHead || ptr != partitionFreelistMask(freelistHead->next)); / / Look for double free one level deeper in debug. |
501 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); | 503 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); |
502 entry->next = partitionFreelistMask(freelistHead); | 504 entry->next = partitionFreelistMask(freelistHead); |
503 page->freelistHead = entry; | 505 page->freelistHead = entry; |
504 --page->numAllocatedSlots; | 506 --page->numAllocatedSlots; |
507 | |
508 PartitionRootBase* root = partitionPageToRoot(page); | |
509 root->totalAllocationSize -= bucketSize; | |
Tom Sepez
2014/06/05 17:52:01
nit: assert you don't underflow here.
| |
510 | |
505 if (UNLIKELY(page->numAllocatedSlots <= 0)) | 511 if (UNLIKELY(page->numAllocatedSlots <= 0)) |
506 partitionFreeSlowPath(page); | 512 partitionFreeSlowPath(page); |
507 } | 513 } |
508 | 514 |
509 ALWAYS_INLINE void partitionFree(void* ptr) | 515 ALWAYS_INLINE void partitionFree(void* ptr) |
510 { | 516 { |
511 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) | 517 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
512 free(ptr); | 518 free(ptr); |
513 #else | 519 #else |
514 ptr = partitionCookieFreePointerAdjust(ptr); | 520 ptr = partitionCookieFreePointerAdjust(ptr); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
662 using WTF::partitionAlloc; | 668 using WTF::partitionAlloc; |
663 using WTF::partitionFree; | 669 using WTF::partitionFree; |
664 using WTF::partitionAllocGeneric; | 670 using WTF::partitionAllocGeneric; |
665 using WTF::partitionFreeGeneric; | 671 using WTF::partitionFreeGeneric; |
666 using WTF::partitionReallocGeneric; | 672 using WTF::partitionReallocGeneric; |
667 using WTF::partitionAllocActualSize; | 673 using WTF::partitionAllocActualSize; |
668 using WTF::partitionAllocSupportsGetSize; | 674 using WTF::partitionAllocSupportsGetSize; |
669 using WTF::partitionAllocGetSize; | 675 using WTF::partitionAllocGetSize; |
670 | 676 |
671 #endif // WTF_PartitionAlloc_h | 677 #endif // WTF_PartitionAlloc_h |
OLD | NEW |