X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=rts%2Fsm%2FEvac.c;h=062b73f0699a355e8e8a43ed178719a95796a880;hb=ebb1d38825c6eafeb1e1ff9885b1557e7d065e49;hp=bbb7fe579596f4ba4e567e6deb0d2628ad759b43;hpb=d600bf7a6afdbfc4a22f9379406a9c6f789a4c2d;p=ghc-hetmet.git diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c index bbb7fe5..062b73f 100644 --- a/rts/sm/Evac.c +++ b/rts/sm/Evac.c @@ -29,6 +29,7 @@ StgWord64 whitehole_spin = 0; #if defined(THREADED_RTS) && !defined(PARALLEL_GC) #define evacuate(p) evacuate1(p) +#define HEAP_ALLOCED_GC(p) HEAP_ALLOCED(p) #endif #if !defined(PARALLEL_GC) @@ -248,10 +249,6 @@ evacuate_large(StgPtr p) stp = bd->step; ACQUIRE_SPIN_LOCK(&stp->sync_large_objects); - // object must be at the beginning of the block (or be a ByteArray) - ASSERT(get_itbl((StgClosure *)p)->type == ARR_WORDS || - (((W_)p & BLOCK_MASK) == 0)); - // already evacuated? if (bd->flags & BF_EVACUATED) { /* Don't forget to set the gct->failed_to_evac flag if we didn't get @@ -287,11 +284,23 @@ evacuate_large(StgPtr p) } ws = &gct->steps[new_stp->abs_no]; + bd->flags |= BF_EVACUATED; bd->step = new_stp; bd->gen_no = new_stp->gen_no; - bd->link = ws->todo_large_objects; - ws->todo_large_objects = bd; + + // If this is a block of pinned objects, we don't have to scan + // these objects, because they aren't allowed to contain any + // pointers. For these blocks, we skip the scavenge stage and put + // them straight on the scavenged_large_objects list. + if (bd->flags & BF_PINNED) { + ASSERT(get_itbl((StgClosure *)p)->type == ARR_WORDS); + dbl_link_onto(bd, &ws->step->scavenged_large_objects); + ws->step->n_scavenged_large_blocks += bd->blocks; + } else { + bd->link = ws->todo_large_objects; + ws->todo_large_objects = bd; + } RELEASE_SPIN_LOCK(&stp->sync_large_objects); } @@ -356,7 +365,7 @@ loop: ASSERT(LOOKS_LIKE_CLOSURE_PTR(q)); - if (!HEAP_ALLOCED(q)) { + if (!HEAP_ALLOCED_GC(q)) { if (!major_gc) return; @@ -772,7 +781,7 @@ unchain_thunk_selectors(StgSelector *p, StgClosure *val) // invoke eval_thunk_selector(), the recursive calls will not // evacuate the value (because we want to select on the value, // not evacuate it), so in this case val is in from-space. - // ASSERT(!HEAP_ALLOCED(val) || Bdescr((P_)val)->gen_no > N || (Bdescr((P_)val)->flags & BF_EVACUATED)); + // ASSERT(!HEAP_ALLOCED_GC(val) || Bdescr((P_)val)->gen_no > N || (Bdescr((P_)val)->flags & BF_EVACUATED)); prev = (StgSelector*)((StgClosure *)p)->payload[0]; @@ -826,7 +835,7 @@ eval_thunk_selector (StgClosure **q, StgSelector * p, rtsBool evac) selector_chain: bd = Bdescr((StgPtr)p); - if (HEAP_ALLOCED(p)) { + if (HEAP_ALLOCED_GC(p)) { // If the THUNK_SELECTOR is in to-space or in a generation that we // are not collecting, then bale out early. We won't be able to // save any space in any case, and updating with an indirection is @@ -943,8 +952,12 @@ selector_loop: // the original selector thunk, p. SET_INFO(p, (StgInfoTable *)info_ptr); LDV_RECORD_DEAD_FILL_SLOP_DYNAMIC((StgClosure *)p); +#if defined(THREADED_RTS) + SET_INFO(p, &stg_WHITEHOLE_info); +#else SET_INFO(p, &stg_BLACKHOLE_info); #endif +#endif // the closure in val is now the "value" of the // THUNK_SELECTOR in p. However, val may itself be a