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 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
692 goto partitionAllocSlowPathFailed; | 692 goto partitionAllocSlowPathFailed; |
693 // Skip the alignment check because it depends on page->bucket, which is not yet set. | 693 // Skip the alignment check because it depends on page->bucket, which is not yet set. |
694 newPage = partitionPointerToPageNoAlignmentCheck(rawNewPage); | 694 newPage = partitionPointerToPageNoAlignmentCheck(rawNewPage); |
695 } | 695 } |
696 | 696 |
697 partitionPageReset(newPage, bucket); | 697 partitionPageReset(newPage, bucket); |
698 bucket->activePagesHead = newPage; | 698 bucket->activePagesHead = newPage; |
699 return partitionPageAllocAndFillFreelist(newPage); | 699 return partitionPageAllocAndFillFreelist(newPage); |
700 | 700 |
701 partitionAllocSlowPathFailed: | 701 partitionAllocSlowPathFailed: |
702 if (returnNull) | 702 if (returnNull) { |
Chris Evans
2014/11/07 03:33:23
Nit: maybe add comment? Something like "If we get
Jens Widell
2014/11/07 14:17:31
Done.
| |
703 bucket->activePagesHead = &PartitionRootGeneric::gSeedPage; | |
703 return nullptr; | 704 return nullptr; |
705 } | |
704 partitionOutOfMemory(); | 706 partitionOutOfMemory(); |
705 return nullptr; | 707 return nullptr; |
706 } | 708 } |
707 | 709 |
708 static ALWAYS_INLINE void partitionFreePage(PartitionRootBase* root, PartitionPa ge* page) | 710 static ALWAYS_INLINE void partitionFreePage(PartitionRootBase* root, PartitionPa ge* page) |
709 { | 711 { |
710 ASSERT(page->freelistHead); | 712 ASSERT(page->freelistHead); |
711 ASSERT(!page->numAllocatedSlots); | 713 ASSERT(!page->numAllocatedSlots); |
712 partitionUnusePage(root, page); | 714 partitionUnusePage(root, page); |
713 // We actually leave the freed page in the active list. We'll sweep it on | 715 // We actually leave the freed page in the active list. We'll sweep it on |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
756 ++currentIndex; | 758 ++currentIndex; |
757 if (currentIndex == kMaxFreeableSpans) | 759 if (currentIndex == kMaxFreeableSpans) |
758 currentIndex = 0; | 760 currentIndex = 0; |
759 root->globalEmptyPageRingIndex = currentIndex; | 761 root->globalEmptyPageRingIndex = currentIndex; |
760 } | 762 } |
761 | 763 |
762 void partitionFreeSlowPath(PartitionPage* page) | 764 void partitionFreeSlowPath(PartitionPage* page) |
763 { | 765 { |
764 PartitionBucket* bucket = page->bucket; | 766 PartitionBucket* bucket = page->bucket; |
765 ASSERT(page != &PartitionRootGeneric::gSeedPage); | 767 ASSERT(page != &PartitionRootGeneric::gSeedPage); |
766 ASSERT(bucket->activePagesHead != &PartitionRootGeneric::gSeedPage); | |
767 if (LIKELY(page->numAllocatedSlots == 0)) { | 768 if (LIKELY(page->numAllocatedSlots == 0)) { |
768 // Page became fully unused. | 769 // Page became fully unused. |
769 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { | 770 if (UNLIKELY(partitionBucketIsDirectMapped(bucket))) { |
770 partitionDirectUnmap(page); | 771 partitionDirectUnmap(page); |
771 return; | 772 return; |
772 } | 773 } |
773 // If it's the current active page, attempt to change it. We'd prefer to leave | 774 // If it's the current active page, attempt to change it. We'd prefer to leave |
774 // the page empty as a gentle force towards defragmentation. | 775 // the page empty as a gentle force towards defragmentation. |
775 if (LIKELY(page == bucket->activePagesHead) && page->nextPage) { | 776 if (LIKELY(page == bucket->activePagesHead) && page->nextPage) { |
776 if (partitionSetNewActivePage(page->nextPage)) { | 777 if (partitionSetNewActivePage(page->nextPage)) { |
(...skipping 17 matching lines...) Expand all Loading... | |
794 ASSERT(page->numAllocatedSlots < 0); | 795 ASSERT(page->numAllocatedSlots < 0); |
795 // A transition of numAllocatedSlots from 0 to -1 is not legal, and | 796 // A transition of numAllocatedSlots from 0 to -1 is not legal, and |
796 // likely indicates a double-free. | 797 // likely indicates a double-free. |
797 RELEASE_ASSERT(page->numAllocatedSlots != -1); | 798 RELEASE_ASSERT(page->numAllocatedSlots != -1); |
798 page->numAllocatedSlots = -page->numAllocatedSlots - 2; | 799 page->numAllocatedSlots = -page->numAllocatedSlots - 2; |
799 ASSERT(page->numAllocatedSlots == partitionBucketSlots(bucket) - 1); | 800 ASSERT(page->numAllocatedSlots == partitionBucketSlots(bucket) - 1); |
800 // Fully used page became partially used. It must be put back on the | 801 // Fully used page became partially used. It must be put back on the |
801 // non-full page list. Also make it the current page to increase the | 802 // non-full page list. Also make it the current page to increase the |
802 // chances of it being filled up again. The old current page will be | 803 // chances of it being filled up again. The old current page will be |
803 // the next page. | 804 // the next page. |
804 page->nextPage = bucket->activePagesHead; | 805 if (bucket->activePagesHead == &PartitionRootGeneric::gSeedPage) |
Chris Evans
2014/11/07 03:33:23
Nit: add UNLIKELY!
Jens Widell
2014/11/07 14:17:31
Done.
| |
806 page->nextPage = 0; | |
807 else | |
808 page->nextPage = bucket->activePagesHead; | |
805 bucket->activePagesHead = page; | 809 bucket->activePagesHead = page; |
806 --bucket->numFullPages; | 810 --bucket->numFullPages; |
807 // Special case: for a partition page with just a single slot, it may | 811 // Special case: for a partition page with just a single slot, it may |
808 // now be empty and we want to run it through the empty logic. | 812 // now be empty and we want to run it through the empty logic. |
809 if (UNLIKELY(page->numAllocatedSlots == 0)) | 813 if (UNLIKELY(page->numAllocatedSlots == 0)) |
810 partitionFreeSlowPath(page); | 814 partitionFreeSlowPath(page); |
811 } | 815 } |
812 } | 816 } |
813 | 817 |
814 bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root, PartitionPa ge* page, size_t newSize) | 818 bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root, PartitionPa ge* page, size_t newSize) |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
973 printf("total live: %zu bytes\n", totalLive); | 977 printf("total live: %zu bytes\n", totalLive); |
974 printf("total resident: %zu bytes\n", totalResident); | 978 printf("total resident: %zu bytes\n", totalResident); |
975 printf("total freeable: %zu bytes\n", totalFreeable); | 979 printf("total freeable: %zu bytes\n", totalFreeable); |
976 fflush(stdout); | 980 fflush(stdout); |
977 } | 981 } |
978 | 982 |
979 #endif // !NDEBUG | 983 #endif // !NDEBUG |
980 | 984 |
981 } // namespace WTF | 985 } // namespace WTF |
982 | 986 |
OLD | NEW |