Chromium Code Reviews| Index: third_party/WebKit/Source/wtf/PartitionAlloc.h |
| diff --git a/third_party/WebKit/Source/wtf/PartitionAlloc.h b/third_party/WebKit/Source/wtf/PartitionAlloc.h |
| index b0e233f4e2d24a442be2936fc08401c1fddc2866..166f06ea8739bf317422667ae941151f9f095cde 100644 |
| --- a/third_party/WebKit/Source/wtf/PartitionAlloc.h |
| +++ b/third_party/WebKit/Source/wtf/PartitionAlloc.h |
| @@ -411,6 +411,46 @@ WTF_EXPORT NEVER_INLINE void* partitionReallocGeneric(PartitionRootGeneric*, voi |
| WTF_EXPORT void partitionDumpStats(PartitionRoot*, const char* partitionName, bool isLightDump, PartitionStatsDumper*); |
| WTF_EXPORT void partitionDumpStatsGeneric(PartitionRootGeneric*, const char* partitionName, bool isLightDump, PartitionStatsDumper*); |
| +class WTF_EXPORT PartitionAllocHooks { |
| +public: |
| + typedef void AllocationHook(void* address, size_t); |
| + typedef void FreeHook(void* address); |
|
haraken
2015/10/20 12:42:00
typedef => using
Ruud van Asseldonk
2015/10/20 13:22:16
Curiously, a using causes compile errors on MSVC b
|
| + |
| + static void setAllocationHook(AllocationHook* hook) { m_allocationHook = hook; } |
| + static void setFreeHook(FreeHook* hook) { m_freeHook = hook; } |
| + |
| + static void allocationHookIfEnabled(void* address, size_t size) |
| + { |
| + AllocationHook* allocationHook = m_allocationHook; |
| + if (UNLIKELY(allocationHook != nullptr)) |
| + allocationHook(address, size); |
| + } |
| + |
| + static void freeHookIfEnabled(void* address) |
| + { |
| + FreeHook* freeHook = m_freeHook; |
| + if (UNLIKELY(freeHook != nullptr)) |
| + freeHook(address); |
| + } |
| + |
| + static void reallocHookIfEnabled(void* oldAddress, void* newAddress, size_t size) |
| + { |
| + // Report a reallocation as a free followed by an allocation. |
| + AllocationHook* allocationHook = m_allocationHook; |
| + FreeHook* freeHook = m_freeHook; |
| + if (UNLIKELY(allocationHook && freeHook)) { |
|
haraken
2015/10/20 12:42:00
if (UNLIKELY(allocationHook)) {
ASSERT(freeHook)
Ruud van Asseldonk
2015/10/20 13:22:16
Done. Why will it be faster though? I expect that
haraken
2015/10/20 13:25:01
Yeah, you're right. Let's check both.
BTW, what h
|
| + freeHook(oldAddress); |
| + allocationHook(newAddress, size); |
| + } |
| + } |
| + |
| +private: |
| + // Pointers to hook functions that PartitionAlloc will call on allocation and |
| + // free if the pointers are non-null. |
| + static AllocationHook* m_allocationHook; |
| + static FreeHook* m_freeHook; |
| +}; |
| + |
| ALWAYS_INLINE PartitionFreelistEntry* partitionFreelistMask(PartitionFreelistEntry* ptr) |
| { |
| // We use bswap on little endian as a fast mask for two reasons: |
| @@ -629,7 +669,9 @@ ALWAYS_INLINE void* partitionAlloc(PartitionRoot* root, size_t size) |
| ASSERT(index < root->numBuckets); |
| ASSERT(size == index << kBucketShift); |
| PartitionBucket* bucket = &root->buckets()[index]; |
| - return partitionBucketAlloc(root, 0, size, bucket); |
| + void* result = partitionBucketAlloc(root, 0, size, bucket); |
| + PartitionAllocHooks::allocationHookIfEnabled(result, size); |
| + return result; |
| #endif // defined(MEMORY_TOOL_REPLACES_ALLOCATOR) |
| } |
| @@ -672,6 +714,7 @@ ALWAYS_INLINE void partitionFree(void* ptr) |
| ASSERT(partitionPointerIsValid(ptr)); |
| PartitionPage* page = partitionPointerToPage(ptr); |
| partitionFreeWithPage(ptr, page); |
| + PartitionAllocHooks::freeHookIfEnabled(ptr); |
| #endif |
| } |
| @@ -701,6 +744,7 @@ ALWAYS_INLINE void* partitionAllocGenericFlags(PartitionRootGeneric* root, int f |
| spinLockLock(&root->lock); |
| void* ret = partitionBucketAlloc(root, flags, size, bucket); |
| spinLockUnlock(&root->lock); |
| + PartitionAllocHooks::allocationHookIfEnabled(ret, size); |
| return ret; |
| #endif |
| } |
| @@ -726,6 +770,7 @@ ALWAYS_INLINE void partitionFreeGeneric(PartitionRootGeneric* root, void* ptr) |
| spinLockLock(&root->lock); |
| partitionFreeWithPage(ptr, page); |
| spinLockUnlock(&root->lock); |
| + PartitionAllocHooks::freeHookIfEnabled(ptr); |
| #endif |
| } |