Add possibly-too-verbose NS_TraceMallocDumpAllocations and its JS window-level function, for leak and bloat analysis.

This commit is contained in:
brendan%mozilla.org 2000-08-29 01:52:13 +00:00
Родитель 8507f2d98b
Коммит 5387c4e16b
5 изменённых файлов: 125 добавлений и 9 удалений

Просмотреть файл

@ -1088,14 +1088,32 @@ TraceMallocLogTimestamp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, j
return JS_TRUE;
}
static JSBool
TraceMallocDumpAllocations(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
JSString *str;
const char *pathname;
str = JS_ValueToString(cx, argv[0]);
if (!str)
return JS_FALSE;
pathname = JS_GetStringBytes(str);
if (NS_TraceMallocDumpAllocations(pathname) < 0) {
JS_ReportError(cx, "can't dump to %s: %s", pathname, strerror(errno));
return JS_FALSE;
}
return JS_TRUE;
}
static JSFunctionSpec TraceMallocFunctions[] = {
{"TraceMallocDisable", TraceMallocDisable, 0, 0, 0},
{"TraceMallocEnable", TraceMallocEnable, 0, 0, 0},
{"TraceMallocOpenLogFile", TraceMallocOpenLogFile, 1, 0, 0},
{"TraceMallocChangeLogFD", TraceMallocChangeLogFD, 1, 0, 0},
{"TraceMallocCloseLogFD", TraceMallocCloseLogFD, 1, 0, 0},
{"TraceMallocLogTimestamp", TraceMallocLogTimestamp, 1, 0, 0},
{NULL, NULL, 0, 0, 0}
{"TraceMallocDisable", TraceMallocDisable, 0, 0, 0},
{"TraceMallocEnable", TraceMallocEnable, 0, 0, 0},
{"TraceMallocOpenLogFile", TraceMallocOpenLogFile, 1, 0, 0},
{"TraceMallocChangeLogFD", TraceMallocChangeLogFD, 1, 0, 0},
{"TraceMallocCloseLogFD", TraceMallocCloseLogFD, 1, 0, 0},
{"TraceMallocLogTimestamp", TraceMallocLogTimestamp, 1, 0, 0},
{"TraceMallocDumpAllocations", TraceMallocDumpAllocations, 1, 0, 0},
{NULL, NULL, 0, 0, 0}
};
#endif /* NS_TRACE_MALLOC */

Просмотреть файл

@ -44,6 +44,7 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
@ -374,6 +375,7 @@ struct callsite {
uint32 serial;
lfd_set lfdset;
char *name;
int offset;
callsite *parent;
callsite *siblings;
callsite *kids;
@ -387,7 +389,7 @@ static uint32 callsite_serial_generator = 0;
static uint32 tmstats_serial_generator = 0;
/* Root of the tree of callsites, the sum of all (cycle-compressed) stacks. */
static callsite calltree_root = {0, 0, LFD_SET_STATIC_INITIALIZER, NULL, NULL, NULL, NULL};
static callsite calltree_root = {0, 0, LFD_SET_STATIC_INITIALIZER, NULL, 0, NULL, NULL, NULL};
/* Basic instrumentation. */
static nsTMStats tmstats = NS_TMSTATS_STATIC_INITIALIZER;
@ -693,6 +695,7 @@ static callsite *calltree(uint32 *bp)
site->serial = ++callsite_serial_generator;
LFD_ZERO(&site->lfdset);
site->name = method;
site->offset = offset;
site->parent = parent;
site->siblings = parent->kids;
parent->kids = site;
@ -1259,4 +1262,40 @@ NS_TraceMallocLogTimestamp(const char *caption)
PR_ExitMonitor(tmmon);
}
static PRIntn
allocation_enumerator(PLHashEntry *he, PRIntn i, void *arg)
{
allocation *alloc = (allocation*) he;
FILE *ofp = (FILE*) arg;
callsite *site = (callsite*) he->value;
fprintf(ofp, "%8p %9lu ", he->key, (unsigned long) alloc->size);
while (site) {
if (site->name || site->parent)
fprintf(ofp, " %s+%d", site->name, site->offset);
site = site->parent;
if (site)
fputc(';', ofp);
}
fputc('\n', ofp);
return HT_ENUMERATE_NEXT;
}
PR_IMPLEMENT(int)
NS_TraceMallocDumpAllocations(const char *pathname)
{
FILE *ofp;
int rv;
ofp = fopen(pathname, "w");
if (!ofp)
return -1;
fprintf(ofp, "Address size stack\n");
if (allocations)
PL_HashTableEnumerateEntries(allocations, allocation_enumerator, ofp);
rv = ferror(ofp) ? -1 : 0;
fclose(ofp);
return rv;
}
#endif /* NS_TRACE_MALLOC */

