/* -----------------------------------------------------------------------------
- * $Id: GCCompact.c,v 1.17 2003/10/22 11:11:59 simonmar Exp $
*
* (c) The GHC Team 2001
*
#include "MBlock.h"
#include "GCCompact.h"
#include "Schedule.h"
-#include "StablePriv.h"
#include "Apply.h"
// Turn off inlining when debugging - it obfuscates things
#ifdef DEBUG
-#define INLINE
-#else
-#define INLINE inline
+# undef STATIC_INLINE
+# define STATIC_INLINE static
#endif
/* -----------------------------------------------------------------------------
except for the info pointer.
-------------------------------------------------------------------------- */
-static INLINE void
+STATIC_INLINE void
thread( StgPtr p )
{
StgPtr q = (StgPtr)*p;
}
}
-static INLINE void
+STATIC_INLINE void
unthread( StgPtr p, StgPtr free )
{
- StgPtr q = (StgPtr)*p, r;
+ StgWord q = *p, r;
- while (((StgWord)q & 1) != 0) {
- (StgWord)q -= 1; // unset the low bit again
- r = (StgPtr)*q;
- *q = (StgWord)free;
+ while ((q & 1) != 0) {
+ q -= 1; // unset the low bit again
+ r = *((StgPtr)q);
+ *((StgPtr)q) = (StgWord)free;
q = r;
}
- *p = (StgWord)q;
+ *p = q;
}
-static INLINE StgInfoTable *
+STATIC_INLINE StgInfoTable *
get_threaded_info( StgPtr p )
{
StgPtr q = (P_)GET_INFO((StgClosure *)p);
// A word-aligned memmove will be faster for small objects than libc's or gcc's.
// Remember, the two regions *might* overlap, but: to <= from.
-static INLINE void
+STATIC_INLINE void
move(StgPtr to, StgPtr from, nat size)
{
for(; size > 0; --size) {
}
}
-static INLINE nat
+STATIC_INLINE nat
obj_sizeW( StgClosure *p, StgInfoTable *info )
{
switch (info->type) {
}
}
-static INLINE void
+STATIC_INLINE void
thread_large_bitmap( StgPtr p, StgLargeBitmap *large_bitmap, nat size )
{
nat i, b;
}
}
-static INLINE StgPtr
+STATIC_INLINE StgPtr
thread_arg_block (StgFunInfoTable *fun_info, StgClosure **args)
{
StgPtr p;
nat size;
p = (StgPtr)args;
- switch (fun_info->fun_type) {
+ switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->bitmap);
- size = BITMAP_SIZE(fun_info->bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.bitmap);
+ size = BITMAP_SIZE(fun_info->f.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
- size = ((StgLargeBitmap *)fun_info->bitmap)->size;
- thread_large_bitmap(p, (StgLargeBitmap *)fun_info->bitmap, size);
+ size = GET_FUN_LARGE_BITMAP(fun_info)->size;
+ thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
p += size;
break;
default:
- bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->fun_type]);
- size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->fun_type]);
+ bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
+ size = BITMAP_SIZE(stg_arg_bitmaps[fun_info->f.fun_type]);
small_bitmap:
while (size > 0) {
if ((bitmap & 1) == 0) {
dyn = ((StgRetDyn *)p)->liveness;
// traverse the bitmap first
- bitmap = GET_LIVENESS(dyn);
+ bitmap = RET_DYN_LIVENESS(dyn);
p = (P_)&((StgRetDyn *)p)->payload[0];
size = RET_DYN_BITMAP_SIZE;
while (size > 0) {
}
// skip over the non-ptr words
- p += GET_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
+ p += RET_DYN_NONPTRS(dyn) + RET_DYN_NONPTR_REGS_SIZE;
// follow the ptr words
- for (size = GET_PTRS(dyn); size > 0; size--) {
+ for (size = RET_DYN_PTRS(dyn); size > 0; size--) {
thread(p);
p++;
}
case RET_BIG:
case RET_VEC_BIG:
p++;
- size = info->i.layout.large_bitmap->size;
- thread_large_bitmap(p, info->i.layout.large_bitmap, size);
+ size = GET_LARGE_BITMAP(&info->i)->size;
+ thread_large_bitmap(p, GET_LARGE_BITMAP(&info->i), size);
p += size;
continue;
}
}
-static INLINE StgPtr
+STATIC_INLINE StgPtr
thread_PAP (StgPAP *pap)
{
StgPtr p;
p = (StgPtr)pap->payload;
size = pap->n_args;
- switch (fun_info->fun_type) {
+ switch (fun_info->f.fun_type) {
case ARG_GEN:
- bitmap = BITMAP_BITS(fun_info->bitmap);
+ bitmap = BITMAP_BITS(fun_info->f.bitmap);
goto small_bitmap;
case ARG_GEN_BIG:
- thread_large_bitmap(p, (StgLargeBitmap *)fun_info->bitmap, size);
+ thread_large_bitmap(p, GET_FUN_LARGE_BITMAP(fun_info), size);
p += size;
break;
case ARG_BCO:
p += size;
break;
default:
- bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->fun_type]);
+ bitmap = BITMAP_BITS(stg_arg_bitmaps[fun_info->f.fun_type]);
small_bitmap:
size = pap->n_args;
while (size > 0) {
return p;
}
-static INLINE StgPtr
+STATIC_INLINE StgPtr
thread_AP_STACK (StgAP_STACK *ap)
{
thread((StgPtr)&ap->fun);
}
}
-static INLINE StgPtr
+STATIC_INLINE StgPtr
thread_obj (StgInfoTable *info, StgPtr p)
{
switch (info->type) {
default:
barf("update_fwd: unknown/strange object %d", (int)(info->type));
+ return NULL;
}
}
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
for (s = 0; s < generations[g].n_steps; s++) {
stp = &generations[g].steps[s];
- IF_DEBUG(gc, fprintf(stderr,"update_fwd: %d.%d\n", stp->gen->no, stp->no););
+ IF_DEBUG(gc, debugBelch("update_fwd: %d.%d\n", stp->gen->no, stp->no););
update_fwd(stp->to_blocks);
update_fwd_large(stp->scavenged_large_objects);
if (g == RtsFlags.GcFlags.generations-1 && stp->blocks != NULL) {
- IF_DEBUG(gc, fprintf(stderr,"update_fwd: %d.%d (compact)\n", stp->gen->no, stp->no););
+ IF_DEBUG(gc, debugBelch("update_fwd: %d.%d (compact)\n", stp->gen->no, stp->no););
update_fwd_compact(stp->blocks);
}
}
stp = &oldest_gen->steps[0];
if (stp->blocks != NULL) {
blocks = update_bkwd_compact(stp);
- IF_DEBUG(gc, fprintf(stderr,"update_bkwd: %d.%d (compact, old: %d blocks, now %d blocks)\n",
+ IF_DEBUG(gc, debugBelch("update_bkwd: %d.%d (compact, old: %d blocks, now %d blocks)\n",
stp->gen->no, stp->no,
stp->n_blocks, blocks););
stp->n_blocks = blocks;