Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(486)

Side by Side Diff: Source/wtf/PartitionAlloc.cpp

Issue 183113003: PartitionAlloc: support in-place resize of directly mapped allocation (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/wtf/PartitionAlloc.h ('k') | Source/wtf/PartitionAllocTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 558 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 PartitionBucket* bucket = reinterpret_cast<PartitionBucket*>(reinterpret_cas t<char*>(page) + kPageMetadataSize); 569 PartitionBucket* bucket = reinterpret_cast<PartitionBucket*>(reinterpret_cas t<char*>(page) + kPageMetadataSize);
570 page->freelistHead = 0; 570 page->freelistHead = 0;
571 page->nextPage = 0; 571 page->nextPage = 0;
572 page->bucket = bucket; 572 page->bucket = bucket;
573 page->numAllocatedSlots = 1; 573 page->numAllocatedSlots = 1;
574 page->numUnprovisionedSlots = 0; 574 page->numUnprovisionedSlots = 0;
575 page->pageOffset = 0; 575 page->pageOffset = 0;
576 page->freeCacheIndex = 0; 576 page->freeCacheIndex = 0;
577 577
578 bucket->activePagesHead = 0; 578 bucket->activePagesHead = 0;
579 bucket->freePagesHead = 0; 579 bucket->freePagesHead = reinterpret_cast<PartitionPage*>(ret + size);
580 bucket->slotSize = size; 580 bucket->slotSize = size;
581 bucket->numSystemPagesPerSlotSpan = 0; 581 bucket->numSystemPagesPerSlotSpan = 0;
582 bucket->numFullPages = 0; 582 bucket->numFullPages = 0;
583 583
584 return ret; 584 return ret;
585 } 585 }
586 586
587 static ALWAYS_INLINE void partitionDirectUnmap(PartitionPage* page) 587 static ALWAYS_INLINE void partitionDirectUnmap(PartitionPage* page)
588 { 588 {
589 size_t unmapSize = page->bucket->slotSize; 589 size_t unmapSize = page->bucket->slotSize;
Jens Widell 2014/02/27 17:02:56 This would need adjusting to use page->bucket->fre
590 // Add on the size of the trailing guard page and preceeding partition 590 // Add on the size of the trailing guard page and preceeding partition
591 // page, then round up to allocation granularity. 591 // page, then round up to allocation granularity.
592 unmapSize += kPartitionPageSize + kSystemPageSize; 592 unmapSize += kPartitionPageSize + kSystemPageSize;
593 unmapSize += kPageAllocationGranularityOffsetMask; 593 unmapSize += kPageAllocationGranularityOffsetMask;
594 unmapSize &= kPageAllocationGranularityBaseMask; 594 unmapSize &= kPageAllocationGranularityBaseMask;
595 595
596 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page)); 596 char* ptr = reinterpret_cast<char*>(partitionPageToPointer(page));
597 // Account for the mapping starting a partition page before the actual 597 // Account for the mapping starting a partition page before the actual
598 // allocation address. 598 // allocation address.
599 ptr -= kPartitionPageSize; 599 ptr -= kPartitionPageSize;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 page->nextPage = bucket->activePagesHead; 756 page->nextPage = bucket->activePagesHead;
757 bucket->activePagesHead = page; 757 bucket->activePagesHead = page;
758 --bucket->numFullPages; 758 --bucket->numFullPages;
759 // Special case: for a partition page with just a single slot, it may 759 // Special case: for a partition page with just a single slot, it may
760 // now be empty and we want to run it through the empty logic. 760 // now be empty and we want to run it through the empty logic.
761 if (UNLIKELY(page->numAllocatedSlots == 0)) 761 if (UNLIKELY(page->numAllocatedSlots == 0))
762 partitionFreeSlowPath(page); 762 partitionFreeSlowPath(page);
763 } 763 }
764 } 764 }
765 765
766 bool partitionReallocDirectMappedInPlace(PartitionRootGeneric* root, void* ptr, size_t newSize)
767 {
768 newSize = partitionCookieSizeAdjustAdd(newSize);
769 ASSERT(partitionDirectMapSize(newSize) == newSize);
770
771 char* realPtr = static_cast<char*>(partitionCookieFreePointerAdjust(ptr));
772 PartitionBucket* bucket = partitionPointerToPage(realPtr)->bucket;
773
774 // bucket->slotSize is the current size of the allocation.
775 // bucket->freePagesHead points to the first system page beyond what we
776 // first allocated; we can grow the allocation up to that point.
777
778 ASSERT(partitionBucketIsDirectMapped(bucket));
779
780 if (newSize < bucket->slotSize) {
781 // Shrink by decommitting unneeded pages and making them inaccessible.
782 // TODO: maybe refuse if the new size is too much smaller?
783 decommitSystemPages(realPtr + newSize, bucket->slotSize - newSize);
784 setSystemPagesInaccessible(realPtr + newSize, kSystemPageSize);
Jens Widell 2014/02/27 17:10:53 Ought to make all decommitted pages inaccessible (
785 } else if (realPtr + newSize <= reinterpret_cast<char*>(bucket->freePagesHea d)) {
786 // Grow within the actually allocated memory. Just need to make the
787 // pages accessible again.
788 setSystemPagesAccessible(realPtr + bucket->slotSize, newSize - bucket->s lotSize);
789
790 #ifndef NDEBUG
791 memset(realPtr + bucket->slotSize, kUninitializedByte, newSize - bucket- >slotSize);
792 #endif
793 } else {
794 // We can't perform the realloc in-place.
795 return false;
796 }
797
798 #ifndef NDEBUG
799 // Write a new trailing cookie.
800 partitionCookieWriteValue(realPtr + newSize - kCookieSize);
801 #endif
802
803 bucket->slotSize = newSize;
804 return true;
805 }
806
766 void* partitionReallocGeneric(PartitionRootGeneric* root, void* ptr, size_t newS ize) 807 void* partitionReallocGeneric(PartitionRootGeneric* root, void* ptr, size_t newS ize)
767 { 808 {
768 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR) 809 #if defined(MEMORY_TOOL_REPLACES_ALLOCATOR)
769 return realloc(ptr, newSize); 810 return realloc(ptr, newSize);
770 #else 811 #else
771 if (UNLIKELY(!ptr)) 812 if (UNLIKELY(!ptr))
772 return partitionAllocGeneric(root, newSize); 813 return partitionAllocGeneric(root, newSize);
773 if (UNLIKELY(!newSize)) { 814 if (UNLIKELY(!newSize)) {
774 partitionFreeGeneric(root, ptr); 815 partitionFreeGeneric(root, ptr);
775 return 0; 816 return 0;
776 } 817 }
777 818
778 ASSERT(partitionPointerIsValid(partitionCookieFreePointerAdjust(ptr))); 819 ASSERT(partitionPointerIsValid(partitionCookieFreePointerAdjust(ptr)));
779 820
780 size_t actualNewSize = partitionAllocActualSize(root, newSize); 821 size_t actualNewSize = partitionAllocActualSize(root, newSize);
781 size_t actualOldSize = partitionAllocGetSize(ptr); 822 size_t actualOldSize = partitionAllocGetSize(ptr);
782 823
783 // TODO: note that tcmalloc will "ignore" a downsizing realloc() unless the 824 // TODO: note that tcmalloc will "ignore" a downsizing realloc() unless the
784 // new size is a significant percentage smaller. We could do the same if we 825 // new size is a significant percentage smaller. We could do the same if we
785 // determine it is a win. 826 // determine it is a win.
786 if (actualNewSize == actualOldSize) { 827 if (actualNewSize == actualOldSize) {
787 // Trying to allocate a block of size newSize would give us a block of 828 // Trying to allocate a block of size newSize would give us a block of
788 // the same size as the one we've already got, so no point in doing 829 // the same size as the one we've already got, so no point in doing
789 // anything here. 830 // anything here.
790 // TODO: for an upsize or downsize on a direct mapped allocation, we
791 // should really try and resize it in-place.
792 return ptr; 831 return ptr;
793 } 832 }
794 833
834 if (partitionSizeIsDirectMapped(actualOldSize) && partitionSizeIsDirectMappe d(actualNewSize)) {
835 // We may be able to perform the realloc in place by changing the
836 // accessibility of memory pages and, if reducing the size, decommitting
837 // them.
838 if (partitionReallocDirectMappedInPlace(root, ptr, actualNewSize))
839 return ptr;
840 }
841
795 // This realloc cannot be resized in-place. Sadness. 842 // This realloc cannot be resized in-place. Sadness.
796 void* ret = partitionAllocGeneric(root, newSize); 843 void* ret = partitionAllocGeneric(root, newSize);
797 size_t copySize = actualOldSize; 844 size_t copySize = actualOldSize;
798 if (newSize < copySize) 845 if (newSize < copySize)
799 copySize = newSize; 846 copySize = newSize;
800 847
801 memcpy(ret, ptr, copySize); 848 memcpy(ret, ptr, copySize);
802 partitionFreeGeneric(root, ptr); 849 partitionFreeGeneric(root, ptr);
803 return ret; 850 return ret;
804 #endif 851 #endif
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 printf("total live: %zu bytes\n", totalLive); 902 printf("total live: %zu bytes\n", totalLive);
856 printf("total resident: %zu bytes\n", totalResident); 903 printf("total resident: %zu bytes\n", totalResident);
857 printf("total freeable: %zu bytes\n", totalFreeable); 904 printf("total freeable: %zu bytes\n", totalFreeable);
858 fflush(stdout); 905 fflush(stdout);
859 } 906 }
860 907
861 #endif // !NDEBUG 908 #endif // !NDEBUG
862 909
863 } // namespace WTF 910 } // namespace WTF
864 911
OLDNEW
« no previous file with comments | « Source/wtf/PartitionAlloc.h ('k') | Source/wtf/PartitionAllocTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698