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

Unified Diff: Source/wtf/PartitionAlloc.h

Issue 1195543005: PartitionAlloc: fixes and improvements to large-chunk size tracking. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Review feedback. Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Source/wtf/PartitionAlloc.cpp » ('j') | Source/wtf/PartitionAlloc.cpp » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/wtf/PartitionAlloc.h
diff --git a/Source/wtf/PartitionAlloc.h b/Source/wtf/PartitionAlloc.h
index 049b40b25e8db5cb10a6cff508205e6105b8c7da..48e71045f9aa2161ecf0f0f88b85746078b09e6c 100644
--- a/Source/wtf/PartitionAlloc.h
+++ b/Source/wtf/PartitionAlloc.h
@@ -218,8 +218,8 @@ static const size_t kReasonableSizeOfUnusedPages = 1024 * 1024 * 1024; // 1GiB
// These two byte values match tcmalloc.
static const unsigned char kUninitializedByte = 0xAB;
static const unsigned char kFreedByte = 0xCD;
-static const uint32_t kCookieValue = 0xDEADBEEFu;
static const size_t kCookieSize = 16; // Handles alignment up to XMM instructions on Intel.
+static const unsigned char kCookieValue[kCookieSize] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xD0, 0x0D, 0x13, 0x37, 0xF0, 0x05, 0xBA, 0x11, 0xAB, 0x1E };
#endif
struct PartitionBucket;
@@ -437,18 +437,18 @@ ALWAYS_INLINE void* partitionCookieFreePointerAdjust(void* ptr)
ALWAYS_INLINE void partitionCookieWriteValue(void* ptr)
{
#if ENABLE(ASSERT)
- uint32_t* cookiePtr = reinterpret_cast<uint32_t*>(ptr);
- for (size_t i = 0; i < kCookieSize / sizeof(kCookieValue); ++i, ++cookiePtr)
- *cookiePtr = kCookieValue;
+ unsigned char* cookiePtr = reinterpret_cast<unsigned char*>(ptr);
+ for (size_t i = 0; i < kCookieSize; ++i, ++cookiePtr)
+ *cookiePtr = kCookieValue[i];
#endif
}
ALWAYS_INLINE void partitionCookieCheckValue(void* ptr)
{
#if ENABLE(ASSERT)
- uint32_t* cookiePtr = reinterpret_cast<uint32_t*>(ptr);
- for (size_t i = 0; i < kCookieSize / sizeof(kCookieValue); ++i, ++cookiePtr)
- ASSERT(*cookiePtr == kCookieValue);
+ unsigned char* cookiePtr = reinterpret_cast<unsigned char*>(ptr);
+ for (size_t i = 0; i < kCookieSize; ++i, ++cookiePtr)
+ ASSERT(*cookiePtr == kCookieValue[i]);
#endif
}
@@ -500,6 +500,43 @@ ALWAYS_INLINE PartitionPage* partitionPointerToPage(void* ptr)
return page;
}
+ALWAYS_INLINE bool partitionBucketIsDirectMapped(const PartitionBucket* bucket)
+{
+ return !bucket->numSystemPagesPerSlotSpan;
+}
+
+ALWAYS_INLINE size_t partitionBucketBytes(const PartitionBucket* bucket)
+{
+ return bucket->numSystemPagesPerSlotSpan * kSystemPageSize;
+}
+
+ALWAYS_INLINE uint16_t partitionBucketSlots(const PartitionBucket* bucket)
+{
+ return static_cast<uint16_t>(partitionBucketBytes(bucket) / bucket->slotSize);
+}
+
+ALWAYS_INLINE size_t* partitionPageGetRawSizePtr(PartitionPage* page)
+{
+ // For single-slot buckets which span more than one partition page, we
+ // have some spare metadata space to store the raw allocation size. We
+ // can use this to report better statistics.
+ PartitionBucket* bucket = page->bucket;
+ if (bucket->slotSize <= kMaxSystemPagesPerSlotSpan * kSystemPageSize)
+ return nullptr;
+
+ ASSERT(partitionBucketIsDirectMapped(bucket) || partitionBucketSlots(bucket) == 1);
+ page++;
+ return reinterpret_cast<size_t*>(&page->freelistHead);
+}
+
+ALWAYS_INLINE size_t partitionPageGetRawSize(PartitionPage* page)
+{
+ size_t* rawSizePtr = partitionPageGetRawSizePtr(page);
+ if (UNLIKELY(rawSizePtr != nullptr))
+ return *rawSizePtr;
+ return 0;
+}
+
ALWAYS_INLINE PartitionRootBase* partitionPageToRoot(PartitionPage* page)
{
PartitionSuperPageExtentEntry* extentEntry = reinterpret_cast<PartitionSuperPageExtentEntry*>(reinterpret_cast<uintptr_t>(page) & kSystemPageBaseMask);
@@ -522,6 +559,9 @@ ALWAYS_INLINE void* partitionBucketAlloc(PartitionRootBase* root, int flags, siz
if (LIKELY(ret != 0)) {
// If these asserts fire, you probably corrupted memory.
ASSERT(partitionPointerIsValid(ret));
+ // All large allocations must go through the slow path to correctly
+ // update the size metadata.
+ ASSERT(partitionPageGetRawSize(page) == 0);
PartitionFreelistEntry* newHead = partitionFreelistMask(static_cast<PartitionFreelistEntry*>(ret)->next);
page->freelistHead = newHead;
page->numAllocatedSlots++;
@@ -532,14 +572,21 @@ ALWAYS_INLINE void* partitionBucketAlloc(PartitionRootBase* root, int flags, siz
#if ENABLE(ASSERT)
if (!ret)
return 0;
- // Fill the uninitialized pattern. and write the cookies.
+ // Fill the uninitialized pattern, and write the cookies.
page = partitionPointerToPage(ret);
- size_t bucketSize = page->bucket->slotSize;
- memset(ret, kUninitializedByte, bucketSize);
- partitionCookieWriteValue(ret);
- partitionCookieWriteValue(reinterpret_cast<char*>(ret) + bucketSize - kCookieSize);
+ size_t slotSize = page->bucket->slotSize;
+ size_t rawSize = partitionPageGetRawSize(page);
+ if (rawSize) {
+ ASSERT(rawSize == size);
+ slotSize = rawSize;
+ }
+ size_t noCookieSize = partitionCookieSizeAdjustSubtract(slotSize);
+ char* charRet = static_cast<char*>(ret);
// The value given to the application is actually just after the cookie.
- ret = static_cast<char*>(ret) + kCookieSize;
+ ret = charRet + kCookieSize;
+ memset(ret, kUninitializedByte, noCookieSize);
+ partitionCookieWriteValue(charRet);
+ partitionCookieWriteValue(charRet + kCookieSize + noCookieSize);
#endif
return ret;
}
@@ -565,10 +612,13 @@ ALWAYS_INLINE void partitionFreeWithPage(void* ptr, PartitionPage* page)
{
// If these asserts fire, you probably corrupted memory.
#if ENABLE(ASSERT)
- size_t bucketSize = page->bucket->slotSize;
+ size_t slotSize = page->bucket->slotSize;
+ size_t rawSize = partitionPageGetRawSize(page);
+ if (rawSize)
+ slotSize = rawSize;
partitionCookieCheckValue(ptr);
- partitionCookieCheckValue(reinterpret_cast<char*>(ptr) + bucketSize - kCookieSize);
- memset(ptr, kFreedByte, bucketSize);
+ partitionCookieCheckValue(reinterpret_cast<char*>(ptr) + slotSize - kCookieSize);
+ memset(ptr, kFreedByte, slotSize);
#endif
ASSERT(page->numAllocatedSlots);
PartitionFreelistEntry* freelistHead = page->freelistHead;
@@ -649,11 +699,6 @@ ALWAYS_INLINE void partitionFreeGeneric(PartitionRootGeneric* root, void* ptr)
#endif
}
-ALWAYS_INLINE bool partitionBucketIsDirectMapped(const PartitionBucket* bucket)
-{
- return !bucket->numSystemPagesPerSlotSpan;
-}
-
ALWAYS_INLINE size_t partitionDirectMapSize(size_t size)
{
// Caller must check that the size is not above the kGenericMaxDirectMapped
« no previous file with comments | « no previous file | Source/wtf/PartitionAlloc.cpp » ('j') | Source/wtf/PartitionAlloc.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698