X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStorage.c;h=45d94aea01f38fd3c771f4748175b0f15bca1dce;hb=abde5fdfcaa5f363d9cf8cf0a10aa281c40887fe;hp=367530fcb6a0467b109b9e891b0cc49769e0196b;hpb=423d477bfecd490de1449c59325c8776f91d7aac;p=ghc-hetmet.git diff --git a/ghc/rts/Storage.c b/ghc/rts/Storage.c index 367530f..45d94ae 100644 --- a/ghc/rts/Storage.c +++ b/ghc/rts/Storage.c @@ -1,7 +1,6 @@ /* ----------------------------------------------------------------------------- - * $Id: Storage.c,v 1.84 2004/08/13 13:11:01 simonmar Exp $ * - * (c) The GHC Team, 1998-1999 + * (c) The GHC Team, 1998-2004 * * Storage manager front end * @@ -29,6 +28,8 @@ #include StgClosure *caf_list = NULL; +StgClosure *revertible_caf_list = NULL; +rtsBool keepCAFs; bdescr *small_alloc_list; /* allocate()d small objects */ bdescr *pinned_object_block; /* allocate pinned objects into this block */ @@ -88,7 +89,7 @@ initStorage( void ) if (RtsFlags.GcFlags.maxHeapSize != 0 && RtsFlags.GcFlags.minAllocAreaSize > RtsFlags.GcFlags.maxHeapSize) { - prog_belch("maximum heap size (-M) is smaller than minimum alloc area size (-A)"); + errorBelch("maximum heap size (-M) is smaller than minimum alloc area size (-A)"); exit(1); } @@ -107,8 +108,7 @@ initStorage( void ) for(g = 0; g < RtsFlags.GcFlags.generations; g++) { gen = &generations[g]; gen->no = g; - gen->mut_list = END_MUT_LIST; - gen->mut_once_list = END_MUT_LIST; + gen->mut_list = allocBlock(); gen->collections = 0; gen->failed_promotions = 0; gen->max_blocks = 0; @@ -177,7 +177,7 @@ initStorage( void ) /* The oldest generation has one step and it is compacted. */ if (RtsFlags.GcFlags.compact) { if (RtsFlags.GcFlags.generations == 1) { - belch("WARNING: compaction is incompatible with -G1; disabled"); + errorBelch("WARNING: compaction is incompatible with -G1; disabled"); } else { oldest_gen->steps[0].is_compacted = 1; } @@ -199,6 +199,7 @@ initStorage( void ) weak_ptr_list = NULL; caf_list = NULL; + revertible_caf_list = NULL; /* initialise the allocate() interface */ small_alloc_list = NULL; @@ -261,25 +262,43 @@ exitStorage (void) void newCAF(StgClosure* caf) { - /* Put this CAF on the mutable list for the old generation. - * This is a HACK - the IND_STATIC closure doesn't really have - * a mut_link field, but we pretend it has - in fact we re-use - * the STATIC_LINK field for the time being, because when we - * come to do a major GC we won't need the mut_link field - * any more and can use it as a STATIC_LINK. - */ ACQUIRE_SM_LOCK; - ((StgIndStatic *)caf)->saved_info = NULL; - ((StgMutClosure *)caf)->mut_link = oldest_gen->mut_once_list; - oldest_gen->mut_once_list = (StgMutClosure *)caf; - + if(keepCAFs) + { + // HACK: + // If we are in GHCi _and_ we are using dynamic libraries, + // then we can't redirect newCAF calls to newDynCAF (see below), + // so we make newCAF behave almost like newDynCAF. + // The dynamic libraries might be used by both the interpreted + // program and GHCi itself, so they must not be reverted. + // This also means that in GHCi with dynamic libraries, CAFs are not + // garbage collected. If this turns out to be a problem, we could + // do another hack here and do an address range test on caf to figure + // out whether it is from a dynamic library. + ((StgIndStatic *)caf)->saved_info = (StgInfoTable *)caf->header.info; + ((StgIndStatic *)caf)->static_link = caf_list; + caf_list = caf; + } + else + { + /* Put this CAF on the mutable list for the old generation. + * This is a HACK - the IND_STATIC closure doesn't really have + * a mut_link field, but we pretend it has - in fact we re-use + * the STATIC_LINK field for the time being, because when we + * come to do a major GC we won't need the mut_link field + * any more and can use it as a STATIC_LINK. + */ + ((StgIndStatic *)caf)->saved_info = NULL; + recordMutableGen(caf, oldest_gen); + } + RELEASE_SM_LOCK; #ifdef PAR /* If we are PAR or DIST then we never forget a CAF */ { globalAddr *newGA; - //belch("<##> Globalising CAF %08x %s",caf,info_type(caf)); + //debugBelch("<##> Globalising CAF %08x %s",caf,info_type(caf)); newGA=makeGlobal(caf,rtsTrue); /*given full weight*/ ASSERT(newGA); } @@ -290,6 +309,8 @@ newCAF(StgClosure* caf) // object code in GHCi. In this case we want to retain *all* CAFs in // the object code, because they might be demanded at any time from an // expression evaluated on the command line. +// Also, GHCi might want to revert CAFs, so we add these to the +// revertible_caf_list. // // The linker hackily arranges that references to newCaf from dynamic // code end up pointing to newDynCAF. @@ -299,8 +320,8 @@ newDynCAF(StgClosure *caf) ACQUIRE_SM_LOCK; ((StgIndStatic *)caf)->saved_info = (StgInfoTable *)caf->header.info; - ((StgIndStatic *)caf)->static_link = caf_list; - caf_list = caf; + ((StgIndStatic *)caf)->static_link = revertible_caf_list; + revertible_caf_list = caf; RELEASE_SM_LOCK; } @@ -418,7 +439,7 @@ resizeNursery ( nat blocks ) } else if (nursery_blocks < blocks) { - IF_DEBUG(gc, fprintf(stderr, "Increasing size of nursery to %d blocks\n", + IF_DEBUG(gc, debugBelch("Increasing size of nursery to %d blocks\n", blocks)); g0s0->blocks = allocNursery(g0s0->blocks, blocks-nursery_blocks); } @@ -426,7 +447,7 @@ resizeNursery ( nat blocks ) else { bdescr *next_bd; - IF_DEBUG(gc, fprintf(stderr, "Decreasing size of nursery to %d blocks\n", + IF_DEBUG(gc, debugBelch("Decreasing size of nursery to %d blocks\n", blocks)); bd = g0s0->blocks; @@ -792,25 +813,28 @@ memInventory(void) /* count the blocks we current have */ for (g = 0; g < RtsFlags.GcFlags.generations; g++) { - for (s = 0; s < generations[g].n_steps; s++) { - stp = &generations[g].steps[s]; - total_blocks += stp->n_blocks; - if (RtsFlags.GcFlags.generations == 1) { - /* two-space collector has a to-space too :-) */ - total_blocks += g0s0->n_to_blocks; + for (bd = generations[g].mut_list; bd != NULL; bd = bd->link) { + total_blocks += bd->blocks; } - for (bd = stp->large_objects; bd; bd = bd->link) { - total_blocks += bd->blocks; - /* hack for megablock groups: they have an extra block or two in - the second and subsequent megablocks where the block - descriptors would normally go. - */ - if (bd->blocks > BLOCKS_PER_MBLOCK) { - total_blocks -= (MBLOCK_SIZE / BLOCK_SIZE - BLOCKS_PER_MBLOCK) - * (bd->blocks/(MBLOCK_SIZE/BLOCK_SIZE)); - } + for (s = 0; s < generations[g].n_steps; s++) { + stp = &generations[g].steps[s]; + total_blocks += stp->n_blocks; + if (RtsFlags.GcFlags.generations == 1) { + /* two-space collector has a to-space too :-) */ + total_blocks += g0s0->n_to_blocks; + } + for (bd = stp->large_objects; bd; bd = bd->link) { + total_blocks += bd->blocks; + /* hack for megablock groups: they have an extra block or two in + the second and subsequent megablocks where the block + descriptors would normally go. + */ + if (bd->blocks > BLOCKS_PER_MBLOCK) { + total_blocks -= (MBLOCK_SIZE / BLOCK_SIZE - BLOCKS_PER_MBLOCK) + * (bd->blocks/(MBLOCK_SIZE/BLOCK_SIZE)); + } + } } - } } /* any blocks held by allocate() */ @@ -832,7 +856,7 @@ memInventory(void) if (total_blocks + free_blocks != mblocks_allocated * BLOCKS_PER_MBLOCK) { - fprintf(stderr, "Blocks: %ld live + %ld free = %ld total (%ld around)\n", + debugBelch("Blocks: %ld live + %ld free = %ld total (%ld around)\n", total_blocks, free_blocks, total_blocks + free_blocks, mblocks_allocated * BLOCKS_PER_MBLOCK); } @@ -873,7 +897,6 @@ checkSanity( void ) checkChain(generations[g].steps[s].large_objects); if (g > 0) { checkMutableList(generations[g].mut_list, g); - checkMutOnceList(generations[g].mut_once_list, g); } } }