Просмотреть файл

@ -158,6 +158,16 @@ PR_EXTERN(void) NS_TraceMallocCloseLogFD(int fd);
*/
PR_EXTERN(void) NS_TraceMallocLogTimestamp(const char *caption);
/**
* Dump a human-readable listing of current allocations and their compressed
* stack backtraces to the file named by pathname. Beware this file may have
* very long lines.
*
* Return -1 on error with errno set by the system, 0 on success.
*/
PR_EXTERN(int)
NS_TraceMallocDumpAllocations(const char *pathname);
PR_END_EXTERN_C
#endif /* nsTraceMalloc_h___ */

Просмотреть файл

@ -44,6 +44,7 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
@ -374,6 +375,7 @@ struct callsite {
uint32 serial;
lfd_set lfdset;
char *name;
int offset;
callsite *parent;
callsite *siblings;
callsite *kids;
@ -387,7 +389,7 @@ static uint32 callsite_serial_generator = 0;
static uint32 tmstats_serial_generator = 0;
/* Root of the tree of callsites, the sum of all (cycle-compressed) stacks. */
static callsite calltree_root = {0, 0, LFD_SET_STATIC_INITIALIZER, NULL, NULL, NULL, NULL};
static callsite calltree_root = {0, 0, LFD_SET_STATIC_INITIALIZER, NULL, 0, NULL, NULL, NULL};
/* Basic instrumentation. */
static nsTMStats tmstats = NS_TMSTATS_STATIC_INITIALIZER;
@ -693,6 +695,7 @@ static callsite *calltree(uint32 *bp)
site->serial = ++callsite_serial_generator;
LFD_ZERO(&site->lfdset);
site->name = method;
site->offset = offset;
site->parent = parent;
site->siblings = parent->kids;
parent->kids = site;
@ -1259,4 +1262,40 @@ NS_TraceMallocLogTimestamp(const char *caption)
PR_ExitMonitor(tmmon);
}
static PRIntn
allocation_enumerator(PLHashEntry *he, PRIntn i, void *arg)
{
allocation *alloc = (allocation*) he;
FILE *ofp = (FILE*) arg;
callsite *site = (callsite*) he->value;
fprintf(ofp, "%8p %9lu ", he->key, (unsigned long) alloc->size);
while (site) {
if (site->name || site->parent)
fprintf(ofp, " %s+%d", site->name, site->offset);
site = site->parent;
if (site)
fputc(';', ofp);
}
fputc('\n', ofp);
return HT_ENUMERATE_NEXT;
}
PR_IMPLEMENT(int)
NS_TraceMallocDumpAllocations(const char *pathname)
{
FILE *ofp;
int rv;
ofp = fopen(pathname, "w");
if (!ofp)
return -1;
fprintf(ofp, "Address size stack\n");
if (allocations)
PL_HashTableEnumerateEntries(allocations, allocation_enumerator, ofp);
rv = ferror(ofp) ? -1 : 0;
fclose(ofp);
return rv;
}
#endif /* NS_TRACE_MALLOC */

Просмотреть файл

@ -158,6 +158,16 @@ PR_EXTERN(void) NS_TraceMallocCloseLogFD(int fd);
*/
PR_EXTERN(void) NS_TraceMallocLogTimestamp(const char *caption);
/**
* Dump a human-readable listing of current allocations and their compressed
* stack backtraces to the file named by pathname. Beware this file may have
* very long lines.
*
* Return -1 on error with errno set by the system, 0 on success.
*/
PR_EXTERN(int)
NS_TraceMallocDumpAllocations(const char *pathname);
PR_END_EXTERN_C
#endif /* nsTraceMalloc_h___ */