summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <simonmarhaskell@gmail.com>2008-04-16 22:13:31 +0000
committerSimon Marlow <simonmarhaskell@gmail.com>2008-04-16 22:13:31 +0000
commit12c1559835a971b49042929b77c41ae6c3f8360b (patch)
tree697b4f25eed92993cb2f0d9ca434521d1b1e409e
parenta75a8790410ce3ffb439bfd0b7c3999e7df72eb1 (diff)
downloadhaskell-12c1559835a971b49042929b77c41ae6c3f8360b.tar.gz
move the scan block pointer into the gct structure
-rw-r--r--rts/sm/GC.c23
-rw-r--r--rts/sm/GC.h6
-rw-r--r--rts/sm/GCUtils.c12
-rw-r--r--rts/sm/Scav.c35
-rw-r--r--rts/sm/Scav.c-inc13
5 files changed, 33 insertions, 56 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index cb2f04084b..68a89812fa 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -418,13 +418,13 @@ GarbageCollect ( rtsBool force_major_gc )
// not step 0
for (s = 1; s < total_steps; s++) {
ws = &thr->steps[s];
- // Not true?
- // ASSERT( ws->scan_bd == ws->todo_bd );
- ASSERT( ws->scan_bd ? ws->scan_bd->u.scan == ws->scan_bd->free : 1 );
// Push the final block
- if (ws->scan_bd) { push_scanned_block(ws->scan_bd, ws); }
-
+ if (ws->todo_bd) {
+ push_scanned_block(ws->todo_bd, ws);
+ }
+
+ ASSERT(gct->scan_bd == NULL);
ASSERT(countBlocks(ws->scavd_list) == ws->n_scavd_blocks);
prev = ws->part_list;
@@ -1011,8 +1011,6 @@ alloc_gc_thread (int n)
ASSERT(s == ws->step->abs_no);
ws->gct = t;
- ws->scan_bd = NULL;
-
ws->todo_bd = NULL;
ws->buffer_todo_bd = NULL;
@@ -1341,8 +1339,6 @@ init_collected_gen (nat g, nat n_threads)
ws = &gc_threads[t]->steps[g * RtsFlags.GcFlags.steps + s];
- ws->scan_bd = NULL;
-
ws->todo_large_objects = NULL;
ws->part_list = NULL;
@@ -1405,15 +1401,11 @@ init_uncollected_gen (nat g, nat threads)
stp->n_blocks -= 1;
stp->n_words -= ws->todo_bd->free - ws->todo_bd->start;
ws->todo_bd->link = NULL;
-
- // this block is also the scan block; we must scan
- // from the current end point.
- ws->scan_bd = ws->todo_bd;
- ws->scan_bd->u.scan = ws->scan_bd->free;
+ // we must scan from the current end point.
+ ws->todo_bd->u.scan = ws->todo_bd->free;
}
else
{
- ws->scan_bd = NULL;
ws->todo_bd = NULL;
alloc_todo_block(ws,0);
}
@@ -1442,6 +1434,7 @@ init_gc_thread (gc_thread *t)
{
t->static_objects = END_OF_STATIC_LIST;
t->scavenged_static_objects = END_OF_STATIC_LIST;
+ t->scan_bd = NULL;
t->evac_step = 0;
t->failed_to_evac = rtsFalse;
t->eager_promotion = rtsTrue;
diff --git a/rts/sm/GC.h b/rts/sm/GC.h
index 0e0d90a48e..62a4872f2b 100644
--- a/rts/sm/GC.h
+++ b/rts/sm/GC.h
@@ -76,9 +76,6 @@ typedef struct step_workspace_ {
step * step; // the step for this workspace
struct gc_thread_ * gct; // the gc_thread that contains this workspace
- // block that is currently being scanned
- bdescr * scan_bd;
-
// where objects to be scavenged go
bdescr * todo_bd;
StgPtr todo_free; // free ptr for todo_bd
@@ -128,6 +125,9 @@ typedef struct gc_thread_ {
lnat gc_count; // number of GCs this thread has done
+ // block that is currently being scanned
+ bdescr * scan_bd;
+
// --------------------
// evacuate flags
diff --git a/rts/sm/GCUtils.c b/rts/sm/GCUtils.c
index 118d5d792a..f7b18197a4 100644
--- a/rts/sm/GCUtils.c
+++ b/rts/sm/GCUtils.c
@@ -115,16 +115,13 @@ todo_block_full (nat size, step_workspace *ws)
ASSERT(bd->link == NULL);
ASSERT(bd->step == ws->step);
- gct->copied += ws->todo_free - bd->free;
- bd->free = ws->todo_free;
-
// If the global list is not empty, or there's not much work in
// this block to push, and there's enough room in
// this block to evacuate the current object, then just increase
// the limit.
if (ws->step->todos != NULL ||
- (bd->free - bd->u.scan < WORK_UNIT_WORDS / 2)) {
- if (bd->free + size < bd->start + BLOCK_SIZE_W) {
+ (ws->todo_free - bd->u.scan < WORK_UNIT_WORDS / 2)) {
+ if (ws->todo_free + size < bd->start + BLOCK_SIZE_W) {
ws->todo_lim = stg_min(bd->start + BLOCK_SIZE_W,
ws->todo_lim + stg_max(WORK_UNIT_WORDS,size));
debugTrace(DEBUG_gc, "increasing limit for %p to %p", bd->start, ws->todo_lim);
@@ -132,11 +129,14 @@ todo_block_full (nat size, step_workspace *ws)
}
}
+ gct->copied += ws->todo_free - bd->free;
+ bd->free = ws->todo_free;
+
ASSERT(bd->u.scan >= bd->start && bd->u.scan <= bd->free);
// If this block is not the scan block, we want to push it out and
// make room for a new todo block.
- if (bd != ws->scan_bd)
+ if (bd != gct->scan_bd)
{
// If this block does not have enough space to allocate the
// current object, but it also doesn't have any work to push, then
diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c
index 0eb4b11d89..1295a1d09f 100644
--- a/rts/sm/Scav.c
+++ b/rts/sm/Scav.c
@@ -1432,44 +1432,20 @@ loop:
}
ws = &gct->steps[s];
- if (ws->todo_bd != NULL)
- {
- bd = ws->todo_bd;
- gct->copied += ws->todo_free - bd->free;
- bd->free = ws->todo_free;
- }
+ gct->scan_bd = NULL;
- // If we have a todo block and no scan block, start
- // scanning the todo block.
- if (ws->scan_bd == NULL && ws->todo_bd != NULL)
- {
- ws->scan_bd = ws->todo_bd;
- }
-
// If we have a scan block with some work to do,
// scavenge everything up to the free pointer.
- if (ws->scan_bd != NULL && ws->scan_bd->u.scan < ws->scan_bd->free)
+ if (ws->todo_bd->u.scan < ws->todo_free)
{
if (n_gc_threads == 1) {
- scavenge_block1(ws->scan_bd);
+ scavenge_block1(ws->todo_bd);
} else {
- scavenge_block(ws->scan_bd);
+ scavenge_block(ws->todo_bd);
}
did_something = rtsTrue;
+ break;
}
-
- if (ws->scan_bd != NULL && ws->scan_bd != ws->todo_bd)
- {
- ASSERT(ws->scan_bd->u.scan == ws->scan_bd->free);
- // we're not going to evac any more objects into
- // this block, so push it now.
- push_scanned_block(ws->scan_bd, ws);
- ws->scan_bd = NULL;
- // we might be able to scan the todo block now.
- did_something = rtsTrue;
- }
-
- if (did_something) break;
// If we have any large objects to scavenge, do them now.
if (ws->todo_large_objects) {
@@ -1488,7 +1464,6 @@ loop:
} else {
scavenge_block(bd);
}
- push_scanned_block(bd, ws);
did_something = rtsTrue;
break;
}
diff --git a/rts/sm/Scav.c-inc b/rts/sm/Scav.c-inc
index 64677c0a5a..8d5a56cc3c 100644
--- a/rts/sm/Scav.c-inc
+++ b/rts/sm/Scav.c-inc
@@ -47,11 +47,10 @@ scavenge_block (bdescr *bd)
rtsBool saved_eager_promotion;
step_workspace *ws;
- p = bd->u.scan;
-
debugTrace(DEBUG_gc, "scavenging block %p (gen %d, step %d) @ %p",
bd->start, bd->gen_no, bd->step->no, p);
+ gct->scan_bd = bd;
gct->evac_step = bd->step;
saved_evac_step = gct->evac_step;
saved_eager_promotion = gct->eager_promotion;
@@ -59,6 +58,8 @@ scavenge_block (bdescr *bd)
ws = &gct->steps[bd->step->abs_no];
+ p = bd->u.scan;
+
// we might be evacuating into the very object that we're
// scavenging, so we have to check the real bd->free pointer each
// time around the loop.
@@ -454,6 +455,14 @@ scavenge_block (bdescr *bd)
// update stats: this is a block that has been scavenged
gct->scanned += bd->free - bd->u.scan;
bd->u.scan = bd->free;
+
+ if (bd != ws->todo_bd) {
+ // we're not going to evac any more objects into
+ // this block, so push it now.
+ push_scanned_block(bd, ws);
+ }
+
+ gct->scan_bd = NULL;
}
#undef scavenge_block