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

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

Issue 1323093004: Clean up and clarify PartitionAlloc (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 3 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
« no previous file with comments | « Source/wtf/PartitionAlloc.h ('k') | no next file » | 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 491 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 502
503 uint16_t numPartitionPages = partitionBucketPartitionPages(bucket); 503 uint16_t numPartitionPages = partitionBucketPartitionPages(bucket);
504 char* pageCharPtr = reinterpret_cast<char*>(page); 504 char* pageCharPtr = reinterpret_cast<char*>(page);
505 for (uint16_t i = 1; i < numPartitionPages; ++i) { 505 for (uint16_t i = 1; i < numPartitionPages; ++i) {
506 pageCharPtr += kPageMetadataSize; 506 pageCharPtr += kPageMetadataSize;
507 PartitionPage* secondaryPage = reinterpret_cast<PartitionPage*>(pageChar Ptr); 507 PartitionPage* secondaryPage = reinterpret_cast<PartitionPage*>(pageChar Ptr);
508 secondaryPage->pageOffset = i; 508 secondaryPage->pageOffset = i;
509 } 509 }
510 } 510 }
511 511
512 static ALWAYS_INLINE size_t partitionRoundUpToSystemPage(size_t size) 512 static ALWAYS_INLINE char* partitionAlignUpToSystemPage(char* ptr)
513 { 513 {
514 return (size + kSystemPageOffsetMask) & kSystemPageBaseMask; 514 size_t addr = reinterpret_cast<size_t>(ptr);
Primiano Tucci (use gerrit) 2015/09/02 21:58:19 Hmm not sure I follow this (And below). What's wro
Ruud van Asseldonk 2015/09/03 08:32:25 This simply moves the casts that were there alread
515 size_t alignedAddr = (addr + kSystemPageOffsetMask) & kSystemPageBaseMask;
516 return reinterpret_cast<char*>(alignedAddr);
515 } 517 }
516 518
517 static ALWAYS_INLINE size_t partitionRoundDownToSystemPage(size_t size) 519 static ALWAYS_INLINE char* partitionAlignDownToSystemPage(char* ptr)
518 { 520 {
519 return size & kSystemPageBaseMask; 521 size_t addr = reinterpret_cast<size_t>(ptr);
522 size_t alignedAddr = addr & kSystemPageBaseMask;
523 return reinterpret_cast<char*>(alignedAddr);
520 } 524 }
521 525
522 static ALWAYS_INLINE char* partitionPageAllocAndFillFreelist(PartitionPage* page ) 526 static ALWAYS_INLINE char* partitionPageAllocAndFillFreelist(PartitionPage* page )
523 { 527 {
524 ASSERT(page != &PartitionRootGeneric::gSeedPage); 528 ASSERT(page != &PartitionRootGeneric::gSeedPage);
525 uint16_t numSlots = page->numUnprovisionedSlots; 529 uint16_t numSlots = page->numUnprovisionedSlots;
526 ASSERT(numSlots); 530 ASSERT(numSlots);
527 PartitionBucket* bucket = page->bucket; 531 PartitionBucket* bucket = page->bucket;
528 // We should only get here when _every_ slot is either used or unprovisioned . 532 // We should only get here when _every_ slot is either used or unprovisioned .
529 // (The third state is "on the freelist". If we have a non-empty freelist, w e should not get here.) 533 // (The third state is "on the freelist". If we have a non-empty freelist, w e should not get here.)
530 ASSERT(numSlots + page->numAllocatedSlots == partitionBucketSlots(bucket)); 534 ASSERT(numSlots + page->numAllocatedSlots == partitionBucketSlots(bucket));
531 // Similarly, make explicitly sure that the freelist is empty. 535 // Similarly, make explicitly sure that the freelist is empty.
532 ASSERT(!page->freelistHead); 536 ASSERT(!page->freelistHead);
533 ASSERT(page->numAllocatedSlots >= 0); 537 ASSERT(page->numAllocatedSlots >= 0);
534 538
535 size_t size = bucket->slotSize; 539 size_t size = bucket->slotSize;
536 char* base = reinterpret_cast<char*>(partitionPageToPointer(page)); 540 char* base = reinterpret_cast<char*>(partitionPageToPointer(page));
537 char* returnObject = base + (size * page->numAllocatedSlots); 541 char* returnObject = base + (size * page->numAllocatedSlots);
538 char* firstFreelistPointer = returnObject + size; 542 char* firstFreelistPointer = returnObject + size;
539 char* firstFreelistPointerExtent = firstFreelistPointer + sizeof(PartitionFr eelistEntry*); 543 char* firstFreelistPointerExtent = firstFreelistPointer + sizeof(PartitionFr eelistEntry*);
540 // Our goal is to fault as few system pages as possible. We calculate the 544 // Our goal is to fault as few system pages as possible. We calculate the
541 // page containing the "end" of the returned slot, and then allow freelist 545 // page containing the "end" of the returned slot, and then allow freelist
542 // pointers to be written up to the end of that page. 546 // pointers to be written up to the end of that page.
543 char* subPageLimit = reinterpret_cast<char*>(partitionRoundUpToSystemPage(re interpret_cast<size_t>(firstFreelistPointer))); 547 char* subPageLimit = partitionAlignUpToSystemPage(firstFreelistPointer);
544 char* slotsLimit = returnObject + (size * numSlots); 548 char* slotsLimit = returnObject + (size * numSlots);
545 char* freelistLimit = subPageLimit; 549 char* freelistLimit = subPageLimit;
546 if (UNLIKELY(slotsLimit < freelistLimit)) 550 if (UNLIKELY(slotsLimit < freelistLimit))
547 freelistLimit = slotsLimit; 551 freelistLimit = slotsLimit;
548 552
549 uint16_t numNewFreelistEntries = 0; 553 uint16_t numNewFreelistEntries = 0;
550 if (LIKELY(firstFreelistPointerExtent <= freelistLimit)) { 554 if (LIKELY(firstFreelistPointerExtent <= freelistLimit)) {
551 // Only consider used space in the slot span. If we consider wasted 555 // Only consider used space in the slot span. If we consider wasted
552 // space, we may get an off-by-one when a freelist pointer fits in the 556 // space, we may get an off-by-one when a freelist pointer fits in the
553 // wasted space, but a slot does not. 557 // wasted space, but a slot does not.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 648
645 static ALWAYS_INLINE void partitionPageSetRawSize(PartitionPage* page, size_t si ze) 649 static ALWAYS_INLINE void partitionPageSetRawSize(PartitionPage* page, size_t si ze)
646 { 650 {
647 size_t* rawSizePtr = partitionPageGetRawSizePtr(page); 651 size_t* rawSizePtr = partitionPageGetRawSizePtr(page);
648 if (UNLIKELY(rawSizePtr != nullptr)) 652 if (UNLIKELY(rawSizePtr != nullptr))
649 *rawSizePtr = size; 653 *rawSizePtr = size;
650 } 654 }
651 655
652 static ALWAYS_INLINE PartitionPage* partitionDirectMap(PartitionRootBase* root, int flags, size_t rawSize) 656 static ALWAYS_INLINE PartitionPage* partitionDirectMap(PartitionRootBase* root, int flags, size_t rawSize)
653 { 657 {
654 size_t size = partitionDirectMapSize(rawSize); 658 size_t size = partitionRoundUpToSystemPage(rawSize);
655 659
656 // Because we need to fake looking like a super page, we need to allocate 660 // Because we need to fake looking like a super page, we need to allocate
657 // a bunch of system pages more than "size": 661 // a bunch of system pages more than "size":
658 // - The first few system pages are the partition page in which the super 662 // - The first few system pages are the partition page in which the super
659 // page metadata is stored. We fault just one system page out of a partition 663 // page metadata is stored. We fault just one system page out of a partition
660 // page sized clump. 664 // page sized clump.
661 // - We add a trailing guard page on 32-bit (on 64-bit we rely on the 665 // - We add a trailing guard page on 32-bit (on 64-bit we rely on the
662 // massive address space plus randomization instead). 666 // massive address space plus randomization instead).
663 size_t mapSize = size + kPartitionPageSize; 667 size_t mapSize = size + kPartitionPageSize;
664 #if !CPU(64BIT) 668 #if !CPU(64BIT)
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 } 973 }
970 974
971 bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root, PartitionPa ge* page, size_t rawSize) 975 bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root, PartitionPa ge* page, size_t rawSize)
972 { 976 {
973 ASSERT(partitionBucketIsDirectMapped(page->bucket)); 977 ASSERT(partitionBucketIsDirectMapped(page->bucket));
974 978
975 rawSize = partitionCookieSizeAdjustAdd(rawSize); 979 rawSize = partitionCookieSizeAdjustAdd(rawSize);
976 980
977 // Note that the new size might be a bucketed size; this function is called 981 // Note that the new size might be a bucketed size; this function is called
978 // whenever we're reallocating a direct mapped allocation. 982 // whenever we're reallocating a direct mapped allocation.
979 size_t newSize = partitionDirectMapSize(rawSize); 983 size_t newSize = partitionRoundUpToSystemPage(rawSize);
980 if (newSize < kGenericMinDirectMappedDownsize) 984 if (newSize < kGenericMinDirectMappedDownsize)
981 return false; 985 return false;
982 986
983 // bucket->slotSize is the current size of the allocation. 987 // bucket->slotSize is the current size of the allocation.
984 size_t currentSize = page->bucket->slotSize; 988 size_t currentSize = page->bucket->slotSize;
985 if (newSize == currentSize) 989 if (newSize == currentSize)
986 return true; 990 return true;
987 991
988 char* charPtr = static_cast<char*>(partitionPageToPointer(page)); 992 char* charPtr = static_cast<char*>(partitionPageToPointer(page));
989 993
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 ASSERT(numSlots); 1140 ASSERT(numSlots);
1137 } 1141 }
1138 // First, do the work of calculating the discardable bytes. Don't actually 1142 // First, do the work of calculating the discardable bytes. Don't actually
1139 // discard anything unless the discard flag was passed in. 1143 // discard anything unless the discard flag was passed in.
1140 char* beginPtr = nullptr; 1144 char* beginPtr = nullptr;
1141 char* endPtr = nullptr; 1145 char* endPtr = nullptr;
1142 size_t unprovisionedBytes = 0; 1146 size_t unprovisionedBytes = 0;
1143 if (truncatedSlots) { 1147 if (truncatedSlots) {
1144 beginPtr = ptr + (numSlots * slotSize); 1148 beginPtr = ptr + (numSlots * slotSize);
1145 endPtr = beginPtr + (slotSize * truncatedSlots); 1149 endPtr = beginPtr + (slotSize * truncatedSlots);
1146 beginPtr = reinterpret_cast<char*>(partitionRoundUpToSystemPage(reinterp ret_cast<size_t>(beginPtr))); 1150 beginPtr = partitionAlignUpToSystemPage(beginPtr);
1147 // We round the end pointer here up and not down because we're at the 1151 // We round the end pointer here up and not down because we're at the
1148 // end of a slot span, so we "own" all the way up the page boundary. 1152 // end of a slot span, so we "own" all the way up the page boundary.
1149 endPtr = reinterpret_cast<char*>(partitionRoundUpToSystemPage(reinterpre t_cast<size_t>(endPtr))); 1153 endPtr = partitionAlignUpToSystemPage(endPtr);
1150 ASSERT(endPtr <= ptr + partitionBucketBytes(bucket)); 1154 ASSERT(endPtr <= ptr + partitionBucketBytes(bucket));
1151 if (beginPtr < endPtr) { 1155 if (beginPtr < endPtr) {
1152 unprovisionedBytes = endPtr - beginPtr; 1156 unprovisionedBytes = endPtr - beginPtr;
1153 discardableBytes += unprovisionedBytes; 1157 discardableBytes += unprovisionedBytes;
1154 } 1158 }
1155 } 1159 }
1156 if (unprovisionedBytes && discard) { 1160 if (unprovisionedBytes && discard) {
1157 ASSERT(truncatedSlots > 0); 1161 ASSERT(truncatedSlots > 0);
1158 size_t numNewEntries = 0; 1162 size_t numNewEntries = 0;
1159 page->numUnprovisionedSlots += truncatedSlots; 1163 page->numUnprovisionedSlots += truncatedSlots;
(...skipping 23 matching lines...) Expand all
1183 for (size_t i = 0; i < numSlots; ++i) { 1187 for (size_t i = 0; i < numSlots; ++i) {
1184 if (slotUsage[i]) 1188 if (slotUsage[i])
1185 continue; 1189 continue;
1186 // The first address we can safely discard is just after the freelist 1190 // The first address we can safely discard is just after the freelist
1187 // pointer. There's one quirk: if the freelist pointer is actually a 1191 // pointer. There's one quirk: if the freelist pointer is actually a
1188 // null, we can discard that pointer value too. 1192 // null, we can discard that pointer value too.
1189 char* beginPtr = ptr + (i * slotSize); 1193 char* beginPtr = ptr + (i * slotSize);
1190 char* endPtr = beginPtr + slotSize; 1194 char* endPtr = beginPtr + slotSize;
1191 if (i != lastSlot) 1195 if (i != lastSlot)
1192 beginPtr += sizeof(PartitionFreelistEntry); 1196 beginPtr += sizeof(PartitionFreelistEntry);
1193 beginPtr = reinterpret_cast<char*>(partitionRoundUpToSystemPage(reinterp ret_cast<size_t>(beginPtr))); 1197 beginPtr = partitionAlignUpToSystemPage(beginPtr);
1194 endPtr = reinterpret_cast<char*>(partitionRoundDownToSystemPage(reinterp ret_cast<size_t>(endPtr))); 1198 endPtr = partitionAlignDownToSystemPage(endPtr);
1195 if (beginPtr < endPtr) { 1199 if (beginPtr < endPtr) {
1196 size_t partialSlotBytes = endPtr - beginPtr; 1200 size_t partialSlotBytes = endPtr - beginPtr;
1197 discardableBytes += partialSlotBytes; 1201 discardableBytes += partialSlotBytes;
1198 if (discard) 1202 if (discard)
1199 discardSystemPages(beginPtr, partialSlotBytes); 1203 discardSystemPages(beginPtr, partialSlotBytes);
1200 } 1204 }
1201 } 1205 }
1202 return discardableBytes; 1206 return discardableBytes;
1203 } 1207 }
1204 1208
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes; 1400 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes;
1397 if (!isLightDump) 1401 if (!isLightDump)
1398 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]); 1402 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]);
1399 } 1403 }
1400 } 1404 }
1401 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats); 1405 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats);
1402 } 1406 }
1403 1407
1404 } // namespace WTF 1408 } // namespace WTF
1405 1409
OLDNEW
« no previous file with comments | « Source/wtf/PartitionAlloc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698