Back to index

plt-scheme  4.2.1
Classes | Defines | Typedefs | Functions | Variables
copy.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include "gc2.h"

Go to the source code of this file.

Classes

struct  ImmobileBox
struct  GC_Weak_Array
struct  GC_Weak_Box
struct  Fnl

Defines

#define USE_MMAP   1
#define GROW_FACTOR   1.5
#define ALIGN_DOUBLES   0
#define TIME   0
#define SEARCH   1
#define SAFETY   1
#define RECYCLE_HEAP   0
#define KEEP_FROM_PTR   0
#define GC_EVERY_ALLOC   0
#define ALLOC_GC_PHASE   0
#define SKIP_FORCED_GC   0
#define CHECK_STACK_EVERY   5
#define CHECK_STACK_START   -1
#define gc_finalization_tag   256
#define gc_finalization_weak_link_tag   257
#define gc_weak_array_tag   258
#define _num_tags_   259
#define STARTING_PLACE   ((void *)0x400000)
#define PAGE_SIZE   4096
#define PTR_ALIGNMENT   4
#define PTR_TO_INT(x)   ((unsigned long)x)
#define INT_TO_PTR(x)   ((void *)x)
#define SKIP   ((Type_Tag)0x7000)
#define MOVED   ((Type_Tag)0x3000)
#define GETTIME()   ((long)scheme_get_process_milliseconds())
#define INITTIME()   /* empty */
#define PRINTTIME(x)   /* empty */

Typedefs

typedef short Type_Tag
typedef struct ImmobileBox ImmobileBox
typedef struct GC_Weak_Array GC_Weak_Array
typedef struct GC_Weak_Box GC_Weak_Box
typedef struct Fnl Fnl
typedef struct Fnl_Weak_Link Fnl_Weak_Link

Functions

voidmalloc_pages (size_t len)
void free_pages (void *p, size_t len)
static int compare_roots (const void *a, const void *b)
static void sort_and_merge_roots ()
void GC_add_roots (void *start, void *end)
voidGC_malloc_immobile_box (void *p)
void GC_free_immobile_box (void *b)
static int size_weak_array (void *p)
static int mark_weak_array (void *p)
static int fixup_weak_array (void *p)
voidGC_malloc_weak_array (size_t size_in_bytes, void *replace_val)
static int size_weak_box (void *p)
static int mark_weak_box (void *p)
static int fixup_weak_box (void *p)
voidGC_malloc_weak_box (void *p, void **secondary, int soffset)
static int size_finalizer (void *p)
static int mark_finalizer (void *p)
static int fixup_finalizer (void *p)
void GC_set_finalizer (void *p, int tagged, int level, void(*f)(void *p, void *data), void *data, void(**oldf)(void *p, void *data), void **olddata)
static int size_finalizer_weak_link (void *p)
static int mark_finalizer_weak_link (void *p)
static int fixup_finalizer_weak_link (void *p)
void GC_finalization_weak_ptr (void **p, int offset)
void GC_set_stack_base (void *base)
unsigned long GC_get_stack_base (void)
void GC_dump (void)
long GC_get_memory_use ()
void GC_init_type_tags (int count, int weakbox)
void stop ()
voidfind_start (void *p)
static void middle (unsigned long p, long delta, unsigned long where)
static void check_interior_pointer (void **pp)
static voidmark (void *p)
void GC_mark (const void *p)
void GC_fixup (void *_p)
void GC_mark_variable_stack (void **var_stack, long delta, void *limit)
void GC_trace_variable_stack (void **var_stack, long delta, void *limit, int just_check)
void GC_fixup_variable_stack (void **var_stack, long delta, void *limit)
void check_variable_stack ()
void gcollect (int needsize)
voidGC_resolve (void *p)
static voidmalloc_tagged (size_t size_in_bytes)
static voidmalloc_untagged (size_t size_in_bytes, unsigned long nonatomic)
voidGC_malloc (size_t size_in_bytes)
voidGC_malloc_one_tagged (size_t size_in_bytes)
voidGC_malloc_one_xtagged (size_t size_in_bytes)
voidGC_malloc_array_tagged (size_t size_in_bytes)
voidGC_malloc_atomic (size_t size_in_bytes)
voidGC_malloc_atomic_uncollectable (size_t size_in_bytes)
voidGC_malloc_allow_interior (size_t size_in_bytes)
void GC_free (void *s)
void GC_register_traversers (Type_Tag tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup)
void GC_gcollect ()

Variables

void(* GC_collect_start_callback )(void)
void(* GC_collect_end_callback )(void)
void(* GC_out_of_memory )(void)
unsigned long(* GC_get_thread_stack_base )(void)
void(* GC_mark_xtagged )(void *obj)
void(* GC_fixup_xtagged )(void *obj)
void ** GC_variable_stack
Type_Tag weak_box_tag
Size_Proc size_table [_num_tags_]
Mark_Proc mark_table [_num_tags_]
Fixup_Proc fixup_table [_num_tags_]
voidGC_alloc_space = STARTING_PLACE
voidGC_alloc_top
static long alloc_size
static long heap_size = 32000
static void ** tagged_high = STARTING_PLACE
static void ** untagged_low = STARTING_PLACE
static void ** new_tagged_high
static void ** new_untagged_low
static voidold_space
static long old_size
static char * alloc_bitmap
static char zero_sized [4]
static voidpark [2]
static int cycle_count = 0
int fd
int fd_created
static long roots_count
static long roots_size
static unsigned long * roots
static ImmobileBoximmobile
static GC_Weak_Arrayweak_arrays
static GC_Weak_Boxweak_boxes
static Fnlfnls
static Fnlrun_queue
static Fnllast_in_queue
static Fnl_Weak_Linkfnl_weaks
static unsigned long stack_base
voidsearch_for
voidsearch_mark
long search_size
int detail_cycle
int atomic_detail_cycle
static int check_count = CHECK_STACK_START
static void ** o_var_stack
static void ** oo_var_stack
static int initialized
static long * prev_ptr
static void ** prev_var_stack

Class Documentation

struct ImmobileBox

Definition at line 506 of file compact.c.

Collaboration diagram for ImmobileBox:
Class Members
struct ImmobileBox * next
void * p
struct ImmobileBox * prev
struct GC_Weak_Array

Definition at line 16 of file commongc_internal.h.

Collaboration diagram for GC_Weak_Array:
Class Members
long count
void * data
short keyex
struct GC_Weak_Array * next
void * replace_val
Type_Tag type
struct GC_Weak_Box

Definition at line 27 of file commongc_internal.h.

