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 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |