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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 spinLockLock(&PartitionRootBase::gInitializedLock); | 105 spinLockLock(&PartitionRootBase::gInitializedLock); |
106 if (!PartitionRootBase::gInitialized) { | 106 if (!PartitionRootBase::gInitialized) { |
107 PartitionRootBase::gInitialized = true; | 107 PartitionRootBase::gInitialized = true; |
108 // We mark the seed page as free to make sure it is skipped by our | 108 // We mark the seed page as free to make sure it is skipped by our |
109 // logic to find a new active page. | 109 // logic to find a new active page. |
110 PartitionRootBase::gPagedBucket.activePagesHead = &PartitionRootGeneric: :gSeedPage; | 110 PartitionRootBase::gPagedBucket.activePagesHead = &PartitionRootGeneric: :gSeedPage; |
111 } | 111 } |
112 spinLockUnlock(&PartitionRootBase::gInitializedLock); | 112 spinLockUnlock(&PartitionRootBase::gInitializedLock); |
113 | 113 |
114 root->initialized = true; | 114 root->initialized = true; |
115 root->totalSizeOfNonFreePages = 0; | |
Chris Evans
2014/06/06 18:30:50
I think we should name this totalSizeOfCommittedPa
kouhei (in TOK)
2014/06/09 05:48:22
Done.
| |
115 root->totalSizeOfSuperPages = 0; | 116 root->totalSizeOfSuperPages = 0; |
116 root->nextSuperPage = 0; | 117 root->nextSuperPage = 0; |
117 root->nextPartitionPage = 0; | 118 root->nextPartitionPage = 0; |
118 root->nextPartitionPageEnd = 0; | 119 root->nextPartitionPageEnd = 0; |
119 root->firstExtent = 0; | 120 root->firstExtent = 0; |
120 root->currentExtent = 0; | 121 root->currentExtent = 0; |
121 | 122 |
122 memset(&root->globalEmptyPageRing, '\0', sizeof(root->globalEmptyPageRing)); | 123 memset(&root->globalEmptyPageRing, '\0', sizeof(root->globalEmptyPageRing)); |
123 root->globalEmptyPageRingIndex = 0; | 124 root->globalEmptyPageRingIndex = 0; |
124 | 125 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
307 { | 308 { |
308 IMMEDIATE_CRASH(); | 309 IMMEDIATE_CRASH(); |
309 } | 310 } |
310 | 311 |
311 static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root, int flags, size_t numPartitionPages) | 312 static ALWAYS_INLINE void* partitionAllocPartitionPages(PartitionRootBase* root, int flags, size_t numPartitionPages) |
312 { | 313 { |
313 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPa geSize)); | 314 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPage) % kPartitionPa geSize)); |
314 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitio nPageSize)); | 315 ASSERT(!(reinterpret_cast<uintptr_t>(root->nextPartitionPageEnd) % kPartitio nPageSize)); |
315 RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage); | 316 RELEASE_ASSERT(numPartitionPages <= kNumPartitionPagesPerSuperPage); |
316 size_t totalSize = kPartitionPageSize * numPartitionPages; | 317 size_t totalSize = kPartitionPageSize * numPartitionPages; |
318 root->totalSizeOfNonFreePages += totalSize; | |
317 size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextParti tionPage) >> kPartitionPageShift; | 319 size_t numPartitionPagesLeft = (root->nextPartitionPageEnd - root->nextParti tionPage) >> kPartitionPageShift; |
318 if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) { | 320 if (LIKELY(numPartitionPagesLeft >= numPartitionPages)) { |
319 // In this case, we can still hand out pages from the current super page | 321 // In this case, we can still hand out pages from the current super page |
320 // allocation. | 322 // allocation. |
321 char* ret = root->nextPartitionPage; | 323 char* ret = root->nextPartitionPage; |
322 root->nextPartitionPage += totalSize; | 324 root->nextPartitionPage += totalSize; |
323 return ret; | 325 return ret; |
324 } | 326 } |
325 | 327 |
326 // Need a new super page. | 328 // Need a new super page. |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
668 // Second, look in our list of freed but reserved pages. | 670 // Second, look in our list of freed but reserved pages. |
669 PartitionPage* newPage = bucket->freePagesHead; | 671 PartitionPage* newPage = bucket->freePagesHead; |
670 if (LIKELY(newPage != 0)) { | 672 if (LIKELY(newPage != 0)) { |
671 ASSERT(newPage != &PartitionRootGeneric::gSeedPage); | 673 ASSERT(newPage != &PartitionRootGeneric::gSeedPage); |
672 ASSERT(!newPage->freelistHead); | 674 ASSERT(!newPage->freelistHead); |
673 ASSERT(!newPage->numAllocatedSlots); | 675 ASSERT(!newPage->numAllocatedSlots); |
674 ASSERT(!newPage->numUnprovisionedSlots); | 676 ASSERT(!newPage->numUnprovisionedSlots); |
675 ASSERT(newPage->freeCacheIndex == -1); | 677 ASSERT(newPage->freeCacheIndex == -1); |
676 bucket->freePagesHead = newPage->nextPage; | 678 bucket->freePagesHead = newPage->nextPage; |
677 void* addr = partitionPageToPointer(newPage); | 679 void* addr = partitionPageToPointer(newPage); |
678 recommitSystemPages(addr, newPage->bucket->numSystemPagesPerSlotSpan * k SystemPageSize); | 680 size_t commitSize = newPage->bucket->numSystemPagesPerSlotSpan * kSystem PageSize; |
681 recommitSystemPages(addr, commitSize); | |
682 root->totalSizeOfNonFreePages += commitSize; | |
Chris Evans
2014/06/06 18:30:50
I think this is the right model: adjusting the
H
kouhei (in TOK)
2014/06/09 05:48:22
Done. I added partition{Re,De}commitPages wrapper
| |
679 } else { | 683 } else { |
680 // Third. If we get here, we need a brand new page. | 684 // Third. If we get here, we need a brand new page. |
681 size_t numPartitionPages = partitionBucketPartitionPages(bucket); | 685 size_t numPartitionPages = partitionBucketPartitionPages(bucket); |
682 void* rawNewPage = partitionAllocPartitionPages(root, flags, numPartitio nPages); | 686 void* rawNewPage = partitionAllocPartitionPages(root, flags, numPartitio nPages); |
683 if (UNLIKELY(!rawNewPage)) { | 687 if (UNLIKELY(!rawNewPage)) { |
684 ASSERT(returnNull); | 688 ASSERT(returnNull); |
685 return 0; | 689 return 0; |
686 } | 690 } |
687 // Skip the alignment check because it depends on page->bucket, which is not yet set. | 691 // Skip the alignment check because it depends on page->bucket, which is not yet set. |
688 newPage = partitionPointerToPageNoAlignmentCheck(rawNewPage); | 692 newPage = partitionPointerToPageNoAlignmentCheck(rawNewPage); |
(...skipping 14 matching lines...) Expand all Loading... | |
703 // this trick enables us to use a singly-linked page list for all cases, | 707 // this trick enables us to use a singly-linked page list for all cases, |
704 // which is critical in keeping the page metadata structure down to 32 | 708 // which is critical in keeping the page metadata structure down to 32 |
705 // bytes in size. | 709 // bytes in size. |
706 page->freelistHead = 0; | 710 page->freelistHead = 0; |
707 page->numUnprovisionedSlots = 0; | 711 page->numUnprovisionedSlots = 0; |
708 } | 712 } |
709 | 713 |
710 static ALWAYS_INLINE void partitionRegisterEmptyPage(PartitionPage* page) | 714 static ALWAYS_INLINE void partitionRegisterEmptyPage(PartitionPage* page) |
711 { | 715 { |
712 PartitionRootBase* root = partitionPageToRoot(page); | 716 PartitionRootBase* root = partitionPageToRoot(page); |
717 size_t pageSize = page->bucket->numSystemPagesPerSlotSpan * kSystemPageSize; | |
718 ASSERT(root->totalSizeOfNonFreePages > pageSize); | |
719 root->totalSizeOfNonFreePages -= pageSize; | |
Chris Evans
2014/06/06 18:30:50
I do not think this is the correct place to do thi
kouhei (in TOK)
2014/06/09 05:48:22
Removed this, and moved counter decrement into par
| |
720 | |
713 // If the page is already registered as empty, give it another life. | 721 // If the page is already registered as empty, give it another life. |
714 if (page->freeCacheIndex != -1) { | 722 if (page->freeCacheIndex != -1) { |
715 ASSERT(page->freeCacheIndex >= 0); | 723 ASSERT(page->freeCacheIndex >= 0); |
716 ASSERT(static_cast<unsigned>(page->freeCacheIndex) < kMaxFreeableSpans); | 724 ASSERT(static_cast<unsigned>(page->freeCacheIndex) < kMaxFreeableSpans); |
717 ASSERT(root->globalEmptyPageRing[page->freeCacheIndex] == page); | 725 ASSERT(root->globalEmptyPageRing[page->freeCacheIndex] == page); |
718 root->globalEmptyPageRing[page->freeCacheIndex] = 0; | 726 root->globalEmptyPageRing[page->freeCacheIndex] = 0; |
719 } | 727 } |
720 | 728 |
721 size_t currentIndex = root->globalEmptyPageRingIndex; | 729 size_t currentIndex = root->globalEmptyPageRingIndex; |
722 PartitionPage* pageToFree = root->globalEmptyPageRing[currentIndex]; | 730 PartitionPage* pageToFree = root->globalEmptyPageRing[currentIndex]; |
(...skipping 27 matching lines...) Expand all Loading... | |
750 { | 758 { |
751 PartitionBucket* bucket = page->bucket; | 759 PartitionBucket* bucket = page->bucket; |
752 ASSERT(page != &PartitionRootGeneric::gSeedPage); | 760 ASSERT(page != &PartitionRootGeneric::gSeedPage); |
753 ASSERT(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage); | 761 ASSERT(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage); |
754 if (LIKELY(page->numAllocatedSlots == 0)) { | 762 if (LIKELY(page->numAllocatedSlots == 0)) { |
755 // Page became fully unused. | 763 // Page became fully unused. |
756 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { | 764 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { |
757 partitionDirectUnmap(page); | 765 partitionDirectUnmap(page); |
758 return; | 766 return; |
759 } | 767 } |
760 // If it's the current page, attempt to change it. We'd prefer to leave | 768 // If it's the current active page, attempt to change it. We'd prefer to leave |
761 // the page empty as a gentle force towards defragmentation. | 769 // the page empty as a gentle force towards defragmentation. |
762 if (LIKELY(page == bucket->activePagesHead) && page->nextPage) { | 770 if (LIKELY(page == bucket->activePagesHead) && page->nextPage) { |
763 if (partitionSetNewActivePage(page->nextPage)) { | 771 if (partitionSetNewActivePage(page->nextPage)) { |
764 ASSERT(bucket->activePagesHead != page); | 772 ASSERT(bucket->activePagesHead != page); |
765 // Link the empty page back in after the new current page, to | 773 // Link the empty page back in after the new current page, to |
766 // avoid losing a reference to it. | 774 // avoid losing a reference to it. |
767 // TODO: consider walking the list to link the empty page after | 775 // TODO: consider walking the list to link the empty page after |
768 // all non-empty pages? | 776 // all non-empty pages? |
769 PartitionPage* currentPage = bucket->activePagesHead; | 777 PartitionPage* currentPage = bucket->activePagesHead; |
770 page->nextPage = currentPage->nextPage; | 778 page->nextPage = currentPage->nextPage; |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
960 printf("total live: %zu bytes\n", totalLive); | 968 printf("total live: %zu bytes\n", totalLive); |
961 printf("total resident: %zu bytes\n", totalResident); | 969 printf("total resident: %zu bytes\n", totalResident); |
962 printf("total freeable: %zu bytes\n", totalFreeable); | 970 printf("total freeable: %zu bytes\n", totalFreeable); |
963 fflush(stdout); | 971 fflush(stdout); |
964 } | 972 } |
965 | 973 |
966 #endif // !NDEBUG | 974 #endif // !NDEBUG |
967 | 975 |
968 } // namespace WTF | 976 } // namespace WTF |
969 | 977 |
OLD | NEW |