Commit d283bfc1 authored by simonmar's avatar simonmar
Browse files

[project @ 2003-10-22 15:00:59 by simonmar]

Fix a nasty bug in the GC mutable list handling, which shows up when
an array is frozen and then unsafeThaw#'d.  The array could end up on
the mutable list twice.

Fixes SourceForge bug #819116.
parent 948e7f38
/* -----------------------------------------------------------------------------
* $Id: GC.c,v 1.160 2003/09/23 15:31:02 simonmar Exp $
* $Id: GC.c,v 1.161 2003/10/22 15:00:59 simonmar Exp $
*
* (c) The GHC Team 1998-2003
*
......@@ -2674,6 +2674,11 @@ scavenge(step *stp)
// false, but that breaks some assumptions (eg. every
// closure on the mutable list is supposed to have the MUT
// flag set, and MUT_ARR_PTRS_FROZEN doesn't).
// Set the mut_link field to NULL, so that we will put this
// array back on the mutable list if it is subsequently thawed
// by unsafeThaw#.
((StgMutArrPtrs*)p)->mut_link = NULL;
break;
}
......@@ -2980,6 +2985,10 @@ linear_scan:
for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
(StgClosure *)*p = evacuate((StgClosure *)*p);
}
// Set the mut_link field to NULL, so that we will put this
// array on the mutable list if it is subsequently thawed
// by unsafeThaw#.
((StgMutArrPtrs*)p)->mut_link = NULL;
break;
}
......@@ -3202,6 +3211,10 @@ scavenge_one(StgPtr p)
for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) {
(StgClosure *)*p = evacuate((StgClosure *)*p);
}
// Set the mut_link field to NULL, so that we will put this
// array on the mutable list if it is subsequently thawed
// by unsafeThaw#.
((StgMutArrPtrs*)p)->mut_link = NULL;
break;
}
......@@ -3406,6 +3419,9 @@ scavenge_mutable_list(generation *gen)
(StgClosure *)*q = evacuate((StgClosure *)*q);
}
evac_gen = 0;
// Set the mut_link field to NULL, so that we will put this
// array back on the mutable list if it is subsequently thawed
// by unsafeThaw#.
p->mut_link = NULL;
if (failed_to_evac) {
failed_to_evac = rtsFalse;
......
/* -----------------------------------------------------------------------------
* $Id: PrimOps.hc,v 1.114 2003/10/01 10:57:41 wolfgang Exp $
* $Id: PrimOps.hc,v 1.115 2003/10/22 15:01:00 simonmar Exp $
*
* (c) The GHC Team, 1998-2002
*
......@@ -402,7 +402,22 @@ FN_(unsafeThawArrayzh_fast)
{
FB_
SET_INFO((StgClosure *)R1.cl,&stg_MUT_ARR_PTRS_info);
recordMutable((StgMutClosure*)R1.cl);
// SUBTLETY TO DO WITH THE OLD GEN MUTABLE LIST
//
// A MUT_ARR_PTRS lives on the mutable list, but a MUT_ARR_PTRS_FROZEN
// normally doesn't. However, when we freeze a MUT_ARR_PTRS, we leave
// it on the mutable list for the GC to remove (removing something from
// the mutable list is not easy, because the mut_list is only singly-linked).
//
// So, when we thaw a MUT_ARR_PTRS_FROZEN, we must cope with two cases:
// either it is on a mut_list, or it isn't. We adopt the convention that
// the mut_link field is NULL if it isn't on a mut_list, and the GC
// maintains this invariant.
//
if (((StgMutArrPtrs *)R1.cl)->mut_link == NULL) {
recordMutable((StgMutClosure*)R1.cl);
}
TICK_RET_UNBOXED_TUP(1);
RET_P(R1.p);
......
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