Collaboration diagram for GC_Weak_Box:
Class Members
short keyex
struct GC_Weak_Box * next
void ** secondary_erase
int soffset
Type_Tag type
void * val
struct Fnl_Weak_Link

Definition at line 621 of file compact.c.

Collaboration diagram for Fnl_Weak_Link:
Class Members
struct Fnl_Weak_Link * next
long offset
int offset
void * p
void * saved
Type_Tag type

Define Documentation

#define _num_tags_   259

Definition at line 66 of file copy.c.

#define ALIGN_DOUBLES   0

Definition at line 22 of file copy.c.

#define ALLOC_GC_PHASE   0

Definition at line 44 of file copy.c.

#define CHECK_STACK_EVERY   5

Definition at line 47 of file copy.c.

#define CHECK_STACK_START   -1

Definition at line 48 of file copy.c.

#define GC_EVERY_ALLOC   0

Definition at line 43 of file copy.c.

#define gc_finalization_tag   256

Definition at line 62 of file copy.c.

Definition at line 63 of file copy.c.

#define gc_weak_array_tag   258

Definition at line 64 of file copy.c.

#define GETTIME ( )    ((long)scheme_get_process_milliseconds())

Definition at line 913 of file copy.c.

#define GROW_FACTOR   1.5

Definition at line 17 of file copy.c.

#define INITTIME ( )    /* empty */

Definition at line 923 of file copy.c.

#define INT_TO_PTR (   x)    ((void *)x)

Definition at line 161 of file copy.c.

#define KEEP_FROM_PTR   0

Definition at line 41 of file copy.c.

#define MOVED   ((Type_Tag)0x3000)

Definition at line 580 of file copy.c.

#define PAGE_SIZE   4096

Definition at line 109 of file copy.c.

#define PRINTTIME (   x)    /* empty */

Definition at line 924 of file copy.c.

#define PTR_ALIGNMENT   4

Definition at line 159 of file copy.c.

#define PTR_TO_INT (   x)    ((unsigned long)x)

Definition at line 160 of file copy.c.

#define RECYCLE_HEAP   0

Definition at line 40 of file copy.c.

#define SAFETY   1

Definition at line 39 of file copy.c.

#define SEARCH   1

Definition at line 38 of file copy.c.

#define SKIP   ((Type_Tag)0x7000)

Definition at line 579 of file copy.c.

#define SKIP_FORCED_GC   0

Definition at line 45 of file copy.c.

#define STARTING_PLACE   ((void *)0x400000)

Definition at line 72 of file copy.c.

#define TIME   0

Definition at line 37 of file copy.c.

#define USE_MMAP   1

Definition at line 16 of file copy.c.


Typedef Documentation

typedef struct Fnl Fnl
typedef short Type_Tag

Definition at line 33 of file copy.c.


Function Documentation

static void check_interior_pointer ( void **  pp) [static]

Definition at line 621 of file copy.c.

