Back to index

plt-scheme  4.2.1
Defines | Functions | Variables
reclaim.c File Reference
#include <stdio.h>
#include "private/gc_priv.h"

Go to the source code of this file.

Defines

#define MAX_LEAKED   40
#define FOUND_FREE(hblk, word_no)
#define DONT_KNOW   2
#define FULL_THRESHOLD   (MARK_BITS_SZ/16)
#define INCR_WORDS(sz)
#define COUNT_PARAM
#define COUNT_ARG
#define COUNT_DECL
#define NWORDS_DECL
#define COUNT_UPDATE
#define MEM_FOUND_ADDR
#define DO_OBJ(start_displ)
#define DO_OBJ(start_displ)
#define DO_OBJ(start_displ)
#define DO_OBJ(start_displ)
#define DO_OBJ(start_displ)

Functions

void GC_add_leaked (ptr_t leaked)
void GC_print_all_errors ()
GC_bool GC_block_empty (hdr *hhdr)
GC_bool GC_block_nearly_full1 (hdr *hhdr, word pat1)
GC_bool GC_block_nearly_full3 (hdr *hhdr, word pat1, word pat2, word pat3)
GC_bool GC_block_nearly_full (hdr *hhdr)
ptr_t GC_reclaim_clear (hbp, hhdr, sz, list COUNT_PARAM) register struct hblk *hbp
NWORDS_DECL GC_ASSERT (hhdr==GC_find_header((ptr_t) hbp))
 while (p<=plim)
COUNT_UPDATE return (list)
ptr_t GC_reclaim_clear2 (hbp, hhdr, list COUNT_PARAM) register struct hblk *hbp
static int set_bits (word n)
int GC_n_set_marks (hdr *hhdr)
void GC_print_block_descr (struct hblk *h, word dummy)
void GC_print_block_list ()
void GC_clear_fl_links (ptr_t *flp)
void GC_start_reclaim (int report_if_found)
void GC_continue_reclaim (word sz, int kind)
GC_bool GC_reclaim_all (GC_stop_func stop_func, GC_bool ignore_old)

Variables

signed_word GC_mem_found = 0
ptr_t GC_leaked [MAX_LEAKED]
unsigned GC_n_leaked = 0
GC_bool GC_have_errors = FALSE
static GC_bool printing_errors = FALSE
register hdrhhdr
register ptr_t list
register word sz
COUNT_DECL register int word_no = 0
register wordp = (word *)(hbp->hb_body)
register wordq
register wordplim
GC_bool init
int report_if_found

Define Documentation

#define COUNT_ARG

Definition at line 298 of file reclaim.c.

#define COUNT_DECL

Definition at line 299 of file reclaim.c.

#define COUNT_PARAM

Definition at line 297 of file reclaim.c.

#define COUNT_UPDATE

Definition at line 301 of file reclaim.c.

#define DO_OBJ (   start_displ)
Value:
if (!(mark_word & ((word)1 << start_displ))) { \
           p[start_displ] = (word)list; \
           list = (ptr_t)(p+start_displ); \
           p[start_displ+1] = 0; \
           INCR_WORDS(2); \
       }
#define DO_OBJ (   start_displ)
Value:
if (!(mark_word & ((word)1 << start_displ))) { \
           p[start_displ] = (word)list; \
           list = (ptr_t)(p+start_displ); \
           p[start_displ+1] = 0; \
           CLEAR_DOUBLE(p + start_displ + 2); \
           INCR_WORDS(4); \
       }
#define DO_OBJ (   start_displ)
Value:
if (!(mark_word & ((word)1 << start_displ))) { \
           p[start_displ] = (word)list; \
           list = (ptr_t)(p+start_displ); \
           INCR_WORDS(2); \
       }
#define DO_OBJ (   start_displ)
Value:
if (!(mark_word & ((word)1 << start_displ))) { \
           p[start_displ] = (word)list; \
           list = (ptr_t)(p+start_displ); \
           INCR_WORDS(4); \
       }
#define DO_OBJ (   start_displ)
Value:
if (!(mark_word & ((word)1 << start_displ))) { \
           p[start_displ] = (word)list; \
           list = (ptr_t)(p+start_displ); \
           INCR_WORDS(1); \
       }
#define DONT_KNOW   2

Definition at line 115 of file reclaim.c.

#define FOUND_FREE (   hblk,
  word_no 
)
Value:
{ \
         GC_add_leaked((ptr_t)hblk + WORDS_TO_BYTES(word_no)); \
      }

Definition at line 82 of file reclaim.c.

#define FULL_THRESHOLD   (MARK_BITS_SZ/16)

Definition at line 165 of file reclaim.c.

#define INCR_WORDS (   sz)

Definition at line 296 of file reclaim.c.

#define MAX_LEAKED   40

