| 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 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 // we really free it. This improves performance, particularly on Mac OS X | 889 // we really free it. This improves performance, particularly on Mac OS X |
| 890 // which has subpar memory management performance. | 890 // which has subpar memory management performance. |
| 891 root->globalEmptyPageRing[currentIndex] = page; | 891 root->globalEmptyPageRing[currentIndex] = page; |
| 892 page->emptyCacheIndex = currentIndex; | 892 page->emptyCacheIndex = currentIndex; |
| 893 ++currentIndex; | 893 ++currentIndex; |
| 894 if (currentIndex == kMaxFreeableSpans) | 894 if (currentIndex == kMaxFreeableSpans) |
| 895 currentIndex = 0; | 895 currentIndex = 0; |
| 896 root->globalEmptyPageRingIndex = currentIndex; | 896 root->globalEmptyPageRingIndex = currentIndex; |
| 897 } | 897 } |
| 898 | 898 |
| 899 static void partitionDecommitFreePages(PartitionRootBase* root) | 899 static void partitionDecommitEmptyPages(PartitionRootBase* root) |
| 900 { | 900 { |
| 901 for (size_t i = 0; i < kMaxFreeableSpans; ++i) { | 901 for (size_t i = 0; i < kMaxFreeableSpans; ++i) { |
| 902 PartitionPage* page = root->globalEmptyPageRing[i]; | 902 PartitionPage* page = root->globalEmptyPageRing[i]; |
| 903 if (page) | 903 if (page) |
| 904 partitionDecommitPageIfPossible(root, page); | 904 partitionDecommitPageIfPossible(root, page); |
| 905 root->globalEmptyPageRing[i] = nullptr; | 905 root->globalEmptyPageRing[i] = nullptr; |
| 906 } | 906 } |
| 907 } | 907 } |
| 908 | 908 |
| 909 void partitionPurgeMemory(PartitionRoot* root) | 909 void partitionPurgeMemory(PartitionRoot* root, int flags) |
| 910 { | 910 { |
| 911 partitionDecommitFreePages(root); | 911 if (flags & PartitionPurgeDecommitEmptyPages) |
| 912 partitionDecommitEmptyPages(root); |
| 912 } | 913 } |
| 913 | 914 |
| 914 void partitionPurgeMemoryGeneric(PartitionRootGeneric* root) | 915 void partitionPurgeMemoryGeneric(PartitionRootGeneric* root, int flags) |
| 915 { | 916 { |
| 916 spinLockLock(&root->lock); | 917 spinLockLock(&root->lock); |
| 917 partitionDecommitFreePages(root); | 918 if (flags & PartitionPurgeDecommitEmptyPages) |
| 919 partitionDecommitEmptyPages(root); |
| 918 spinLockUnlock(&root->lock); | 920 spinLockUnlock(&root->lock); |
| 919 } | 921 } |
| 920 | 922 |
| 921 void partitionFreeSlowPath(PartitionPage* page) | 923 void partitionFreeSlowPath(PartitionPage* page) |
| 922 { | 924 { |
| 923 PartitionBucket* bucket = page->bucket; | 925 PartitionBucket* bucket = page->bucket; |
| 924 ASSERT(page != &PartitionRootGeneric::gSeedPage); | 926 ASSERT(page != &PartitionRootGeneric::gSeedPage); |
| 925 if (LIKELY(page->numAllocatedSlots == 0)) { | 927 if (LIKELY(page->numAllocatedSlots == 0)) { |
| 926 // Page became fully unused. | 928 // Page became fully unused. |
| 927 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { | 929 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page
)); | 1095 size_t rawSize = partitionPageGetRawSize(const_cast<PartitionPage*>(page
)); |
| 1094 if (rawSize) | 1096 if (rawSize) |
| 1095 statsOut->activeBytes += static_cast<uint32_t>(partitionRoundUpToSys
temPage(rawSize)); | 1097 statsOut->activeBytes += static_cast<uint32_t>(partitionRoundUpToSys
temPage(rawSize)); |
| 1096 else | 1098 else |
| 1097 statsOut->activeBytes += (page->numAllocatedSlots * statsOut->bucket
SlotSize); | 1099 statsOut->activeBytes += (page->numAllocatedSlots * statsOut->bucket
SlotSize); |
| 1098 size_t pageBytesResident = (bucketNumSlots - page->numUnprovisionedSlots
) * statsOut->bucketSlotSize; | 1100 size_t pageBytesResident = (bucketNumSlots - page->numUnprovisionedSlots
) * statsOut->bucketSlotSize; |
| 1099 // Round up to system page size. | 1101 // Round up to system page size. |
| 1100 size_t pageBytesResidentRounded = partitionRoundUpToSystemPage(pageBytes
Resident); | 1102 size_t pageBytesResidentRounded = partitionRoundUpToSystemPage(pageBytes
Resident); |
| 1101 statsOut->residentBytes += pageBytesResidentRounded; | 1103 statsOut->residentBytes += pageBytesResidentRounded; |
| 1102 if (!page->numAllocatedSlots) { | 1104 if (!page->numAllocatedSlots) { |
| 1103 statsOut->freeableBytes += pageBytesResidentRounded; | 1105 statsOut->decommittableBytes += pageBytesResidentRounded; |
| 1104 ++statsOut->numEmptyPages; | 1106 ++statsOut->numEmptyPages; |
| 1105 } else if (page->numAllocatedSlots == bucketNumSlots) { | 1107 } else if (page->numAllocatedSlots == bucketNumSlots) { |
| 1106 ++statsOut->numFullPages; | 1108 ++statsOut->numFullPages; |
| 1107 } else { | 1109 } else { |
| 1108 ++statsOut->numActivePages; | 1110 ++statsOut->numActivePages; |
| 1109 } | 1111 } |
| 1110 } | 1112 } |
| 1111 } | 1113 } |
| 1112 | 1114 |
| 1113 static void partitionDumpBucketStats(PartitionBucketMemoryStats* statsOut, const
PartitionBucket* bucket) | 1115 static void partitionDumpBucketStats(PartitionBucketMemoryStats* statsOut, const
PartitionBucket* bucket) |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 // partitionsDumpBucketStats is called after collecting stats because it | 1215 // partitionsDumpBucketStats is called after collecting stats because it |
| 1214 // can use PartitionAlloc to allocate and this can affect the statistics. | 1216 // can use PartitionAlloc to allocate and this can affect the statistics. |
| 1215 for (size_t i = 0; i < partitionNumBuckets; ++i) { | 1217 for (size_t i = 0; i < partitionNumBuckets; ++i) { |
| 1216 if (memoryStats[i].isValid) | 1218 if (memoryStats[i].isValid) |
| 1217 partitionStatsDumper->partitionsDumpBucketStats(partitionName, &memo
ryStats[i]); | 1219 partitionStatsDumper->partitionsDumpBucketStats(partitionName, &memo
ryStats[i]); |
| 1218 } | 1220 } |
| 1219 } | 1221 } |
| 1220 | 1222 |
| 1221 } // namespace WTF | 1223 } // namespace WTF |
| 1222 | 1224 |
| OLD | NEW |