From: simonmar Date: Mon, 7 Nov 2005 14:43:34 +0000 (+0000) Subject: [project @ 2005-11-07 14:43:34 by simonmar] X-Git-Tag: Initial_conversion_from_CVS_complete~63 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=6470f502f738e3b7b1348089deb3a7fbec221f1e;p=ghc-hetmet.git [project @ 2005-11-07 14:43:34 by simonmar] Fix some problems with array thawing/freezing and the GC. --- diff --git a/ghc/rts/ClosureFlags.c b/ghc/rts/ClosureFlags.c index 8a3d97a..df9ef7b 100644 --- a/ghc/rts/ClosureFlags.c +++ b/ghc/rts/ClosureFlags.c @@ -78,7 +78,7 @@ StgWord16 closure_flags[] = { /* MVAR = */ (_HNF| _NS| _MUT|_UPT ), /* ARR_WORDS = */ (_HNF| _NS| _UPT ), /* MUT_ARR_PTRS = */ (_HNF| _NS| _MUT|_UPT ), -/* MUT_ARR_PTRS_FROZEN0 = */ (_HNF| _NS| _UPT ), +/* MUT_ARR_PTRS_FROZEN0 = */ (_HNF| _NS| _MUT|_UPT ), /* MUT_ARR_PTRS_FROZEN = */ (_HNF| _NS| _UPT ), /* MUT_VAR = */ (_HNF| _NS| _MUT|_UPT ), /* WEAK = */ (_HNF| _NS| _UPT ), diff --git a/ghc/rts/GC.c b/ghc/rts/GC.c index 9a21af8..0399d60 100644 --- a/ghc/rts/GC.c +++ b/ghc/rts/GC.c @@ -2953,10 +2953,14 @@ scavenge(step *stp) for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) { *p = (StgWord)(StgPtr)evacuate((StgClosure *)*p); } - // it's tempting to recordMutable() if failed_to_evac is - // 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). + + // If we're going to put this object on the mutable list, then + // set its info ptr to MUT_ARR_PTRS_FROZEN0 to indicate that. + if (failed_to_evac) { + ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN0_info; + } else { + ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN_info; + } break; } @@ -3307,12 +3311,20 @@ linear_scan: case MUT_ARR_PTRS_FROZEN0: // follow everything { - StgPtr next; + StgPtr next, q = p; next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p); for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) { *p = (StgWord)(StgPtr)evacuate((StgClosure *)*p); } + + // If we're going to put this object on the mutable list, then + // set its info ptr to MUT_ARR_PTRS_FROZEN0 to indicate that. + if (failed_to_evac) { + ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN0_info; + } else { + ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN_info; + } break; } @@ -3621,12 +3633,20 @@ scavenge_one(StgPtr p) case MUT_ARR_PTRS_FROZEN0: { // follow everything - StgPtr next; + StgPtr next, q=p; next = p + mut_arr_ptrs_sizeW((StgMutArrPtrs*)p); for (p = (P_)((StgMutArrPtrs *)p)->payload; p < next; p++) { *p = (StgWord)(StgPtr)evacuate((StgClosure *)*p); } + + // If we're going to put this object on the mutable list, then + // set its info ptr to MUT_ARR_PTRS_FROZEN0 to indicate that. + if (failed_to_evac) { + ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN0_info; + } else { + ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN_info; + } break; } diff --git a/ghc/rts/PrimOps.cmm b/ghc/rts/PrimOps.cmm index 1eaf727..630319f 100644 --- a/ghc/rts/PrimOps.cmm +++ b/ghc/rts/PrimOps.cmm @@ -126,21 +126,25 @@ unsafeThawArrayzh_fast // the mutable list is not easy, because the mut_list is only singly-linked). // // So that we can tell whether a MUT_ARR_PTRS_FROZEN is on the mutable list, - // when we freeze it we set the info ptr to be MUT_ARR_PTRS_FROZEN0 to indicate - // that it is still on the mutable list. - + // when we freeze it we set the info ptr to be MUT_ARR_PTRS_FROZEN0 + // to indicate that it is still on the mutable list. + // // 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 closure type is MUT_ARR_PTRS_FROZEN0 if it is on the mutable list, - // and MUT_ARR_PTRS_FROZEN otherwise. + // and MUT_ARR_PTRS_FROZEN otherwise. In fact it wouldn't matter if + // we put it on the mutable list more than once, but it would get scavenged + // multiple times during GC, which would be unnecessarily slow. // - if (%INFO_TYPE(%GET_STD_INFO(R1)) != HALF_W_(MUT_ARR_PTRS_FROZEN0)) { + if (StgHeader_info(R1) != stg_MUT_ARR_PTRS_FROZEN0_info) { + SET_INFO(R1,stg_MUT_ARR_PTRS_info); foreign "C" recordMutableLock(R1 "ptr") [R1]; + // must be done after SET_INFO, because it ASSERTs closure_MUTABLE() + RET_P(R1); + } else { + SET_INFO(R1,stg_MUT_ARR_PTRS_info); + RET_P(R1); } - - SET_INFO(R1,stg_MUT_ARR_PTRS_info); - - RET_P(R1); } /* -----------------------------------------------------------------------------