{
  void *p = *pp;

  if (check_count--)
    return;
  else
    check_count = CHECK_STACK_EVERY;

  if (!((long)p & 0x1)
      && (p >= GC_alloc_space)
      && (p <= GC_alloc_top)) {
    long diff = ((char *)p - (char *)GC_alloc_space) >> 2;
    
    if (((long)p & 0x3) || !(alloc_bitmap[diff >> 3] & (1 << (diff & 0x7)))) {
      long diff1 = ((char *)p - (char *)GC_alloc_space);
      
      while (!(alloc_bitmap[diff >> 3] & (1 << (diff & 0x7)))) {
       diff--;
      }
      
      diff <<= 2;
      
      if (((diff + (char *)GC_alloc_space) > (char *)tagged_high)
         && ((*(long *)(diff + (char *)GC_alloc_space - 4) & 0x20000000))) {
       /* Middle is ok. */
      } else {
       middle((unsigned long)p, diff1 - diff, (unsigned long)pp);
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 893 of file copy.c.

{
  void **limit, **var_stack;

  if (!alloc_bitmap)
    return;

  limit = (void **)(GC_get_thread_stack_base
                  ? GC_get_thread_stack_base()
                  : stack_base);

  var_stack = GC_variable_stack;

  GC_trace_variable_stack(var_stack, 0, limit, 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int compare_roots ( const void a,
const void b 
) [static]

Definition at line 167 of file copy.c.

{
  if (*(unsigned long *)a < *(unsigned long *)b)
    return -1;
  else
    return 1;
}

Here is the caller graph for this function:

void* find_start ( void p)

Definition at line 597 of file copy.c.

{
  long diff = ((char *)p - (char *)GC_alloc_space) >> 2;

  if (((long)p & 0x3) || !(alloc_bitmap[diff >> 3] & (1 << (diff & 0x7)))) {
    while (!(alloc_bitmap[diff >> 3] & (1 << (diff & 0x7)))) {
      diff--;
    }
      
    diff <<= 2;

    return (void *)((char *)GC_alloc_space + diff);
  } else
    return p;
}
static int fixup_finalizer ( void p) [static]

Definition at line 416 of file copy.c.

{
  Fnl *fnl = (Fnl *)p;
  
  gcFIXUP(fnl->next);
  gcFIXUP(fnl->data);
  if (!fnl->eager_level) {
    /* Queued for run: */
    gcFIXUP(fnl->p);
  }

  return gcBYTES_TO_WORDS(sizeof(Fnl));
}

Here is the caller graph for this function:

static int fixup_finalizer_weak_link ( void p) [static]

Definition at line 515 of file copy.c.

Here is the caller graph for this function:

static int fixup_weak_array ( void p) [static]

Definition at line 299 of file copy.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static int fixup_weak_box ( void p) [static]

Definition at line 356 of file copy.c.

{
  GC_Weak_Box *wb = (GC_Weak_Box *)p;
  
  gcFIXUP(wb->secondary_erase);
  if (wb->val) {
    wb->next = weak_boxes;
    weak_boxes = wb;
  }

  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box));
}

Here is the caller graph for this function:

void free_pages ( void p,
size_t  len 
)

Definition at line 134 of file copy.c.

{
  munmap(p, len);
}

Here is the caller graph for this function:

void GC_add_roots ( void start,
void end 
)

Definition at line 211 of file copy.c.

{
  if (roots_count >= roots_size) {
    unsigned long *naya;

    roots_size = roots_size ? 2 * roots_size : 500;
    naya = (unsigned long *)malloc(sizeof(unsigned long) * (roots_size + 1));

    memcpy((void *)naya, (void *)roots, 
          sizeof(unsigned long) * roots_count);

    if (roots)
      free(roots);

    roots = naya;
  }

  roots[roots_count++] = PTR_TO_INT(start);
  roots[roots_count++] = PTR_TO_INT(end) - PTR_ALIGNMENT;
}
void GC_dump ( void  )

Definition at line 564 of file copy.c.

{
  fprintf(stderr, "Memory use: %ld\n", GC_get_memory_use());
}

Here is the call graph for this function:

void GC_finalization_weak_ptr ( void **  p,
int  offset 
)

Definition at line 524 of file copy.c.

{
  Fnl_Weak_Link *wl;

#ifdef SAFETY
  if (((void *)p < GC_alloc_space) || (p >= GC_alloc_top)) {
    *(int *)0x0 = 1;
  }
#endif

  /* Allcation might trigger GC, so we use park: */
  park[0] = p;

  wl = (Fnl_Weak_Link *)GC_malloc_one_tagged(sizeof(Fnl_Weak_Link));

  p = park[0];
  park[0] = NULL;

  wl->type = gc_finalization_weak_link_tag;
  wl->p = p;
  wl->offset = offset * sizeof(void*);
  wl->next = fnl_weaks;

  fnl_weaks = wl;
}

Here is the call graph for this function:

void GC_fixup ( void _p)

Definition at line 801 of file copy.c.

{
  void *p;

  p = *(void **)_p;

  if (!((long)p & 0x1)
      && (p >= GC_alloc_space)
      && (p <= GC_alloc_top))
    *(void **)_p = mark(p);
}
void GC_fixup_variable_stack ( void **  var_stack,
long  delta,
void limit 
)

Definition at line 885 of file copy.c.

{
  GC_trace_variable_stack(var_stack, delta, limit, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_free ( void s)

Definition at line 1747 of file copy.c.

{
}

Definition at line 255 of file copy.c.

{
  ImmobileBox *ib = (ImmobileBox *)b;

  if (!ib)
    return;

  if (ib->prev)
    ib->prev->next = ib->next;
  else
    immobile = ib->next;
  if (ib->next)
    ib->next->prev = ib->prev;

  free(ib);
}

Definition at line 1758 of file copy.c.

{
  gcollect(0);
}

Here is the call graph for this function:

long GC_get_memory_use ( void  )

Definition at line 569 of file copy.c.

{
  return (alloc_size - ((untagged_low - tagged_high) << 2));
}
unsigned long GC_get_stack_base ( void  )

Definition at line 559 of file copy.c.

{
  return stack_base;
}
void GC_init_type_tags ( int  count,
int  weakbox 
)

Definition at line 574 of file copy.c.

{
  weak_box_tag = weakbox;
}
void* GC_malloc ( size_t  size_in_bytes)

Definition at line 1708 of file copy.c.

{
  return malloc_untagged(size_in_bytes, 0x80000000);
}

Here is the call graph for this function:

void* GC_malloc_allow_interior ( size_t  size_in_bytes)

Definition at line 1742 of file copy.c.

{
  return malloc_untagged(size_in_bytes, 0xA0000000);
}

Here is the call graph for this function:

void* GC_malloc_array_tagged ( size_t  size_in_bytes)

Definition at line 1724 of file copy.c.

{
  return malloc_untagged(size_in_bytes, 0x40000000);
}

Here is the call graph for this function:

void* GC_malloc_atomic ( size_t  size_in_bytes)

Definition at line 1730 of file copy.c.

{
  return malloc_untagged(size_in_bytes, 0x00000000);
}

Here is the call graph for this function:

void* GC_malloc_atomic_uncollectable ( size_t  size_in_bytes)

Definition at line 1736 of file copy.c.

{
  return malloc(size_in_bytes);
}

Definition at line 239 of file copy.c.

{
  ImmobileBox *ib;

  ib = (ImmobileBox *)malloc(sizeof(ImmobileBox));
  ib->p = p;
  ib->next = immobile;
  if (immobile)
    immobile->prev = ib;
  ib->prev = NULL;

  immobile = ib;

  return ib;
}
void* GC_malloc_one_tagged ( size_t  size_in_bytes)

Definition at line 1714 of file copy.c.

{
  return malloc_tagged(size_in_bytes);
}

Here is the call graph for this function:

void* GC_malloc_one_xtagged ( size_t  size_in_bytes)

Definition at line 1719 of file copy.c.

{
  return malloc_untagged(size_in_bytes, 0x10000000);
}

Here is the call graph for this function:

void* GC_malloc_weak_array ( size_t  size_in_bytes,
void replace_val 
)

Definition at line 311 of file copy.c.

{
  GC_Weak_Array *w;

  /* Allcation might trigger GC, so we use park: */
  park[0] = replace_val;

  w = (GC_Weak_Array *)GC_malloc_one_tagged(size_in_bytes 
                                       + sizeof(GC_Weak_Array) 
                                       - sizeof(void *));

  replace_val = park[0];
  park[0] = NULL;

  w->type = gc_weak_array_tag;
  w->replace_val = replace_val;
  w->count = (size_in_bytes >> 2);
  
  return w;
}

Here is the caller graph for this function:

void* GC_malloc_weak_box ( void p,
void **  secondary,
int  soffset 
)

Definition at line 369 of file copy.c.

{
  GC_Weak_Box *w;

  /* Allcation might trigger GC, so we use park: */
  park[0] = p;
  park[1] = secondary;

  w = (GC_Weak_Box *)GC_malloc_one_tagged(sizeof(GC_Weak_Box));

  p = park[0];
  park[0] = NULL;
  secondary = (void **)park[1];
  park[1] = NULL;
  
  w->type = weak_box_tag;
  w->val = p;
  w->secondary_erase = secondary;
  w->soffset = soffset;

  return w;
}

Here is the caller graph for this function:

void GC_mark ( const void p)

Definition at line 796 of file copy.c.

{
  /* Not used. */
}
void GC_mark_variable_stack ( void **  var_stack,
long  delta,
void limit 
)

Definition at line 815 of file copy.c.

{
  /* Not used. */
}

Here is the caller graph for this function:

void GC_register_traversers ( Type_Tag  tag,
Size_Proc  size,
Mark_Proc  mark,
Fixup_Proc  fixup 
)

Definition at line 1751 of file copy.c.

{
  size_table[tag] = size;
  mark_table[tag] = mark;
  fixup_table[tag] = fixup;
}
void* GC_resolve ( void p)

Definition at line 1507 of file copy.c.

{
  if (!((long)p & 0x1) && (p >= GC_alloc_space) && (p <= GC_alloc_top)) {  
    if (p < (void *)tagged_high) {
      Type_Tag tag = *(Type_Tag *)p;

      if (tag == MOVED)
       return ((void **)p)[1];
      else
       return p;
    } else {
      long size;
      
      p -= 4;
      size = ((*(long *)p) & 0x0FFFFFFF);
      
      if (!size)
       return ((void **)p)[1];
      else
       return p + 4;
    }
  } else
    return p;
}
void GC_set_finalizer ( void p,
int  tagged,
int  level,
void(*)(void *p, void *data f,
void data,
void(**)(void *p, void *data oldf,
void **  olddata 
)

Definition at line 430 of file copy.c.

{
  Fnl *fnl, *prev;

  if (((long)p & 0x1) || (p < GC_alloc_space) || (p > GC_alloc_top)) {
    /* Never collected. Don't finalize it. */
    if (oldf) *oldf = NULL;
    if (olddata) *olddata = NULL;
    return;
  }

  fnl = fnls;
  prev = NULL;
  while (fnl) {
    if (fnl->p == p) {
      if (oldf) *oldf = fnl->f;
      if (olddata) *olddata = fnl->data;
      if (f) {
       fnl->f = f;
       fnl->data = data;
       fnl->eager_level = level;
      } else {
       if (prev)
         prev->next = fnl->next;
       else
         fnls = fnl->next;
       return;
      }
      return;
    } else {
      prev = fnl;
      fnl = fnl->next;
    }
  }
  
  if (oldf) *oldf = NULL;
  if (olddata) *olddata = NULL;

  if (!f)
    return;

  /* Allcation might trigger GC, so we use park: */
  park[0] = p;
  park[1] = data;

  fnl = GC_malloc_one_tagged(sizeof(Fnl));

  p = park[0];
  park[0] = NULL;
  data = park[1];
  park[1] = NULL;

  fnl->type = gc_finalization_tag;
  fnl->next = fnls;
  fnl->p = p;
  fnl->f = f;
  fnl->data = data;
  fnl->eager_level = level;

  fnls = fnl;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 554 of file copy.c.

{
  stack_base = (unsigned long)base;
}
void GC_trace_variable_stack ( void **  var_stack,
long  delta,
void limit,
int  just_check 
)

Definition at line 822 of file copy.c.

{
  int stack_depth;

  stack_depth = 0;
  while (var_stack) {
    long size;
    void ***p;

    var_stack = (void **)((char *)var_stack + delta);
    if (var_stack == limit)
      return;

    size = *(long *)(var_stack + 1);

    oo_var_stack = o_var_stack;
    o_var_stack = var_stack;

    p = (void ***)(var_stack + 2);
    
    while (size--) {
      if (!*p) {
       /* Array */
       long count = ((long *)p)[2];
       void **a = ((void ***)p)[1];
       p += 2;
       size -= 2;
       a = (void **)((char *)a + delta);
       while (count--) {
#ifdef SAFETY
         if (just_check) {
           check_interior_pointer(a);
         } else 
#endif
           { gcFIXUP(*a); }
         a++;
       }
      } else {
       void **a = *p;
       a = (void **)((char *)a + delta);
#ifdef SAFETY
       if (just_check) {
         check_interior_pointer(a);
       } else
#endif
         { gcFIXUP(*a); }
      }
      p++;
    }

#if SAFETY
    if (*var_stack && ((unsigned long)*var_stack <= (unsigned long)var_stack))
      *(int *)0x0 = 1;
#endif

    var_stack = *var_stack;
    stack_depth++;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void gcollect ( int  needsize)

Definition at line 933 of file copy.c.

{
  /* Check old: */
  long *p, *top;
  void *new_space;
  long new_size;
  void **tagged_mark, **untagged_mark;
  char *bitmap;
  int i, did_fnls;
  long diff, iterations;
  ImmobileBox *ib;
  GC_Weak_Box *wb;
  GC_Weak_Array *wa;

  INITTIME();
  PRINTTIME((STDERR, "gc: start: %ld\n", GETTIMEREL()));

  cycle_count++;

  if (!initialized) {
    GC_register_traversers(weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box);
    GC_register_traversers(gc_weak_array_tag, size_weak_array, mark_weak_array, fixup_weak_array);
    GC_register_traversers(gc_finalization_tag, size_finalizer, mark_finalizer, fixup_finalizer);
    GC_register_traversers(gc_finalization_weak_link_tag, size_finalizer_weak_link, mark_finalizer_weak_link, fixup_finalizer_weak_link);

    GC_add_roots(&fnls, (char *)&fnls + sizeof(fnls) + 1);
    GC_add_roots(&fnl_weaks, (char *)&fnl_weaks + sizeof(fnl_weaks) + 1);
    GC_add_roots(&run_queue, (char *)&run_queue + sizeof(run_queue) + 1);
    GC_add_roots(&last_in_queue, (char *)&last_in_queue + sizeof(last_in_queue) + 1);
    GC_add_roots(&park, (char *)&park + sizeof(park) + 1);
    initialized = 1;
  }

  weak_boxes = NULL;
  weak_arrays = NULL;
  did_fnls = 0;

  if (GC_collect_start_callback)
    GC_collect_start_callback();

  sort_and_merge_roots();

  new_size = (heap_size * GROW_FACTOR);
  if (new_size < alloc_size)
    new_size = alloc_size;

  new_size += needsize;

  /* word-aligned: */
  new_size = (new_size + 3) & 0xFFFFFFFC;
  
  if (old_size >= new_size) {
    new_size = old_size;
    new_space = old_space;
  } else {
    if (old_size) {
      free_pages(old_space, old_size);
      old_size = 0;
    }

    new_space = malloc_pages(new_size + 4);

    if (!new_space) {
      printf("Out of memory");
      abort();
    }
  }

  /******************** Mark/Copy ****************************/

  tagged_mark = new_tagged_high = (void **)new_space;
  untagged_mark = new_untagged_low = (void **)(new_space + new_size);

#if KEEP_FROM_PTR
  mark_source = FROM_STACK;
#endif

  GC_fixup_variable_stack(GC_variable_stack,
                       0,
                       (void *)(GC_get_thread_stack_base
                               ? GC_get_thread_stack_base()
                               : stack_base));

  PRINTTIME((STDERR, "gc: stack: %ld\n", GETTIMEREL()));

#if KEEP_FROM_PTR
  mark_source = FROM_ROOT;
#endif

  for (i = 0; i < roots_count; i += 2) {
    void **s = (void **)roots[i];
    void **e = (void **)roots[i + 1];
    
    while (s < e) {
      gcFIXUP(*s);
      s++;
    }
  }

#if KEEP_FROM_PTR
  mark_source = FROM_IMM;
#endif

  /* Do immobiles: */
  for (ib = immobile; ib; ib = ib->next) {
    gcFIXUP(ib->p);
  }

  PRINTTIME((STDERR, "gc: roots: %ld\n", GETTIMEREL()));

  iterations = 0;

  while (1) { /* Loop to do finalization */

    while ((tagged_mark < new_tagged_high)
          || (untagged_mark > new_untagged_low)) {
      
      iterations++;
      
      while (tagged_mark < new_tagged_high) {
       Type_Tag tag;
       long size;
       
#if KEEP_FROM_PTR
       tagged_mark++;
#endif

       tag = *(Type_Tag *)tagged_mark;

#if ALIGN_DOUBLES
       if (tag == SKIP)
         tagged_mark++;
       else {
#endif
         
#if SAFETY
         if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
           *(int *)0x0 = 1;
         }
#endif
         
#if KEEP_FROM_PTR
         mark_source = tagged_mark;
#endif

         size = size_table[tag](tagged_mark);
         fixup_table[tag](tagged_mark);
         
#if SAFETY
         if (size <= 1) {
           *(int *)0x0 = 1;
         }
#endif
         
         tagged_mark += size;
         
#if SAFETY
         if ((void *)tagged_mark < new_space) {
           *(int *)0x0 = 1;
         }
#endif
#if ALIGN_DOUBLES
       }
#endif
      }

      while (untagged_mark > new_untagged_low) {
       void **mp, **started;
       
       mp = started = new_untagged_low;
       while (mp < untagged_mark) {
         long v, size;
#if KEEP_FROM_PTR
         mp++;
#endif
         v = *(long *)mp;
         size = (v & 0x0FFFFFFF);
         
         if (v & 0xF0000000) {
#if KEEP_FROM_PTR
           mark_source = mp;
#endif
           mp++;         
           if (v & 0x80000000) {
             /* Array of pointers */
             int i;
             /* printf("parray: %d %lx\n", size, (long)mp); */
             for (i = size; i--; mp++) {
              gcFIXUP(*mp);
             }
           } else if (v & 0x10000000) {
             /* xtagged */
             GC_fixup_xtagged(mp);
             mp += size;
           } else {
             /* Array of tagged */
             int i, elem_size;
             Type_Tag tag = *(Type_Tag *)mp;
             
             elem_size = size_table[tag](mp);
             fixup_table[tag](mp);
             mp += elem_size;
             for (i = elem_size; i < size; i += elem_size, mp += elem_size)
              fixup_table[tag](mp);
           }
         } else
           mp += v + 1;
       }
       untagged_mark = started;
      }
    }
      
    if ((did_fnls >= 3) || !fnls) {
      if (did_fnls == 3) {
       /* Finish up ordered finalization */
       Fnl *f, *next, *prev;
       Fnl_Weak_Link *wl;

       /* Enqueue and mark level 3 finalizers that still haven't been marked. */
       /* (Recursive marking is already done, though.) */
       prev = NULL;
       for (f = fnls; f; f = next) {
         next = f->next;
         if (f->eager_level == 3) {
           void *v;

           v = GC_resolve(f->p);

           if (v == f->p) {
             /* Not yet marked. Mark it and enqueue it. */
#if KEEP_FROM_PTR
             mark_source = f;
#endif
             gcFIXUP(f->p);

             if (prev)
              prev->next = next;
             else
              fnls = next;
             
             f->eager_level = 0; /* indicates queued */
             
             f->next = NULL;
             if (last_in_queue) {
              last_in_queue->next = f;
              last_in_queue = f;
             } else {
              run_queue = last_in_queue = f;
             }
           } else {
             f->p = v;
             prev = f;
           }
         }
       }

       /* Restore zeroed out weak links, marking as we go: */  
       for (wl = fnl_weaks; wl; wl = wl->next) {
         void *wp = (void *)GC_resolve(wl->p);
         int markit;
         markit = (wp != wl->p);
         wp = (wp + wl->offset);
         if (markit)
           gcFIXUP(wl->saved);
         *(void **)wp = wl->saved;
       }
       
       /* We have to mark one more time, because restoring a weak
           link may have made something reachable. */

       did_fnls++;
      } else
       break;
    } else {
      int eager_level = did_fnls + 1;
      
      if (eager_level == 3) {
       /* Ordered finalization */
       Fnl *f;
       Fnl_Weak_Link *wl;

       /* Zero out weak links for ordered finalization */
       for (wl = fnl_weaks; wl; wl = wl->next) {
         void *wp = (void *)GC_resolve(wl->p);
         wl->saved = *(void **)(wp + wl->offset);
         *(void **)(wp + wl->offset) = NULL;
       }

       /* Mark content of not-yet-marked finalized objects,
          but don't mark the finalized objects themselves. */  
       for (f = fnls; f; f = f->next) {
         if (f->eager_level == 3) {
           void *v;

           v = GC_resolve(f->p);

           if (v == f->p) {
             /* Not yet marked. Do content. */
             Type_Tag tag = *(Type_Tag *)v;
#if SAFETY
             if ((tag < 0) || (tag >= _num_tags_) || !fixup_table[tag]) {
              *(int *)0x0 = 1;
             }
#endif
#if KEEP_FROM_PTR
             mark_source = FROM_FNL;
#endif
             fixup_table[tag](v);
           }
         }
       }
      } else {
       /* Unordered finalization */
       Fnl *f, *prev, *queue;

       f = fnls;
       prev = NULL;
       queue = NULL;
       
       while (f) {
         if (f->eager_level == eager_level) {
           void *v;

           v = GC_resolve(f->p);

           if (v == f->p) {
             /* Not yet marked. Move finalization to run queue. */
             Fnl *next = f->next;

             if (prev)
              prev->next = next;
             else
              fnls = next;
             
             f->eager_level = 0; /* indicates queued */
             
             f->next = NULL;
             if (last_in_queue) {
              last_in_queue->next = f;
              last_in_queue = f;
             } else {
              run_queue = last_in_queue = f;
             }
             if (!queue)
              queue = f;

             f = next;
           } else {
             f->p = v;
             prev = f;
             f = f->next;
           }
         } else {
           prev = f;
           f = f->next;
         }
       }
       
       /* Mark items added to run queue: */
       f = queue;
       while (f) {
#if KEEP_FROM_PTR
         mark_source = f;
#endif
         gcFIXUP(f->p);
         f = f->next;
       }
      }
       
      did_fnls++;
    }

  }

  PRINTTIME((STDERR, "gc: mark/copy (%d): %ld\n", iterations, GETTIMEREL()));

  /******************************************************/

  /* Do weak boxes: */
  wb = weak_boxes;
  while (wb) {
    if (!((long)wb->val & 0x1) && ((void *)wb->val >= GC_alloc_space) && ((void *)wb->val <= GC_alloc_top)) {
      void *v;
      v = GC_resolve(wb->val);
      if (v == wb->val) {
       wb->val = NULL;
       if (wb->secondary_erase) {
         *(wb->secondary_erase + wb->soffset) = NULL;
         wb->secondary_erase = NULL;
       }
      } else
       wb->val = v;
    } /* else not collectable */

    wb = wb->next;
  }

  /* Do weak arrays: */
  wa = weak_arrays;
  while (wa) {
    int i;

    for (i = wa->count; i--; ) {
      void *p = wa->data[i];
      if (!((long)p & 0x1) && (p >= GC_alloc_space) && (p <= GC_alloc_top)) {
       void *v;    
       v = GC_resolve(p);
       if (v == p)
         wa->data[i] = wa->replace_val;
       else
         wa->data[i] = v;
      } /* else not collectable */
    }

    wa = wa->next;
  }

  /* Cleanup weak finalization links: */
  {
    Fnl_Weak_Link *wl, *prev, *next;

    prev = NULL;
    for (wl = fnl_weaks; wl; wl = next) {
      void *wp;
      next = wl->next;
      wp = (void *)GC_resolve(wl->p);
      if (wp == wl->p) {
       /* Collectable. Removed this link. */
       if (prev)
         prev->next = next;
       else
         fnl_weaks = next;
      } else {
       wl->p = wp;
       prev = wl;
      }
    }
  }

  /******************************************************/
  
#if RECYCLE_HEAP
  old_space = GC_alloc_space;
  old_size = alloc_size;
#else
  if (alloc_size)
    free_pages(GC_alloc_space, alloc_size + 4);
#endif

  free(alloc_bitmap);

  PRINTTIME((STDERR, "gc: free: %ld\n", GETTIMEREL()));

  if (new_untagged_low < new_tagged_high) {
    printf("Ouch: Tagged area collided with untagged area.\n");
    abort();
  }

  alloc_size = new_size;
  GC_alloc_space = new_space;
  GC_alloc_top = GC_alloc_space + alloc_size;
  tagged_high = new_tagged_high;
  untagged_low = new_untagged_low;

  heap_size = new_size - ((untagged_low - tagged_high) << 2);
  
  {
    long *p = (long *)untagged_low;
    while (p-- > (long *)tagged_high)
      *p = 0;
  }

  PRINTTIME((STDERR, "gc: restored: %ld\n", GETTIMEREL()));

  /******************** Make initial bitmap image: ****************************/

  {
    alloc_bitmap = bitmap = (char *)malloc((alloc_size >> 5) + 1);
    memset(bitmap, 0, (alloc_size >> 5) + 1);
  }

  p = (long *)untagged_low;
  diff = (((char *)p - (char *)GC_alloc_space) + 4) >> 2;
  top = (long *)GC_alloc_top;
  while (p < top) {
    long size;

#if KEEP_FROM_PTR
    diff++;
    p++;
#endif

    size = (*p & 0x0FFFFFFF) + 1;

    bitmap[diff >> 3] |= (1 << (diff & 0x7));

    p += size;
    diff += size;
  }

  p = ((long *)GC_alloc_space);
  diff = ((char *)p - (char *)GC_alloc_space) >> 2;
  while (p < (long *)tagged_high) {
    Type_Tag tag;
    long size;
      
#if KEEP_FROM_PTR
    diff++;
    p++;
#endif
    tag = *(Type_Tag *)p;

#if ALIGN_DOUBLES
    if (tag == SKIP) {
      p++;
      diff++;
    } else {
#endif
      bitmap[diff >> 3] |= (1 << (diff & 0x7));

#if SEARCH
      if (cycle_count == detail_cycle)
       printf("tag: %lx =  %d\n", (long)p, tag);
#endif

#if SAFETY
      if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
       fflush(NULL);
       *(int *)0x0 = 1;
      }
      prev_ptr = p;
      prev_var_stack = GC_variable_stack;
#endif
      size = size_table[tag](p);
#if SAFETY
      if (prev_var_stack != GC_variable_stack) {
       *(int *)0x0 = 1;
      }
#endif
      
      p += size;
      diff += size;
#if ALIGN_DOUBLES
    }
#endif
  }

  PRINTTIME((STDERR, "gc: done (t=%d, u=%d): %ld\n", 
            (long)((void *)tagged_high - GC_alloc_space),
            (long)(GC_alloc_top - (void *)untagged_low),
            GETTIMEREL()));

  if (GC_collect_start_callback)
    GC_collect_end_callback();

  /**********************************************************************/

  /* Run Finalizations. Collections may happen */

  while (run_queue) {
    Fnl *f;
    void **gcs;

    f = run_queue;
    run_queue = run_queue->next;
    if (!run_queue)
      last_in_queue = NULL;

    gcs = GC_variable_stack;
    f->f(f->p, f->data);
    GC_variable_stack = gcs;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* malloc_pages ( size_t  len)

Definition at line 111 of file copy.c.

{
  void *r;

  if (!fd_created) {
    fd_created = 1;
    fd = open("/dev/zero", O_RDWR);
  }

  if (len & (PAGE_SIZE - 1)) {
    len += PAGE_SIZE - (len & (PAGE_SIZE - 1));
  }

  r = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);

  if (r  == (void *)-1) {
    printf("mmap failed: %s\n", strerror(errno));
    exit(-1);
  }

  return r;
}

Here is the caller graph for this function:

static void* malloc_tagged ( size_t  size_in_bytes) [static]

Definition at line 1532 of file copy.c.

{
  void **m, **naya;

#if SAFETY
  check_variable_stack();
#endif

#if GC_EVERY_ALLOC
# if SKIP_FORCED_GC
  if (!skipped_first) {
    alloc_cycle++;
    if (alloc_cycle >= SKIP_FORCED_GC) {
      alloc_cycle = 0;
      skipped_first = 1;
    }
  }
# endif
  if (skipped_first) {
    alloc_cycle++;
    if (alloc_cycle >= GC_EVERY_ALLOC) {
      alloc_cycle = 0;
      gcollect(size_in_bytes);
    }
  }
#endif

#if KEEP_FROM_PTR
  size_in_bytes += 4;
#endif

  size_in_bytes = ((size_in_bytes + 3) & 0xFFFFFFFC);
#if ALIGN_DOUBLES
  if (!(size_in_bytes & 0x4)) {
    /* Make sure memory is 8-aligned */
    if (((long)tagged_high & 0x4)) {
      if (tagged_high == untagged_low) {
       gcollect(size_in_bytes);
#if KEEP_FROM_PTR
       size_in_bytes -= 4;
#endif
       return malloc_tagged(size_in_bytes);
      }
      ((Type_Tag *)tagged_high)[0] = SKIP;
      tagged_high += 1;
    }
  }
#endif

#if SEARCH
  if (size_in_bytes == search_size)
    stop();
#endif

  m = tagged_high;
  naya = tagged_high + (size_in_bytes >> 2);
  if (naya > untagged_low) {
    gcollect(size_in_bytes);
#if KEEP_FROM_PTR
    size_in_bytes -= 4;
#endif
    return malloc_tagged(size_in_bytes);
  }
  tagged_high = naya;

#if KEEP_FROM_PTR
  *m = FROM_NEW;
  m++;
#endif

#if SEARCH
  if (m == search_for) {
    stop();
  }
#endif

  {
    long diff = ((char *)m - (char *)GC_alloc_space) >> 2;

    alloc_bitmap[diff >> 3] |= (1 << (diff & 0x7));
  }

  return m;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* malloc_untagged ( size_t  size_in_bytes,
unsigned long  nonatomic 
) [static]

Definition at line 1617 of file copy.c.

{
  void **naya;

#if SAFETY
  check_variable_stack();
#endif

#if GC_EVERY_ALLOC
# if SKIP_FORCED_GC
  if (!skipped_first) {
    alloc_cycle++;
    if (alloc_cycle >= SKIP_FORCED_GC) {
      alloc_cycle = 0;
      skipped_first = 1;
    }
  }
# endif
  if (skipped_first) {
    alloc_cycle++;
    if (alloc_cycle >= GC_EVERY_ALLOC) {
      alloc_cycle = 0;
      gcollect(size_in_bytes);
    }
  }
#endif

  if (!size_in_bytes)
    return zero_sized;

#if KEEP_FROM_PTR
  size_in_bytes += 4;
#endif

  size_in_bytes = ((size_in_bytes + 3) & 0xFFFFFFFC);
#if ALIGN_DOUBLES
  if (!(size_in_bytes & 0x4)) {
    /* Make sure memory is 8-aligned */
    if ((long)untagged_low & 0x4) {
      if (untagged_low == tagged_high) {
#if KEEP_FROM_PTR
       size_in_bytes -= 4;
#endif
       gcollect(size_in_bytes);
       return malloc_untagged(size_in_bytes, nonatomic);
      }
      untagged_low -= 1;
      ((long *)untagged_low)[0] = 0;
    }
  }
#endif

#if SEARCH
  if (size_in_bytes == search_size)
    stop();
#endif

  naya = untagged_low - ((size_in_bytes >> 2) + 1);
  if (naya < tagged_high) {
    gcollect(size_in_bytes);
#if KEEP_FROM_PTR
    size_in_bytes -= 4;
#endif
    return malloc_untagged(size_in_bytes, nonatomic);
  }
  untagged_low = naya;

#if KEEP_FROM_PTR
  *naya = FROM_NEW;
  naya++;
  size_in_bytes -= 4;
#endif

  ((long *)naya)[0] = (size_in_bytes >> 2) | nonatomic;
  
#if SEARCH
  if ((naya + 1) == search_for) {
    stop();
  }
#endif

  {
    long diff = ((char *)(naya + 1) - (char *)GC_alloc_space) >> 2;

    alloc_bitmap[diff >> 3] |= (1 << (diff & 0x7));
  }

  return naya + 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* mark ( void p) [static]

Definition at line 655 of file copy.c.

{
  long diff = ((char *)p - (char *)GC_alloc_space) >> 2;

#if SEARCH
  if (p == search_mark)
    stop();
#endif

  if (((long)p & 0x3) || !(alloc_bitmap[diff >> 3] & (1 << (diff & 0x7)))) {
    long diff1 = ((char *)p - (char *)GC_alloc_space);
      
    while (!(alloc_bitmap[diff >> 3] & (1 << (diff & 0x7)))) {
      diff--;
    }
      
    diff <<= 2;

#ifdef SAFETY
    if (((diff + (char *)GC_alloc_space) > (char *)tagged_high)
       && ((*(long *)(diff + (char *)GC_alloc_space - 4) & 0x20000000)
           || (!(*(long *)(diff + (char *)GC_alloc_space - 4))
              && (*(long **)(diff + (char *)GC_alloc_space))[-1] & 0x20000000))) {
      /* Middle is ok. */
    } else {
      middle((unsigned long)p, diff1 - diff, 0);
    }
#endif

    return (void *)((char *)mark(diff + (char *)GC_alloc_space) + (diff1 - diff));
  } else {
    if (p < (void *)tagged_high) {
      Type_Tag tag = *(Type_Tag *)p;
      long size;
      void *naya;
       
      if (tag == MOVED)
       return ((void **)p)[1];

#if SAFETY    
      if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) {
       *(int *)0x0 = 1;
      }
#endif
       
      size = size_table[tag](p);
#if ALIGN_DOUBLES
      if (!(size & 0x1)) {
       if ((long)new_tagged_high & 0x4) {
         ((Type_Tag *)new_tagged_high)[0] = SKIP;
         new_tagged_high += 1;
       }
      }
#endif
       
#if KEEP_FROM_PTR
      *new_tagged_high = mark_source;
      new_tagged_high++;
#endif

      {
       int i;
       long *a, *b;
       a = (long *)new_tagged_high;
       b = (void *)p;
       for (i = size; i--; )
         *(a++) = *(b++);
      }
       
      naya = new_tagged_high;
      ((Type_Tag *)p)[0] = MOVED;
      ((void **)p)[1] = naya;
       
      new_tagged_high += size;
#if SEARCH
      if (naya == search_for) {
       stop();
      }
#endif
      return naya;
    } else {
      long size;
       
      p -= 4;
      size = ((*(long *)p) & 0x0FFFFFFF);
       
      if (!size)
       return ((void **)p)[1];

#if ALIGN_DOUBLES
      if (!(size & 1)) {
       if (!((long)new_untagged_low & 0x4)) {
         new_untagged_low--;
         *(long *)new_untagged_low = 0;
       }
      }
#endif
      size++;

      new_untagged_low -= size;

#if SAFETY
      if ((unsigned long)new_untagged_low < (unsigned long)new_tagged_high) {
       *(int *)0x0 = 1;
      }
#endif 

      {
       int i;
       long *a, *b;
       a = (long *)new_untagged_low;
       b = (void *)p;
       for (i = size; i--; )
         *(a++) = *(b++);
      }
      ((void **)p)[1] = new_untagged_low + 1;
      ((long *)p)[0] = 0;
       
#if SEARCH
      if ((new_untagged_low + 1) == search_for) {
       stop();
      }
#endif

#if SEARCH
      if (atomic_detail_cycle == cycle_count) {
       printf("%ld at %lx\n", size, (long)new_untagged_low);
      }
#endif

#if KEEP_FROM_PTR
      --new_untagged_low;
      *new_untagged_low = mark_source;
      return new_untagged_low + 2;
#else
      return new_untagged_low + 1;
#endif
    }
  }
}

Here is the call graph for this function:

static int mark_finalizer ( void p) [static]

Definition at line 410 of file copy.c.

{
  /* Not used */
  return gcBYTES_TO_WORDS(sizeof(Fnl));
}

Here is the caller graph for this function:

static int mark_finalizer_weak_link ( void p) [static]

Definition at line 509 of file copy.c.

{
  /* Not used */
  return gcBYTES_TO_WORDS(sizeof(Fnl_Weak_Link));
}

Here is the caller graph for this function:

static int mark_weak_array ( void p) [static]

Definition at line 293 of file copy.c.

{
  /* Not used */
  return size_weak_array(p);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int mark_weak_box ( void p) [static]

Definition at line 350 of file copy.c.

{
  /* Not used */
  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box));
}

Here is the caller graph for this function:

static void middle ( unsigned long  p,
long  delta,
unsigned long  where 
) [static]

Definition at line 614 of file copy.c.

{
  fprintf(stderr, "Middle!: 0x%lx d: %ld at 0x%lx\n", p, delta, where);
}

Here is the caller graph for this function:

static int size_finalizer ( void p) [static]

Definition at line 405 of file copy.c.

{
  return gcBYTES_TO_WORDS(sizeof(Fnl));
}

Here is the caller graph for this function:

static int size_finalizer_weak_link ( void p) [static]

Definition at line 504 of file copy.c.

{
  return gcBYTES_TO_WORDS(sizeof(Fnl_Weak_Link));
}

Here is the caller graph for this function:

static int size_weak_array ( void p) [static]

Definition at line 285 of file copy.c.

{
  GC_Weak_Array *a = (GC_Weak_Array *)p;

  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Array) 
                       + ((a->count - 1) * sizeof(void *)));
}

Here is the caller graph for this function:

static int size_weak_box ( void p) [static]

Definition at line 345 of file copy.c.

{
  return gcBYTES_TO_WORDS(sizeof(GC_Weak_Box));
}

Here is the caller graph for this function:

static void sort_and_merge_roots ( ) [static]

Definition at line 175 of file copy.c.

{
  static int counter = 0;
  int i, offset, top;

  if (roots_count < 4)
    return;

  /* Only try this every 5 collections or so: */
  if (counter--)
    return;
  counter = 5;

  qsort(roots, roots_count >> 1, 2 * sizeof(unsigned long), compare_roots);
  offset = 0;
  top = roots_count;
  for (i = 2; i < top; i += 2) {
    if ((roots[i - 2 - offset] <= roots[i])
       && ((roots[i - 1 - offset] + (PTR_ALIGNMENT - 1)) >= roots[i])) {
      /* merge: */
      if (roots[i + 1] > roots[i - 1 - offset])
       roots[i - 1 - offset] = roots[i + 1];
      offset += 2;
      roots_count -= 2;
    } else if (roots[i] == roots[i + 1]) {
      /* Remove empty range: */
      offset += 2;
      roots_count -= 2;
    } else if (offset) {
      /* compact: */
      roots[i - offset] = roots[i];
      roots[i + 1 - offset] = roots[i + 1];
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void stop ( )

Definition at line 590 of file copy.c.

{
  printf("stopped\n");
}

Here is the caller graph for this function:


Variable Documentation

char* alloc_bitmap [static]

Definition at line 82 of file copy.c.

long alloc_size [static]

Definition at line 75 of file copy.c.

Definition at line 586 of file copy.c.

Definition at line 619 of file copy.c.

int cycle_count = 0 [static]

Definition at line 88 of file copy.c.

Definition at line 585 of file copy.c.

Definition at line 107 of file copy.c.

Definition at line 107 of file copy.c.

Definition at line 70 of file copy.c.

Definition at line 502 of file copy.c.

Fnl* fnls [static]

Definition at line 403 of file copy.c.

Definition at line 74 of file copy.c.

Definition at line 74 of file copy.c.

Definition at line 51 of file copy.c.

Definition at line 50 of file copy.c.

Definition at line 56 of file copy.c.

unsigned long(* GC_get_thread_stack_base)(void)

Definition at line 53 of file copy.c.

Definition at line 55 of file copy.c.

Definition at line 52 of file copy.c.

Definition at line 58 of file copy.c.

long heap_size = 32000 [static]

Definition at line 75 of file copy.c.

ImmobileBox* immobile [static]

Definition at line 237 of file copy.c.

int initialized [static]

Definition at line 927 of file copy.c.

Fnl * last_in_queue [static]

Definition at line 403 of file copy.c.

Definition at line 69 of file copy.c.

void** new_tagged_high [static]

Definition at line 77 of file copy.c.

void ** new_untagged_low [static]

Definition at line 77 of file copy.c.

void** o_var_stack [static]

Definition at line 813 of file copy.c.

long old_size [static]

Definition at line 80 of file copy.c.

void* old_space [static]

Definition at line 79 of file copy.c.

void ** oo_var_stack [static]

Definition at line 813 of file copy.c.

void* park[2] [static]

Definition at line 86 of file copy.c.

long* prev_ptr [static]

Definition at line 929 of file copy.c.

void** prev_var_stack [static]

Definition at line 930 of file copy.c.

unsigned long* roots [static]

Definition at line 165 of file copy.c.

long roots_count [static]

Definition at line 163 of file copy.c.

long roots_size [static]

Definition at line 164 of file copy.c.

Fnl * run_queue [static]

Definition at line 403 of file copy.c.

Definition at line 583 of file copy.c.

Definition at line 583 of file copy.c.

Definition at line 584 of file copy.c.

Definition at line 68 of file copy.c.

unsigned long stack_base [static]

Definition at line 552 of file copy.c.

Definition at line 76 of file copy.c.

Definition at line 76 of file copy.c.

Definition at line 283 of file copy.c.

Definition at line 60 of file copy.c.

Definition at line 343 of file copy.c.

char zero_sized[4] [static]

Definition at line 84 of file copy.c.