Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
mark.c File Reference
#include <stdio.h>
#include "gc_priv.h"
#include "gc_mark.h"

Go to the source code of this file.

Defines

#define INITIAL_MARK_STACK_SIZE   (1*HBLKSIZE)
#define PROF(n)
#define source   0
#define SPLIT_RANGE_WORDS   128 /* Must be power of 2. */
#define BASE(p)   (word)GC_base((char *)(p))
#define source   0
#define GC_greatest_plausible_heap_addr   greatest_ha
#define GC_least_plausible_heap_addr   least_ha
#define GC_greatest_plausible_heap_addr   greatest_ha
#define GC_least_plausible_heap_addr   least_ha

Functions

void GC_noop ()
void GC_noop1 (word x)
GC_bool GC_collection_in_progress ()
void GC_clear_hdr_marks (hdr *hhdr)
void GC_set_hdr_marks (hdr *hhdr)
static void clear_marks_for_block (struct hblk *h, word dummy)
void GC_set_mark_bit (ptr_t p)
void GC_clear_mark_bit (ptr_t p)
GC_bool GC_is_marked (ptr_t p)
void GC_clear_marks ()
void GC_initiate_gc ()
static void alloc_mark_stack ()
GC_bool GC_mark_some (ptr_t cold_gc_frame)
GC_bool GC_mark_stack_empty ()
word GC_find_start (word current, hdr *hhdr)
void GC_invalidate_mark_state ()
mseGC_signal_mark_stack_overflow (mse *msp)
void GC_mark_from_mark_stack ()
static void alloc_mark_stack (word n)
void GC_mark_init ()
void GC_push_all (ptr_t bottom, ptr_t top)
void GC_push_dirty (ptr_t bottom, ptr_t top, int(*dirty_fn)(), void(*push_fn)())
void GC_push_conditional (ptr_t bottom, ptr_t top, int all)
void GC_push_one (word p)
void GC_push_one_checked (word p, GC_bool interior_ptrs)
void GC_push_all_eager (ptr_t bottom, ptr_t top)
void GC_push_all_stack_partially_eager (ptr_t bottom, ptr_t top, ptr_t cold_gc_frame)
void GC_push_all_stack (ptr_t bottom, ptr_t top)
void GC_push_marked1 (struct hblk *h, hdr *hhdr)
void GC_push_marked (struct hblk *h, hdr *hhdr)
GC_bool GC_block_was_dirty (struct hblk *h, hdr *hhdr)
struct hblkGC_push_next_marked (struct hblk *h)
struct hblkGC_push_next_marked_dirty (struct hblk *h)
struct hblkGC_push_next_marked_uncollectable (struct hblk *h)

Variables

word GC_n_mark_procs = 0
int GC_n_kinds = 4
word GC_n_rescuing_pages
mseGC_mark_stack
word GC_mark_stack_size = 0
mseGC_mark_stack_top
static struct hblkscan_ptr
mark_state_t GC_mark_state = MS_NONE
GC_bool GC_mark_stack_too_small = FALSE
GC_bool GC_objects_are_marked = FALSE

Define Documentation

#define BASE (   p)    (word)GC_base((char *)(p))

Definition at line 680 of file mark.c.

Definition at line 87 of file mark.c.

#define PROF (   n)

Definition at line 348 of file mark.c.

#define source   0
#define source   0
#define SPLIT_RANGE_WORDS   128 /* Must be power of 2. */

Function Documentation

static void alloc_mark_stack ( ) [static]

Here is the caller graph for this function:

static void alloc_mark_stack ( word  n) [static]

Definition at line 515 of file mark.c.

