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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 static void partitionCollectIfSuperPage(PartitionPageHeader* partitionPage, Vect
or<PartitionPageHeader*>* superPages) | 78 static void partitionCollectIfSuperPage(PartitionPageHeader* partitionPage, Vect
or<PartitionPageHeader*>* superPages) |
79 { | 79 { |
80 PartitionPageHeader* superPage = reinterpret_cast<PartitionPageHeader*>(rein
terpret_cast<uintptr_t>(partitionPage) & kSuperPageBaseMask); | 80 PartitionPageHeader* superPage = reinterpret_cast<PartitionPageHeader*>(rein
terpret_cast<uintptr_t>(partitionPage) & kSuperPageBaseMask); |
81 uintptr_t superPageOffset = reinterpret_cast<uintptr_t>(partitionPage) & kSu
perPageOffsetMask; | 81 uintptr_t superPageOffset = reinterpret_cast<uintptr_t>(partitionPage) & kSu
perPageOffsetMask; |
82 // If this partition page is at the start of a super page, note it so we can | 82 // If this partition page is at the start of a super page, note it so we can |
83 // free all the distinct super pages. | 83 // free all the distinct super pages. |
84 if (!superPageOffset) | 84 if (!superPageOffset) |
85 superPages->append(superPage); | 85 superPages->append(superPage); |
86 } | 86 } |
87 | 87 |
88 static void partitionAllocShutdownBucket(PartitionBucket* bucket, Vector<Partiti
onPageHeader*>* superPages) | 88 static bool partitionAllocShutdownBucket(PartitionBucket* bucket, Vector<Partiti
onPageHeader*>* superPages) |
89 { | 89 { |
90 // Failure here indicates a memory leak. | 90 // Failure here indicates a memory leak. |
91 ASSERT(!bucket->numFullPages); | 91 bool noLeaks = !bucket->numFullPages; |
92 PartitionFreepagelistEntry* entry = bucket->freePages; | 92 PartitionFreepagelistEntry* entry = bucket->freePages; |
93 while (entry) { | 93 while (entry) { |
94 PartitionFreepagelistEntry* next = entry->next; | 94 PartitionFreepagelistEntry* next = entry->next; |
95 partitionCollectIfSuperPage(entry->page, superPages); | 95 partitionCollectIfSuperPage(entry->page, superPages); |
96 partitionFree(entry); | 96 partitionFree(entry); |
97 entry = next; | 97 entry = next; |
98 } | 98 } |
99 PartitionPageHeader* page = bucket->currPage; | 99 PartitionPageHeader* page = bucket->currPage; |
100 do { | 100 do { |
101 // Failure here indicates a memory leak. | 101 if (page->numAllocatedSlots) |
102 ASSERT(bucket == &bucket->root->buckets[kFreePageBucket] || !page->numAl
locatedSlots); | 102 noLeaks = false; |
103 PartitionPageHeader* next = page->next; | 103 PartitionPageHeader* next = page->next; |
104 if (page != &bucket->root->seedPage) | 104 if (page != &bucket->root->seedPage) |
105 partitionCollectIfSuperPage(page, superPages); | 105 partitionCollectIfSuperPage(page, superPages); |
106 page = next; | 106 page = next; |
107 } while (page != bucket->currPage); | 107 } while (page != bucket->currPage); |
| 108 |
| 109 return noLeaks; |
108 } | 110 } |
109 | 111 |
110 void partitionAllocShutdown(PartitionRoot* root) | 112 bool partitionAllocShutdown(PartitionRoot* root) |
111 { | 113 { |
| 114 bool noLeaks = true; |
112 ASSERT(root->initialized); | 115 ASSERT(root->initialized); |
113 root->initialized = false; | 116 root->initialized = false; |
114 // As we iterate through all the partition pages, we keep a list of all the | 117 // As we iterate through all the partition pages, we keep a list of all the |
115 // distinct super pages that we have seen. This is so that we can free all | 118 // distinct super pages that we have seen. This is so that we can free all |
116 // the super pages correctly. A super page must be freed all at once -- it | 119 // the super pages correctly. A super page must be freed all at once -- it |
117 // is not permissible to free a super page by freeing all its component | 120 // is not permissible to free a super page by freeing all its component |
118 // partition pages. | 121 // partition pages. |
119 // Note that we cannot free a super page upon discovering it, because a | 122 // Note that we cannot free a super page upon discovering it, because a |
120 // single super page will likely contain partition pages from multiple | 123 // single super page will likely contain partition pages from multiple |
121 // different buckets. | 124 // different buckets. |
122 Vector<PartitionPageHeader*> superPages; | 125 Vector<PartitionPageHeader*> superPages; |
123 size_t i; | 126 size_t i; |
124 // First, free the non-freepage buckets. Freeing the free pages in these | 127 // First, free the non-freepage buckets. Freeing the free pages in these |
125 // buckets will depend on the freepage bucket. | 128 // buckets will depend on the freepage bucket. |
126 for (i = 0; i < kNumBuckets; ++i) { | 129 for (i = 0; i < kNumBuckets; ++i) { |
127 if (i != kFreePageBucket) { | 130 if (i != kFreePageBucket) { |
128 PartitionBucket* bucket = &root->buckets[i]; | 131 PartitionBucket* bucket = &root->buckets[i]; |
129 partitionAllocShutdownBucket(bucket, &superPages); | 132 if (!partitionAllocShutdownBucket(bucket, &superPages)) |
| 133 noLeaks = false; |
130 } | 134 } |
131 } | 135 } |
132 // Finally, free the freepage bucket. | 136 // Finally, free the freepage bucket. |
133 partitionAllocShutdownBucket(&root->buckets[kFreePageBucket], &superPages); | 137 (void) partitionAllocShutdownBucket(&root->buckets[kFreePageBucket], &superP
ages); |
134 // Now that we've examined all partition pages in all buckets, it's safe | 138 // Now that we've examined all partition pages in all buckets, it's safe |
135 // to free all our super pages. | 139 // to free all our super pages. |
136 for (Vector<PartitionPageHeader*>::iterator it = superPages.begin(); it != s
uperPages.end(); ++it) | 140 for (Vector<PartitionPageHeader*>::iterator it = superPages.begin(); it != s
uperPages.end(); ++it) |
137 partitionFreeSuperPage(*it); | 141 partitionFreeSuperPage(*it); |
| 142 |
| 143 return noLeaks; |
138 } | 144 } |
139 | 145 |
140 static ALWAYS_INLINE PartitionPageHeader* partitionAllocPage(PartitionRoot* root
) | 146 static ALWAYS_INLINE PartitionPageHeader* partitionAllocPage(PartitionRoot* root
) |
141 { | 147 { |
142 char* ret = 0; | 148 char* ret = 0; |
143 if (LIKELY(root->nextPartitionPage != 0)) { | 149 if (LIKELY(root->nextPartitionPage != 0)) { |
144 // In this case, we can still hand out pages from a previous | 150 // In this case, we can still hand out pages from a previous |
145 // super page allocation. | 151 // super page allocation. |
146 ret = root->nextPartitionPage; | 152 ret = root->nextPartitionPage; |
147 root->nextPartitionPage += kPartitionPageSize; | 153 root->nextPartitionPage += kPartitionPageSize; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 } | 352 } |
347 page = page->next; | 353 page = page->next; |
348 } while (page != bucket.currPage); | 354 } while (page != bucket.currPage); |
349 printf("bucket size %ld: %ld/%ld bytes, %ld free pages\n", bucketSlotSiz
e, numActiveBytes, numActivePages * kPartitionPageSize, numFreePages); | 355 printf("bucket size %ld: %ld/%ld bytes, %ld free pages\n", bucketSlotSiz
e, numActiveBytes, numActivePages * kPartitionPageSize, numFreePages); |
350 } | 356 } |
351 } | 357 } |
352 #endif // !NDEBUG | 358 #endif // !NDEBUG |
353 | 359 |
354 } // namespace WTF | 360 } // namespace WTF |
355 | 361 |
OLD | NEW |