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

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

Issue 1666083002: Oilpan: Discard unused system pages when sweeping NormalPageHeaps (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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 | « third_party/WebKit/Source/wtf/PageAllocator.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 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 517
518 uint16_t numPartitionPages = partitionBucketPartitionPages(bucket); 518 uint16_t numPartitionPages = partitionBucketPartitionPages(bucket);
519 char* pageCharPtr = reinterpret_cast<char*>(page); 519 char* pageCharPtr = reinterpret_cast<char*>(page);
520 for (uint16_t i = 1; i < numPartitionPages; ++i) { 520 for (uint16_t i = 1; i < numPartitionPages; ++i) {
521 pageCharPtr += kPageMetadataSize; 521 pageCharPtr += kPageMetadataSize;
522 PartitionPage* secondaryPage = reinterpret_cast<PartitionPage*>(pageChar Ptr); 522 PartitionPage* secondaryPage = reinterpret_cast<PartitionPage*>(pageChar Ptr);
523 secondaryPage->pageOffset = i; 523 secondaryPage->pageOffset = i;
524 } 524 }
525 } 525 }
526 526
527 static ALWAYS_INLINE size_t partitionRoundUpToSystemPage(size_t size)
528 {
529 return (size + kSystemPageOffsetMask) & kSystemPageBaseMask;
530 }
531
532 static ALWAYS_INLINE size_t partitionRoundDownToSystemPage(size_t size)
533 {
534 return size & kSystemPageBaseMask;
535 }
536
537 static ALWAYS_INLINE char* partitionPageAllocAndFillFreelist(PartitionPage* page ) 527 static ALWAYS_INLINE char* partitionPageAllocAndFillFreelist(PartitionPage* page )
538 { 528 {
539 ASSERT(page != &PartitionRootGeneric::gSeedPage); 529 ASSERT(page != &PartitionRootGeneric::gSeedPage);
540 uint16_t numSlots = page->numUnprovisionedSlots; 530 uint16_t numSlots = page->numUnprovisionedSlots;
541 ASSERT(numSlots); 531 ASSERT(numSlots);
542 PartitionBucket* bucket = page->bucket; 532 PartitionBucket* bucket = page->bucket;
543 // We should only get here when _every_ slot is either used or unprovisioned . 533 // We should only get here when _every_ slot is either used or unprovisioned .
544 // (The third state is "on the freelist". If we have a non-empty freelist, w e should not get here.) 534 // (The third state is "on the freelist". If we have a non-empty freelist, w e should not get here.)
545 ASSERT(numSlots + page->numAllocatedSlots == partitionBucketSlots(bucket)); 535 ASSERT(numSlots + page->numAllocatedSlots == partitionBucketSlots(bucket));
546 // Similarly, make explicitly sure that the freelist is empty. 536 // Similarly, make explicitly sure that the freelist is empty.
547 ASSERT(!page->freelistHead); 537 ASSERT(!page->freelistHead);
548 ASSERT(page->numAllocatedSlots >= 0); 538 ASSERT(page->numAllocatedSlots >= 0);
549 539
550 size_t size = bucket->slotSize; 540 size_t size = bucket->slotSize;
551 char* base = reinterpret_cast<char*>(partitionPageToPointer(page)); 541 char* base = reinterpret_cast<char*>(partitionPageToPointer(page));
552 char* returnObject = base + (size * page->numAllocatedSlots); 542 char* returnObject = base + (size * page->numAllocatedSlots);
553 char* firstFreelistPointer = returnObject + size; 543 char* firstFreelistPointer = returnObject + size;
554 char* firstFreelistPointerExtent = firstFreelistPointer + sizeof(PartitionFr eelistEntry*); 544 char* firstFreelistPointerExtent = firstFreelistPointer + sizeof(PartitionFr eelistEntry*);
555 // Our goal is to fault as few system pages as possible. We calculate the 545 // Our goal is to fault as few system pages as possible. We calculate the
556 // page containing the "end" of the returned slot, and then allow freelist 546 // page containing the "end" of the returned slot, and then allow freelist
557 // pointers to be written up to the end of that page. 547 // pointers to be written up to the end of that page.
558 char* subPageLimit = reinterpret_cast<char*>(partitionRoundUpToSystemPage(re interpret_cast<size_t>(firstFreelistPointer))); 548 char* subPageLimit = reinterpret_cast<char*>(WTF::roundUpToSystemPage(reinte rpret_cast<size_t>(firstFreelistPointer)));
559 char* slotsLimit = returnObject + (size * numSlots); 549 char* slotsLimit = returnObject + (size * numSlots);
560 char* freelistLimit = subPageLimit; 550 char* freelistLimit = subPageLimit;
561 if (UNLIKELY(slotsLimit < freelistLimit)) 551 if (UNLIKELY(slotsLimit < freelistLimit))
562 freelistLimit = slotsLimit; 552 freelistLimit = slotsLimit;
563 553
564 uint16_t numNewFreelistEntries = 0; 554 uint16_t numNewFreelistEntries = 0;
565 if (LIKELY(firstFreelistPointerExtent <= freelistLimit)) { 555 if (LIKELY(firstFreelistPointerExtent <= freelistLimit)) {
566 // Only consider used space in the slot span. If we consider wasted 556 // Only consider used space in the slot span. If we consider wasted
567 // space, we may get an off-by-one when a freelist pointer fits in the 557 // space, we may get an off-by-one when a freelist pointer fits in the
568 // wasted space, but a slot does not. 558 // wasted space, but a slot does not.
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 const PartitionBucket* bucket = page->bucket; 1092 const PartitionBucket* bucket = page->bucket;
1103 size_t slotSize = bucket->slotSize; 1093 size_t slotSize = bucket->slotSize;
1104 if (slotSize < kSystemPageSize || !page->numAllocatedSlots) 1094 if (slotSize < kSystemPageSize || !page->numAllocatedSlots)
1105 return 0; 1095 return 0;
1106 1096
1107 size_t bucketNumSlots = partitionBucketSlots(bucket); 1097 size_t bucketNumSlots = partitionBucketSlots(bucket);
1108 size_t discardableBytes = 0; 1098 size_t discardableBytes = 0;
1109 1099
1110 size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page)); 1100 size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page));
1111 if (rawSize) { 1101 if (rawSize) {
1112 uint32_t usedBytes = static_cast<uint32_t>(partitionRoundUpToSystemPage( rawSize)); 1102 uint32_t usedBytes = static_cast<uint32_t>(WTF::roundUpToSystemPage(rawS ize));
1113 discardableBytes = bucket->slotSize - usedBytes; 1103 discardableBytes = bucket->slotSize - usedBytes;
1114 if (discardableBytes && discard) { 1104 if (discardableBytes && discard) {
1115 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page)); 1105 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page));
1116 ptr += usedBytes; 1106 ptr += usedBytes;
1117 discardSystemPages(ptr, discardableBytes); 1107 discardSystemPages(ptr, discardableBytes);
1118 } 1108 }
1119 return discardableBytes; 1109 return discardableBytes;
1120 } 1110 }
1121 1111
1122 const size_t maxSlotCount = (kPartitionPageSize * kMaxPartitionPagesPerSlotS pan) / kSystemPageSize; 1112 const size_t maxSlotCount = (kPartitionPageSize * kMaxPartitionPagesPerSlotS pan) / kSystemPageSize;
(...skipping 30 matching lines...) Expand all
1153 ASSERT(numSlots); 1143 ASSERT(numSlots);
1154 } 1144 }
1155 // First, do the work of calculating the discardable bytes. Don't actually 1145 // First, do the work of calculating the discardable bytes. Don't actually
1156 // discard anything unless the discard flag was passed in. 1146 // discard anything unless the discard flag was passed in.
1157 char* beginPtr = nullptr; 1147 char* beginPtr = nullptr;
1158 char* endPtr = nullptr; 1148 char* endPtr = nullptr;
1159 size_t unprovisionedBytes = 0; 1149 size_t unprovisionedBytes = 0;
1160 if (truncatedSlots) { 1150 if (truncatedSlots) {
1161 beginPtr = ptr + (numSlots * slotSize); 1151 beginPtr = ptr + (numSlots * slotSize);
1162 endPtr = beginPtr + (slotSize * truncatedSlots); 1152 endPtr = beginPtr + (slotSize * truncatedSlots);
1163 beginPtr = reinterpret_cast<char*>(partitionRoundUpToSystemPage(reinterp ret_cast<size_t>(beginPtr))); 1153 beginPtr = reinterpret_cast<char*>(WTF::roundUpToSystemPage(reinterpret_ cast<size_t>(beginPtr)));
1164 // We round the end pointer here up and not down because we're at the 1154 // We round the end pointer here up and not down because we're at the
1165 // end of a slot span, so we "own" all the way up the page boundary. 1155 // end of a slot span, so we "own" all the way up the page boundary.
1166 endPtr = reinterpret_cast<char*>(partitionRoundUpToSystemPage(reinterpre t_cast<size_t>(endPtr))); 1156 endPtr = reinterpret_cast<char*>(WTF::roundUpToSystemPage(reinterpret_ca st<size_t>(endPtr)));
1167 ASSERT(endPtr <= ptr + partitionBucketBytes(bucket)); 1157 ASSERT(endPtr <= ptr + partitionBucketBytes(bucket));
1168 if (beginPtr < endPtr) { 1158 if (beginPtr < endPtr) {
1169 unprovisionedBytes = endPtr - beginPtr; 1159 unprovisionedBytes = endPtr - beginPtr;
1170 discardableBytes += unprovisionedBytes; 1160 discardableBytes += unprovisionedBytes;
1171 } 1161 }
1172 } 1162 }
1173 if (unprovisionedBytes && discard) { 1163 if (unprovisionedBytes && discard) {
1174 ASSERT(truncatedSlots > 0); 1164 ASSERT(truncatedSlots > 0);
1175 size_t numNewEntries = 0; 1165 size_t numNewEntries = 0;
1176 page->numUnprovisionedSlots += static_cast<uint16_t>(truncatedSlots); 1166 page->numUnprovisionedSlots += static_cast<uint16_t>(truncatedSlots);
(...skipping 23 matching lines...) Expand all
1200 for (size_t i = 0; i < numSlots; ++i) { 1190 for (size_t i = 0; i < numSlots; ++i) {
1201 if (slotUsage[i]) 1191 if (slotUsage[i])
1202 continue; 1192 continue;
1203 // The first address we can safely discard is just after the freelist 1193 // The first address we can safely discard is just after the freelist
1204 // pointer. There's one quirk: if the freelist pointer is actually a 1194 // pointer. There's one quirk: if the freelist pointer is actually a
1205 // null, we can discard that pointer value too. 1195 // null, we can discard that pointer value too.
1206 char* beginPtr = ptr + (i * slotSize); 1196 char* beginPtr = ptr + (i * slotSize);
1207 char* endPtr = beginPtr + slotSize; 1197 char* endPtr = beginPtr + slotSize;
1208 if (i != lastSlot) 1198 if (i != lastSlot)
1209 beginPtr += sizeof(PartitionFreelistEntry); 1199 beginPtr += sizeof(PartitionFreelistEntry);
1210 beginPtr = reinterpret_cast<char*>(partitionRoundUpToSystemPage(reinterp ret_cast<size_t>(beginPtr))); 1200 beginPtr = reinterpret_cast<char*>(WTF::roundUpToSystemPage(reinterpret_ cast<size_t>(beginPtr)));
1211 endPtr = reinterpret_cast<char*>(partitionRoundDownToSystemPage(reinterp ret_cast<size_t>(endPtr))); 1201 endPtr = reinterpret_cast<char*>(WTF::roundDownToSystemPage(reinterpret_ cast<size_t>(endPtr)));
1212 if (beginPtr < endPtr) { 1202 if (beginPtr < endPtr) {
1213 size_t partialSlotBytes = endPtr - beginPtr; 1203 size_t partialSlotBytes = endPtr - beginPtr;
1214 discardableBytes += partialSlotBytes; 1204 discardableBytes += partialSlotBytes;
1215 if (discard) 1205 if (discard)
1216 discardSystemPages(beginPtr, partialSlotBytes); 1206 discardSystemPages(beginPtr, partialSlotBytes);
1217 } 1207 }
1218 } 1208 }
1219 return discardableBytes; 1209 return discardableBytes;
1220 } 1210 }
1221 1211
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 } 1253 }
1264 1254
1265 statsOut->discardableBytes += partitionPurgePage(const_cast<PartitionPage*>( page), false); 1255 statsOut->discardableBytes += partitionPurgePage(const_cast<PartitionPage*>( page), false);
1266 1256
1267 size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page)); 1257 size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page));
1268 if (rawSize) 1258 if (rawSize)
1269 statsOut->activeBytes += static_cast<uint32_t>(rawSize); 1259 statsOut->activeBytes += static_cast<uint32_t>(rawSize);
1270 else 1260 else
1271 statsOut->activeBytes += (page->numAllocatedSlots * statsOut->bucketSlot Size); 1261 statsOut->activeBytes += (page->numAllocatedSlots * statsOut->bucketSlot Size);
1272 1262
1273 size_t pageBytesResident = partitionRoundUpToSystemPage((bucketNumSlots - pa ge->numUnprovisionedSlots) * statsOut->bucketSlotSize); 1263 size_t pageBytesResident = WTF::roundUpToSystemPage((bucketNumSlots - page-> numUnprovisionedSlots) * statsOut->bucketSlotSize);
1274 statsOut->residentBytes += pageBytesResident; 1264 statsOut->residentBytes += pageBytesResident;
1275 if (partitionPageStateIsEmpty(page)) { 1265 if (partitionPageStateIsEmpty(page)) {
1276 statsOut->decommittableBytes += pageBytesResident; 1266 statsOut->decommittableBytes += pageBytesResident;
1277 ++statsOut->numEmptyPages; 1267 ++statsOut->numEmptyPages;
1278 } else if (partitionPageStateIsFull(page)) { 1268 } else if (partitionPageStateIsFull(page)) {
1279 ++statsOut->numFullPages; 1269 ++statsOut->numFullPages;
1280 } else { 1270 } else {
1281 ASSERT(partitionPageStateIsActive(page)); 1271 ASSERT(partitionPageStateIsActive(page));
1282 ++statsOut->numActivePages; 1272 ++statsOut->numActivePages;
1283 } 1273 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes; 1402 partitionStats.totalDiscardableBytes += memoryStats[i].discardableBy tes;
1413 if (!isLightDump) 1403 if (!isLightDump)
1414 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]); 1404 partitionStatsDumper->partitionsDumpBucketStats(partitionName, & memoryStats[i]);
1415 } 1405 }
1416 } 1406 }
1417 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats); 1407 partitionStatsDumper->partitionDumpTotals(partitionName, &partitionStats);
1418 } 1408 }
1419 1409
1420 } // namespace WTF 1410 } // namespace WTF
1421 1411
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/PageAllocator.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698