Modified: trunk/Source/WTF/wtf/FastMalloc.cpp (153766 => 153767)
--- trunk/Source/WTF/wtf/FastMalloc.cpp 2013-08-06 21:55:42 UTC (rev 153766)
+++ trunk/Source/WTF/wtf/FastMalloc.cpp 2013-08-06 22:10:02 UTC (rev 153767)
@@ -1509,10 +1509,72 @@
PageHeapAllocator<TCMalloc_ThreadCache>* m_pageHeapAllocator;
};
+// This method declaration, and the constants below, are taken from Libc/gen/malloc.c.
+extern "C" void (*malloc_logger)(uint32_t typeFlags, uintptr_t zone, uintptr_t size, uintptr_t pointer, uintptr_t returnValue, uint32_t numberOfFramesToSkip);
+
#endif
+class MallocHook {
+ static bool stackLoggingEnabled;
+
+#if OS(DARWIN)
+
+ enum StackLoggingType {
+ StackLoggingTypeAlloc = 2,
+ StackLoggingTypeDealloc = 4,
+ };
+
+ static void record(uint32_t typeFlags, uintptr_t zone, uintptr_t size, void* pointer, void* returnValue, uint32_t numberOfFramesToSkip)
+ {
+ malloc_logger(typeFlags, zone, size, reinterpret_cast<uintptr_t>(pointer), reinterpret_cast<uintptr_t>(returnValue), numberOfFramesToSkip);
+ }
+
+ static NEVER_INLINE void recordAllocation(void* pointer, size_t size)
+ {
+ // StackLoggingTypeAlloc takes the newly-allocated address in the returnValue argument, the size of the allocation
+ // in the size argument and ignores all other arguments.
+ record(StackLoggingTypeAlloc, 0, size, 0, pointer, 0);
+ }
+
+ static NEVER_INLINE void recordDeallocation(void* pointer)
+ {
+ // StackLoggingTypeDealloc takes the pointer in the size argument and ignores all other arguments.
+ record(StackLoggingTypeDealloc, 0, reinterpret_cast<uintptr_t>(pointer), 0, 0, 0);
+ }
+
#endif
+public:
+ static void init()
+ {
+#if OS(DARWIN)
+ // If the system allocator's malloc_logger has been set up then stack logging is enabled.
+ stackLoggingEnabled = malloc_logger;
+#endif
+ }
+
+#if OS(DARWIN)
+ static ALWAYS_INLINE void InvokeNewHook(void* pointer, size_t size)
+ {
+ if (UNLIKELY(stackLoggingEnabled))
+ recordAllocation(pointer, size);
+ }
+
+ static ALWAYS_INLINE void InvokeDeleteHook(void* pointer)
+ {
+
+ if (UNLIKELY(stackLoggingEnabled))
+ recordDeallocation(pointer);
+ }
+#else
+ static ALWAYS_INLINE void InvokeNewHook(void*, size_t) { }
+ static ALWAYS_INLINE void InvokeDeleteHook(void*) { }
+#endif
+};
+bool MallocHook::stackLoggingEnabled = false;
+
+#endif
+
#ifndef WTF_CHANGES
// This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if
// you're porting to a system where you really can't get a stacktrace.
@@ -3402,6 +3464,7 @@
pageheap->init();
phinited = 1;
#if defined(WTF_CHANGES) && OS(DARWIN)
+ MallocHook::init();
FastMallocZone::init();
#endif
}
@@ -4217,9 +4280,7 @@
void* result = do_malloc(size);
#endif
-#ifndef WTF_CHANGES
MallocHook::InvokeNewHook(result, size);
-#endif
return result;
}
@@ -4231,9 +4292,7 @@
dataLogF("fastFree freeing %p.\n", ptr);
#endif
-#ifndef WTF_CHANGES
MallocHook::InvokeDeleteHook(ptr);
-#endif
#if ENABLE(WTF_MALLOC_VALIDATION)
if (!ptr)
@@ -4302,9 +4361,7 @@
}
#endif
-#ifndef WTF_CHANGES
MallocHook::InvokeNewHook(result, totalBytes);
-#endif
return result;
}
@@ -4366,16 +4423,12 @@
void* result = malloc<crashOnFailure>(new_size);
#else
void* result = do_malloc(new_size);
-#ifndef WTF_CHANGES
MallocHook::InvokeNewHook(result, new_size);
#endif
-#endif
return result;
}
if (new_size == 0) {
-#ifndef WTF_CHANGES
MallocHook::InvokeDeleteHook(old_ptr);
-#endif
free(old_ptr);
return NULL;
}
@@ -4415,13 +4468,9 @@
if (new_ptr == NULL) {
return NULL;
}
-#ifndef WTF_CHANGES
MallocHook::InvokeNewHook(new_ptr, new_size);
-#endif
memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size));
-#ifndef WTF_CHANGES
MallocHook::InvokeDeleteHook(old_ptr);
-#endif
// We could use a variant of do_free() that leverages the fact
// that we already know the sizeclass of old_ptr. The benefit
// would be small, so don't bother.