Chromium Code Reviews| 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 |