Definition at line 33 of file reclaim.c.

#define MEM_FOUND_ADDR

Definition at line 302 of file reclaim.c.

#define NWORDS_DECL

Definition at line 300 of file reclaim.c.


Function Documentation

void GC_add_leaked ( ptr_t  leaked)

Definition at line 39 of file reclaim.c.

{
    if (GC_n_leaked < MAX_LEAKED) {
      GC_have_errors = TRUE;
      GC_leaked[GC_n_leaked++] = leaked;
      /* Make sure it's not reclaimed this cycle */
        GC_set_mark_bit(leaked);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

GC_bool GC_block_empty ( hdr hhdr)

Definition at line 99 of file reclaim.c.

{
    /* We treat hb_marks as an array of words here, even if it is     */
    /* actually an array of bytes.  Since we only check for zero, there      */
    /* are no endian-ness issues.                              */
    register word *p = (word *)(&(hhdr -> hb_marks[0]));
    register word * plim =
           (word *)(&(hhdr -> hb_marks[MARK_BITS_SZ]));
    while (p < plim) {
       if (*p++) return(FALSE);
    }
    return(TRUE);
}

Here is the caller graph for this function:

Definition at line 220 of file reclaim.c.

{
    int sz = hhdr -> hb_sz;

#   if CPP_WORDSZ != 32 && CPP_WORDSZ != 64
      return DONT_KNOW;     /* Shouldn't be used in any standard config.     */
#   endif
#   if CPP_WORDSZ == 32
      switch(sz) {
        case 1:
         return GC_block_nearly_full1(hhdr, 0xffffffffl);
       case 2:
         return GC_block_nearly_full1(hhdr, 0x55555555l);
       case 4:
         return GC_block_nearly_full1(hhdr, 0x11111111l);
       case 6:
         return GC_block_nearly_full3(hhdr, 0x41041041l,
                                         0x10410410l,
                                          0x04104104l);
       case 8:
         return GC_block_nearly_full1(hhdr, 0x01010101l);
       case 12:
         return GC_block_nearly_full3(hhdr, 0x01001001l,
                                         0x10010010l,
                                          0x00100100l);
       case 16:
         return GC_block_nearly_full1(hhdr, 0x00010001l);
       case 32:
         return GC_block_nearly_full1(hhdr, 0x00000001l);
       default:
         return DONT_KNOW;
      }
#   endif
#   if CPP_WORDSZ == 64
      switch(sz) {
        case 1:
         return GC_block_nearly_full1(hhdr, 0xffffffffffffffffl);
       case 2:
         return GC_block_nearly_full1(hhdr, 0x5555555555555555l);
       case 4:
         return GC_block_nearly_full1(hhdr, 0x1111111111111111l);
       case 6:
         return GC_block_nearly_full3(hhdr, 0x1041041041041041l,
                                          0x4104104104104104l,
                                            0x0410410410410410l);
       case 8:
         return GC_block_nearly_full1(hhdr, 0x0101010101010101l);
       case 12:
         return GC_block_nearly_full3(hhdr, 0x1001001001001001l,
                                          0x0100100100100100l,
                                            0x0010010010010010l);
       case 16:
         return GC_block_nearly_full1(hhdr, 0x0001000100010001l);
       case 32:
         return GC_block_nearly_full1(hhdr, 0x0000000100000001l);
       default:
         return DONT_KNOW;
      }
#   endif
}

Here is the call graph for this function:

GC_bool GC_block_nearly_full1 ( hdr hhdr,
word  pat1 
)

Definition at line 167 of file reclaim.c.

{
    unsigned i;
    unsigned misses = 0;
    GC_ASSERT((MARK_BITS_SZ & 1) == 0);
    for (i = 0; i < MARK_BITS_SZ; ++i) {
       if ((hhdr -> hb_marks[i] | ~pat1) != ONES) {
           if (++misses > FULL_THRESHOLD) return FALSE;
       }
    }
    return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GC_bool GC_block_nearly_full3 ( hdr hhdr,
word  pat1,
word  pat2,
word  pat3 
)

Definition at line 188 of file reclaim.c.

{
    unsigned i;
    unsigned misses = 0;

    if (MARK_BITS_SZ < 4) {
      return DONT_KNOW;
    }
    for (i = 0; i < MARK_BITS_SZ - 2; i += 3) {
       if ((hhdr -> hb_marks[i] | ~pat1) != ONES) {
           if (++misses > FULL_THRESHOLD) return FALSE;
       }
       if ((hhdr -> hb_marks[i+1] | ~pat2) != ONES) {
           if (++misses > FULL_THRESHOLD) return FALSE;
       }
       if ((hhdr -> hb_marks[i+2] | ~pat3) != ONES) {
           if (++misses > FULL_THRESHOLD) return FALSE;
       }
    }
    return TRUE;
}

Here is the caller graph for this function:

Definition at line 909 of file reclaim.c.

{
    ptr_t next = *flp;

    while (0 != next) {
       *flp = 0;
       flp = &(obj_link(next));
       next = *flp;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_continue_reclaim ( word  sz,
int  kind 
)

Definition at line 987 of file reclaim.c.

{
    register hdr * hhdr;
    register struct hblk * hbp;
    register struct obj_kind * ok = &(GC_obj_kinds[kind]);
    struct hblk ** rlh = ok -> ok_reclaim_list;
    ptr_t *flh = &(ok -> ok_freelist[sz]);
    
    if (rlh == 0) return;   /* No blocks of this kind.  */
    rlh += sz;
    while ((hbp = *rlh) != 0) {
        hhdr = HDR(hbp);
        *rlh = hhdr -> hb_next;
        GC_reclaim_small_nonempty_block(hbp, FALSE MEM_FOUND_ADDR);
        if (*flh != 0) break;
    }
}

Here is the caller graph for this function:

int GC_n_set_marks ( hdr hhdr)

Definition at line 849 of file reclaim.c.

{
    register int result = 0;
    register int i;
    
    for (i = 0; i < MARK_BITS_SZ; i++) {
        result += set_bits(hhdr -> hb_marks[i]);
    }
    return(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 53 of file reclaim.c.

{
    unsigned i;

    LOCK();
    if (printing_errors) {
       UNLOCK();
       return;
    }
    printing_errors = TRUE;
    UNLOCK();
    if (GC_debugging_started) GC_print_all_smashed();
    for (i = 0; i < GC_n_leaked; ++i) {
       ptr_t p = GC_leaked[i];
       if (HDR(p) -> hb_obj_kind == PTRFREE) {
           GC_err_printf0("Leaked atomic object at ");
       } else {
           GC_err_printf0("Leaked composite object at ");
       }
       GC_print_heap_obj(p);
       GC_err_printf0("\n");
       GC_free(p);
       GC_leaked[i] = 0;
    }
    GC_n_leaked = 0;
    printing_errors = FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_print_block_descr ( struct hblk h,
word  dummy 
)

Definition at line 867 of file reclaim.c.

{
    register hdr * hhdr = HDR(h);
    register size_t bytes = WORDS_TO_BYTES(hhdr -> hb_sz);
    struct Print_stats *ps;
    
    GC_printf3("(%lu:%lu,%lu)", (unsigned long)(hhdr -> hb_obj_kind),
                             (unsigned long)bytes,
                             (unsigned long)(GC_n_set_marks(hhdr)));
    bytes += HBLKSIZE-1;
    bytes &= ~(HBLKSIZE-1);

    ps = (struct Print_stats *)dummy;
    ps->total_bytes += bytes;
    ps->number_of_blocks++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 887 of file reclaim.c.

{
    struct Print_stats pstats;

    GC_printf1("(kind(0=ptrfree,1=normal,2=unc.,%lu=stubborn):size_in_bytes, #_marks_set)\n", STUBBORN);
    pstats.number_of_blocks = 0;
    pstats.total_bytes = 0;
    GC_apply_to_all_blocks(GC_print_block_descr, (word)&pstats);
    GC_printf2("\nblocks = %lu, bytes = %lu\n",
              (unsigned long)pstats.number_of_blocks,
              (unsigned long)pstats.total_bytes);
}

Here is the call graph for this function:

Here is the caller graph for this function:

GC_bool GC_reclaim_all ( GC_stop_func  stop_func,
GC_bool  ignore_old 
)

Definition at line 1016 of file reclaim.c.

{
    register word sz;
    register int kind;
    register hdr * hhdr;
    register struct hblk * hbp;
    register struct obj_kind * ok;
    struct hblk ** rlp;
    struct hblk ** rlh;
#   ifdef PRINTTIMES
       CLOCK_TYPE start_time;
       CLOCK_TYPE done_time;
       
       GET_TIME(start_time);
#   endif
    
    for (kind = 0; kind < GC_n_kinds; kind++) {
       ok = &(GC_obj_kinds[kind]);
       rlp = ok -> ok_reclaim_list;
       if (rlp == 0) continue;
       for (sz = 1; sz <= MAXOBJSZ; sz++) {
           rlh = rlp + sz;
           while ((hbp = *rlh) != 0) {
               if (stop_func != (GC_stop_func)0 && (*stop_func)()) {
                   return(FALSE);
               }
              hhdr = HDR(hbp);
              *rlh = hhdr -> hb_next;
              if (!ignore_old || hhdr -> hb_last_reclaimed == GC_gc_no - 1) {
                  /* It's likely we'll need it this time, too  */
                  /* It's been touched recently, so this       */
                  /* shouldn't trigger paging.          */
                  GC_reclaim_small_nonempty_block(hbp, FALSE MEM_FOUND_ADDR);
              }
            }
        }
    }
#   ifdef PRINTTIMES
       GET_TIME(done_time);
       GC_printf1("Disposing of reclaim lists took %lu msecs\n",
                  MS_TIME_DIFF(done_time,start_time));
#   endif
    return(TRUE);
}

Here is the caller graph for this function:

ptr_t GC_reclaim_clear ( hbp  ,
hhdr  ,
sz  ,
list  COUNT_PARAM 
)
ptr_t GC_reclaim_clear2 ( hbp  ,
hhdr  ,
list  COUNT_PARAM 
)
void GC_start_reclaim ( int  report_if_found)

Definition at line 925 of file reclaim.c.

{
    int kind;
    
#   if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
      GC_ASSERT(0 == GC_fl_builder_count);
#   endif
    /* Clear reclaim- and free-lists */
      for (kind = 0; kind < GC_n_kinds; kind++) {
        ptr_t *fop;
        ptr_t *lim;
        struct hblk ** rlp;
        struct hblk ** rlim;
        struct hblk ** rlist = GC_obj_kinds[kind].ok_reclaim_list;
       GC_bool should_clobber = (GC_obj_kinds[kind].ok_descriptor != 0);
        
        if (rlist == 0) continue;  /* This kind not used.      */
        if (!report_if_found) {
            lim = &(GC_obj_kinds[kind].ok_freelist[MAXOBJSZ+1]);
           for( fop = GC_obj_kinds[kind].ok_freelist; fop < lim; fop++ ) {
             if (*fop != 0) {
              if (should_clobber) {
                GC_clear_fl_links(fop);
              } else {
                 *fop = 0;
              }
             }
           }
       } /* otherwise free list objects are marked,     */
         /* and its safe to leave them                  */
       rlim = rlist + MAXOBJSZ+1;
       for( rlp = rlist; rlp < rlim; rlp++ ) {
           *rlp = 0;
       }
      }
    
#   ifdef PRINTBLOCKS
        GC_printf0("GC_reclaim: current block sizes:\n");
        GC_print_block_list();
#   endif

  /* Go through all heap blocks (in hblklist) and reclaim unmarked objects */
  /* or enqueue the block for later processing.                          */
    GC_apply_to_all_blocks(GC_reclaim_block, (word)report_if_found);

# ifdef EAGER_SWEEP
    /* This is a very stupid thing to do.  We make it possible anyway,       */
    /* so that you can convince yourself that it really is very stupid.      */
    GC_reclaim_all((GC_stop_func)0, FALSE);
# endif
# if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
    GC_ASSERT(0 == GC_fl_builder_count);
# endif
    
}

Here is the call graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

static int set_bits ( word  n) [static]

Definition at line 835 of file reclaim.c.

{
    register word m = n;
    register int result = 0;
    
    while (m > 0) {
       if (m & 1) result++;
       m >>= 1;
    }
    return(result);
}

Here is the caller graph for this function:

while ( p<=  plim)

Definition at line 328 of file reclaim.c.

                           {
           if( mark_bit_from_hdr(hhdr, word_no) ) {
              p += sz;
           } else {
              INCR_WORDS(sz);
              /* object is available - put on list */
                  obj_link(p) = list;
                  list = ((ptr_t)p);
              /* Clear object, advance p to next object in the process */
                  q = p + sz;
#                 ifdef USE_MARK_BYTES
                    GC_ASSERT(!(sz & 1)
                            && !((word)p & (2 * sizeof(word) - 1)));
                    p[1] = 0;
                      p += 2;
                      while (p < q) {
                     CLEAR_DOUBLE(p);
                     p += 2;
                    }
#                 else
                      p++; /* Skip link field */
                      while (p < q) {
                     *p++ = 0;
                    }
#                 endif
           }
           word_no += sz;
       }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 37 of file reclaim.c.

Definition at line 34 of file reclaim.c.

Definition at line 20 of file reclaim.c.

unsigned GC_n_leaked = 0

Definition at line 35 of file reclaim.c.

hdr * hhdr

Definition at line 312 of file reclaim.c.

Definition at line 664 of file reclaim.c.

Definition at line 313 of file reclaim.c.

p = (word *)(hbp->hb_body)

Definition at line 318 of file reclaim.c.

Initial value:
 (word *)((((word)hbp) + HBLKSIZE)
                 - WORDS_TO_BYTES(sz))

Definition at line 318 of file reclaim.c.

Definition at line 50 of file reclaim.c.

register word * q

Definition at line 318 of file reclaim.c.

Definition at line 722 of file reclaim.c.

Definition at line 314 of file reclaim.c.

word_no = 0

Definition at line 317 of file reclaim.c.