bug 113738 Cost of malloc into trace-malloc log r=blythe, sr=brendan

This commit is contained in:
dp@netscape.com
2001-12-15 00:24:12 +00:00
parent 26b9530193
commit 97ae98bb5e
8 changed files with 172 additions and 82 deletions

View File

@@ -58,6 +58,7 @@
#include "prmon.h" #include "prmon.h"
#include "prprf.h" #include "prprf.h"
#include "prenv.h" #include "prenv.h"
#include "prnetdb.h"
#include "nsTraceMalloc.h" #include "nsTraceMalloc.h"
#include "nscore.h" #include "nscore.h"
@@ -73,11 +74,6 @@
#endif /* WIN32 */ #endif /* WIN32 */
/*
* Record the intervals in a platform independent manner.
*/
#define MILLISECONDS_NOW PR_IntervalToMilliseconds(PR_IntervalNow())
#ifdef XP_UNIX #ifdef XP_UNIX
#define WRITE_FLAGS "w" #define WRITE_FLAGS "w"
@@ -474,6 +470,13 @@ static void log_event7(logfile *fp, char event, uint32 serial, uint32 ui2,
log_uint32(fp, ui7); log_uint32(fp, ui7);
} }
static void log_event8(logfile *fp, char event, uint32 serial, uint32 ui2,
uint32 ui3, uint32 ui4, uint32 ui5, uint32 ui6,
uint32 ui7, uint32 ui8)
{
log_event7(fp, event, serial, ui2, ui3, ui4, ui5, ui6, ui7);
log_uint32(fp, ui8);
}
typedef struct callsite callsite; typedef struct callsite callsite;
@@ -1301,12 +1304,15 @@ static PLHashTable *new_allocations(void)
__ptr_t malloc(size_t size) __ptr_t malloc(size_t size)
{ {
PRUint32 start, end;
__ptr_t *ptr; __ptr_t *ptr;
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
allocation *alloc; allocation *alloc;
start = PR_IntervalNow();
ptr = __libc_malloc(size); ptr = __libc_malloc(size);
end = PR_IntervalNow();
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
tmstats.malloc_calls++; tmstats.malloc_calls++;
if (!ptr) { if (!ptr) {
@@ -1314,8 +1320,8 @@ __ptr_t malloc(size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(1); site = backtrace(1);
if (site) if (site)
log_event4(logfp, TM_EVENT_MALLOC, log_event5(logfp, TM_EVENT_MALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1333,12 +1339,15 @@ __ptr_t malloc(size_t size)
__ptr_t calloc(size_t count, size_t size) __ptr_t calloc(size_t count, size_t size)
{ {
PRUint32 start, end;
__ptr_t *ptr; __ptr_t *ptr;
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
allocation *alloc; allocation *alloc;
start = PR_IntervalNow();
ptr = __libc_calloc(count, size); ptr = __libc_calloc(count, size);
end = PR_IntervalNow();
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
tmstats.calloc_calls++; tmstats.calloc_calls++;
if (!ptr) { if (!ptr) {
@@ -1347,8 +1356,8 @@ __ptr_t calloc(size_t count, size_t size)
site = backtrace(1); site = backtrace(1);
size *= count; size *= count;
if (site) if (site)
log_event4(logfp, TM_EVENT_CALLOC, log_event5(logfp, TM_EVENT_CALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1366,6 +1375,7 @@ __ptr_t calloc(size_t count, size_t size)
__ptr_t realloc(__ptr_t ptr, size_t size) __ptr_t realloc(__ptr_t ptr, size_t size)
{ {
PRUint32 start, end;
__ptr_t oldptr; __ptr_t oldptr;
callsite *oldsite, *site; callsite *oldsite, *site;
size_t oldsize; size_t oldsize;
@@ -1393,7 +1403,9 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
} }
TM_EXIT_MONITOR(); TM_EXIT_MONITOR();
start = PR_IntervalNow();
ptr = __libc_realloc(ptr, size); ptr = __libc_realloc(ptr, size);
end = PR_IntervalNow();
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
if (!ptr && size) { if (!ptr && size) {
@@ -1405,8 +1417,8 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(1); site = backtrace(1);
if (site) { if (site) {
log_event7(logfp, TM_EVENT_REALLOC, log_event8(logfp, TM_EVENT_REALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size, (uint32)NS_PTR_TO_INT32(ptr), size,
oldsite ? oldsite->serial : 0, oldsite ? oldsite->serial : 0,
(uint32)NS_PTR_TO_INT32(oldptr), oldsize); (uint32)NS_PTR_TO_INT32(oldptr), oldsize);
@@ -1448,6 +1460,8 @@ void free(__ptr_t ptr)
PLHashEntry **hep, *he; PLHashEntry **hep, *he;
callsite *site; callsite *site;
allocation *alloc; allocation *alloc;
uint32 serial = 0, size = 0;
PRUint32 start, end;
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
tmstats.free_calls++; tmstats.free_calls++;
@@ -1461,22 +1475,40 @@ void free(__ptr_t ptr)
site = (callsite*) he->value; site = (callsite*) he->value;
if (site) { if (site) {
alloc = (allocation*) he; alloc = (allocation*) he;
log_event4(logfp, TM_EVENT_FREE, serial = site->serial;
site->serial, MILLISECONDS_NOW, size = alloc->size;
(uint32)NS_PTR_TO_INT32(ptr), alloc->size);
} }
PL_HashTableRawRemove(allocations, hep, he); PL_HashTableRawRemove(allocations, hep, he);
} }
} }
} }
TM_EXIT_MONITOR(); TM_EXIT_MONITOR();
start = PR_IntervalNow();
__libc_free(ptr); __libc_free(ptr);
end = PR_IntervalNow();
if (size != 0) {
TM_ENTER_MONITOR();
log_event5(logfp, TM_EVENT_FREE,
serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size);
TM_EXIT_MONITOR();
}
} }
#endif /* XP_UNIX */ #endif /* XP_UNIX */
static const char magic[] = NS_TRACE_MALLOC_MAGIC; static const char magic[] = NS_TRACE_MALLOC_MAGIC;
static void
log_header(int logfd)
{
uint32 ticksPerSec = PR_htonl(PR_TicksPerSecond());
(void) write(logfd, magic, NS_TRACE_MALLOC_MAGIC_SIZE);
(void) write(logfd, &ticksPerSec, sizeof ticksPerSec);
}
PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd) PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd)
{ {
/* We must be running on the primordial thread. */ /* We must be running on the primordial thread. */
@@ -1490,8 +1522,7 @@ PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd)
logfile_list = &default_logfile; logfile_list = &default_logfile;
logfp->prevp = &logfile_list; logfp->prevp = &logfile_list;
logfile_tail = &logfp->next; logfile_tail = &logfp->next;
(void) write(logfd, magic, NS_TRACE_MALLOC_MAGIC_SIZE); log_header(logfd);
flush_logfile(logfp);
} }
atexit(NS_TraceMallocShutdown); atexit(NS_TraceMallocShutdown);
@@ -1562,7 +1593,9 @@ PR_IMPLEMENT(int) NS_TraceMallocStartupArgs(int argc, char* argv[])
} }
if (tmlogname) { if (tmlogname) {
#ifdef XP_UNIX
int pipefds[2]; int pipefds[2];
#endif
switch (*tmlogname) { switch (*tmlogname) {
#ifdef XP_UNIX #ifdef XP_UNIX
@@ -1716,7 +1749,7 @@ PR_IMPLEMENT(int) NS_TraceMallocChangeLogFD(int fd)
if (!fp) if (!fp)
return -2; return -2;
if (fd >= 0 && fstat(fd, &sb) == 0 && sb.st_size == 0) if (fd >= 0 && fstat(fd, &sb) == 0 && sb.st_size == 0)
(void) write(fd, magic, NS_TRACE_MALLOC_MAGIC_SIZE); log_header(fd);
logfp = fp; logfp = fp;
} }
TM_EXIT_MONITOR(); TM_EXIT_MONITOR();
@@ -1883,7 +1916,7 @@ NS_TraceMallocFlushLogfiles()
#ifdef XP_WIN32 #ifdef XP_WIN32
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
MallocCallback(void *ptr, size_t size) MallocCallback(void *ptr, size_t size, PRUint32 start, PRUint32 end)
{ {
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
@@ -1896,8 +1929,8 @@ MallocCallback(void *ptr, size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(4); site = backtrace(4);
if (site) if (site)
log_event4(logfp, TM_EVENT_MALLOC, log_event5(logfp, TM_EVENT_MALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1913,7 +1946,7 @@ MallocCallback(void *ptr, size_t size)
} }
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
CallocCallback(void *ptr, size_t count, size_t size) CallocCallback(void *ptr, size_t count, size_t size, PRUint32 start, PRUint32 end)
{ {
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
@@ -1927,8 +1960,8 @@ CallocCallback(void *ptr, size_t count, size_t size)
site = backtrace(1); site = backtrace(1);
size *= count; size *= count;
if (site) if (site)
log_event4(logfp, TM_EVENT_CALLOC, log_event5(logfp, TM_EVENT_CALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1944,7 +1977,7 @@ CallocCallback(void *ptr, size_t count, size_t size)
} }
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
ReallocCallback(void * oldptr, void *ptr, size_t size) ReallocCallback(void * oldptr, void *ptr, size_t size, PRUint32 start, PRUint32 end)
{ {
callsite *oldsite, *site; callsite *oldsite, *site;
size_t oldsize; size_t oldsize;
@@ -1979,8 +2012,8 @@ ReallocCallback(void * oldptr, void *ptr, size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(1); site = backtrace(1);
if (site) { if (site) {
log_event7(logfp, TM_EVENT_REALLOC, log_event8(logfp, TM_EVENT_REALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size, (uint32)NS_PTR_TO_INT32(ptr), size,
oldsite ? oldsite->serial : 0, oldsite ? oldsite->serial : 0,
(uint32)NS_PTR_TO_INT32(oldptr), oldsize); (uint32)NS_PTR_TO_INT32(oldptr), oldsize);
@@ -2016,7 +2049,7 @@ ReallocCallback(void * oldptr, void *ptr, size_t size)
} }
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
FreeCallback(void * ptr) FreeCallback(void * ptr, PRUint32 start, PRUint32 end)
{ {
PLHashEntry **hep, *he; PLHashEntry **hep, *he;
callsite *site; callsite *site;
@@ -2034,8 +2067,8 @@ FreeCallback(void * ptr)
site = (callsite*) he->value; site = (callsite*) he->value;
if (site) { if (site) {
alloc = (allocation*) he; alloc = (allocation*) he;
log_event4(logfp, TM_EVENT_FREE, log_event5(logfp, TM_EVENT_FREE,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), alloc->size); (uint32)NS_PTR_TO_INT32(ptr), alloc->size);
} }
PL_HashTableRawRemove(allocations, hep, he); PL_HashTableRawRemove(allocations, hep, he);

View File

@@ -45,7 +45,7 @@ PR_BEGIN_EXTERN_C
* NS_TraceMallocStartup comment (below) for magic number differences in log * NS_TraceMallocStartup comment (below) for magic number differences in log
* file structure. * file structure.
*/ */
#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog06\r\n\032" #define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog07\r\n\032"
#define NS_TRACE_MALLOC_MAGIC_SIZE 16 #define NS_TRACE_MALLOC_MAGIC_SIZE 16
/** /**

View File

@@ -7,10 +7,10 @@ PR_BEGIN_EXTERN_C
PR_EXTERN(void) StartupHooker();/*implemented in TraceMalloc.cpp*/ PR_EXTERN(void) StartupHooker();/*implemented in TraceMalloc.cpp*/
PR_EXTERN(void) ShutdownHooker(); PR_EXTERN(void) ShutdownHooker();
PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize);/*implemented in nsTraceMalloc.c*/ PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize, PRUint32 start, PRUint32 end);/*implemented in nsTraceMalloc.c*/
PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize); PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize, PRUint32 start, PRUint32 end);
PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize); PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize, PRUint32 start, PRUint32 end);
PR_EXTERN(void) FreeCallback(void *aPtr); PR_EXTERN(void) FreeCallback(void *aPtr, PRUint32 start, PRUint32 end);
PR_END_EXTERN_C PR_END_EXTERN_C

View File

@@ -138,14 +138,16 @@ DHWImportHooker &getMallocHooker()
void * __cdecl dhw_malloc( size_t size ) void * __cdecl dhw_malloc( size_t size )
{ {
PRUint32 start = PR_IntervalNow();
void* result = DHW_ORIGINAL(MALLOC_, getMallocHooker())(size); void* result = DHW_ORIGINAL(MALLOC_, getMallocHooker())(size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return result; return result;
g_lockOut = TRUE; g_lockOut = TRUE;
#ifdef VERBOSE #ifdef VERBOSE
printf("* malloc called to get %d bytes. returned %#x\n", size, result); printf("* malloc called to get %d bytes. returned %#x\n", size, result);
#endif #endif
MallocCallback(result, size); MallocCallback(result, size, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -162,13 +164,16 @@ DHWImportHooker &getCallocHooker()
void * __cdecl dhw_calloc( size_t count, size_t size ) void * __cdecl dhw_calloc( size_t count, size_t size )
{ {
PRUint32 start = PR_IntervalNow();
void* result = DHW_ORIGINAL(CALLOC_, getCallocHooker())(count,size); void* result = DHW_ORIGINAL(CALLOC_, getCallocHooker())(count,size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return result; return result;
g_lockOut = TRUE; g_lockOut = TRUE;
#ifdef VERBOSE #ifdef VERBOSE
printf("* calloc called to get %d many of %d bytes. returned %#x\n", count, size, result); printf("* calloc called to get %d many of %d bytes. returned %#x\n", count, size, result);
#endif CallocCallback(result, count, size); #endif
CallocCallback(result, count, size, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -184,14 +189,16 @@ DHWImportHooker &getFreeHooker()
void __cdecl dhw_free( void* p ) void __cdecl dhw_free( void* p )
{ {
PRUint32 start = PR_IntervalNow();
DHW_ORIGINAL(FREE_, getFreeHooker())(p); DHW_ORIGINAL(FREE_, getFreeHooker())(p);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return; return;
g_lockOut = TRUE; g_lockOut = TRUE;
#ifdef VERBOSE #ifdef VERBOSE
printf("* free called for %#x\n", p); printf("* free called for %#x\n", p);
#endif #endif
FreeCallback(p); FreeCallback(p, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -207,7 +214,9 @@ DHWImportHooker &getReallocHooker()
void * __cdecl dhw_realloc(void * pin, size_t size) void * __cdecl dhw_realloc(void * pin, size_t size)
{ {
PRUint32 start = PR_IntervalNow();
void* pout = DHW_ORIGINAL(REALLOC_, getReallocHooker())(pin, size); void* pout = DHW_ORIGINAL(REALLOC_, getReallocHooker())(pin, size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return pout; return pout;
g_lockOut = TRUE; g_lockOut = TRUE;
@@ -216,7 +225,7 @@ void * __cdecl dhw_realloc(void * pin, size_t size)
printf("* realloc called to resize to %d. old ptr: %#x. new ptr: %#x\n", printf("* realloc called to resize to %d. old ptr: %#x. new ptr: %#x\n",
size, pin, pout); size, pin, pout);
#endif #endif
ReallocCallback(pin,pout,size); ReallocCallback(pin, pout, size, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -233,8 +242,9 @@ DHWImportHooker &getNewHooker()
void * __cdecl dhw_new(size_t size) void * __cdecl dhw_new(size_t size)
{ {
PRUint32 start = PR_IntervalNow();
void* result = DHW_ORIGINAL(NEW_, getNewHooker())(size); void* result = DHW_ORIGINAL(NEW_, getNewHooker())(size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return result; return result;
g_lockOut = TRUE; g_lockOut = TRUE;
@@ -243,7 +253,7 @@ void * __cdecl dhw_new(size_t size)
printf("* new called to get %d bytes. returned %#x\n", size, result); printf("* new called to get %d bytes. returned %#x\n", size, result);
dumpStack(); dumpStack();
#endif #endif
MallocCallback(result,size);//do we need a different one for new? MallocCallback(result, size, start, end);//do we need a different one for new?
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
return result; return result;
@@ -259,7 +269,9 @@ DHWImportHooker &getDeleteHooker()
void __cdecl dhw_delete(void* p) void __cdecl dhw_delete(void* p)
{ {
PRUint32 start = PR_IntervalNow();
DHW_ORIGINAL(DELETE_, getDeleteHooker())(p); DHW_ORIGINAL(DELETE_, getDeleteHooker())(p);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return; return;
g_lockOut = TRUE; g_lockOut = TRUE;
@@ -267,7 +279,7 @@ void __cdecl dhw_delete(void* p)
printf("* delete called for %#x\n", p); printf("* delete called for %#x\n", p);
dumpStack(); dumpStack();
#endif #endif
FreeCallback(p); FreeCallback(p, start, end);
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
} }

View File

@@ -58,6 +58,7 @@
#include "prmon.h" #include "prmon.h"
#include "prprf.h" #include "prprf.h"
#include "prenv.h" #include "prenv.h"
#include "prnetdb.h"
#include "nsTraceMalloc.h" #include "nsTraceMalloc.h"
#include "nscore.h" #include "nscore.h"
@@ -73,11 +74,6 @@
#endif /* WIN32 */ #endif /* WIN32 */
/*
* Record the intervals in a platform independent manner.
*/
#define MILLISECONDS_NOW PR_IntervalToMilliseconds(PR_IntervalNow())
#ifdef XP_UNIX #ifdef XP_UNIX
#define WRITE_FLAGS "w" #define WRITE_FLAGS "w"
@@ -474,6 +470,13 @@ static void log_event7(logfile *fp, char event, uint32 serial, uint32 ui2,
log_uint32(fp, ui7); log_uint32(fp, ui7);
} }
static void log_event8(logfile *fp, char event, uint32 serial, uint32 ui2,
uint32 ui3, uint32 ui4, uint32 ui5, uint32 ui6,
uint32 ui7, uint32 ui8)
{
log_event7(fp, event, serial, ui2, ui3, ui4, ui5, ui6, ui7);
log_uint32(fp, ui8);
}
typedef struct callsite callsite; typedef struct callsite callsite;
@@ -1301,12 +1304,15 @@ static PLHashTable *new_allocations(void)
__ptr_t malloc(size_t size) __ptr_t malloc(size_t size)
{ {
PRUint32 start, end;
__ptr_t *ptr; __ptr_t *ptr;
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
allocation *alloc; allocation *alloc;
start = PR_IntervalNow();
ptr = __libc_malloc(size); ptr = __libc_malloc(size);
end = PR_IntervalNow();
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
tmstats.malloc_calls++; tmstats.malloc_calls++;
if (!ptr) { if (!ptr) {
@@ -1314,8 +1320,8 @@ __ptr_t malloc(size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(1); site = backtrace(1);
if (site) if (site)
log_event4(logfp, TM_EVENT_MALLOC, log_event5(logfp, TM_EVENT_MALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1333,12 +1339,15 @@ __ptr_t malloc(size_t size)
__ptr_t calloc(size_t count, size_t size) __ptr_t calloc(size_t count, size_t size)
{ {
PRUint32 start, end;
__ptr_t *ptr; __ptr_t *ptr;
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
allocation *alloc; allocation *alloc;
start = PR_IntervalNow();
ptr = __libc_calloc(count, size); ptr = __libc_calloc(count, size);
end = PR_IntervalNow();
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
tmstats.calloc_calls++; tmstats.calloc_calls++;
if (!ptr) { if (!ptr) {
@@ -1347,8 +1356,8 @@ __ptr_t calloc(size_t count, size_t size)
site = backtrace(1); site = backtrace(1);
size *= count; size *= count;
if (site) if (site)
log_event4(logfp, TM_EVENT_CALLOC, log_event5(logfp, TM_EVENT_CALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1366,6 +1375,7 @@ __ptr_t calloc(size_t count, size_t size)
__ptr_t realloc(__ptr_t ptr, size_t size) __ptr_t realloc(__ptr_t ptr, size_t size)
{ {
PRUint32 start, end;
__ptr_t oldptr; __ptr_t oldptr;
callsite *oldsite, *site; callsite *oldsite, *site;
size_t oldsize; size_t oldsize;
@@ -1393,7 +1403,9 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
} }
TM_EXIT_MONITOR(); TM_EXIT_MONITOR();
start = PR_IntervalNow();
ptr = __libc_realloc(ptr, size); ptr = __libc_realloc(ptr, size);
end = PR_IntervalNow();
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
if (!ptr && size) { if (!ptr && size) {
@@ -1405,8 +1417,8 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(1); site = backtrace(1);
if (site) { if (site) {
log_event7(logfp, TM_EVENT_REALLOC, log_event8(logfp, TM_EVENT_REALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size, (uint32)NS_PTR_TO_INT32(ptr), size,
oldsite ? oldsite->serial : 0, oldsite ? oldsite->serial : 0,
(uint32)NS_PTR_TO_INT32(oldptr), oldsize); (uint32)NS_PTR_TO_INT32(oldptr), oldsize);
@@ -1448,6 +1460,8 @@ void free(__ptr_t ptr)
PLHashEntry **hep, *he; PLHashEntry **hep, *he;
callsite *site; callsite *site;
allocation *alloc; allocation *alloc;
uint32 serial = 0, size = 0;
PRUint32 start, end;
TM_ENTER_MONITOR(); TM_ENTER_MONITOR();
tmstats.free_calls++; tmstats.free_calls++;
@@ -1461,22 +1475,40 @@ void free(__ptr_t ptr)
site = (callsite*) he->value; site = (callsite*) he->value;
if (site) { if (site) {
alloc = (allocation*) he; alloc = (allocation*) he;
log_event4(logfp, TM_EVENT_FREE, serial = site->serial;
site->serial, MILLISECONDS_NOW, size = alloc->size;
(uint32)NS_PTR_TO_INT32(ptr), alloc->size);
} }
PL_HashTableRawRemove(allocations, hep, he); PL_HashTableRawRemove(allocations, hep, he);
} }
} }
} }
TM_EXIT_MONITOR(); TM_EXIT_MONITOR();
start = PR_IntervalNow();
__libc_free(ptr); __libc_free(ptr);
end = PR_IntervalNow();
if (size != 0) {
TM_ENTER_MONITOR();
log_event5(logfp, TM_EVENT_FREE,
serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size);
TM_EXIT_MONITOR();
}
} }
#endif /* XP_UNIX */ #endif /* XP_UNIX */
static const char magic[] = NS_TRACE_MALLOC_MAGIC; static const char magic[] = NS_TRACE_MALLOC_MAGIC;
static void
log_header(int logfd)
{
uint32 ticksPerSec = PR_htonl(PR_TicksPerSecond());
(void) write(logfd, magic, NS_TRACE_MALLOC_MAGIC_SIZE);
(void) write(logfd, &ticksPerSec, sizeof ticksPerSec);
}
PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd) PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd)
{ {
/* We must be running on the primordial thread. */ /* We must be running on the primordial thread. */
@@ -1490,8 +1522,7 @@ PR_IMPLEMENT(void) NS_TraceMallocStartup(int logfd)
logfile_list = &default_logfile; logfile_list = &default_logfile;
logfp->prevp = &logfile_list; logfp->prevp = &logfile_list;
logfile_tail = &logfp->next; logfile_tail = &logfp->next;
(void) write(logfd, magic, NS_TRACE_MALLOC_MAGIC_SIZE); log_header(logfd);
flush_logfile(logfp);
} }
atexit(NS_TraceMallocShutdown); atexit(NS_TraceMallocShutdown);
@@ -1562,7 +1593,9 @@ PR_IMPLEMENT(int) NS_TraceMallocStartupArgs(int argc, char* argv[])
} }
if (tmlogname) { if (tmlogname) {
#ifdef XP_UNIX
int pipefds[2]; int pipefds[2];
#endif
switch (*tmlogname) { switch (*tmlogname) {
#ifdef XP_UNIX #ifdef XP_UNIX
@@ -1716,7 +1749,7 @@ PR_IMPLEMENT(int) NS_TraceMallocChangeLogFD(int fd)
if (!fp) if (!fp)
return -2; return -2;
if (fd >= 0 && fstat(fd, &sb) == 0 && sb.st_size == 0) if (fd >= 0 && fstat(fd, &sb) == 0 && sb.st_size == 0)
(void) write(fd, magic, NS_TRACE_MALLOC_MAGIC_SIZE); log_header(fd);
logfp = fp; logfp = fp;
} }
TM_EXIT_MONITOR(); TM_EXIT_MONITOR();
@@ -1883,7 +1916,7 @@ NS_TraceMallocFlushLogfiles()
#ifdef XP_WIN32 #ifdef XP_WIN32
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
MallocCallback(void *ptr, size_t size) MallocCallback(void *ptr, size_t size, PRUint32 start, PRUint32 end)
{ {
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
@@ -1896,8 +1929,8 @@ MallocCallback(void *ptr, size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(4); site = backtrace(4);
if (site) if (site)
log_event4(logfp, TM_EVENT_MALLOC, log_event5(logfp, TM_EVENT_MALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1913,7 +1946,7 @@ MallocCallback(void *ptr, size_t size)
} }
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
CallocCallback(void *ptr, size_t count, size_t size) CallocCallback(void *ptr, size_t count, size_t size, PRUint32 start, PRUint32 end)
{ {
callsite *site; callsite *site;
PLHashEntry *he; PLHashEntry *he;
@@ -1927,8 +1960,8 @@ CallocCallback(void *ptr, size_t count, size_t size)
site = backtrace(1); site = backtrace(1);
size *= count; size *= count;
if (site) if (site)
log_event4(logfp, TM_EVENT_CALLOC, log_event5(logfp, TM_EVENT_CALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size); (uint32)NS_PTR_TO_INT32(ptr), size);
if (get_allocations()) { if (get_allocations()) {
suppress_tracing++; suppress_tracing++;
@@ -1944,7 +1977,7 @@ CallocCallback(void *ptr, size_t count, size_t size)
} }
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
ReallocCallback(void * oldptr, void *ptr, size_t size) ReallocCallback(void * oldptr, void *ptr, size_t size, PRUint32 start, PRUint32 end)
{ {
callsite *oldsite, *site; callsite *oldsite, *site;
size_t oldsize; size_t oldsize;
@@ -1979,8 +2012,8 @@ ReallocCallback(void * oldptr, void *ptr, size_t size)
} else if (suppress_tracing == 0) { } else if (suppress_tracing == 0) {
site = backtrace(1); site = backtrace(1);
if (site) { if (site) {
log_event7(logfp, TM_EVENT_REALLOC, log_event8(logfp, TM_EVENT_REALLOC,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), size, (uint32)NS_PTR_TO_INT32(ptr), size,
oldsite ? oldsite->serial : 0, oldsite ? oldsite->serial : 0,
(uint32)NS_PTR_TO_INT32(oldptr), oldsize); (uint32)NS_PTR_TO_INT32(oldptr), oldsize);
@@ -2016,7 +2049,7 @@ ReallocCallback(void * oldptr, void *ptr, size_t size)
} }
PR_IMPLEMENT(void) PR_IMPLEMENT(void)
FreeCallback(void * ptr) FreeCallback(void * ptr, PRUint32 start, PRUint32 end)
{ {
PLHashEntry **hep, *he; PLHashEntry **hep, *he;
callsite *site; callsite *site;
@@ -2034,8 +2067,8 @@ FreeCallback(void * ptr)
site = (callsite*) he->value; site = (callsite*) he->value;
if (site) { if (site) {
alloc = (allocation*) he; alloc = (allocation*) he;
log_event4(logfp, TM_EVENT_FREE, log_event5(logfp, TM_EVENT_FREE,
site->serial, MILLISECONDS_NOW, site->serial, start, end - start,
(uint32)NS_PTR_TO_INT32(ptr), alloc->size); (uint32)NS_PTR_TO_INT32(ptr), alloc->size);
} }
PL_HashTableRawRemove(allocations, hep, he); PL_HashTableRawRemove(allocations, hep, he);

View File

@@ -45,7 +45,7 @@ PR_BEGIN_EXTERN_C
* NS_TraceMallocStartup comment (below) for magic number differences in log * NS_TraceMallocStartup comment (below) for magic number differences in log
* file structure. * file structure.
*/ */
#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog06\r\n\032" #define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog07\r\n\032"
#define NS_TRACE_MALLOC_MAGIC_SIZE 16 #define NS_TRACE_MALLOC_MAGIC_SIZE 16
/** /**

View File

@@ -7,10 +7,10 @@ PR_BEGIN_EXTERN_C
PR_EXTERN(void) StartupHooker();/*implemented in TraceMalloc.cpp*/ PR_EXTERN(void) StartupHooker();/*implemented in TraceMalloc.cpp*/
PR_EXTERN(void) ShutdownHooker(); PR_EXTERN(void) ShutdownHooker();
PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize);/*implemented in nsTraceMalloc.c*/ PR_EXTERN(void) MallocCallback(void *aPtr, size_t aSize, PRUint32 start, PRUint32 end);/*implemented in nsTraceMalloc.c*/
PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize); PR_EXTERN(void) CallocCallback(void *aPtr, size_t aCount, size_t aSize, PRUint32 start, PRUint32 end);
PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize); PR_EXTERN(void) ReallocCallback(void *aPin, void* aPout, size_t aSize, PRUint32 start, PRUint32 end);
PR_EXTERN(void) FreeCallback(void *aPtr); PR_EXTERN(void) FreeCallback(void *aPtr, PRUint32 start, PRUint32 end);
PR_END_EXTERN_C PR_END_EXTERN_C

View File

@@ -138,14 +138,16 @@ DHWImportHooker &getMallocHooker()
void * __cdecl dhw_malloc( size_t size ) void * __cdecl dhw_malloc( size_t size )
{ {
PRUint32 start = PR_IntervalNow();
void* result = DHW_ORIGINAL(MALLOC_, getMallocHooker())(size); void* result = DHW_ORIGINAL(MALLOC_, getMallocHooker())(size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return result; return result;
g_lockOut = TRUE; g_lockOut = TRUE;
#ifdef VERBOSE #ifdef VERBOSE
printf("* malloc called to get %d bytes. returned %#x\n", size, result); printf("* malloc called to get %d bytes. returned %#x\n", size, result);
#endif #endif
MallocCallback(result, size); MallocCallback(result, size, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -162,13 +164,16 @@ DHWImportHooker &getCallocHooker()
void * __cdecl dhw_calloc( size_t count, size_t size ) void * __cdecl dhw_calloc( size_t count, size_t size )
{ {
PRUint32 start = PR_IntervalNow();
void* result = DHW_ORIGINAL(CALLOC_, getCallocHooker())(count,size); void* result = DHW_ORIGINAL(CALLOC_, getCallocHooker())(count,size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return result; return result;
g_lockOut = TRUE; g_lockOut = TRUE;
#ifdef VERBOSE #ifdef VERBOSE
printf("* calloc called to get %d many of %d bytes. returned %#x\n", count, size, result); printf("* calloc called to get %d many of %d bytes. returned %#x\n", count, size, result);
#endif CallocCallback(result, count, size); #endif
CallocCallback(result, count, size, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -184,14 +189,16 @@ DHWImportHooker &getFreeHooker()
void __cdecl dhw_free( void* p ) void __cdecl dhw_free( void* p )
{ {
PRUint32 start = PR_IntervalNow();
DHW_ORIGINAL(FREE_, getFreeHooker())(p); DHW_ORIGINAL(FREE_, getFreeHooker())(p);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return; return;
g_lockOut = TRUE; g_lockOut = TRUE;
#ifdef VERBOSE #ifdef VERBOSE
printf("* free called for %#x\n", p); printf("* free called for %#x\n", p);
#endif #endif
FreeCallback(p); FreeCallback(p, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -207,7 +214,9 @@ DHWImportHooker &getReallocHooker()
void * __cdecl dhw_realloc(void * pin, size_t size) void * __cdecl dhw_realloc(void * pin, size_t size)
{ {
PRUint32 start = PR_IntervalNow();
void* pout = DHW_ORIGINAL(REALLOC_, getReallocHooker())(pin, size); void* pout = DHW_ORIGINAL(REALLOC_, getReallocHooker())(pin, size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return pout; return pout;
g_lockOut = TRUE; g_lockOut = TRUE;
@@ -216,7 +225,7 @@ void * __cdecl dhw_realloc(void * pin, size_t size)
printf("* realloc called to resize to %d. old ptr: %#x. new ptr: %#x\n", printf("* realloc called to resize to %d. old ptr: %#x. new ptr: %#x\n",
size, pin, pout); size, pin, pout);
#endif #endif
ReallocCallback(pin,pout,size); ReallocCallback(pin, pout, size, start, end);
// dumpStack(); // dumpStack();
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
@@ -233,8 +242,9 @@ DHWImportHooker &getNewHooker()
void * __cdecl dhw_new(size_t size) void * __cdecl dhw_new(size_t size)
{ {
PRUint32 start = PR_IntervalNow();
void* result = DHW_ORIGINAL(NEW_, getNewHooker())(size); void* result = DHW_ORIGINAL(NEW_, getNewHooker())(size);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return result; return result;
g_lockOut = TRUE; g_lockOut = TRUE;
@@ -243,7 +253,7 @@ void * __cdecl dhw_new(size_t size)
printf("* new called to get %d bytes. returned %#x\n", size, result); printf("* new called to get %d bytes. returned %#x\n", size, result);
dumpStack(); dumpStack();
#endif #endif
MallocCallback(result,size);//do we need a different one for new? MallocCallback(result, size, start, end);//do we need a different one for new?
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
return result; return result;
@@ -259,7 +269,9 @@ DHWImportHooker &getDeleteHooker()
void __cdecl dhw_delete(void* p) void __cdecl dhw_delete(void* p)
{ {
PRUint32 start = PR_IntervalNow();
DHW_ORIGINAL(DELETE_, getDeleteHooker())(p); DHW_ORIGINAL(DELETE_, getDeleteHooker())(p);
PRUint32 end = PR_IntervalNow();
if (g_lockOut) if (g_lockOut)
return; return;
g_lockOut = TRUE; g_lockOut = TRUE;
@@ -267,7 +279,7 @@ void __cdecl dhw_delete(void* p)
printf("* delete called for %#x\n", p); printf("* delete called for %#x\n", p);
dumpStack(); dumpStack();
#endif #endif
FreeCallback(p); FreeCallback(p, start, end);
// printf("\n"); // printf("\n");
g_lockOut = FALSE; g_lockOut = FALSE;
} }