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 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 static NEVER_INLINE void partitionOutOfMemory() | 301 static NEVER_INLINE void partitionOutOfMemory() |
302 { | 302 { |
303 IMMEDIATE_CRASH(); | 303 IMMEDIATE_CRASH(); |
304 } | 304 } |
305 | 305 |
306 static NEVER_INLINE void partitionFull() | 306 static NEVER_INLINE void partitionFull() |
307 { | 307 { |
308 IMMEDIATE_CRASH(); | 308 IMMEDIATE_CRASH(); |
309 } | 309 } |
310 | 310 |
311 static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root,
size_t numPartitionPages) | 311 static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root,
int flags, size_t numPartitionPages) |
312 { | 312 { |
313 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPa
geSize)); | 313 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPa
geSize)); |
314 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitio
nPageSize)); | 314 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitio
nPageSize)); |
315 RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage); | 315 RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage); |
316 size_t totalSize = kPartitionPageSize * numPartitionPages; | 316 size_t totalSize = kPartitionPageSize * numPartitionPages; |
317 size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextParti
tionPage) >> kPartitionPageShift; | 317 size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextParti
tionPage) >> kPartitionPageShift; |
318 if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) { | 318 if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) { |
319 // In this case, we can still hand out pages from the current super page | 319 // In this case, we can still hand out pages from the current super page |
320 // allocation. | 320 // allocation. |
321 char* ret = root->nextPartitionPage; | 321 char* ret = root->nextPartitionPage; |
322 root->nextPartitionPage += totalSize; | 322 root->nextPartitionPage += totalSize; |
323 return ret; | 323 return ret; |
324 } | 324 } |
325 | 325 |
326 // Need a new super page. | 326 // Need a new super page. |
327 root->totalSizeOfSuperPages += kSuperPageSize; | 327 root->totalSizeOfSuperPages += kSuperPageSize; |
328 if (root->totalSizeOfSuperPages > kMaxPartitionSize) | 328 if (root->totalSizeOfSuperPages > kMaxPartitionSize) |
329 partitionFull(); | 329 partitionFull(); |
330 char* requestedAddress = root->nextSuperPage; | 330 char* requestedAddress = root->nextSuperPage; |
331 char* superPage = reinterpret_cast<char*>(allocPages(requestedAddress, kSupe
rPageSize, kSuperPageSize)); | 331 char* superPage = reinterpret_cast<char*>(allocPages(requestedAddress, kSupe
rPageSize, kSuperPageSize)); |
332 // TODO: handle allocation failure here with PartitionAllocReturnNull. | 332 if (UNLIKELY(!superPage)) { |
333 if (!superPage) | 333 if (flags & PartitionAllocReturnNull) |
| 334 return 0; |
334 partitionOutOfMemory(); | 335 partitionOutOfMemory(); |
| 336 } |
335 root->nextSuperPage = superPage + kSuperPageSize; | 337 root->nextSuperPage = superPage + kSuperPageSize; |
336 char* ret = superPage + kPartitionPageSize; | 338 char* ret = superPage + kPartitionPageSize; |
337 root->nextPartitionPage = ret + totalSize; | 339 root->nextPartitionPage = ret + totalSize; |
338 root->nextPartitionPageEnd = root->nextSuperPage - kPartitionPageSize; | 340 root->nextPartitionPageEnd = root->nextSuperPage - kPartitionPageSize; |
339 // Make the first partition page in the super page a guard page, but leave a | 341 // Make the first partition page in the super page a guard page, but leave a |
340 // hole in the middle. | 342 // hole in the middle. |
341 // This is where we put page metadata and also a tiny amount of extent | 343 // This is where we put page metadata and also a tiny amount of extent |
342 // metadata. | 344 // metadata. |
343 setSystemPagesInaccessible(superPage, kSystemPageSize); | 345 setSystemPagesInaccessible(superPage, kSystemPageSize); |
344 setSystemPagesInaccessible(superPage + (kSystemPageSize * 2), kPartitionPage
Size - (kSystemPageSize * 2)); | 346 setSystemPagesInaccessible(superPage + (kSystemPageSize * 2), kPartitionPage
Size - (kSystemPageSize * 2)); |
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 ASSERT(!newPage->freelistHead); | 672 ASSERT(!newPage->freelistHead); |
671 ASSERT(!newPage->numAllocatedSlots); | 673 ASSERT(!newPage->numAllocatedSlots); |
672 ASSERT(!newPage->numUnprovisionedSlots); | 674 ASSERT(!newPage->numUnprovisionedSlots); |
673 ASSERT(newPage->freeCacheIndex == -1); | 675 ASSERT(newPage->freeCacheIndex == -1); |
674 bucket->freePagesHead = newPage->nextPage; | 676 bucket->freePagesHead = newPage->nextPage; |
675 void* addr = partitionPageToPointer(newPage); | 677 void* addr = partitionPageToPointer(newPage); |
676 recommitSystemPages(addr, newPage->bucket->numSystemPagesPerSlotSpan * k
SystemPageSize); | 678 recommitSystemPages(addr, newPage->bucket->numSystemPagesPerSlotSpan * k
SystemPageSize); |
677 } else { | 679 } else { |
678 // Third. If we get here, we need a brand new page. | 680 // Third. If we get here, we need a brand new page. |
679 size_t numPartitionPages = partitionBucketPartitionPages(bucket); | 681 size_t numPartitionPages = partitionBucketPartitionPages(bucket); |
680 void* rawNewPage = partitionAllocPartitionPages(root, numPartitionPages)
; | 682 void* rawNewPage = partitionAllocPartitionPages(root, flags, numPartitio
nPages); |
| 683 if (UNLIKELY(!rawNewPage)) { |
| 684 ASSERT(returnNull); |
| 685 return 0; |
| 686 } |
681 // Skip the alignment check because it depends on page->bucket, which is
not yet set. | 687 // Skip the alignment check because it depends on page->bucket, which is
not yet set. |
682 newPage = partitionPointerToPageNoAlignmentCheck(rawNewPage); | 688 newPage = partitionPointerToPageNoAlignmentCheck(rawNewPage); |
683 } | 689 } |
684 | 690 |
685 partitionPageReset(newPage, bucket); | 691 partitionPageReset(newPage, bucket); |
686 bucket->activePagesHead = newPage; | 692 bucket->activePagesHead = newPage; |
687 return partitionPageAllocAndFillFreelist(newPage); | 693 return partitionPageAllocAndFillFreelist(newPage); |
688 } | 694 } |
689 | 695 |
690 static ALWAYS_INLINE void partitionFreePage(PartitionPage* page) | 696 static ALWAYS_INLINE void partitionFreePage(PartitionPage* page) |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 printf("total live: %zu bytes\n", totalLive); | 960 printf("total live: %zu bytes\n", totalLive); |
955 printf("total resident: %zu bytes\n", totalResident); | 961 printf("total resident: %zu bytes\n", totalResident); |
956 printf("total freeable: %zu bytes\n", totalFreeable); | 962 printf("total freeable: %zu bytes\n", totalFreeable); |
957 fflush(stdout); | 963 fflush(stdout); |
958 } | 964 } |
959 | 965 |
960 #endif // !NDEBUG | 966 #endif // !NDEBUG |
961 | 967 |
962 } // namespace WTF | 968 } // namespace WTF |
963 | 969 |
OLD | NEW |