Modified: branches/safari-537.73-branch/Source/WTF/ChangeLog (157731 => 157732)
--- branches/safari-537.73-branch/Source/WTF/ChangeLog 2013-10-21 20:42:11 UTC (rev 157731)
+++ branches/safari-537.73-branch/Source/WTF/ChangeLog 2013-10-21 20:59:29 UTC (rev 157732)
@@ -1,3 +1,29 @@
+2013-10-21 Lucas Forschler <lforsch...@apple.com>
+
+ Merge r153767
+
+ 2013-08-05 Mark Rowe <mr...@apple.com>
+
+ <rdar://problem/5927399> FastMalloc should support MallocStackLogging
+
+ Call the malloc stack logging function from within the various entry points to FastMalloc
+ when stack logging is enabled.
+
+ Reviewed by Oliver Hunt and Geoff Garen.
+
+ * wtf/FastMalloc.cpp:
+ Call in to MallocHook::InvokeNewHook / MallocHook::InvokeDeleteHook at the appropriate entry
+ points to FastMalloc. The naming comes from TCMalloc's existing, unused concept of malloc hooks.
+ (WTF::MallocHook::record): Call the stack logging function with appropriate argument types.
+ (WTF::MallocHook::recordAllocation): Out-of-line slow path for when stack logging is enabled
+ that calls record with the values in the right arguments.
+ (WTF::MallocHook::recordDeallocation): Ditto.
+ (WTF::MallocHook::init): Stack logging is enabled if the system allocator has enabled stack logging.
+ (WTF::MallocHook::InvokeNewHook): Call recordAllocation in the unlikely event that stack logging is
+ enabled.
+ (WTF::MallocHook::InvokeDeleteHook): Ditto for recordDeallocation.
+ (WTF::TCMalloc_ThreadCache::InitModule): Initialize the malloc hook.
+
2013-09-04 Lucas Forschler <lforsch...@apple.com>
Merge r155020
Modified: branches/safari-537.73-branch/Source/WTF/wtf/FastMalloc.cpp (157731 => 157732)
--- branches/safari-537.73-branch/Source/WTF/wtf/FastMalloc.cpp 2013-10-21 20:42:11 UTC (rev 157731)
+++ branches/safari-537.73-branch/Source/WTF/wtf/FastMalloc.cpp 2013-10-21 20:59:29 UTC (rev 157732)
@@ -1508,10 +1508,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.
@@ -3401,6 +3463,7 @@
pageheap->init();
phinited = 1;
#if defined(WTF_CHANGES) && OS(DARWIN)
+ MallocHook::init();
FastMallocZone::init();
#endif
}
@@ -4206,9 +4269,7 @@
void* result = do_malloc(size);
#endif
-#ifndef WTF_CHANGES
MallocHook::InvokeNewHook(result, size);
-#endif
return result;
}
@@ -4216,9 +4277,7 @@
extern "C"
#endif
void free(void* ptr) {
-#ifndef WTF_CHANGES
MallocHook::InvokeDeleteHook(ptr);
-#endif
#if ENABLE(WTF_MALLOC_VALIDATION)
if (!ptr)
@@ -4281,9 +4340,7 @@
}
#endif
-#ifndef WTF_CHANGES
MallocHook::InvokeNewHook(result, totalBytes);
-#endif
return result;
}
@@ -4339,16 +4396,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;
}
@@ -4388,13 +4441,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.