{
    mse * new_stack = (mse *)GC_scratch_alloc(n * sizeof(struct ms_entry));
    
    GC_mark_stack_too_small = FALSE;
    if (GC_mark_stack_size != 0) {
        if (new_stack != 0) {
          word displ = (word)GC_mark_stack & (GC_page_size - 1);
          signed_word size = GC_mark_stack_size * sizeof(struct ms_entry);
          
          /* Recycle old space */
             if (0 != displ) displ = GC_page_size - displ;
             size = (size - displ) & ~(GC_page_size - 1);
             if (size > 0) {
               GC_add_to_heap((struct hblk *)
                            ((word)GC_mark_stack + displ), (word)size);
             }
          GC_mark_stack = new_stack;
          GC_mark_stack_size = n;
#        ifdef PRINTSTATS
             GC_printf1("Grew mark stack to %lu frames\n",
                      (unsigned long) GC_mark_stack_size);
#        endif
        } else {
#        ifdef PRINTSTATS
             GC_printf1("Failed to grow mark stack to %lu frames\n",
                      (unsigned long) n);
#        endif
        }
    } else {
        if (new_stack == 0) {
            GC_err_printf0("No space for mark stack\n");
            EXIT();
        }
        GC_mark_stack = new_stack;
        GC_mark_stack_size = n;
    }
    GC_mark_stack_top = GC_mark_stack-1;
}

Here is the call graph for this function:

static void clear_marks_for_block ( struct hblk h,
word  dummy 
) [static]

Definition at line 146 of file mark.c.

{
    register hdr * hhdr = HDR(h);
    
    if (IS_UNCOLLECTABLE(hhdr -> hb_obj_kind)) return;
        /* Mark bit for these is cleared only once the object is      */
        /* explicitly deallocated.  This either frees the block, or   */
        /* the bit is cleared once the object is on the free list.    */
    GC_clear_hdr_marks(hhdr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

GC_bool GC_block_was_dirty ( struct hblk h,
hdr hhdr 
)

Definition at line 1078 of file mark.c.

{
    register int sz = hhdr -> hb_sz;
    
    if (sz < MAXOBJSZ) {
         return(GC_page_was_dirty(h));
    } else {
        register ptr_t p = (ptr_t)h;
         sz += HDR_WORDS;
         sz = WORDS_TO_BYTES(sz);
         while (p < (ptr_t)h + sz) {
             if (GC_page_was_dirty((struct hblk *)p)) return(TRUE);
             p += HBLKSIZE;
         }
         return(FALSE);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 125 of file mark.c.

{
    BZERO(hhdr -> hb_marks, MARK_BITS_SZ*sizeof(word));
}

Definition at line 170 of file mark.c.

{
    register struct hblk *h = HBLKPTR(p);
    register hdr * hhdr = HDR(h);
    register int word_no = (word *)p - (word *)h;
    
    clear_mark_bit_from_hdr(hhdr, word_no);
}

Definition at line 196 of file mark.c.

{
    GC_apply_to_all_blocks(clear_marks_for_block, (word)0);
    GC_objects_are_marked = FALSE;
    GC_mark_state = MS_INVALID;
    scan_ptr = 0;
#   ifdef GATHERSTATS
       /* Counters reflect currently marked objects: reset here */
        GC_composite_in_use = 0;
        GC_atomic_in_use = 0;
#   endif

}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 119 of file mark.c.

{
    return(GC_mark_state != MS_NONE);
}

Here is the caller graph for this function:

word GC_find_start ( word  current,
hdr hhdr 
)

Definition at line 362 of file mark.c.

{
#   ifdef ALL_INTERIOR_POINTERS
       if (hhdr != 0) {
           register word orig = current;
           
           current = (word)HBLKPTR(current) + HDR_BYTES;
           do {
             current = current - HBLKSIZE*(word)hhdr;
             hhdr = HDR(current);
           } while(IS_FORWARDING_ADDR_OR_NIL(hhdr));
           /* current points to the start of the large object */
           if (hhdr -> hb_flags & IGNORE_OFF_PAGE) return(0);
           if ((word *)orig - (word *)current
                >= (ptrdiff_t)(hhdr->hb_sz)) {
               /* Pointer past the end of the block */
               GC_ADD_TO_BLACK_LIST_NORMAL(orig, source);
               return(0);
           }
           return(current);
       } else {
           GC_ADD_TO_BLACK_LIST_NORMAL(current, source);
           return(0);
        }
#   else
        GC_ADD_TO_BLACK_LIST_NORMAL(current, source);
        return(0);
#   endif
#   undef source
}

Definition at line 213 of file mark.c.

{
    if (GC_dirty_maintained) GC_read_dirty();
#   ifdef STUBBORN_ALLOC
       GC_read_changed();
#   endif
#   ifdef CHECKSUMS
       {
           extern void GC_check_dirty();
           
           if (GC_dirty_maintained) GC_check_dirty();
       }
#   endif
#   ifdef GATHERSTATS
       GC_n_rescuing_pages = 0;
#   endif
    if (GC_mark_state == MS_NONE) {
        GC_mark_state = MS_PUSH_RESCUERS;
    } else if (GC_mark_state != MS_INVALID) {
       ABORT("unexpected state");
    } /* else this is really a full collection, and mark       */
      /* bits are invalid.                              */
    scan_ptr = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 397 of file mark.c.

Here is the caller graph for this function:

Definition at line 180 of file mark.c.

{
    register struct hblk *h = HBLKPTR(p);
    register hdr * hhdr = HDR(h);
    register int word_no = (word *)p - (word *)h;
    
    return(mark_bit_from_hdr(hhdr, word_no));
}

Definition at line 424 of file mark.c.

{
  mse * GC_mark_stack_reg = GC_mark_stack;
  mse * GC_mark_stack_top_reg = GC_mark_stack_top;
  mse * mark_stack_limit = &(GC_mark_stack[GC_mark_stack_size]);
  int credit = HBLKSIZE;    /* Remaining credit for marking work      */
  register word * current_p;       /* Pointer to current candidate ptr.      */
  register word current;    /* Candidate pointer.                     */
  register word * limit;    /* (Incl) limit of current candidate      */
                            /* range                           */
  register word descr;
  register ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
  register ptr_t least_ha = GC_least_plausible_heap_addr;
# define SPLIT_RANGE_WORDS 128  /* Must be power of 2.         */

  GC_objects_are_marked = TRUE;
# if defined(OS2) /* Use untweaked version to circumvent compiler problem */
  while (GC_mark_stack_top_reg >= GC_mark_stack_reg && credit >= 0) {
# else
  while ((((ptr_t)GC_mark_stack_top_reg - (ptr_t)GC_mark_stack_reg) | credit)
       >= 0) {
# endif
    current_p = GC_mark_stack_top_reg -> mse_start;
  retry:
    descr = GC_mark_stack_top_reg -> mse_descr;
    if (descr & ((~(WORDS_TO_BYTES(SPLIT_RANGE_WORDS) - 1)) | DS_TAGS)) {
      word tag = descr & DS_TAGS;
      
      switch(tag) {
        case DS_LENGTH:
          /* Large length.                                      */
          /* Process part of the range to avoid pushing too much on the      */
          /* stack.                                            */
          GC_mark_stack_top_reg -> mse_start =
              limit = current_p + SPLIT_RANGE_WORDS-1;
          GC_mark_stack_top_reg -> mse_descr -=
                     WORDS_TO_BYTES(SPLIT_RANGE_WORDS-1);
          /* Make sure that pointers overlapping the two ranges are   */
          /* considered.                                       */
          limit = (word *)((char *)limit + sizeof(word) - ALIGNMENT);
          break;
        case DS_BITMAP:
          GC_mark_stack_top_reg--;
          descr &= ~DS_TAGS;
          credit -= WORDS_TO_BYTES(WORDSZ/2); /* guess */
          while (descr != 0) {
            if ((signed_word)descr < 0) {
              current = *current_p;
             if ((ptr_t)current >= least_ha && (ptr_t)current < greatest_ha) {
                PUSH_CONTENTS(current, GC_mark_stack_top_reg, mark_stack_limit,
                           current_p, exit1);
             }
            }
           descr <<= 1;
           ++ current_p;
          }
          continue;
        case DS_PROC:
          GC_mark_stack_top_reg--;
          credit -= PROC_BYTES;
          GC_mark_stack_top_reg =
              (*PROC(descr))
                         (current_p, GC_mark_stack_top_reg,
                         mark_stack_limit, ENV(descr));
          continue;
        case DS_PER_OBJECT:
          GC_mark_stack_top_reg -> mse_descr =
                     *(word *)((ptr_t)current_p + descr - tag);
          goto retry;
      }
    } else {
      GC_mark_stack_top_reg--;
      limit = (word *)(((ptr_t)current_p) + (word)descr);
    }
    /* The simple case in which we're scanning a range. */
    credit -= (ptr_t)limit - (ptr_t)current_p;
    limit -= 1;
    while (current_p <= limit) {
      current = *current_p;
      if ((ptr_t)current >= least_ha && (ptr_t)current <  greatest_ha) {
        PUSH_CONTENTS(current, GC_mark_stack_top_reg,
                    mark_stack_limit, current_p, exit2);
      }
      current_p = (word *)((char *)current_p + ALIGNMENT);
    }
  }
  GC_mark_stack_top = GC_mark_stack_top_reg;
}

Here is the caller graph for this function:

Definition at line 556 of file mark.c.

Here is the call graph for this function:

Here is the caller graph for this function:

GC_bool GC_mark_some ( ptr_t  cold_gc_frame)

Definition at line 248 of file mark.c.

{
    switch(GC_mark_state) {
       case MS_NONE:
           return(FALSE);
           
       case MS_PUSH_RESCUERS:
           if (GC_mark_stack_top
               >= GC_mark_stack + INITIAL_MARK_STACK_SIZE/4) {
               GC_mark_from_mark_stack();
               return(FALSE);
           } else {
               scan_ptr = GC_push_next_marked_dirty(scan_ptr);
               if (scan_ptr == 0) {
#                 ifdef PRINTSTATS
                     GC_printf1("Marked from %lu dirty pages\n",
                               (unsigned long)GC_n_rescuing_pages);
#                 endif
                  GC_push_roots(FALSE, cold_gc_frame);
                  GC_objects_are_marked = TRUE;
                  if (GC_mark_state != MS_INVALID) {
                      GC_mark_state = MS_ROOTS_PUSHED;
                  }
              }
           }
           return(FALSE);
       
       case MS_PUSH_UNCOLLECTABLE:
           if (GC_mark_stack_top
               >= GC_mark_stack + INITIAL_MARK_STACK_SIZE/4) {
               GC_mark_from_mark_stack();
               return(FALSE);
           } else {
               scan_ptr = GC_push_next_marked_uncollectable(scan_ptr);
               if (scan_ptr == 0) {
                  GC_push_roots(TRUE, cold_gc_frame);
                  GC_objects_are_marked = TRUE;
                  if (GC_mark_state != MS_INVALID) {
                      GC_mark_state = MS_ROOTS_PUSHED;
                  }
              }
           }
           return(FALSE);
       
       case MS_ROOTS_PUSHED:
           if (GC_mark_stack_top >= GC_mark_stack) {
               GC_mark_from_mark_stack();
               return(FALSE);
           } else {
               GC_mark_state = MS_NONE;
               if (GC_mark_stack_too_small) {
                   alloc_mark_stack(2*GC_mark_stack_size);
               }
               return(TRUE);
           }
           
       case MS_INVALID:
       case MS_PARTIALLY_INVALID:
           if (!GC_objects_are_marked) {
              GC_mark_state = MS_PUSH_UNCOLLECTABLE;
              return(FALSE);
           }
           if (GC_mark_stack_top >= GC_mark_stack) {
               GC_mark_from_mark_stack();
               return(FALSE);
           }
           if (scan_ptr == 0 && GC_mark_state == MS_INVALID) {
              /* About to start a heap scan for marked objects. */
              /* Mark stack is empty.  OK to reallocate.         */
              if (GC_mark_stack_too_small) {
                   alloc_mark_stack(2*GC_mark_stack_size);
              }
              GC_mark_state = MS_PARTIALLY_INVALID;
           }
           scan_ptr = GC_push_next_marked(scan_ptr);
           if (scan_ptr == 0 && GC_mark_state == MS_PARTIALLY_INVALID) {
              GC_push_roots(TRUE, cold_gc_frame);
              GC_objects_are_marked = TRUE;
              if (GC_mark_state != MS_INVALID) {
                  GC_mark_state = MS_ROOTS_PUSHED;
              }
           }
           return(FALSE);
       default:
           ABORT("GC_mark_some: bad state");
           return(FALSE);
    }
}

Here is the call graph for this function:

Definition at line 339 of file mark.c.

Definition at line 27 of file mark.c.

{}

Here is the caller graph for this function:

void GC_noop1 ( word  x)

Definition at line 31 of file mark.c.

{
    static VOLATILE word sink;

    sink = x;
}
void GC_push_all ( ptr_t  bottom,
ptr_t  top 
)

Definition at line 568 of file mark.c.

{
    register word length;
    
    bottom = (ptr_t)(((word) bottom + ALIGNMENT-1) & ~(ALIGNMENT-1));
    top = (ptr_t)(((word) top) & ~(ALIGNMENT-1));
    if (top == 0 || bottom == top) return;
    GC_mark_stack_top++;
    if (GC_mark_stack_top >= GC_mark_stack + GC_mark_stack_size) {
       ABORT("unexpected mark stack overflow");
    }
    length = top - bottom;
#   if DS_TAGS > ALIGNMENT - 1
       length += DS_TAGS;
       length &= ~DS_TAGS;
#   endif
    GC_mark_stack_top -> mse_start = (word *)bottom;
    GC_mark_stack_top -> mse_descr = length;
}
void GC_push_all_eager ( ptr_t  bottom,
ptr_t  top 
)

Definition at line 803 of file mark.c.

{
    word * b = (word *)(((long) bottom + ALIGNMENT-1) & ~(ALIGNMENT-1));
    word * t = (word *)(((long) top) & ~(ALIGNMENT-1));
    register word *p;
    register word q;
    register word *lim;
    register ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
    register ptr_t least_ha = GC_least_plausible_heap_addr;
#   define GC_greatest_plausible_heap_addr greatest_ha
#   define GC_least_plausible_heap_addr least_ha

    if (top == 0) return;
    /* check all pointers in range and put in push if they appear */
    /* to be valid.                                       */
      lim = t - 1 /* longword */;
      for (p = b; p <= lim; p = (word *)(((char *)p) + ALIGNMENT)) {
       q = *p;
       GC_PUSH_ONE_STACK(q, p);
      }
#   undef GC_greatest_plausible_heap_addr
#   undef GC_least_plausible_heap_addr
}
void GC_push_all_stack ( ptr_t  bottom,
ptr_t  top 
)

Definition at line 867 of file mark.c.

{
# ifdef ALL_INTERIOR_POINTERS
    GC_push_all(bottom, top);
# else
    GC_push_all_eager(bottom, top);
# endif
}

Here is the call graph for this function:

void GC_push_all_stack_partially_eager ( ptr_t  bottom,
ptr_t  top,
ptr_t  cold_gc_frame 
)

Definition at line 837 of file mark.c.

{
# ifdef ALL_INTERIOR_POINTERS
#   define EAGER_BYTES 1024
    /* Push the hot end of the stack eagerly, so that register values   */
    /* saved inside GC frames are marked before they disappear.              */
    /* The rest of the marking can be deferred until later.           */
    if (0 == cold_gc_frame) {
       GC_push_all_stack(bottom, top);
       return;
    }
#   ifdef STACK_GROWS_DOWN
       GC_push_all_eager(bottom, cold_gc_frame);
       GC_push_all(cold_gc_frame - sizeof(ptr_t), top);
#   else /* STACK_GROWS_UP */
       GC_push_all_eager(cold_gc_frame, top);
       GC_push_all(bottom, cold_gc_frame + sizeof(ptr_t));
#   endif /* STACK_GROWS_UP */
# else
    GC_push_all_eager(bottom, top);
# endif
# ifdef TRACE_BUF
      GC_add_trace_entry("GC_push_all_stack", bottom, top);
# endif
}

Here is the call graph for this function:

void GC_push_conditional ( ptr_t  bottom,
ptr_t  top,
int  all 
)

Definition at line 645 of file mark.c.

{
    if (all) {
      if (GC_dirty_maintained) {
#      ifdef PROC_VDB
           /* Pages that were never dirtied cannot contain pointers   */
           GC_push_dirty(bottom, top, GC_page_was_ever_dirty, GC_push_all);
#      else
           GC_push_all(bottom, top);
#      endif
      } else {
       GC_push_all(bottom, top);
      }
    } else {
       GC_push_dirty(bottom, top, GC_page_was_dirty, GC_push_all);
    }
}

Here is the call graph for this function:

void GC_push_dirty ( ptr_t  bottom,
ptr_t  top,
int (*)()  dirty_fn,
void (*)()  push_fn 
)

Definition at line 599 of file mark.c.

{
    register struct hblk * h;

    bottom = (ptr_t)(((long) bottom + ALIGNMENT-1) & ~(ALIGNMENT-1));
    top = (ptr_t)(((long) top) & ~(ALIGNMENT-1));

    if (top == 0 || bottom == top) return;
    h = HBLKPTR(bottom + HBLKSIZE);
    if (top <= (ptr_t) h) {
       if ((*dirty_fn)(h-1)) {
           (*push_fn)(bottom, top);
       }
       return;
    }
    if ((*dirty_fn)(h-1)) {
        (*push_fn)(bottom, (ptr_t)h);
    }
    while ((ptr_t)(h+1) <= top) {
       if ((*dirty_fn)(h)) {
           if ((word)(GC_mark_stack_top - GC_mark_stack)
              > 3 * GC_mark_stack_size / 4) {
              /* Danger of mark stack overflow */
              (*push_fn)((ptr_t)h, top);
              return;
           } else {
              (*push_fn)((ptr_t)h, (ptr_t)(h+1));
           }
       }
       h++;
    }
    if ((ptr_t)h != top) {
       if ((*dirty_fn)(h)) {
            (*push_fn)((ptr_t)h, top);
        }
    }
    if (GC_mark_stack_top >= GC_mark_stack + GC_mark_stack_size) {
        ABORT("unexpected mark stack overflow");
    }
}
void GC_push_marked ( struct hblk h,
hdr hhdr 
)

Definition at line 1011 of file mark.c.

{
    register int sz = hhdr -> hb_sz;
    register word * p;
    register int word_no;
    register word * lim;
    register mse * GC_mark_stack_top_reg;
    register mse * mark_stack_limit = &(GC_mark_stack[GC_mark_stack_size]);
    
    /* Some quick shortcuts: */
       { 
           struct obj_kind *ok = &(GC_obj_kinds[hhdr -> hb_obj_kind]);
           if ((0 | DS_LENGTH) == ok -> ok_descriptor
              && FALSE == ok -> ok_relocate_descr)
              return;
       }
        if (GC_block_empty(hhdr)/* nothing marked */) return;
#   ifdef GATHERSTATS
        GC_n_rescuing_pages++;
#   endif
    GC_objects_are_marked = TRUE;
    if (sz > MAXOBJSZ) {
        lim = (word *)(h + 1);
    } else {
        lim = (word *)(h + 1) - sz;
    }
    
    switch(sz) {
#   if !defined(SMALL_CONFIG)    
     case 1:
       GC_push_marked1(h, hhdr);
       break;
#   endif
#   if !defined(SMALL_CONFIG) && !defined(UNALIGNED)
     case 2:
       GC_push_marked2(h, hhdr);
       break;
     case 4:
       GC_push_marked4(h, hhdr);
       break;
#   endif       
     default:
      GC_mark_stack_top_reg = GC_mark_stack_top;
      for (p = (word *)h + HDR_WORDS, word_no = HDR_WORDS; p <= lim;
         p += sz, word_no += sz) {
         /* This ignores user specified mark procs.  This currently   */
         /* doesn't matter, since marking from the whole object              */
         /* is always sufficient, and we will eventually use the user */
         /* mark proc to avoid any bogus pointers.                    */
         if (mark_bit_from_hdr(hhdr, word_no)) {
           /* Mark from fields inside the object */
             PUSH_OBJ((word *)p, hhdr, GC_mark_stack_top_reg, mark_stack_limit);
#           ifdef GATHERSTATS
              /* Subtract this object from total, since it was */
              /* added in twice.                               */
              GC_composite_in_use -= sz;
#           endif
         }
      }
      GC_mark_stack_top = GC_mark_stack_top_reg;
    }
}

Here is the call graph for this function:

void GC_push_marked1 ( struct hblk h,
hdr hhdr 
)

Definition at line 881 of file mark.c.

{
    word * mark_word_addr = &(hhdr->hb_marks[divWORDSZ(HDR_WORDS)]);
    register word *p;
    word *plim;
    register int i;
    register word q;
    register word mark_word;
    register ptr_t greatest_ha = GC_greatest_plausible_heap_addr;
    register ptr_t least_ha = GC_least_plausible_heap_addr;
#   define GC_greatest_plausible_heap_addr greatest_ha
#   define GC_least_plausible_heap_addr least_ha
    
    p = (word *)(h->hb_body);
    plim = (word *)(((word)h) + HBLKSIZE);

    /* go through all words in block */
       while( p < plim )  {
           mark_word = *mark_word_addr++;
           i = 0;
           while(mark_word != 0) {
             if (mark_word & 1) {
                 q = p[i];
                 GC_PUSH_ONE_HEAP(q, p + i);
             }
             i++;
             mark_word >>= 1;
           }
           p += WORDSZ;
       }
#   undef GC_greatest_plausible_heap_addr
#   undef GC_least_plausible_heap_addr        
}

Here is the caller graph for this function:

struct hblk* GC_push_next_marked ( struct hblk h) [read]

Definition at line 1100 of file mark.c.

{
    register hdr * hhdr;
    
    h = GC_next_block(h);
    if (h == 0) return(0);
    hhdr = HDR(h);
    GC_push_marked(h, hhdr);
    return(h + OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz));
}

Here is the call graph for this function:

struct hblk* GC_push_next_marked_dirty ( struct hblk h) [read]

Definition at line 1114 of file mark.c.

{
    register hdr * hhdr = HDR(h);
    
    if (!GC_dirty_maintained) { ABORT("dirty bits not set up"); }
    for (;;) {
        h = GC_next_block(h);
        if (h == 0) return(0);
        hhdr = HDR(h);
#      ifdef STUBBORN_ALLOC
          if (hhdr -> hb_obj_kind == STUBBORN) {
            if (GC_page_was_changed(h) && GC_block_was_dirty(h, hhdr)) {
                break;
            }
          } else {
            if (GC_block_was_dirty(h, hhdr)) break;
          }
#      else
         if (GC_block_was_dirty(h, hhdr)) break;
#      endif
        h += OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz);
    }
    GC_push_marked(h, hhdr);
    return(h + OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz));
}

Here is the call graph for this function:

struct hblk* GC_push_next_marked_uncollectable ( struct hblk h) [read]

Definition at line 1144 of file mark.c.

{
    register hdr * hhdr = HDR(h);
    
    for (;;) {
        h = GC_next_block(h);
        if (h == 0) return(0);
        hhdr = HDR(h);
       if (hhdr -> hb_obj_kind == UNCOLLECTABLE) break;
        h += OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz);
    }
    GC_push_marked(h, hhdr);
    return(h + OBJ_SZ_TO_BLOCKS(hhdr -> hb_sz));
}

Here is the call graph for this function:

Definition at line 670 of file mark.c.

void GC_push_one_checked ( word  p,
GC_bool  interior_ptrs 
)

Definition at line 688 of file mark.c.

{
    register word r;
    register hdr * hhdr; 
    register int displ;
  
    GET_HDR(p, hhdr);
    if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) {
        if (hhdr != 0 && interior_ptrs) {
          r = BASE(p);
         hhdr = HDR(r);
         displ = BYTES_TO_WORDS(HBLKDISPL(r));
       } else {
         hhdr = 0;
       }
    } else {
        register map_entry_type map_entry;
        
        displ = HBLKDISPL(p);
        map_entry = MAP_ENTRY((hhdr -> hb_map), displ);
        if (map_entry == OBJ_INVALID) {
#        ifndef ALL_INTERIOR_POINTERS
            if (interior_ptrs) {
              r = BASE(p);
             displ = BYTES_TO_WORDS(HBLKDISPL(r));
             if (r == 0) hhdr = 0;
            } else {
              hhdr = 0;
            }
#        else
           /* map already reflects interior pointers */
           hhdr = 0;
#        endif
        } else {
          displ = BYTES_TO_WORDS(displ);
          displ -= map_entry;
          r = (word)((word *)(HBLKPTR(p)) + displ);
        }
    }
    /* If hhdr != 0 then r == GC_base(p), only we did it faster. */
    /* displ is the word index within the block.         */
    if (hhdr == 0) {
       if (interior_ptrs) {
#          ifdef PRINT_BLACK_LIST
             GC_add_to_black_list_stack(p, source);
#          else
             GC_add_to_black_list_stack(p);
#          endif
       } else {
           GC_ADD_TO_BLACK_LIST_NORMAL(p, source);
#          undef source  /* In case we had to define it. */
       }
    } else {
       if (!mark_bit_from_hdr(hhdr, displ)) {
           set_mark_bit_from_hdr(hhdr, displ);
           PUSH_OBJ((word *)r, hhdr, GC_mark_stack_top,
                    &(GC_mark_stack[GC_mark_stack_size]));
       }
    }
}

Here is the call graph for this function:

void GC_set_hdr_marks ( hdr hhdr)

Definition at line 132 of file mark.c.

{
    register int i;

    for (i = 0; i < MARK_BITS_SZ; ++i) {
       hhdr -> hb_marks[i] = ONES;
    }
}

Definition at line 160 of file mark.c.

{
    register struct hblk *h = HBLKPTR(p);
    register hdr * hhdr = HDR(h);
    register int word_no = (word *)p - (word *)h;
    
    set_mark_bit_from_hdr(hhdr, word_no);
}

Definition at line 403 of file mark.c.

{
    GC_mark_state = MS_INVALID;
    GC_mark_stack_too_small = TRUE;
#   ifdef PRINTSTATS
       GC_printf1("Mark stack overflow; current size = %lu entries\n",
                  GC_mark_stack_size);
#    endif
     return(msp-INITIAL_MARK_STACK_SIZE/8);
}

Variable Documentation

Definition at line 101 of file mark.c.

Definition at line 103 of file mark.c.

Definition at line 111 of file mark.c.

Definition at line 105 of file mark.c.

Definition at line 109 of file mark.c.

Definition at line 79 of file mark.c.

Definition at line 41 of file mark.c.

Definition at line 98 of file mark.c.

Definition at line 113 of file mark.c.

struct hblk* scan_ptr [static]

Definition at line 107 of file mark.c.