Bug 913224 - Fix js::DumpHeapComplete() to work with GGC r=billm r=mccr8

This commit is contained in:
Jon Coppeard 2013-09-30 13:05:32 +01:00
parent bab1cc9c89
commit 4a148110a7
5 changed files with 60 additions and 21 deletions

View File

@ -827,32 +827,52 @@ FinalizeCount(JSContext *cx, unsigned argc, jsval *vp)
static bool
DumpHeapComplete(JSContext *cx, unsigned argc, jsval *vp)
{
const char *fileName = nullptr;
JSAutoByteString fileNameBytes;
if (argc > 0) {
Value v = JS_ARGV(cx, vp)[0];
CallArgs args = CallArgsFromVp(argc, vp);
DumpHeapNurseryBehaviour nurseryBehaviour = js::IgnoreNurseryObjects;
FILE *dumpFile = NULL;
unsigned i = 0;
if (argc > i) {
Value v = args[i];
if (v.isString()) {
JSString *str = v.toString();
bool same = false;
if (!JS_StringEqualsAscii(cx, str, "collectNurseryBeforeDump", &same))
return false;
if (same) {
nurseryBehaviour = js::CollectNurseryBeforeDump;
++i;
}
}
}
if (argc > i) {
Value v = args[i];
if (v.isString()) {
JSString *str = v.toString();
JSAutoByteString fileNameBytes;
if (!fileNameBytes.encodeLatin1(cx, str))
return false;
fileName = fileNameBytes.ptr();
const char *fileName = fileNameBytes.ptr();
dumpFile = fopen(fileName, "w");
if (!dumpFile) {
JS_ReportError(cx, "can't open %s", fileName);
return false;
}
++i;
}
}
FILE *dumpFile;
if (!fileName) {
dumpFile = stdout;
} else {
dumpFile = fopen(fileName, "w");
if (!dumpFile) {
JS_ReportError(cx, "can't open %s", fileName);
return false;
}
if (i != argc) {
JS_ReportError(cx, "bad arguments passed to dumpHeapComplete");
return false;
}
js::DumpHeapComplete(JS_GetRuntime(cx), dumpFile);
js::DumpHeapComplete(JS_GetRuntime(cx), dumpFile ? dumpFile : stdout, nurseryBehaviour);
fclose(dumpFile);
if (dumpFile)
fclose(dumpFile);
JS_SET_RVAL(cx, vp, JSVAL_VOID);
return true;
@ -1184,8 +1204,10 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
" If true, obj is a proxy of some sort"),
JS_FN_HELP("dumpHeapComplete", DumpHeapComplete, 1, 0,
"dumpHeapComplete([filename])",
" Dump reachable and unreachable objects to a file."),
"dumpHeapComplete(['collectNurseryBeforeDump'], [filename])",
" Dump reachable and unreachable objects to the named file, or to stdout. If\n"
" 'collectNurseryBeforeDump' is specified, a minor GC is performed first,\n"
" otherwise objects in the nursery are ignored."),
JS_FN_HELP("terminate", Terminate, 0, 0,
"terminate()",

View File

@ -0,0 +1 @@
dumpHeapComplete();

View File

@ -753,6 +753,9 @@ DumpHeapVisitCell(JSRuntime *rt, void *data, void *thing,
static void
DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
if (gc::IsInsideNursery(trc->runtime, *thingp))
return;
JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
char buffer[1024];
fprintf(dtrc->output, "> %p %c %s\n", *thingp, MarkDescriptor(*thingp),
@ -762,6 +765,9 @@ DumpHeapVisitChild(JSTracer *trc, void **thingp, JSGCTraceKind kind)
static void
DumpHeapVisitRoot(JSTracer *trc, void **thingp, JSGCTraceKind kind)
{
if (gc::IsInsideNursery(trc->runtime, *thingp))
return;
JSDumpHeapTracer *dtrc = static_cast<JSDumpHeapTracer *>(trc);
char buffer[1024];
fprintf(dtrc->output, "%p %c %s\n", *thingp, MarkDescriptor(*thingp),
@ -769,10 +775,15 @@ DumpHeapVisitRoot(JSTracer *trc, void **thingp, JSGCTraceKind kind)
}
void
js::DumpHeapComplete(JSRuntime *rt, FILE *fp)
js::DumpHeapComplete(JSRuntime *rt, FILE *fp, js::DumpHeapNurseryBehaviour nurseryBehaviour)
{
JSDumpHeapTracer dtrc(fp);
#ifdef JSGC_GENERATIONAL
if (nurseryBehaviour == js::CollectNurseryBeforeDump)
MinorGC(rt, JS::gcreason::API);
#endif
JS_TracerInit(&dtrc, rt, DumpHeapVisitRoot);
dtrc.eagerlyTraceWeakMaps = TraceWeakMapKeysValues;
TraceRuntime(&dtrc);

View File

@ -255,12 +255,17 @@ GetCompartmentZone(JSCompartment *comp);
typedef bool
(* PreserveWrapperCallback)(JSContext *cx, JSObject *obj);
typedef enum {
CollectNurseryBeforeDump,
IgnoreNurseryObjects
} DumpHeapNurseryBehaviour;
/*
* Dump the complete object graph of heap-allocated things.
* fp is the file for the dump output.
*/
extern JS_FRIEND_API(void)
DumpHeapComplete(JSRuntime *rt, FILE *fp);
DumpHeapComplete(JSRuntime *rt, FILE *fp, DumpHeapNurseryBehaviour nurseryBehaviour);
#ifdef JS_OLD_GETTER_SETTER_METHODS
JS_FRIEND_API(bool) obj_defineGetter(JSContext *cx, unsigned argc, JS::Value *vp);

View File

@ -968,7 +968,7 @@ CycleCollectedJSRuntime::DeferredFinalize(nsISupports* aSupports)
void
CycleCollectedJSRuntime::DumpJSHeap(FILE* file)
{
js::DumpHeapComplete(Runtime(), file);
js::DumpHeapComplete(Runtime(), file, js::CollectNurseryBeforeDump);
}