summaryrefslogtreecommitdiff
path: root/rts/sm
diff options
context:
space:
mode:
Diffstat (limited to 'rts/sm')
-rw-r--r--rts/sm/Compact.c1
-rw-r--r--rts/sm/Evac.c12
-rw-r--r--rts/sm/GC.c22
-rw-r--r--rts/sm/GC.h8
-rw-r--r--rts/sm/Sanity.c1
-rw-r--r--rts/sm/Scav.c73
-rw-r--r--rts/sm/Storage.c9
-rw-r--r--rts/sm/Storage.h3
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