Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(518)

Side by Side Diff: Source/wtf/PartitionAlloc.h

Issue 136333002: PartitionAlloc: simplify PartitionPage structure some more. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | Source/wtf/PartitionAlloc.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 // The significant page transitions are: 216 // The significant page transitions are:
217 // - free() will detect when a full page has a slot free()'d and immediately 217 // - free() will detect when a full page has a slot free()'d and immediately
218 // return the page to the head of the active list. 218 // return the page to the head of the active list.
219 // - free() will detect when a page is fully emptied. It _may_ add it to the 219 // - free() will detect when a page is fully emptied. It _may_ add it to the
220 // free list and it _may_ leave it on the active list until a future list scan. 220 // free list and it _may_ leave it on the active list until a future list scan.
221 // - malloc() _may_ scan the active page list in order to fulfil the request. 221 // - malloc() _may_ scan the active page list in order to fulfil the request.
222 // If it does this, full and free pages encountered will be booted out of the 222 // If it does this, full and free pages encountered will be booted out of the
223 // active list. If there are no suitable active pages found, a free page (if one 223 // active list. If there are no suitable active pages found, a free page (if one
224 // exists) will be pulled from the free list on to the active list. 224 // exists) will be pulled from the free list on to the active list.
225 struct PartitionPage { 225 struct PartitionPage {
226 union { // Accessed most in hot path => goes first. 226 PartitionFreelistEntry* freelistHead;
227 PartitionFreelistEntry* freelistHead; // If the page is active. 227 PartitionPage* next;
Tom Sepez 2014/01/13 18:15:55 nit: nextPage or some such. Too many lists to sim
228 PartitionPage* freePageNext; // If the page is free.
229 } u;
230 PartitionPage* activePageNext;
231 PartitionBucket* bucket; 228 PartitionBucket* bucket;
232 int16_t numAllocatedSlots; // Deliberately signed, -1 for free page, -n for full pages. 229 int16_t numAllocatedSlots; // Deliberately signed, -1 for free page, -n for full pages.
233 uint16_t numUnprovisionedSlots; 230 uint16_t numUnprovisionedSlots;
234 uint16_t pageOffset; 231 uint16_t pageOffset;
235 uint16_t flags;
236 }; 232 };
237 static uint16_t kPartitionPageFlagFree = 1; 233 static uint16_t kPartitionPageFlagFree = 1;
238 234
239 struct PartitionBucket { 235 struct PartitionBucket {
240 PartitionPage* activePagesHead; // Accessed most in hot path => goes first. 236 PartitionPage* activePagesHead; // Accessed most in hot path => goes first.
241 PartitionPage* freePagesHead; 237 PartitionPage* freePagesHead;
242 uint16_t slotSize; 238 uint16_t slotSize;
243 uint16_t numSystemPagesPerSlotSpan; 239 uint16_t numSystemPagesPerSlotSpan;
244 uint32_t numFullPages; 240 uint32_t numFullPages;
245 }; 241 };
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 PartitionSuperPageExtentEntry* entry = firstExtent->next; 460 PartitionSuperPageExtentEntry* entry = firstExtent->next;
465 while (UNLIKELY(entry != 0)) { 461 while (UNLIKELY(entry != 0)) {
466 if (ptr >= entry->superPageBase && ptr < entry->superPagesEnd) 462 if (ptr >= entry->superPageBase && ptr < entry->superPagesEnd)
467 return true; 463 return true;
468 entry = entry->next; 464 entry = entry->next;
469 } 465 }
470 466
471 return false; 467 return false;
472 } 468 }
473 469
474 ALWAYS_INLINE bool partitionPageIsFree(PartitionPage* page)
475 {
476 return (page->flags & kPartitionPageFlagFree);
477 }
478
479 ALWAYS_INLINE PartitionFreelistEntry* partitionPageFreelistHead(PartitionPage* p age)
480 {
481 ASSERT((page == &PartitionRootBase::gSeedPage && !page->u.freelistHead) || ! partitionPageIsFree(page));
482 return page->u.freelistHead;
483 }
484
485 ALWAYS_INLINE void partitionPageSetFreelistHead(PartitionPage* page, PartitionFr eelistEntry* newHead)
486 {
487 ASSERT(!partitionPageIsFree(page));
488 page->u.freelistHead = newHead;
489 }
490
491 ALWAYS_INLINE void* partitionBucketAlloc(PartitionRootBase* root, size_t size, P artitionBucket* bucket) 470 ALWAYS_INLINE void* partitionBucketAlloc(PartitionRootBase* root, size_t size, P artitionBucket* bucket)
492 { 471 {
493 PartitionPage* page = bucket->activePagesHead; 472 PartitionPage* page = bucket->activePagesHead;
494 ASSERT(page == &PartitionRootBase::gSeedPage || page->numAllocatedSlots >= 0 ); 473 ASSERT(page->numAllocatedSlots >= 0);
495 void* ret = partitionPageFreelistHead(page); 474 void* ret = page->freelistHead;
496 if (LIKELY(ret != 0)) { 475 if (LIKELY(ret != 0)) {
497 // If these asserts fire, you probably corrupted memory. 476 // If these asserts fire, you probably corrupted memory.
498 ASSERT(partitionPointerIsValid(root, ret)); 477 ASSERT(partitionPointerIsValid(root, ret));
499 ASSERT(partitionPointerToPage(ret)); 478 ASSERT(partitionPointerToPage(ret));
500 PartitionFreelistEntry* newHead = partitionFreelistMask(static_cast<Part itionFreelistEntry*>(ret)->next); 479 PartitionFreelistEntry* newHead = partitionFreelistMask(static_cast<Part itionFreelistEntry*>(ret)->next);
501 partitionPageSetFreelistHead(page, newHead); 480 page->freelistHead = newHead;
502 ASSERT(!ret || partitionPointerIsValid(root, ret)); 481 ASSERT(!ret || partitionPointerIsValid(root, ret));
503 ASSERT(!ret || partitionPointerToPage(ret)); 482 ASSERT(!ret || partitionPointerToPage(ret));
504 page->numAllocatedSlots++; 483 page->numAllocatedSlots++;
505 } else { 484 } else {
506 ret = partitionAllocSlowPath(root, size, bucket); 485 ret = partitionAllocSlowPath(root, size, bucket);
507 } 486 }
508 #ifndef NDEBUG 487 #ifndef NDEBUG
509 // This will go away once we don't use tcmalloc to back larger allocations. 488 // This will go away once we don't use tcmalloc to back larger allocations.
510 if (!partitionPointerIsValid(root, ret)) 489 if (!partitionPointerIsValid(root, ret))
511 return ret; 490 return ret;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page) 526 ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page)
548 { 527 {
549 // If these asserts fire, you probably corrupted memory. 528 // If these asserts fire, you probably corrupted memory.
550 #ifndef NDEBUG 529 #ifndef NDEBUG
551 size_t bucketSize = page->bucket->slotSize; 530 size_t bucketSize = page->bucket->slotSize;
552 void* ptrEnd = static_cast<char*>(ptr) + bucketSize; 531 void* ptrEnd = static_cast<char*>(ptr) + bucketSize;
553 ASSERT(*(static_cast<uintptr_t*>(ptr)) == kCookieValue); 532 ASSERT(*(static_cast<uintptr_t*>(ptr)) == kCookieValue);
554 ASSERT(*(static_cast<uintptr_t*>(ptrEnd) - 1) == kCookieValue); 533 ASSERT(*(static_cast<uintptr_t*>(ptrEnd) - 1) == kCookieValue);
555 memset(ptr, kFreedByte, bucketSize); 534 memset(ptr, kFreedByte, bucketSize);
556 #endif 535 #endif
557 PartitionFreelistEntry* freelistHead = partitionPageFreelistHead(page); 536 ASSERT(page->numAllocatedSlots);
537 PartitionFreelistEntry* freelistHead = page->freelistHead;
558 ASSERT(!freelistHead || partitionPointerIsValid(partitionPageToRoot(page), f reelistHead)); 538 ASSERT(!freelistHead || partitionPointerIsValid(partitionPageToRoot(page), f reelistHead));
559 ASSERT(!freelistHead || partitionPointerToPage(freelistHead)); 539 ASSERT(!freelistHead || partitionPointerToPage(freelistHead));
560 RELEASE_ASSERT(ptr != freelistHead); // Catches an immediate double free. 540 RELEASE_ASSERT(ptr != freelistHead); // Catches an immediate double free.
561 ASSERT(!freelistHead || ptr != partitionFreelistMask(freelistHead->next)); / / Look for double free one level deeper in debug. 541 ASSERT(!freelistHead || ptr != partitionFreelistMask(freelistHead->next)); / / Look for double free one level deeper in debug.
562 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr); 542 PartitionFreelistEntry* entry = static_cast<PartitionFreelistEntry*>(ptr);
563 entry->next = partitionFreelistMask(freelistHead); 543 entry->next = partitionFreelistMask(freelistHead);
564 partitionPageSetFreelistHead(page, entry); 544 page->freelistHead = entry;
565 --page->numAllocatedSlots; 545 --page->numAllocatedSlots;
566 if (UNLIKELY(page->numAllocatedSlots <= 0)) 546 if (UNLIKELY(page->numAllocatedSlots <= 0))
567 partitionFreeSlowPath(page); 547 partitionFreeSlowPath(page);
568 } 548 }
569 549
570 ALWAYS_INLINE void partitionFree(void* ptr) 550 ALWAYS_INLINE void partitionFree(void* ptr)
571 { 551 {
572 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 552 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
573 free(ptr); 553 free(ptr);
574 #else 554 #else
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 using WTF::PartitionRoot; 643 using WTF::PartitionRoot;
664 using WTF::partitionAllocInit; 644 using WTF::partitionAllocInit;
665 using WTF::partitionAllocShutdown; 645 using WTF::partitionAllocShutdown;
666 using WTF::partitionAlloc; 646 using WTF::partitionAlloc;
667 using WTF::partitionFree; 647 using WTF::partitionFree;
668 using WTF::partitionAllocGeneric; 648 using WTF::partitionAllocGeneric;
669 using WTF::partitionFreeGeneric; 649 using WTF::partitionFreeGeneric;
670 using WTF::partitionReallocGeneric; 650 using WTF::partitionReallocGeneric;
671 651
672 #endif // WTF_PartitionAlloc_h 652 #endif // WTF_PartitionAlloc_h
OLDNEW
« no previous file with comments | « no previous file | Source/wtf/PartitionAlloc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698