diff options
Diffstat (limited to 'rts/sm')
-rw-r--r-- | rts/sm/Compact.c | 1 | ||||
-rw-r--r-- | rts/sm/Evac.c | 12 | ||||
-rw-r--r-- | rts/sm/GC.c | 22 | ||||
-rw-r--r-- | rts/sm/GC.h | 8 | ||||
-rw-r--r-- | rts/sm/Sanity.c | 1 | ||||
-rw-r--r-- | rts/sm/Scav.c | 73 | ||||
-rw-r--r-- | rts/sm/Storage.c | 9 | ||||
-rw-r--r-- | rts/sm/Storage.h | 3 |
8 files changed, 114 insertions, 15 deletions
diff --git a/rts/sm/Compact.c b/rts/sm/Compact.c index 34111f9206..02183c6946 100644 --- a/rts/sm/Compact.c +++ b/rts/sm/Compact.c @@ -603,6 +603,7 @@ thread_obj (StgInfoTable *info, StgPtr p) case MUT_PRIM: case MUT_VAR_CLEAN: case MUT_VAR_DIRTY: + case TVAR: case BLACKHOLE: case BLOCKING_QUEUE: { diff --git a/rts/sm/Evac.c b/rts/sm/Evac.c index 0ac9e2623a..4dfbad7e37 100644 --- a/rts/sm/Evac.c +++ b/rts/sm/Evac.c @@ -540,13 +540,6 @@ loop: case WHITEHOLE: goto loop; - case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: - case MVAR_CLEAN: - case MVAR_DIRTY: - copy(p,info,q,sizeW_fromITBL(INFO_PTR_TO_STRUCT(info)),gen_no); - return; - // For ints and chars of low value, save space by replacing references to // these with closures with references to common, shared ones in the RTS. // @@ -646,6 +639,11 @@ loop: goto loop; } + case MUT_VAR_CLEAN: + case MUT_VAR_DIRTY: + case MVAR_CLEAN: + case MVAR_DIRTY: + case TVAR: case BLOCKING_QUEUE: case WEAK: case PRIM: diff --git a/rts/sm/GC.c b/rts/sm/GC.c index b9485f2c36..7ce8a4e30d 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -109,6 +109,12 @@ static W_ g0_pcnt_kept = 30; // percentage of g0 live at last minor GC nat mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, + mutlist_TVAR, + mutlist_TVAR_WATCH_QUEUE, + mutlist_TREC_CHUNK, + mutlist_TREC_HEADER, + mutlist_ATOMIC_INVARIANT, + mutlist_INVARIANT_CHECK_QUEUE, mutlist_OTHERS; #endif @@ -218,6 +224,13 @@ GarbageCollect (nat collect_gen, #ifdef DEBUG mutlist_MUTVARS = 0; mutlist_MUTARRS = 0; + mutlist_MVARS = 0; + mutlist_TVAR = 0; + mutlist_TVAR_WATCH_QUEUE = 0; + mutlist_TREC_CHUNK = 0; + mutlist_TREC_HEADER = 0; + mutlist_ATOMIC_INVARIANT = 0; + mutlist_INVARIANT_CHECK_QUEUE = 0; mutlist_OTHERS = 0; #endif @@ -499,9 +512,14 @@ GarbageCollect (nat collect_gen, copied += mut_list_size; debugTrace(DEBUG_gc, - "mut_list_size: %lu (%d vars, %d arrays, %d MVARs, %d others)", + "mut_list_size: %lu (%d vars, %d arrays, %d MVARs, %d TVARs, %d TVAR_WATCH_QUEUEs, %d TREC_CHUNKs, %d TREC_HEADERs, %d ATOMIC_INVARIANTs, %d INVARIANT_CHECK_QUEUEs, %d others)", (unsigned long)(mut_list_size * sizeof(W_)), - mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, mutlist_OTHERS); + mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, + mutlist_TVAR, mutlist_TVAR_WATCH_QUEUE, + mutlist_TREC_CHUNK, mutlist_TREC_HEADER, + mutlist_ATOMIC_INVARIANT, + mutlist_INVARIANT_CHECK_QUEUE, + mutlist_OTHERS); } bdescr *next, *prev; diff --git a/rts/sm/GC.h b/rts/sm/GC.h index 4dc7347597..54b7c86367 100644 --- a/rts/sm/GC.h +++ b/rts/sm/GC.h @@ -37,7 +37,13 @@ extern long copied; extern rtsBool work_stealing; #ifdef DEBUG -extern nat mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, mutlist_OTHERS; +extern nat mutlist_MUTVARS, mutlist_MUTARRS, mutlist_MVARS, mutlist_OTHERS, + mutlist_TVAR, + mutlist_TVAR_WATCH_QUEUE, + mutlist_TREC_CHUNK, + mutlist_TREC_HEADER, + mutlist_ATOMIC_INVARIANT, + mutlist_INVARIANT_CHECK_QUEUE; #endif #if defined(PROF_SPIN) && defined(THREADED_RTS) diff --git a/rts/sm/Sanity.c b/rts/sm/Sanity.c index fb6a857f9e..f0e1659e12 100644 --- a/rts/sm/Sanity.c +++ b/rts/sm/Sanity.c @@ -282,6 +282,7 @@ checkClosure( StgClosure* p ) case MUT_PRIM: case MUT_VAR_CLEAN: case MUT_VAR_DIRTY: + case TVAR: case CONSTR_STATIC: case CONSTR_NOCAF_STATIC: case THUNK_STATIC: diff --git a/rts/sm/Scav.c b/rts/sm/Scav.c index 668b95da6b..1e0411a972 100644 --- a/rts/sm/Scav.c +++ b/rts/sm/Scav.c @@ -424,6 +424,23 @@ scavenge_block (bdescr *bd) break; } + case TVAR: + { + StgTVar *tvar = ((StgTVar *)p); + gct->eager_promotion = rtsFalse; + evacuate((StgClosure **)&tvar->current_value); + evacuate((StgClosure **)&tvar->first_watch_queue_entry); + gct->eager_promotion = saved_eager_promotion; + + if (gct->failed_to_evac) { + tvar->header.info = &stg_TVAR_DIRTY_info; + } else { + tvar->header.info = &stg_TVAR_CLEAN_info; + } + p += sizeofW(StgTVar); + break; + } + case FUN_2_0: scavenge_fun_srt(info); evacuate(&((StgClosure *)p)->payload[1]); @@ -783,6 +800,22 @@ scavenge_mark_stack(void) break; } + case TVAR: + { + StgTVar *tvar = ((StgTVar *)p); + gct->eager_promotion = rtsFalse; + evacuate((StgClosure **)&tvar->current_value); + evacuate((StgClosure **)&tvar->first_watch_queue_entry); + gct->eager_promotion = saved_eager_promotion; + + if (gct->failed_to_evac) { + tvar->header.info = &stg_TVAR_DIRTY_info; + } else { + tvar->header.info = &stg_TVAR_CLEAN_info; + } + break; + } + case FUN_2_0: scavenge_fun_srt(info); evacuate(&((StgClosure *)p)->payload[1]); @@ -1088,6 +1121,22 @@ scavenge_one(StgPtr p) break; } + case TVAR: + { + StgTVar *tvar = ((StgTVar *)p); + gct->eager_promotion = rtsFalse; + evacuate((StgClosure **)&tvar->current_value); + evacuate((StgClosure **)&tvar->first_watch_queue_entry); + gct->eager_promotion = saved_eager_promotion; + + if (gct->failed_to_evac) { + tvar->header.info = &stg_TVAR_DIRTY_info; + } else { + tvar->header.info = &stg_TVAR_CLEAN_info; + } + break; + } + case THUNK: case THUNK_1_0: case THUNK_0_1: @@ -1363,10 +1412,26 @@ scavenge_mutable_list(bdescr *bd, generation *gen) case MVAR_CLEAN: barf("MVAR_CLEAN on mutable list"); case MVAR_DIRTY: - mutlist_MVARS++; break; - default: - mutlist_OTHERS++; break; - } + mutlist_MVARS++; break; + case TVAR: + mutlist_TVAR++; break; + case TREC_CHUNK: + mutlist_TREC_CHUNK++; break; + case MUT_PRIM: + if (((StgClosure*)p)->header.info == &stg_TVAR_WATCH_QUEUE_info) + mutlist_TVAR_WATCH_QUEUE++; + else if (((StgClosure*)p)->header.info == &stg_TREC_HEADER_info) + mutlist_TREC_HEADER++; + else if (((StgClosure*)p)->header.info == &stg_ATOMIC_INVARIANT_info) + mutlist_ATOMIC_INVARIANT++; + else if (((StgClosure*)p)->header.info == &stg_INVARIANT_CHECK_QUEUE_info) + mutlist_INVARIANT_CHECK_QUEUE++; + else + mutlist_OTHERS++; + break; + default: + mutlist_OTHERS++; break; + } #endif // Check whether this object is "clean", that is it diff --git a/rts/sm/Storage.c b/rts/sm/Storage.c index e5258c2517..ff4f172ac5 100644 --- a/rts/sm/Storage.c +++ b/rts/sm/Storage.c @@ -845,6 +845,15 @@ dirty_MUT_VAR(StgRegTable *reg, StgClosure *p) } } +void +dirty_TVAR(Capability *cap, StgTVar *p) +{ + if (p->header.info == &stg_TVAR_CLEAN_info) { + p->header.info = &stg_TVAR_DIRTY_info; + recordClosureMutated(cap,(StgClosure*)p); + } +} + // Setting a TSO's link field with a write barrier. // It is *not* necessary to call this function when // * setting the link field to END_TSO_QUEUE diff --git a/rts/sm/Storage.h b/rts/sm/Storage.h index 05690d0a4f..65f5242c31 100644 --- a/rts/sm/Storage.h +++ b/rts/sm/Storage.h @@ -69,10 +69,11 @@ extern Mutex sm_mutex; #endif /* ----------------------------------------------------------------------------- - The write barrier for MVARs + The write barrier for MVARs and TVARs -------------------------------------------------------------------------- */ void dirty_MVAR(StgRegTable *reg, StgClosure *p); +void dirty_TVAR(Capability *cap, StgTVar *p); /* ----------------------------------------------------------------------------- Nursery manipulation |