Commit 4a0610ef authored by Ben Gamari's avatar Ben Gamari 🐢

Trace dump

parent d0111113
......@@ -274,8 +274,6 @@ GarbageCollect (uint32_t collect_gen,
*/
N = collect_gen;
major_gc = (N == RtsFlags.GcFlags.generations-1);
if (major_gc)
trace_dump_start_gc();
/* See Note [Deadlock detection under nonmoving collector]. */
deadlock_detect_gc = deadlock_detect;
......@@ -401,6 +399,8 @@ GarbageCollect (uint32_t collect_gen,
struct long_pause_ctx pause;
LONG_PAUSE_START(&pause);
if (n_gc_threads == 1) {
trace_dump_set_source("capabilities");
trace_dump_note("scavenging capability mut_lists");
for (n = 0; n < n_capabilities; n++) {
#if defined(THREADED_RTS)
scavenge_capability_mut_Lists1(capabilities[n]);
......@@ -410,6 +410,7 @@ GarbageCollect (uint32_t collect_gen,
}
} else {
scavenge_capability_mut_lists(gct->cap);
trace_dump_note("scavenging capability mut_lists");
for (n = 0; n < n_capabilities; n++) {
if (idle_cap[n]) {
markCapability(mark_root, gct, capabilities[n],
......@@ -422,12 +423,15 @@ GarbageCollect (uint32_t collect_gen,
trace(TRACE_gc, "done scavenging mut_lists");
// follow roots from the CAF list (used by GHCi)
trace_dump_note("scavenging CAFs");
LONG_PAUSE_START(&pause);
gct->evac_gen_no = 0;
markCAFs(mark_root, gct);
// follow all the roots that the application knows about.
gct->evac_gen_no = 0;
trace_dump_set_source("capabilities");
trace_dump_note("scavenging capability mut_lists again");
if (n_gc_threads == 1) {
for (n = 0; n < n_capabilities; n++) {
markCapability(mark_root, gct, capabilities[n],
......@@ -439,13 +443,19 @@ GarbageCollect (uint32_t collect_gen,
LONG_PAUSE_END(&pause, 50, "mark caps&sched");
LONG_PAUSE_START(&pause);
trace_dump_set_source("scheduler");
trace_dump_note("scavenging scheduler");
markScheduler(mark_root, gct);
// Mark the weak pointer list, and prepare to detect dead weak pointers.
trace_dump_set_source("weak ptr list");
trace_dump_note("weak ptr list");
markWeakPtrList();
initWeakForGC();
// Mark the stable pointer table.
trace_dump_set_source("stable ptr table");
trace_dump_note("stable ptr table");
markStablePtrTable(mark_root, gct);
// Remember old stable name addresses.
......@@ -460,6 +470,7 @@ GarbageCollect (uint32_t collect_gen,
StgWeak *dead_weak_ptr_list = NULL;
StgTSO *resurrected_threads = END_TSO_QUEUE;
trace_dump_note("main scavenging");
LONG_PAUSE_START(&pause);
for (;;)
{
......
......@@ -8,6 +8,7 @@
#include "GCThread.h" // for GCUtils.h
#include "GCUtils.h"
#include "Printer.h"
#include "TraceDump.h"
#include "MarkWeak.h" // scavengeLiveWeak
void
......@@ -372,10 +373,12 @@ scavengeNonmovingSegment (struct NonmovingSegment *seg)
StgPtr scan_end = (P_)nonmovingSegmentGetBlock(seg, seg->next_free);
if (seg_block->u.scan == scan_end)
return;
trace_dump_note("scavenging segment");
nonmoving_block_idx p_idx = nonmovingGetBlockIdx(seg_block->u.scan);
while (seg_block->u.scan < scan_end) {
StgClosure *p = (StgClosure*)seg_block->u.scan;
trace_dump_set_source_closure(p);
// bit set = was allocated in a previous GC, no need to scavenge
// bit not set = new allocation, so scavenge
......
......@@ -2073,6 +2073,7 @@ loop:
ASSERT(seg->todo_link);
ws->todo_seg = seg->todo_link;
seg->todo_link = NULL;
trace_dump_set_source("nonmoving");
scavengeNonmovingSegment(seg);
did_something = true;
break;
......
......@@ -24,7 +24,7 @@ trace_dump_start_gc(void)
gc_n++;
}
void
void
trace_dump_end_gc(void)
{
if (trace_dump) {
......@@ -34,6 +34,14 @@ trace_dump_end_gc(void)
trace_dump = NULL;
}
void
trace_dump_note(const char *s)
{
if (!trace_dump)
return;
fprintf(trace_dump, " # %s\n", s);
}
void
trace_dump_set_source(const char *c)
{
......@@ -64,8 +72,19 @@ trace_dump_set_source_closure(StgClosure *c)
type = closure_type_names[info->type];
}
fprintf(trace_dump, " \"%p\" [label=\"%p\\n%s\" info=\"%p\" type=\"%s\"];\n",
UNTAG_CLOSURE(c), UNTAG_CLOSURE(c), type, info, type);
const char *where;
if (HEAP_ALLOCED(c)) {
if (Bdescr((StgPtr) c)->flags & BF_NONMOVING) {
where = "nonmoving";
} else {
where = "moving";
}
} else {
where = "static";
}
fprintf(trace_dump, " \"%p\" [label=\"%p\\n%s\" info=\"%p\" type=\"%s\" where=\"%s\"];\n",
UNTAG_CLOSURE(c), UNTAG_CLOSURE(c), type, info, type, where);
}
void
......
#if defined(DEBUG)
//#define TRACE_DUMP
#endif
#if defined(TRACE_DUMP)
void trace_dump_start_gc(void);
void trace_dump_end_gc(void);
void trace_dump_note(const char *s);
void trace_dump_set_source(const char *c);
void trace_dump_set_source_closure(StgClosure *c);
void trace_dump_edge(StgClosure *tgt);
......@@ -11,9 +15,9 @@ void trace_dump_edge(StgClosure *tgt);
static inline void trace_dump_start_gc(void) {}
static inline void trace_dump_end_gc(void) {}
static inline void trace_dump_set_source_closure(StgClosure *c STG_UNUSED) {}
static inline void trace_dump_note(const char *s STG_UNUSED) {}
static inline void trace_dump_set_source(const char *c STG_UNUSED) {}
static inline void trace_dump_node(StgClosure *c STG_UNUSED) {}
static inline void trace_dump_set_source_closure(StgClosure *c STG_UNUSED) {}
static inline void trace_dump_edge(StgClosure *tgt STG_UNUSED) {}
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment