Back to index

plt-scheme  4.2.1
Classes | Defines | Typedefs | Functions | Variables
compact.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "platforms.h"
#include "gc2.h"
#include "compactgc_internal.h"
#include "../src/schpriv.h"
#include "gc2_dump.h"
#include "msgprint.c"
#include "my_qsort.c"
#include "vm.c"
#include "roots.c"
#include "weak.c"
#include "fnls.c"
#include "sighand.c"
#include "stack_comp.c"
#include "var_stack.c"

Go to the source code of this file.

Classes

struct  MPage
struct  MSet
struct  ImmobileBox
union  MPage.u
union  MPage.o

Defines

#define NUMBER_OF_TAGS   512
#define GCTYPE   CompactGC
#define GC_get_GC()   (GC)
#define ofm_malloc   malloc
#define GROW_FACTOR   1.5
#define GROW_ADDITION   500000
#define GENERATIONS   1
#define OS_X_GENERATIONS   1
#define WIN32_GENERATIONS   1
#define USE_FREELIST   0
#define COMPACTING   SELECTIVELY_COMPACT
#define ALWAYS_COMPACT   2
#define SELECTIVELY_COMPACT   1
#define NEVER_COMPACT   0
#define COMPACT_THRESHOLD   0.2
#define ALIGN_DOUBLES   0
#define LOG_WORD_SIZE   2
#define WORD_SIZE   (1 << LOG_WORD_SIZE)
#define WORD_BIT_COUNT   (WORD_SIZE << 3)
#define INCREMENT_CYCLE_COUNT_GROWTH   1048576
#define BYTEPTR(x)   ((char *)x)
#define TIME   0
#define SEARCH   0
#define CHECKS   0
#define CHECK_STACK_PTRS   0
#define NOISY   0
#define MARK_STATS   0
#define ALLOC_GC_PHASE   0
#define SKIP_FORCED_GC   0
#define RECORD_MARK_SRC   0
#define KEEP_BACKPOINTERS   0
#define DEFINE_MALLOC_FREE   0
#define MARK_STACK_MAX   4096
#define gc_on_free_list_tag   511
#define SQUASH_OFFSETS   1
#define LOG_MPAGE_SIZE   14
#define MPAGE_SIZE   (1 << LOG_MPAGE_SIZE)
#define MPAGE_WORDS   (1 << (LOG_MPAGE_SIZE - LOG_WORD_SIZE))
#define MPAGE_MASK   ((1 << LOG_MPAGE_SIZE) - 1)
#define MPAGE_START   ~MPAGE_MASK
#define BIGBLOCK_MIN_SIZE   (1 << (LOG_MPAGE_SIZE - 2))
#define FREE_LIST_ARRAY_SIZE   (BIGBLOCK_MIN_SIZE >> LOG_WORD_SIZE)
#define LOG_OPAGE_SIZE   (LOG_MPAGE_SIZE - LOG_WORD_SIZE - SQUASH_OFFSETS)
#define OPAGE_SIZE   (sizeof(OffsetTy) << LOG_OPAGE_SIZE)
#define LOG_MAP_SIZE   9
#define LOG_MAPS_SIZE   (WORD_BIT_COUNT - LOG_MAP_SIZE - LOG_MPAGE_SIZE)
#define MAP_SIZE   (1 << LOG_MAP_SIZE)
#define MAPS_SIZE   (1 << LOG_MAPS_SIZE)
#define MAPS_SHIFT   (WORD_BIT_COUNT - LOG_MAPS_SIZE)
#define MAP_MASK   ((1 << (LOG_MAP_SIZE + LOG_MPAGE_SIZE)) - 1)
#define MAP_SHIFT   LOG_MPAGE_SIZE
#define MTYPE_NONE   0
#define MTYPE_TAGGED   1
#define MTYPE_ATOMIC   2
#define MTYPE_TAGGED_ARRAY   3
#define MTYPE_ARRAY   4
#define MTYPE_XTAGGED   5
#define MTYPE_MALLOCFREE   6
#define COLOR_MASK   0x3
#define MFLAG_GRAY   0x1
#define MFLAG_BLACK   0x2
#define NONCOLOR_MASK   0xFC
#define MFLAG_BIGBLOCK   0x4
#define MFLAG_CONTINUED   0x8
#define MFLAG_OLD   0x10
#define MFLAG_MODIFIED   0x20
#define MFLAG_INITED   0x40
#define MFLAG_MARK   0x80
#define OFFSET_COLOR_UNMASKED(offsets, pos)   (offsets[pos])
#define OFFSET_COLOR(offsets, pos)   (offsets[pos] & COLOR_MASK)
#define OFFSET_SET_COLOR_UNMASKED(offsets, pos, c)   (offsets[pos] = c)
#define OFFSET_HI_MASK   0xFC
#define OFFSET_LO_MASK   0xFF
#define OFFSET_HI_SHIFT   6
#define OFFSET_SIZE(offsets, pos)   (((OffsetTy)(offsets[pos] & OFFSET_HI_MASK) << OFFSET_HI_SHIFT) | (offsets[(pos)+1]))
#define OFFSET_SET_SIZE_UNMASKED(offsets, pos, s)   (offsets[pos] = (((s) >> OFFSET_HI_SHIFT) & OFFSET_HI_MASK), offsets[(pos)+1] = ((s) & OFFSET_LO_MASK))
#define SKIP   ((Type_Tag)0x7000)
#define TAGGED_EOM   ((Type_Tag)0x6000)
#define UNTAGGED_EOM   (MPAGE_SIZE + 1)
#define NUM_SETS   5
#define NUM_TAGGED_SETS   1
#define NUM_NONATOMIC_SETS   4
#define FREE_LIST_DELTA   0
#define DONT_NEED_MAX_HEAP_SIZE
#define weak_box_resolve(p)   (p)
#define PLUS_ALIGNMENT
#define GC_X_variable_stack   GC_mark_variable_stack
#define X_source(stk, p)   /* */
#define gcX(a)   gcMARK(*a)
#define GC_X_variable_stack   GC_fixup_variable_stack
#define gcX(a)   gcFIXUP(*a)
#define X_source(stk, p)   /* */
#define GETTIME()   ((long)scheme_get_process_milliseconds())
#define INITTIME()   /* empty */
#define PRINTTIME(x)   /* empty */
#define STATS_FORMAT
#define STATS_ARGS
#define THRESH_FREE_LIST_DELTA   FREE_LIST_DELTA
#define gcINLINE   inline

Typedefs

typedef unsigned short OffsetTy
typedef unsigned char OffsetArrTy
typedef unsigned char mtype_t
typedef unsigned char mflags_t
typedef struct MPage MPage
typedef struct ImmobileBox ImmobileBox
typedef struct Fnl_Weak_Link Fnl_Weak_Link

Functions

void ** GC_get_variable_stack ()
void GC_set_variable_stack (void **p)
void GC_register_root_custodian (void *_c)
static MPagefind_page (void *p)
static voidmalloc_pages (size_t len, size_t alignment)
static void free_pages (void *p, size_t len)
void GC_set_stack_base (void *base)
void CompactGC_initialize (CompactGC *gc)
void GC_init_type_tags (int count, int pair, int mutable_pair, int weakbox, int ephemeron, int weakarray, int custbox)
void GC_register_traversers (Type_Tag tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup, int is_constant_size, int is_atomic)
void GC_register_thread (void *p, void *c)
void GC_register_new_thread (void *p, void *c)
void ** GC_malloc_immobile_box (void *p)
void GC_free_immobile_box (void **b)
static int is_marked (CompactGC *gc, void *p)
static int is_finalizable_page (CompactGC *gc, void *p)
static void mark_finalizer (Fnl *fnl)
static void fixup_finalizer (Fnl *fnl)
static void mark_finalizer_weak_link (Fnl_Weak_Link *wl)
static void fixup_finalizer_weak_link (Fnl_Weak_Link *wl)
void GC_finalization_weak_ptr (void **p, int offset)
int GC_is_allocated (void *p)
static void init_tagged_mpage (void **p, MPage *page)
static void init_untagged_mpage (void **p, MPage *page)
static void init_all_mpages (int young)
void GC_mark (const void *p)
static void propagate_tagged_mpage (void **bottom, MPage *page)
static void propagate_tagged_whole_mpage (void **p, MPage *page)
static void propagate_array_mpage (void **bottom, MPage *page)
static void propagate_array_whole_mpage (void **p, MPage *page)
static void propagate_tagged_array_mpage (void **bottom, MPage *page)
static void propagate_tagged_array_whole_mpage (void **p, MPage *page)
static void propagate_xtagged_mpage (void **bottom, MPage *page)
static void propagate_xtagged_whole_mpage (void **p, MPage *page)
static void do_bigblock (void **p, MPage *page, int fixup)
static void propagate_all_mpages ()
static void compact_tagged_mpage (void **p, MPage *page)
static void compact_untagged_mpage (void **p, MPage *page)
static void compact_all_mpages ()
void GC_fixup (void *pp)
void reverse_propagate_new_age (void)
static void fixup_tagged_mpage (void **p, MPage *page)
static void fixup_array_mpage (void **p, MPage *page)
static void fixup_tagged_array_mpage (void **p, MPage *page)
static void fixup_xtagged_mpage (void **p, MPage *page)
static void fixup_all_mpages ()
static void free_unused_mpages ()
void promote_all_ages ()
void protect_old_mpages ()
static int designate_modified (void *p)
static int designate_modified_maybe (void *p, int no_barrier_ok)
void GC_write_barrier (void *p)
static void set_ending_tags (void)
static void init (void)
long scheme_get_process_milliseconds ()
static void mark_roots ()
static void fixup_roots ()
static void gcollect (int full)
voidGC_resolve (void *p)
voidGC_fixup_self (void *p)
voidmalloc_pages_try_hard (size_t len, size_t alignment)
static MPageget_page_rec (void *p, mtype_t mtype, mflags_t flags)
static void new_page (mtype_t mtype, mflags_t mflags, MSet *set, int link)
static voidmalloc_bigblock (long size_in_bytes, mtype_t mtype, int link)
voidGC_malloc_one_tagged (size_t size_in_bytes)
voidGC_malloc_one_small_tagged (size_t size_in_bytes)
voidGC_malloc_one_small_dirty_tagged (size_t size_in_bytes)
voidGC_malloc_pair (void *a, void *b)
static gcINLINE voidmalloc_untagged (size_t size_in_bytes, mtype_t mtype, MSet *set)
voidGC_malloc (size_t size_in_bytes)
voidGC_malloc_allow_interior (size_t size_in_bytes)
voidGC_malloc_atomic_allow_interior (size_t size_in_bytes)
voidGC_malloc_tagged_allow_interior (size_t size_in_bytes)
voidGC_malloc_array_tagged (size_t size_in_bytes)
voidGC_malloc_one_xtagged (size_t size_in_bytes)
voidGC_malloc_atomic (size_t size_in_bytes)
voidGC_malloc_atomic_uncollectable (size_t size_in_bytes)
static void free_bigpage (MPage *page)
void GC_free (void *p)
long GC_malloc_stays_put_threshold ()
void GC_gcollect ()
long GC_get_memory_use (void *c)
int GC_set_account_hook (int type, void *cust, unsigned long b, void *f)
int GC_mtrace_new_id (void *f)
int GC_mtrace_union_current_with (int newval)
unsigned long GC_get_stack_base (void)
static long scan_tagged_mpage (void **p, MPage *page, short trace_for_tag, GC_for_each_found_proc for_each_found)
static long scan_untagged_mpage (void **p, MPage *page)
void GC_dump_with_traces (int flags, GC_get_type_name_proc get_type_name, GC_get_xtagged_name_proc get_xtagged_name, GC_for_each_found_proc for_each_found, short trace_for_tag, GC_print_tagged_value_proc print_tagged_value, int path_length_limit)
void GC_dump (void)
void GC_free_all (void)

Variables

static THREAD_LOCAL CompactGCGC
static voidmark_stack [MARK_STACK_MAX]
static unsigned short mark_stack_type [MARK_STACK_MAX]
static long mark_stack_pos = 0
void(* GC_collect_start_callback )(void)
void(* GC_collect_end_callback )(void)
void(* GC_collect_inform_callback )(int major_gc, long pre_used, long post_used)
void(* GC_out_of_memory )(void)
void(* GC_report_out_of_memory )(void)
unsigned long(* GC_get_thread_stack_base )(void)
void(* GC_mark_xtagged )(void *obj)
void(* GC_fixup_xtagged )(void *obj)
THREAD_LOCAL void ** GC_variable_stack
Type_Tag weak_box_tag = 42
Type_Tag ephemeron_tag = 42
Type_Tag weak_array_tag = 42
Type_Tag pair_tag = 42
Size_Proc size_table [NUMBER_OF_TAGS]
Mark_Proc mark_table [NUMBER_OF_TAGS]
Fixup_Proc fixup_table [NUMBER_OF_TAGS]
static MPagefirst
static MPagelast
static MPagegray_first
MPage ** mpage_maps
static MSet tagged
static MSet atomic
static MSet array
static MSet tagged_array
static MSet xtagged
static MSetsets [NUM_SETS]
static long page_allocations = 0
static long memory_in_use
static long gc_threshold = GROW_ADDITION
static long max_memory_use
static int prev_memory_in_use
static int memory_use_growth
static int generations_available = 1
static long num_seg_faults
static int cycle_count = 0
static int compact_count = 0
static int gc_count = 0
static int skipped_pages
static int scanned_pages
static int young_pages
static int inited_pages
static long iterations
static int fnl_weak_link_count
static int ran_final
static int running_finals
static char zero_sized [4]
static voidpark [2]
static voidpark_save [2]
static int during_gc
static int avoid_collection
static int resolve_for_fixup = 0
static unsigned long stack_base
static ImmobileBoximmobile
static Fnlrun_queue
static Fnllast_in_queue
static Fnl_Weak_Linkfnl_weaks
static int old_tag
static voidold_p
static int min_referenced_page_age
static int initialized
static long dump_info_array [BIGBLOCK_MIN_SIZE]

Class Documentation

struct MPage

Definition at line 227 of file compact.c.

Collaboration diagram for MPage:
Class Members
short age
short alloc_boundary
void * block_start
short compact_boundary
short compact_to_age
mflags_t flags
OffsetTy gray_end
struct MPage * gray_next
OffsetTy gray_start
struct MPage * next
union MPage o
struct MPage * prev
short refs_age
mtype_t type
union MPage u
struct MSet

Definition at line 341 of file compact.c.

Collaboration diagram for MSet:
Class Members
MPage * compact_page
void ** compact_to
OffsetTy compact_to_offset
void ** high
void ** low
MPage * malloc_page
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 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
union MPage.u

Definition at line 233 of file compact.c.

Class Members
OffsetArrTy * offsets
long size
union MPage.o

Definition at line 237 of file compact.c.

Class Members
void * bigblock_start
void ** compact_to

Define Documentation

#define ALIGN_DOUBLES   0

Definition at line 84 of file compact.c.

#define ALLOC_GC_PHASE   0

Definition at line 105 of file compact.c.

#define ALWAYS_COMPACT   2

Definition at line 67 of file compact.c.

#define BIGBLOCK_MIN_SIZE   (1 << (LOG_MPAGE_SIZE - 2))

Definition at line 269 of file compact.c.

#define BYTEPTR (   x)    ((char *)x)

Definition at line 96 of file compact.c.

#define CHECK_STACK_PTRS   0

Definition at line 102 of file compact.c.

#define CHECKS   0

Definition at line 101 of file compact.c.

#define COLOR_MASK   0x3

Definition at line 300 of file compact.c.

#define COMPACT_THRESHOLD   0.2

Definition at line 70 of file compact.c.

Definition at line 66 of file compact.c.

#define DEFINE_MALLOC_FREE   0

Definition at line 109 of file compact.c.

Definition at line 426 of file compact.c.

Definition at line 270 of file compact.c.

#define FREE_LIST_DELTA   0

Definition at line 366 of file compact.c.

#define GC_get_GC ( )    (GC)

Definition at line 22 of file compact.c.

#define gc_on_free_list_tag   511

Definition at line 179 of file compact.c.

Definition at line 2757 of file compact.c.

Definition at line 2757 of file compact.c.

#define gcINLINE   inline

Definition at line 3882 of file compact.c.

#define GCTYPE   CompactGC

Definition at line 21 of file compact.c.

#define gcX (   a)    gcMARK(*a)

Definition at line 2758 of file compact.c.

#define gcX (   a)    gcFIXUP(*a)

Definition at line 2758 of file compact.c.

#define GENERATIONS   1

Definition at line 30 of file compact.c.

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

Definition at line 2880 of file compact.c.

#define GROW_ADDITION   500000

Definition at line 28 of file compact.c.

#define GROW_FACTOR   1.5

Definition at line 27 of file compact.c.

#define INCREMENT_CYCLE_COUNT_GROWTH   1048576

Definition at line 91 of file compact.c.

#define INITTIME ( )    /* empty */

Definition at line 2890 of file compact.c.

#define KEEP_BACKPOINTERS   0

Definition at line 108 of file compact.c.

#define LOG_MAP_SIZE   9

Definition at line 279 of file compact.c.

Definition at line 280 of file compact.c.

#define LOG_MPAGE_SIZE   14

Definition at line 263 of file compact.c.

Definition at line 273 of file compact.c.

#define LOG_WORD_SIZE   2

Definition at line 87 of file compact.c.

#define MAP_MASK   ((1 << (LOG_MAP_SIZE + LOG_MPAGE_SIZE)) - 1)

Definition at line 286 of file compact.c.

#define MAP_SHIFT   LOG_MPAGE_SIZE

Definition at line 287 of file compact.c.

#define MAP_SIZE   (1 << LOG_MAP_SIZE)

Definition at line 281 of file compact.c.

Definition at line 285 of file compact.c.

#define MAPS_SIZE   (1 << LOG_MAPS_SIZE)

Definition at line 282 of file compact.c.

#define MARK_STACK_MAX   4096

Definition at line 125 of file compact.c.

#define MARK_STATS   0

Definition at line 104 of file compact.c.

#define MFLAG_BIGBLOCK   0x4

Definition at line 307 of file compact.c.

#define MFLAG_BLACK   0x2

Definition at line 303 of file compact.c.

#define MFLAG_CONTINUED   0x8

Definition at line 308 of file compact.c.

#define MFLAG_GRAY   0x1

Definition at line 302 of file compact.c.

#define MFLAG_INITED   0x40

Definition at line 312 of file compact.c.

#define MFLAG_MARK   0x80

Definition at line 313 of file compact.c.

#define MFLAG_MODIFIED   0x20

Definition at line 311 of file compact.c.

#define MFLAG_OLD   0x10

Definition at line 310 of file compact.c.

#define MPAGE_MASK   ((1 << LOG_MPAGE_SIZE) - 1)

Definition at line 266 of file compact.c.

#define MPAGE_SIZE   (1 << LOG_MPAGE_SIZE)

Definition at line 264 of file compact.c.

#define MPAGE_START   ~MPAGE_MASK

Definition at line 267 of file compact.c.

#define MPAGE_WORDS   (1 << (LOG_MPAGE_SIZE - LOG_WORD_SIZE))

Definition at line 265 of file compact.c.

#define MTYPE_ARRAY   4

Definition at line 294 of file compact.c.

#define MTYPE_ATOMIC   2

Definition at line 292 of file compact.c.

#define MTYPE_MALLOCFREE   6

Definition at line 296 of file compact.c.

#define MTYPE_NONE   0

Definition at line 290 of file compact.c.

#define MTYPE_TAGGED   1

Definition at line 291 of file compact.c.

#define MTYPE_TAGGED_ARRAY   3

Definition at line 293 of file compact.c.

#define MTYPE_XTAGGED   5

Definition at line 295 of file compact.c.

#define NEVER_COMPACT   0

Definition at line 69 of file compact.c.

#define NOISY   0

Definition at line 103 of file compact.c.

#define NONCOLOR_MASK   0xFC

Definition at line 305 of file compact.c.

#define NUM_NONATOMIC_SETS   4

Definition at line 353 of file compact.c.

#define NUM_SETS   5

Definition at line 351 of file compact.c.

#define NUM_TAGGED_SETS   1

Definition at line 352 of file compact.c.

#define NUMBER_OF_TAGS   512

Definition at line 16 of file compact.c.

#define OFFSET_COLOR (   offsets,
  pos 
)    (offsets[pos] & COLOR_MASK)

Definition at line 318 of file compact.c.

#define OFFSET_COLOR_UNMASKED (   offsets,
  pos 
)    (offsets[pos])

Definition at line 317 of file compact.c.

#define OFFSET_HI_MASK   0xFC

Definition at line 322 of file compact.c.

#define OFFSET_HI_SHIFT   6

Definition at line 324 of file compact.c.

#define OFFSET_LO_MASK   0xFF

Definition at line 323 of file compact.c.

#define OFFSET_SET_COLOR_UNMASKED (   offsets,
  pos,
 
)    (offsets[pos] = c)

Definition at line 319 of file compact.c.

#define OFFSET_SET_SIZE_UNMASKED (   offsets,
  pos,
 
)    (offsets[pos] = (((s) >> OFFSET_HI_SHIFT) & OFFSET_HI_MASK), offsets[(pos)+1] = ((s) & OFFSET_LO_MASK))

Definition at line 326 of file compact.c.

#define OFFSET_SIZE (   offsets,
  pos 
)    (((OffsetTy)(offsets[pos] & OFFSET_HI_MASK) << OFFSET_HI_SHIFT) | (offsets[(pos)+1]))

Definition at line 325 of file compact.c.

#define ofm_malloc   malloc

Definition at line 23 of file compact.c.

#define OPAGE_SIZE   (sizeof(OffsetTy) << LOG_OPAGE_SIZE)

Definition at line 274 of file compact.c.

#define OS_X_GENERATIONS   1

Definition at line 33 of file compact.c.

#define PLUS_ALIGNMENT
#define PRINTTIME (   x)    /* empty */

Definition at line 2891 of file compact.c.

#define RECORD_MARK_SRC   0

Definition at line 107 of file compact.c.

#define SEARCH   0

Definition at line 100 of file compact.c.

#define SELECTIVELY_COMPACT   1

Definition at line 68 of file compact.c.

#define SKIP   ((Type_Tag)0x7000)

Definition at line 335 of file compact.c.

#define SKIP_FORCED_GC   0

Definition at line 106 of file compact.c.

#define SQUASH_OFFSETS   1

Definition at line 201 of file compact.c.

#define STATS_ARGS
#define STATS_FORMAT
#define TAGGED_EOM   ((Type_Tag)0x6000)

Definition at line 336 of file compact.c.

#define TIME   0

Definition at line 99 of file compact.c.

#define UNTAGGED_EOM   (MPAGE_SIZE + 1)

Definition at line 337 of file compact.c.

#define USE_FREELIST   0

Definition at line 63 of file compact.c.

#define weak_box_resolve (   p)    (p)

Definition at line 564 of file compact.c.

#define WIN32_GENERATIONS   1

Definition at line 34 of file compact.c.

#define WORD_BIT_COUNT   (WORD_SIZE << 3)

Definition at line 89 of file compact.c.

#define WORD_SIZE   (1 << LOG_WORD_SIZE)

Definition at line 88 of file compact.c.

#define X_source (   stk,
  p 
)    /* */

Definition at line 2759 of file compact.c.

#define X_source (   stk,
  p 
)    /* */

Definition at line 2759 of file compact.c.


Typedef Documentation

typedef unsigned char mflags_t

Definition at line 225 of file compact.c.

typedef struct MPage MPage
typedef unsigned char mtype_t

Definition at line 224 of file compact.c.

typedef unsigned char OffsetArrTy

Definition at line 219 of file compact.c.

typedef unsigned short OffsetTy

Definition at line 217 of file compact.c.


Function Documentation

static void compact_all_mpages ( ) [static]

Definition at line 2022 of file compact.c.

{
  MPage *page;
  int i;

  for (i = 0; i < NUM_SETS; i++)
    sets[i]->compact_to_offset = MPAGE_WORDS;

  for (page = first; page; page = page->next) {
    if (!(page->flags & (MFLAG_BIGBLOCK | MFLAG_OLD))) {
      if (page->flags & COLOR_MASK) {
       void *p;
       
       page->flags -= (page->flags & MFLAG_INITED);
       p = page->block_start;
       
       if (page->type <= MTYPE_TAGGED)
         compact_tagged_mpage((void **)p, page);
       else
         compact_untagged_mpage((void **)p, page);
      } else {
       /* Set compact_boundar to 0 to indicate no moves: */
       page->compact_boundary = 0;
#if NOISY
       GCPRINT(GCOUTF, "x: %lx\n", (long)page->block_start);
#endif
      }
    }
  }

  for (i = 0; i < NUM_TAGGED_SETS; i++) {
    if (sets[i]->compact_to_offset < MPAGE_WORDS)
      *(Type_Tag *)(sets[i]->compact_to + sets[i]->compact_to_offset) = TAGGED_EOM;
  }
  for (i = NUM_TAGGED_SETS; i < NUM_SETS; i++) {
    if (sets[i]->compact_to_offset < MPAGE_WORDS)
      *(long *)(sets[i]->compact_to + sets[i]->compact_to_offset) = UNTAGGED_EOM - 1;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void compact_tagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 1752 of file compact.c.

{
  int to_near = 0, set_age = 0;
  OffsetTy offset, dest_offset, dest_start_offset;
  OffsetArrTy *offsets;
  void **dest, **startp;
  void **top;
  MSet *set;

  offsets = page->u.offsets;

  top = p + page->alloc_boundary;

  startp = p;
  switch (page->type) {
  case MTYPE_TAGGED:
  default:
    set = &tagged;
    break;
  }
  dest = set->compact_to;
  dest_start_offset = set->compact_to_offset;
  dest_offset = dest_start_offset;
  offset = 0;

  page->o.compact_to = dest;
  page->compact_boundary = MPAGE_WORDS;
  
  while (p < top) {
    long size;

    size = OFFSET_SIZE(offsets, offset);

#if CHECKS
    if (!size) {
      CRASH(19);
    }
    prev_prev_prev_ptr = prev_prev_ptr;
    prev_prev_ptr = prev_ptr;
    prev_ptr = p;
#endif

    if (OFFSET_COLOR(offsets, offset)) {
#if ALIGN_DOUBLES
#define PLUS_ALIGNMENT + alignment
      long alignment;
      if (!(size & 0x1) && (dest_offset & 0x1))
       alignment = 1;
      else
       alignment = 0;
#else
# define PLUS_ALIGNMENT       
#endif
      
      if (dest_offset + size PLUS_ALIGNMENT > MPAGE_WORDS) {
       /* Set end of allocation area in previous page: */
       if (dest_offset < MPAGE_WORDS)
         *(Type_Tag *)(dest + dest_offset) = TAGGED_EOM;
       
#if NOISY
       GCPRINT(GCOUTF, "t: %lx [0,%d] -> %lx [%d,%d]\n", 
              (long)startp, offset,
              (long)dest, dest_start_offset, dest_offset);
#endif

       dest_offset = 0;
       dest = startp;
       to_near = 1;
       if (set_age) {
         page->compact_boundary = offset;
         set->compact_page->age = page->age;
         set->compact_page->refs_age = page->age;
       } else
         /* Haven't moved anything; set boundary to 0 to indicate this */
         page->compact_boundary = 0;
      } else {
       set_age = 1;
#if ALIGN_DOUBLES
       if (alignment) {
         *(Type_Tag *)(dest + dest_offset) = SKIP;
         dest_offset++;
       }
#endif
      }
      
      if (!to_near || (dest_offset != offset)) {
       memmove(dest + dest_offset, p, size << LOG_WORD_SIZE);
#if KEEP_BACKPOINTERS
       if (to_near)
         page->backpointer_page[dest_offset] = page->backpointer_page[offset];
       else
         set->compact_page->backpointer_page[dest_offset] = page->backpointer_page[offset];
#endif
      }
      
      OFFSET_SET_SIZE_UNMASKED(offsets, offset, dest_offset);
      offset += size;
      dest_offset += size;
 
      p += size;
    } else {
      p += size;
      offset += size;
    }
  }

  if (to_near)
    set->compact_page = page;
  set->compact_to = dest;
  set->compact_to_offset = dest_offset;

  if (!to_near) {
    /* Nothing left in here. Reset color to white: */
    page->flags = (page->flags & NONCOLOR_MASK);
#if NOISY
    GCPRINT(GCOUTF, "t: %lx [all=%d] -> %lx [%d,%d]\n", 
           (long)startp, offset,
           (long)dest, dest_start_offset, dest_offset);
#endif
  }
}

Here is the caller graph for this function:

static void compact_untagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 1874 of file compact.c.

{
  int to_near = 0, set_age = 0;
  OffsetTy offset = 0, dest_offset;
  OffsetArrTy *offsets;
  void **dest, **startp, **top;
  MSet *set;

  offsets = page->u.offsets;

  startp = p;
  switch (page->type) {
  case MTYPE_TAGGED_ARRAY:
    set = &tagged_array;
    break;
  case MTYPE_ATOMIC:
    set = &atomic;
    break;
  case MTYPE_XTAGGED:
    set = &xtagged;
    break;
  default:
    set = &array;
    break;
  }

  dest = set->compact_to;
  dest_offset = set->compact_to_offset;

  page->o.compact_to = dest;
  page->compact_boundary = MPAGE_WORDS;

  top = p + MPAGE_WORDS;

#if CHECKS
  if (dest == startp) {
    if (dest_offset < MPAGE_WORDS) {
      /* Can't compact to self! */
      CRASH(20);
    }
  }
#endif

  while (p < top) {
    long size;
      
    size = *(long *)p + 1;
    
    if (size == UNTAGGED_EOM) {
#if CHECKS
      if (p < startp + page->alloc_boundary) {
       /* Premature end */
       CRASH(21);
      }
#endif
      break;
    }

#if CHECKS
    if (size >= BIGBLOCK_MIN_SIZE) {
      CRASH(22);
    }
#endif

    if (OFFSET_COLOR(offsets, offset)) {
#if ALIGN_DOUBLES
      long alignment;
      if ((size & 0x1) && !(dest_offset & 0x1))
       alignment = 1;
      else
       alignment = 0;
#endif
       
      if ((long)dest_offset + size PLUS_ALIGNMENT > MPAGE_WORDS) {
       /* Set end of allocation area in previous page: */
       if (dest_offset < MPAGE_WORDS)
         *(long *)(dest + dest_offset) = UNTAGGED_EOM - 1;
       
#if NOISY
       GCPRINT(GCOUTF, "u: %lx -> %lx [%d]\n", (long)startp, (long)dest, offset);
#endif

       dest_offset = 0;
       dest = startp;
       to_near = 1;
#if ALIGN_DOUBLES
       if (size & 0x1) {
         dest[0] = 0;
         dest_offset++;
       }
#endif

       if (set_age) {
         page->compact_boundary = offset;
         set->compact_page->age = page->age;
         set->compact_page->refs_age = page->age;
       } else
         /* Haven't moved anything; set boundary to 0 to indicate this */
         page->compact_boundary = 0;
      } else {
       set_age = 1;
#if ALIGN_DOUBLES
       if (alignment) {
         dest[dest_offset] = 0;
         dest_offset++;
       }
#endif
      }

      if (!to_near || (dest_offset != offset)) {
       memmove(dest + dest_offset, p, size << LOG_WORD_SIZE);
#if KEEP_BACKPOINTERS
       if (to_near)
         page->backpointer_page[dest_offset] = page->backpointer_page[offset];
       else
         set->compact_page->backpointer_page[dest_offset] = page->backpointer_page[offset];
#endif
      }
      
      OFFSET_SET_SIZE_UNMASKED(offsets, offset, dest_offset+1);
#if CHECKS
      if (!offsets[offset] && !offsets[offset+1])
       CRASH(23);
#endif
      offset += size;
      dest_offset += size;
 
      p += size;
    } else {
      p += size;
      offset += size;
    }
  }

  set->compact_to = dest;
  set->compact_to_offset = dest_offset;
  if (to_near)
    set->compact_page = page;

  if (!to_near) {
    /* Nothing left in here. Reset color to white: */
    page->flags = (page->flags & NONCOLOR_MASK);
#if NOISY
    GCPRINT(GCOUTF, "u: %lx -> %lx [all]\n", (long)startp, (long)dest);
#endif
  }
}

Here is the caller graph for this function:

Definition at line 453 of file compact.c.

                                         {
  memset(gc, 0, sizeof(CompactGC));
  gc->vm = vm_create();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int designate_modified ( void p) [static]

Definition at line 2714 of file compact.c.

{
  return designate_modified_maybe(p, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int designate_modified_maybe ( void p,
int  no_barrier_ok 
) [static]

Definition at line 2659 of file compact.c.

{
  unsigned long g = ((unsigned long)p >> MAPS_SHIFT);
  MPage *map;

#if CHECKS
  if (during_gc)
    CRASH(31);
#endif

  map = mpage_maps[g];
  if (map) {
    unsigned long addr = (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);
    MPage *page;

    page = map + addr;
    if (page->type) {
      if (page->flags & MFLAG_CONTINUED) {
       designate_modified(page->o.bigblock_start);
       num_seg_faults++;
       return 1;
      } else if (page->age) {
        if (page->flags & MFLAG_MODIFIED) {
          if (no_barrier_ok)
            return 0;
        } else {
          page->flags |= MFLAG_MODIFIED;
          p = (void *)((long)p & MPAGE_START);
          if (page->flags & MFLAG_BIGBLOCK)
            vm_protect_pages(p, page->u.size, 1);
          else
            vm_protect_pages(p, MPAGE_SIZE, 1);
          num_seg_faults++;
          return 1;
        }
      } else if (no_barrier_ok) {
        return 0;
      }

      GCPRINT(GCOUTF, "Seg fault (internal error) at %lx [%ld]\n", 
             (long)p, num_seg_faults);
      return 0;
    }
  }

  
  GCPRINT(GCOUTF, "Access on unmapped page at %lx [%ld]\n", 
         (long)p, num_seg_faults);

#if defined(_WIN32) && defined(CHECKS)
  DebugBreak();
#endif
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_bigblock ( void **  p,
MPage page,
int  fixup 
) [static]

Definition at line 1521 of file compact.c.

{
  switch (page->type) {
  case MTYPE_ATOMIC:
    return;

  case MTYPE_TAGGED:
    {
      Type_Tag tag;

      tag = *(Type_Tag *)p;

#if CHECKS
      if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
       CRASH(16);
      }
      prev_var_stack = GC_variable_stack;
#endif
#if RECORD_MARK_SRC
      mark_src = p;
      mark_type = MTYPE_TAGGED;
#endif

      if (fixup)
       fixup_table[tag](p);
      else
       mark_table[tag](p);

#if CHECKS
      if (prev_var_stack != GC_variable_stack) {
       CRASH(17);
      }
#endif
    
      return;
    }

  case MTYPE_TAGGED_ARRAY:
    {
      int i, elem_size, size;
      void **mp = p;
      Type_Tag tag;
      Mark_Proc mark;

      size = page->u.size >> LOG_WORD_SIZE;
      tag = *(Type_Tag *)mp;

#if RECORD_MARK_SRC
      mark_src = mp;
      mark_type = MTYPE_TAGGED_ARRAY;
#endif

      if (fixup)
       mark = fixup_table[tag];
      else
       mark = mark_table[tag];
      elem_size = mark(mp);      
      mp += elem_size;
      for (i = elem_size; i < size; i += elem_size, mp += elem_size)
       mark(mp);

      return;
    }

  case MTYPE_ARRAY:
    {
      int i;
      long size = page->u.size >> LOG_WORD_SIZE;
    
      if (fixup) {
       for (i = 0; i < size; i++, p++) {
         if (*p)
           gcFIXUP(*p);
       }
      } else {
#if RECORD_MARK_SRC
       mark_src = p;
       mark_type = MTYPE_ARRAY;
#endif
       for (i = 0; i < size; i++, p++) {
         if (*p)
           gcMARK(*p);
       }
      }

      return;
    }

  case MTYPE_XTAGGED:
  default:
#if RECORD_MARK_SRC
    mark_src = p;
    mark_type = MTYPE_XTAGGED;
#endif
   if (fixup)
     GC_fixup_xtagged(p);
   else
     GC_mark_xtagged(p);
   return;
  }
}

Here is the caller graph for this function:

static MPage * find_page ( void p) [static]

Definition at line 672 of file compact.c.

{
  unsigned long g = ((unsigned long)p >> MAPS_SHIFT);
  MPage *map;

  map = mpage_maps[g];
  if (map) {
    unsigned long addr = (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);
    MPage *page;

    page = map + addr;
    return page;
  }
  
  return NULL;  
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_all_mpages ( ) [static]

Definition at line 2491 of file compact.c.

{
  MPage *page;

  for (page = first; page; page = page->next) {
    if (page->flags & COLOR_MASK) {
      if (page->type != MTYPE_ATOMIC) {
       void *p;

       scanned_pages++;
       min_referenced_page_age = page->age;
       p = page->block_start;

#if NOISY
       GCPRINT(GCOUTF, "Fixup %lx\n", (long)p);
#endif

       if (page->flags & MFLAG_BIGBLOCK) {
         do_bigblock((void **)p, page, 1);
#if KEEP_BACKPOINTERS
         GC_fixup((void *)&(page->backpointer_page));
#endif
       } else {
         switch (page->type) {
         case MTYPE_TAGGED:
           fixup_tagged_mpage((void **)p, page);
           break;
         case MTYPE_TAGGED_ARRAY:
           fixup_tagged_array_mpage((void **)p, page);
           break;
         case MTYPE_XTAGGED:
           fixup_xtagged_mpage((void **)p, page);
           break;
         default:
           fixup_array_mpage((void **)p, page);
         }
       }

       page->refs_age = min_referenced_page_age;
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_array_mpage ( void **  p,
MPage page 
) [static]

Definition at line 2375 of file compact.c.

{
  void **top;
#if KEEP_BACKPOINTERS
  long bp_delta = page->backpointer_page - p;
#endif

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM)
      break;

#if CHECKS
    if (size >= BIGBLOCK_MIN_SIZE) {
      CRASH(29);
    }
#endif

#if KEEP_BACKPOINTERS
    GC_fixup((void *)(p + bp_delta));
#endif

    for (p++; --size; p++) {
      gcFIXUP(*p);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_finalizer ( Fnl fnl) [static]

Definition at line 599 of file compact.c.

{
#if CHECKS
  static void *old_fnl_p;
  static MPage *old_fnl_page;
  
  old_fnl_p = fnl->p;
  old_fnl_page = find_page(fnl->p);
#endif
  
  gcFIXUP(fnl->next);
  gcFIXUP(fnl->data);
  gcFIXUP(fnl->p);

#if CHECKS
  if (!fnl->tagged && fnl->size < BIGBLOCK_MIN_SIZE) {
    if (!(((long)fnl->p) & MPAGE_MASK))
      CRASH(3);
  }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_finalizer_weak_link ( Fnl_Weak_Link wl) [static]

Definition at line 635 of file compact.c.

{
  gcFIXUP(wl->next);
  gcFIXUP(wl->p);
}

Here is the caller graph for this function:

static void fixup_roots ( ) [static]

Definition at line 2937 of file compact.c.

{
  Roots *roots = &GC->roots;
  ImmobileBox *ib;
  int i;

  for (i = 0; i < roots->count; i += 2) {
    void **s = (void **)roots->roots[i];
    void **e = (void **)roots->roots[i + 1];

    while (s < e) {
      gcFIXUP(*s);
      s++;
    }
  }

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

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

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_tagged_array_mpage ( void **  p,
MPage page 
) [static]

Definition at line 2408 of file compact.c.

{
  void **top;
#if KEEP_BACKPOINTERS
  long bp_delta = page->backpointer_page - p;
#endif

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size;
    int i, elem_size;
    void **mp;
    Type_Tag tag;
    Fixup_Proc traverse;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM)
      break;

    mp = p + 1;
    p += size;
    size--;

#if ALIGN_DOUBLES
    if (size) {
#endif
#if KEEP_BACKPOINTERS
      GC_fixup((void *)(mp - 1 + bp_delta));
#endif
      tag = *(Type_Tag *)mp;

      traverse = fixup_table[tag];
      elem_size = traverse(mp);
      mp += elem_size;
      for (i = elem_size; i < size; i += elem_size, mp += elem_size)
       traverse(mp);

#if ALIGN_DOUBLES
    }
#endif
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_tagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 2328 of file compact.c.

{
  void **top;
#if KEEP_BACKPOINTERS
  long bp_delta = page->backpointer_page - p;
#endif

  top = p + MPAGE_WORDS;

  while (p < top) {
    Type_Tag tag;
    long size;

    tag = *(Type_Tag *)p;

    if (tag == TAGGED_EOM)
      break;

#if ALIGN_DOUBLES
    if (tag == SKIP) {
      p++;
    } else {
#endif

#if CHECKS
      if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
       GCFLUSHOUT();
       CRASH(28);
      }
      prev_var_stack = prev_ptr;
      prev_ptr = p;
#endif

      size = fixup_table[tag](p);

#if KEEP_BACKPOINTERS
      GC_fixup((void *)(p + bp_delta));
#endif

      p += size;

#if ALIGN_DOUBLES
    }
#endif
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void fixup_xtagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 2453 of file compact.c.

{
  void **top;
#if KEEP_BACKPOINTERS
  long bp_delta = page->backpointer_page - p;
#endif

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM)
      break;

#if CHECKS
    if (size >= BIGBLOCK_MIN_SIZE) {
      CRASH(30);
    }
#endif

#if ALIGN_DOUBLES
    if (size > 1) {
#endif
      GC_fixup_xtagged(p + 1);
#if KEEP_BACKPOINTERS
      GC_fixup((void *)(p + bp_delta));
#endif
#if ALIGN_DOUBLES
    }
#endif

    p += size;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_bigpage ( MPage page) [static]

Definition at line 4009 of file compact.c.

{
  long s;
  unsigned long i, j;

  page->type = 0;
  page->flags = 0;

  free_pages(page->block_start, page->u.size);
       
  s = page->u.size;
  i = ((unsigned long)page->block_start >> MAPS_SHIFT);
  j = (((unsigned long)page->block_start & MAP_MASK) >> MAP_SHIFT);
  while (s > MPAGE_SIZE) {
    s -= MPAGE_SIZE;
    j++;
    if (j == MAP_SIZE) {
      j = 0;
      i++;
    }
    mpage_maps[i][j].type = 0;
    mpage_maps[i][j].flags = 0;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_pages ( void p,
size_t  len 
) [static]

Definition at line 436 of file compact.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void free_unused_mpages ( ) [static]

Definition at line 2541 of file compact.c.

{
  MPage *page, *next;
  memory_in_use = 0;

  for (page = first; page; page = next) {
    next = page->next;
    if (!(page->flags & (COLOR_MASK | MFLAG_OLD))) {
      void *p;
      p = page->block_start;

      if (page->prev)
       page->prev->next = page->next;
      else
       first = page->next;
      if (page->next)
       page->next->prev = page->prev;
      else
       last = page->prev;

      if (page->flags & MFLAG_BIGBLOCK) {
#if NOISY
       GCPRINT(GCOUTF, "Free %lx - %lx\n", (long)p,
              (long)p + page->u.size);
#endif

       free_pages((void *)p, page->u.size);
       
       {
        long s = page->u.size;
        unsigned long i = ((unsigned long)p >> MAPS_SHIFT);
        unsigned long j = (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);
        while (s > MPAGE_SIZE) {
          s -= MPAGE_SIZE;
          j++;
          if (j == MAP_SIZE) {
            j = 0;
            i++;
          }
          mpage_maps[i][j].type = 0;
          mpage_maps[i][j].flags = 0;
        }
       }
      } else {
#if NOISY
       GCPRINT(GCOUTF, "Free %lx\n", (long)p);
#endif
       free_pages((void *)p, MPAGE_SIZE);
       free_pages(page->u.offsets, OPAGE_SIZE);
#if KEEP_BACKPOINTERS
       free_pages(page->backpointer_page, MPAGE_SIZE);
#endif
      }
      
      if (page->flags & MFLAG_INITED)
       scanned_pages++;
      
      page->type = 0;
      page->flags = 0;
      skipped_pages++;
    } else {
      if (page->flags & MFLAG_BIGBLOCK) {
       if (!(page->flags & MFLAG_CONTINUED))
         memory_in_use += page->u.size;
      } else
       memory_in_use += MPAGE_SIZE;
    }
  }

  vm_flush_freed_pages(GC->vm);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void GC_dump ( void  )

Definition at line 4786 of file compact.c.

Here is the call graph for this function:

void GC_dump_with_traces ( int  flags,
GC_get_type_name_proc  get_type_name,
GC_get_xtagged_name_proc  get_xtagged_name,
GC_for_each_found_proc  for_each_found,
short  trace_for_tag,
GC_print_tagged_value_proc  print_tagged_value,
int  path_length_limit 
)

Definition at line 4508 of file compact.c.

{
  int i;
  long waste = 0;

  if (!(flags & GC_DUMP_SHOW_TRACE))
    trace_for_tag = -1;
#if KEEP_BACKPOINTERS
  reset_object_traces();
#endif
  if (for_each_found)
    avoid_collection++;

  if (flags & GC_DUMP_SHOW_DETAILS) {
    GCPRINT(GCOUTF, "t=tagged a=atomic v=array x=xtagged g=tagarray\n");
    GCPRINT(GCOUTF, "mpagesize=%ld  opagesize=%ld\n", (long)MPAGE_SIZE, (long)OPAGE_SIZE);
    GCPRINT(GCOUTF, "[");
    for (i = 0; i < MAPS_SIZE; i++) {
      if (i && !(i & 63))
       GCPRINT(GCOUTF, "\n ");

      if (mpage_maps[i])
       GCPRINT(GCOUTF, "*");
      else
       GCPRINT(GCOUTF, "-");
    }
    GCPRINT(GCOUTF, "]\n");
    for (i = 0; i < MAPS_SIZE; i++) {
      MPage *maps = mpage_maps[i];
      if (maps) {
       int j;
       GCPRINT(GCOUTF, "%.2x:\n ", i);
       for (j = 0; j < MAP_SIZE; j++) {
         if (j && !(j & 63))
           GCPRINT(GCOUTF, "\n ");

         if (maps[j].type
#if DEFINE_MALLOC_FREE
             && (maps[j].type != MTYPE_MALLOCFREE)
#endif
             ) {
           int c;

           if (maps[j].flags & MFLAG_CONTINUED) 
             c = '.';
           else {
             if (maps[j].type <= MTYPE_TAGGED)
              c = 't';
             else if (maps[j].type == MTYPE_TAGGED_ARRAY)
              c = 'g';
             else if (maps[j].type == MTYPE_ATOMIC)
              c = 'a';
             else if (maps[j].type == MTYPE_XTAGGED)
              c = 'x';
             else
              c = 'v';
           
             if (maps[j].flags & MFLAG_BIGBLOCK)
              c = c - ('a' - 'A');
           }

           GCPRINT(GCOUTF, "%c", c);
         } else {
           GCPRINT(GCOUTF, "-");
         }
       }
       GCPRINT(GCOUTF, "\n");
      }
    }

    {
      MPage *page;

      GCPRINT(GCOUTF, "Block info: [type][modified?][age][refs-age]\n");
      for (page = first, i = 0; page; page = page->next, i++) {
       int c;

       if (page->flags & MFLAG_CONTINUED) 
         c = '.';
       else {
         if (page->type <= MTYPE_TAGGED)
           c = 't';
         else if (page->type == MTYPE_TAGGED_ARRAY)
           c = 'g';
         else if (page->type == MTYPE_ATOMIC)
           c = 'a';
         else if (page->type == MTYPE_XTAGGED)
           c = 'x';
         else
           c = 'v';
        
         if (page->flags & MFLAG_BIGBLOCK)
           c = c - ('a' - 'A');
       }
       
       GCPRINT(GCOUTF, " %c%c%c%c",
              c,
              ((page->flags & MFLAG_MODIFIED)
               ? 'M'
               : '_'),
              ((page->age < 10)
               ? (page->age + '0')
               : (page->age + 'a' - 10)),
              ((page->type == MTYPE_ATOMIC)
               ? '-'
               : ((page->refs_age < 10)
                  ? (page->refs_age + '0')
                  : (page->refs_age + 'a' - 10))));
       if ((i % 10) == 9)
         GCPRINT(GCOUTF, "\n");
      }
      GCPRINT(GCOUTF, "\n");
    }
  }

  {
    int j;

    init();
    set_ending_tags();

    for (j = 0; j < NUM_SETS; j++) {
      int kind, i;
      char *name;
      MPage *page;
      long used, total;

      switch (j) {
      case 1: kind = MTYPE_ARRAY; name = "array"; break;
      case 2: kind = MTYPE_ATOMIC; name = "atomic"; break;
      case 3: kind = MTYPE_XTAGGED; name = "xtagged"; break;
      case 4: kind = MTYPE_TAGGED_ARRAY; name = "tagarray"; break;
      default: kind = MTYPE_TAGGED; name = "tagged"; break;
      }

      for (i = 0; i < (BIGBLOCK_MIN_SIZE >> LOG_WORD_SIZE); i++)
       dump_info_array[i] = 0;

      total = 0;

      for (page = first; page; page = page->next) {
       if ((page->type == kind) && !(page->flags & MFLAG_BIGBLOCK)) {
         if (j >= NUM_TAGGED_SETS)
           used = scan_untagged_mpage(page->block_start, page); /* gets size counts */
         else
           used = scan_tagged_mpage(page->block_start, page, 
                                 trace_for_tag, for_each_found); /* gets tag counts */

         total += used;
         waste += (MPAGE_WORDS - used);
       }
       if ((page->flags & MFLAG_BIGBLOCK)
           && (page->type == kind)
           && (((trace_for_tag >= (BIGBLOCK_MIN_SIZE >> LOG_WORD_SIZE))
               && (page->u.size > trace_for_tag))
              || (page->u.size == -trace_for_tag))) {
#if KEEP_BACKPOINTERS
         register_traced_object(page->block_start);
#endif
         if (for_each_found)
           for_each_found(page->block_start);
       }
      }

      if (j >= NUM_TAGGED_SETS) {
       int k = 0;
       if (flags & GC_DUMP_SHOW_DETAILS) {
         GCPRINT(GCOUTF, "%s counts: ", name);
         for (i = 0; i < (BIGBLOCK_MIN_SIZE >> LOG_WORD_SIZE); i++) {
           if (dump_info_array[i]) {
             k++;
             if (k == 10) {
              GCPRINT(GCOUTF, "\n    ");
              k = 0;
             }
             GCPRINT(GCOUTF, " [%d:%ld]", i << LOG_WORD_SIZE, dump_info_array[i]);
           }
         }
         GCPRINT(GCOUTF, "\n");
       }
      } else {
       GCPRINT(GCOUTF, "Tag counts and sizes:\n");
       GCPRINT(GCOUTF, "Begin MzScheme3m\n");
       for (i = 0; i < NUMBER_OF_TAGS; i++) {
         if (dump_info_array[i]) {
           char *tn, buf[256];
           switch(i) {
           case gc_on_free_list_tag: tn = "freelist-elem"; break;
           default:
             if (i == weak_array_tag)
              tn = "weak-array";
             else if (get_type_name)
              tn = get_type_name((Type_Tag)i);
             else
              tn = NULL;
             if (!tn) {
              sprintf(buf, "unknown,%d", i);
              tn = buf;
             }
             break;
           }
           GCPRINT(GCOUTF, "  %20.20s: %10ld %10ld\n", tn, dump_info_array[i], (dump_info_array[i + NUMBER_OF_TAGS]) << LOG_WORD_SIZE);
         }
       }
       GCPRINT(GCOUTF, "End MzScheme3m\n");
      }

      if (flags & GC_DUMP_SHOW_DETAILS) {
       int did_big = 0;
       for (page = first; page; page = page->next) {
         if ((page->type == kind) && (page->flags & MFLAG_BIGBLOCK) && !(page->flags & MFLAG_CONTINUED)) {
           if (!did_big) {
             GCPRINT(GCOUTF, "    ");
             did_big = 1;
           }
           if (j >= NUM_TAGGED_SETS)
             GCPRINT(GCOUTF, " [+%ld]", page->u.size);
           else
             GCPRINT(GCOUTF, " %d:[+%ld]", (int)*(Type_Tag *)(page->block_start), page->u.size);
           
           total += (page->u.size >> LOG_WORD_SIZE);
           waste += ((page->u.size >> LOG_WORD_SIZE)  & (MPAGE_WORDS - 1));
         }
       }
       if (did_big)
         GCPRINT(GCOUTF, "\n");
      }

      GCPRINT(GCOUTF, " Total %s: %ld\n", name, total << LOG_WORD_SIZE);
    }
  }

  GCPRINT(GCOUTF, "Active fnls: %d\n", GC->num_fnls);
  GCPRINT(GCOUTF, "Active fnl weak links: %d\n", fnl_weak_link_count);

  if (memory_in_use > max_memory_use)
    max_memory_use = memory_in_use;
  
  GCPRINT(GCOUTF, "Number of collections: %d  (%d compacting)\n", gc_count, compact_count);
  GCPRINT(GCOUTF, "Memory high point: %ld\n", max_memory_use);

  GCPRINT(GCOUTF, "Memory use: %ld\n", memory_in_use - FREE_LIST_DELTA);
  GCPRINT(GCOUTF, "Memory wasted: %ld (%.2f%%)\n", waste << LOG_WORD_SIZE, 
         (100.0 * (waste << LOG_WORD_SIZE)) / memory_in_use);
  GCPRINT(GCOUTF, "Memory overhead: %ld (%.2f%%)   %ld (%.2f%%) on free list\n", 
         page_allocations - memory_in_use + FREE_LIST_DELTA,
         (100.0 * ((double)page_allocations - memory_in_use)) / memory_in_use,
         (long)FREE_LIST_DELTA,
         (100.0 * FREE_LIST_DELTA) / memory_in_use);
  GCPRINT(GCOUTF, "Mmap overhead: %ld (%.2f%%)\n", 
         vm_memory_allocated(GC->vm) - memory_in_use + FREE_LIST_DELTA,
         (100.0 * ((double) vm_memory_allocated(GC->vm) - memory_in_use)) / memory_in_use);

#if KEEP_BACKPOINTERS
  if (flags & GC_DUMP_SHOW_TRACE) {
    print_traced_objects(path_length_limit, get_type_name, get_xtagged_name, print_tagged_value);
  }
  if (flags & GC_DUMP_SHOW_FINALS) {
    Fnl *f;
    avoid_collection++;
    GCPRINT(GCOUTF, "Begin Finalizations\n");
    for (f = finalizers; f; f = f->next) {
      print_out_pointer("==@ ", f->p, get_type_name, get_xtagged_name, print_tagged_value);
    }
    GCPRINT(GCOUTF, "End Finalizations\n");
    --avoid_collection;
  }
#endif
  if (for_each_found)
    --avoid_collection;
}

Here is the caller graph for this function:

void GC_finalization_weak_ptr ( void **  p,
int  offset 
)

Definition at line 641 of file compact.c.

{
  Fnl_Weak_Link *wl;

#if CHECKS
  if (offset < 0)
    CRASH(6);
#endif

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

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

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

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

  fnl_weaks = wl;

  fnl_weak_link_count++;
}

Here is the caller graph for this function:

void GC_fixup ( void pp)

Definition at line 2226 of file compact.c.

{
  void *p = *(void **)pp;
  unsigned long g;
  MPage *map;

  if ((long)p & 0x1) return;
  g = ((unsigned long)p >> MAPS_SHIFT);

  map = mpage_maps[g];
  if (map) {
    unsigned long addr = (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);
    MPage *page;

    page = map + addr;

#if DEFINE_MALLOC_FREE
    if (page->type == MTYPE_MALLOCFREE)
      return;
#endif

    if (page->type) {
      if (page->compact_to_age < min_referenced_page_age)
       min_referenced_page_age = page->compact_to_age;

      if (!(page->flags & (MFLAG_OLD | MFLAG_BIGBLOCK))) {
       long offset = ((long)p & MPAGE_MASK) >> LOG_WORD_SIZE;
       OffsetTy v;
       void *r;

       if (page->type > MTYPE_TAGGED) {
#if CHECKS
         if (!offset) {
           /* Can't point to beginning of non-tagged block! */
           CRASH(25);
         }
#endif
         offset--;
       }

       v = OFFSET_SIZE(page->u.offsets, offset);
#if CHECKS
       if (page->type > MTYPE_TAGGED) {
         if (!v) {
           /* Can't point to beginning of non-tagged block! */
           CRASH(26);
         }
       }
#endif
       
       if (offset < page->compact_boundary)
         r = (void *)(page->o.compact_to + v);
       else
         r = (void *)(((long)p & MPAGE_START) + ((long)v << LOG_WORD_SIZE));

#if SEARCH
       if (r == search_for)
         stop();
#endif

#if CHECKS
       if (!(find_page(r)->flags & COLOR_MASK)) {
         bad_dest_addr = r;
         CRASH(27);
       }
#endif

       if (r != p)
         *(void **)pp = r;
      }
    }
  }
}

Here is the caller graph for this function:

void* GC_fixup_self ( void p)

Definition at line 3578 of file compact.c.

{
  return p;
}
void GC_free ( void p)

Definition at line 4034 of file compact.c.

{
  MPage *page;

  page = find_page(p);

  if ((page->flags & MFLAG_BIGBLOCK)
      && !(page->flags & MFLAG_CONTINUED)
      && (p == page->block_start)) {
    memory_in_use -= page->u.size;

    if (page->prev)
      page->prev->next = page->next;
    else
      first = page->next;
    if (page->next)
      page->next->prev = page->prev;
    else
      last = page->prev;

    free_bigpage(page);
  }
}

Definition at line 4795 of file compact.c.

Here is the caller graph for this function:

Definition at line 529 of file compact.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);
}

Here is the caller graph for this function:

Definition at line 4063 of file compact.c.

{
  gcollect(1);
}

Here is the caller graph for this function:

long GC_get_memory_use ( void c)

Definition at line 4068 of file compact.c.

{
  return memory_in_use;
}
unsigned long GC_get_stack_base ( void  )

Definition at line 4088 of file compact.c.

{
  return stack_base;
}

Definition at line 169 of file compact.c.

{ return GC_variable_stack; }
void GC_init_type_tags ( int  count,
int  pair,
int  mutable_pair,
int  weakbox,
int  ephemeron,
int  weakarray,
int  custbox 
)

Definition at line 458 of file compact.c.

{
  CompactGC *gc;
  weak_box_tag = weakbox;
  ephemeron_tag = ephemeron;
  weak_array_tag = weakarray;
  pair_tag = pair;

  gc = malloc(sizeof(CompactGC));
  GC = gc;
  CompactGC_initialize(gc);
}

Here is the caller graph for this function:

Definition at line 689 of file compact.c.

{
  return !!find_page(p);
}

Here is the call graph for this function:

void* GC_malloc ( size_t  size_in_bytes)

Definition at line 3960 of file compact.c.

{
  return malloc_untagged(size_in_bytes, MTYPE_ARRAY, &array);
}

Here is the call graph for this function:

void* GC_malloc_allow_interior ( size_t  size_in_bytes)

Definition at line 3965 of file compact.c.

{
  return malloc_bigblock(size_in_bytes, MTYPE_ARRAY, 1);
}
void* GC_malloc_array_tagged ( size_t  size_in_bytes)

Definition at line 3980 of file compact.c.

{
  return malloc_untagged(size_in_bytes, MTYPE_TAGGED_ARRAY, &tagged_array);
}

Here is the caller graph for this function:

void* GC_malloc_atomic ( size_t  size_in_bytes)

Definition at line 3991 of file compact.c.

{
  return malloc_untagged(size_in_bytes, MTYPE_ATOMIC, &atomic);
}

Here is the call graph for this function:

void* GC_malloc_atomic_allow_interior ( size_t  size_in_bytes)

Definition at line 3970 of file compact.c.

{
  return malloc_bigblock(size_in_bytes, MTYPE_ATOMIC, 1);
}
void* GC_malloc_atomic_uncollectable ( size_t  size_in_bytes)

Definition at line 3997 of file compact.c.

{
  void *p;
  p = malloc(size_in_bytes);
  memset(p, 0, size_in_bytes);
  return p;
}

Here is the caller graph for this function:

Definition at line 513 of file compact.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 (void **)ib;
}

Here is the caller graph for this function:

void* GC_malloc_one_small_dirty_tagged ( size_t  size_in_bytes)

Definition at line 3859 of file compact.c.

{
  return GC_malloc_one_tagged(size_in_bytes);
}
void* GC_malloc_one_small_tagged ( size_t  size_in_bytes)

Definition at line 3854 of file compact.c.

{
  return GC_malloc_one_tagged(size_in_bytes);
}
void* GC_malloc_one_tagged ( size_t  size_in_bytes)

Definition at line 3780 of file compact.c.

{
  size_t size_in_words;
  void **m, **naya;

#if CHECKS
  GC_check_variable_stack();
#endif

  size_in_words = ((size_in_bytes + 3) >> LOG_WORD_SIZE);

#if CHECKS
  if (size_in_words < 2)
    CRASH(37);
#endif

  if (size_in_words >= (BIGBLOCK_MIN_SIZE >> LOG_WORD_SIZE)) {
    return malloc_bigblock(size_in_words << LOG_WORD_SIZE, MTYPE_TAGGED, 1);
  }

#if USE_FREELIST
  m = (void *)tagged.free_lists[size_in_words];
  if (m) {
    int i;

    tagged.free_lists[size_in_words] = m[1];

    for (i = 0; i < size_in_words; i++)
      m[i] = NULL;

    on_free_list -= size_in_words;
    
    return m;
  }
#endif

#if ALIGN_DOUBLES
  if (!(size_in_words & 0x1)) {
    /* Make sure memory is 8-aligned */
    if (((long)tagged.low & 0x4)) {
      if (tagged.low == tagged.high) {
       new_page(MTYPE_TAGGED, 0, &tagged, 1);
       return GC_malloc_one_tagged(size_in_words << LOG_WORD_SIZE);
      }
      ((Type_Tag *)tagged.low)[0] = SKIP;
      tagged.low += 1;
    }
  }
#endif

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

  m = tagged.low;
  naya = tagged.low + size_in_words;
  if (naya >= tagged.high) {
    if (tagged.low < tagged.high)
      *(Type_Tag *)tagged.low = TAGGED_EOM;
    new_page(MTYPE_TAGGED, 0, &tagged, 1);
    return GC_malloc_one_tagged(size_in_words << LOG_WORD_SIZE);
  }
  tagged.low = naya;

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

  return m;
}

Here is the caller graph for this function:

void* GC_malloc_one_xtagged ( size_t  size_in_bytes)

Definition at line 3985 of file compact.c.

{
  return malloc_untagged(size_in_bytes, MTYPE_XTAGGED, &xtagged);
}
void* GC_malloc_pair ( void a,
void b 
)

Definition at line 3864 of file compact.c.

{
  void *p;

  park[0] = a;
  park[1] = b;
  p = GC_malloc_one_tagged(3 << LOG_WORD_SIZE);
  a = park[0];
  b = park[1];

  ((Type_Tag *)p)[0] = pair_tag;
  ((void **)p)[1] = a;
  ((void **)p)[2] = b;

  return p;
}

Here is the caller graph for this function:

Definition at line 4058 of file compact.c.

{ 
  return BIGBLOCK_MIN_SIZE;
}

Here is the caller graph for this function:

void* GC_malloc_tagged_allow_interior ( size_t  size_in_bytes)

Definition at line 3975 of file compact.c.

{
  return malloc_bigblock(size_in_bytes, MTYPE_TAGGED, 1);
}

Here is the caller graph for this function:

void GC_mark ( const void p)

Definition at line 981 of file compact.c.

{
  unsigned long g;
  MPage *map;

#if CHECKS
  if (just_checking) {
    return;
  }
#endif
#if MARK_STATS
  mark_calls++;
#endif

  if ((long)p & 0x1) return;
  g = ((unsigned long)p >> MAPS_SHIFT);

  map = mpage_maps[g];
  if (map) {
    MPage *page;
    mflags_t flags;

    page = map + (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);

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

#if DEFINE_MALLOC_FREE
    if (page->type == MTYPE_MALLOCFREE) {
#if CHECKS
      check_not_freed(page, p);
#endif
      return;
    }
#endif

    flags = page->flags;
    if (flags & (MFLAG_MARK | MFLAG_CONTINUED)) {
#if MARK_STATS
      mark_hits++;
#endif

      if (flags & MFLAG_BIGBLOCK) {
       if (flags & MFLAG_CONTINUED) {
         void *p2;
         unsigned long g2;
#if MARK_STATS
         mark_recalls++;
#endif
         p2 = page->o.bigblock_start;
         g2 = ((unsigned long)p2 >> MAPS_SHIFT);
         page = mpage_maps[g2] + (((unsigned long)p2 & MAP_MASK) >> MAP_SHIFT);
         flags = page->flags;

         if (!(flags & MFLAG_MARK))
           return;
       }

       if (!(flags & COLOR_MASK)) {
#if MARK_STATS
         mark_colors++;
#endif
         page->flags = (flags | MFLAG_GRAY);
         
         if (page->type != MTYPE_ATOMIC) {
           page->gray_next = gray_first;
           gray_first = page;
         }

#if KEEP_BACKPOINTERS
         page->backpointer_page = mark_src;
#endif
       }
      } else {
       long offset;
       OffsetArrTy v;
       mtype_t type;
       
       type = page->type;

       /* Check for lazy initialization: */
       if (!(flags & MFLAG_INITED)) {
         if (type <= MTYPE_TAGGED)
           init_tagged_mpage((void **)page->block_start, page);
         else
           init_untagged_mpage((void **)page->block_start, page);
         flags |= MFLAG_INITED;
         page->flags = flags;
       }

       if (type > MTYPE_TAGGED) {
#if CHECKS
         if (!((long)p & MPAGE_MASK)) {
           /* Can't point to beginning of non-tagged block! */
           CRASH(9);
         }
#endif
         p = BYTEPTR(p) - WORD_SIZE;
       }

       offset = ((long)p & MPAGE_MASK) >> LOG_WORD_SIZE;

#if CHECKS
       if (offset >= page->alloc_boundary) {
         /* Past allocation region. */
         CRASH(10);
       }
#endif

       v = OFFSET_COLOR_UNMASKED(page->u.offsets, offset);
       if (!(v & COLOR_MASK)) {
#if MARK_STATS
         mark_colors++;
#endif

         switch(type) {
         case MTYPE_ATOMIC:
           OFFSET_SET_COLOR_UNMASKED(page->u.offsets, offset, v | MFLAG_BLACK);
           if (!(flags & MFLAG_BLACK)) {
             page->flags = (flags | MFLAG_BLACK);
           }
#if KEEP_BACKPOINTERS
           page->backpointer_page[offset] = mark_src;
#endif
           break;
         case MTYPE_TAGGED:
#if CHECKS
           {
             Type_Tag tag = *(Type_Tag *)p;
             if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
              GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p);
              CRASH(11);
             }
           }
#endif
         case MTYPE_XTAGGED:
         case MTYPE_ARRAY:
           if (mark_stack_pos < MARK_STACK_MAX) {
             page->flags = (flags | MFLAG_BLACK);
             OFFSET_SET_COLOR_UNMASKED(page->u.offsets, offset, v | MFLAG_BLACK); /* black can mean on stack */
# if RECORD_MARK_SRC
#  if CHECKS
             if ((long)mark_src & 0x1) CRASH(12);
#  endif
             mark_src_stack[mark_stack_pos] = mark_src;
             mark_src_type[mark_stack_pos] = mark_type;
# endif
             mark_stack[mark_stack_pos] = (void *)p;
             mark_stack_type[mark_stack_pos++] = type;
#if KEEP_BACKPOINTERS
             page->backpointer_page[offset] = mark_src;
#endif
             break;
           }
         default: /* ^^^ fallthrough */
           OFFSET_SET_COLOR_UNMASKED(page->u.offsets, offset, v | MFLAG_GRAY);
#if TIME
           mark_stackoflw++;
#endif
#if KEEP_BACKPOINTERS
           page->backpointer_page[offset] = mark_src;
#endif
           if (!(flags & MFLAG_GRAY)) {
             page->flags = (flags | MFLAG_GRAY);
             
             page->gray_next = gray_first;
             gray_first = page;
             
             page->gray_start = offset;
             page->gray_end = offset;
           } else {
             if (page->gray_start > offset)
              page->gray_start = offset;
             if (page->gray_end < offset)
              page->gray_end = offset;
           }
         }
       } else {
#if CHECKS
         if (!(flags & COLOR_MASK)) {
           CRASH(13);
         }
#endif
       }
      }
    }
  }
}

Definition at line 4078 of file compact.c.

{
  return 0;
}

Here is the caller graph for this function:

Definition at line 4083 of file compact.c.

{
  return 0;
}

Here is the caller graph for this function:

void GC_register_new_thread ( void p,
void c 
)

Definition at line 495 of file compact.c.

{
}

Here is the caller graph for this function:

Definition at line 171 of file compact.c.

{}

Here is the caller graph for this function:

void GC_register_thread ( void p,
void c 
)

Definition at line 492 of file compact.c.

{
}

Here is the caller graph for this function:

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

Definition at line 471 of file compact.c.

{
  if (is_constant_size) {
    long v;
    v = size(NULL);
    if (v < 100)
      size = (Size_Proc)v;
  }

  size_table[tag] = size;
  mark_table[tag] = mark;
  fixup_table[tag] = fixup;
}

Here is the caller graph for this function:

void* GC_resolve ( void p)

Definition at line 3569 of file compact.c.

{
  if (resolve_for_fixup) {
    GC_fixup(&p);
    return p;
  } else
    return p;
}

Here is the caller graph for this function:

int GC_set_account_hook ( int  type,
void cust,
unsigned long  b,
void f 
)

Definition at line 4073 of file compact.c.

{
  return 0;
}

Here is the caller graph for this function:

Definition at line 448 of file compact.c.

{
  stack_base = (unsigned long)base;
}

Here is the caller graph for this function:

Definition at line 170 of file compact.c.

Definition at line 2719 of file compact.c.

static void gcollect ( int  full) [static]

Definition at line 2966 of file compact.c.

{
  CompactGC *gc = GC;
  int did_fnls;
#if TIME
  struct rusage pre, post;
#endif
  int young;
  int compact;
  int i;

  INITTIME();
  PRINTTIME((STDERR, "gc: << start with %ld [%d]: %ld\n", 
            memory_in_use, cycle_count, GETTIMEREL()));

  if (memory_in_use > max_memory_use)
    max_memory_use = memory_in_use;

  init();

  set_ending_tags();

  init_weak_boxes(gc);
  init_ephemerons(gc);
  init_weak_arrays(gc);

  did_fnls = 0;

  gray_first = NULL;

  if (GC_collect_start_callback)
    GC_collect_start_callback();

#if TIME
  getrusage(RUSAGE_SELF, &pre);
#endif

  sort_and_merge_roots(&GC->roots);

  during_gc = 1;

  /******************** Init ****************************/

  skipped_pages = 0;
  scanned_pages = 0;
  young_pages = 0;
  inited_pages = 0;

  if (full)
    young = 15;
  else if ((cycle_count & 0xF) == 0xF)
    young = 15;
  else if ((cycle_count & 0x7) == 0x7)
    young = 7;
  else if ((cycle_count & 0x3) == 0x3)
    young = 3;
  else if ((cycle_count & 0x1) == 0x1)
    young = 1;
  else
    young = 0;

#if !GENERATIONS
  young = 15;
#else
  if (!generations_available)
    young = 15;
#endif

#if USE_FREELIST && (COMPACTING == SELECTIVELY_COMPACT)
  if (full)
    compact = 1;
  else {
    /* Remaining free list items few enough? */
    if (((float)(on_free_list << LOG_WORD_SIZE) / memory_in_use) < COMPACT_THRESHOLD)
      compact = 0;
    else
      compact = 1;
  }
#else
# if (COMPACTING == ALWAYS_COMPACT) || !USE_FREELIST
  compact = 1;
# endif
# if (COMPACTING == NEVER_COMPACT)
  compact = 0;
# endif
#endif

  if (compact)
    compact_count++;

  init_all_mpages(young);

  PRINTTIME((STDERR, "gc: init %s [freelist=%f] (young:%d skip:%d scan:%d init:%d): %ld\n", 
            compact ? "cmpct" : "frlst", (double)(FREE_LIST_DELTA << LOG_WORD_SIZE) / memory_in_use,
            young_pages, skipped_pages, scanned_pages, inited_pages,
            GETTIMEREL()));

  /************* Mark and Propagate *********************/

  inited_pages = 0;
#if TIME
  mark_stackoflw = 0;
#endif

#if MARK_STATS
  mark_calls = mark_hits = mark_recalls = mark_colors = mark_many = mark_slow = 0;
#endif

  mark_roots();

  {
    Fnl *f;
    for (f = GC->finalizers; f; f = f->next) {
#if RECORD_MARK_SRC
      mark_src = f;
      mark_type = MTYPE_FINALIZER;
#endif
      mark_finalizer(f);
    }
    for (f = run_queue; f; f = f->next) {
#if RECORD_MARK_SRC
      mark_src = f;
      mark_type = MTYPE_FINALIZER;
#endif
      mark_finalizer(f);
    }
  }

  {
    Fnl_Weak_Link *wl;
    for (wl = fnl_weaks; wl; wl = wl->next) {
#if RECORD_MARK_SRC
      mark_src = wl;
      mark_type = MTYPE_WEAKLINK;
#endif
      mark_finalizer_weak_link(wl);
    }
  }

#if TIME
  getrusage(RUSAGE_SELF, &post);
#endif

#if MARK_STATS
# define STATS_FORMAT " {c=%ld h=%ld c=%ld r=%ld m=%ld s=%ld}"
# define STATS_ARGS mark_calls, mark_hits, mark_colors, mark_recalls, mark_many, mark_slow,
#else
# define STATS_FORMAT
# define STATS_ARGS
#endif

  PRINTTIME((STDERR, "gc: roots (init:%d deep:%d)"
            STATS_FORMAT
            " [%ld/%ld faults]: %ld\n", 
            inited_pages, stack_depth, 
            STATS_ARGS
            post.ru_minflt - pre.ru_minflt, post.ru_majflt - pre.ru_majflt,
            GETTIMEREL()));

  iterations = 0;

  /* Propagate, mark ready ephemerons */
  propagate_all_mpages();
  mark_ready_ephemerons(gc);

  /* Propagate, loop to do finalization */
  while (1) { 

    /* Propagate all marks. */
    propagate_all_mpages();
    
    if ((did_fnls >= 3) || !GC->finalizers) {
      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 = GC->finalizers; f; f = next) {
         next = f->next;
         if (f->eager_level == 3) {
           if (!is_marked(gc, f->p)) {
             /* Not yet marked. Mark it and enqueue it. */
#if RECORD_MARK_SRC
             mark_src = f;
             mark_type = MTYPE_FINALIZER;
#endif
             gcMARK(f->p);

             if (prev)
              prev->next = next;
             else
              GC->finalizers = 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 {
             prev = f;
           }
         } else {
           prev = f;
         }
       }

       if (young == 15) {
         /* Restore zeroed out weak links, marking as we go: */       
         for (wl = fnl_weaks; wl; wl = wl->next) {
           void *wp = (void *)wl->p;
           int markit;
           markit = is_marked(gc, wp);
           if (markit) {
#if RECORD_MARK_SRC
             mark_src = wp;
             mark_type = MTYPE_WEAKLINKX;
#endif
             gcMARK(wl->saved);
           }
           *(void **)(BYTEPTR(wp) + wl->offset) = 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;

       /* If full collect, zero out weak links for ordered finalization. */
       /* (Only done on full collect to avoid modifying old pages.) */
       if (young == 15) {
         for (wl = fnl_weaks; wl; wl = wl->next) {
           void *wp = (void *)wl->p;
           wl->saved = *(void **)(BYTEPTR(wp) + wl->offset);
           *(void **)(BYTEPTR(wp) + wl->offset) = NULL;
         }
       }

       /* Mark content of not-yet-marked finalized objects,
          but don't mark the finalized objects themselves. */  
       for (f = GC->finalizers; f; f = f->next) {
         if (f->eager_level == 3) {
#if RECORD_MARK_SRC
           mark_src = f;
           mark_type = MTYPE_TAGGED;
#endif
           if (!is_marked(gc, f->p)) {
             /* Not yet marked. Mark content. */
             if (f->tagged) {
              Type_Tag tag = *(Type_Tag *)f->p;
#if CHECKS
              if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
                CRASH(34);
              }
#endif
              mark_table[tag](f->p);
             } else {
              GC_mark_xtagged(f->p);
             }
           }
         }
       }
      } else {
       /* Unordered finalization */
       Fnl *f, *prev, *queue;

       f = GC->finalizers;
       prev = NULL;
       queue = NULL;
       
       while (f) {
         if (f->eager_level == eager_level) {
           if (!is_marked(gc, f->p)) {
             /* Not yet marked. Move finalization to run queue. */
             Fnl *next = f->next;

             if (prev)
              prev->next = next;
             else
              GC->finalizers = 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 {
             prev = f;
             f = f->next;
           }
         } else {
           prev = f;
           f = f->next;
         }
       }
       
       /* Mark items added to run queue: */
       f = queue;
       while (f) {
#if RECORD_MARK_SRC
         mark_src = f;
         mark_type = MTYPE_FINALIZER;
#endif
         gcMARK(f->p);
         f = f->next;
       }

       mark_ready_ephemerons(gc);
      }
       
      did_fnls++;
    }
  }

#if CHECKS
  {
    Fnl *f;
    /* All finalized objects must be marked at this point. */
    for (f = finalizers; f; f = f->next) {
      if (!is_marked(f->p))
       CRASH(35);
    }
    for (f = run_queue; f; f = f->next) {
      if (!is_marked(f->p))
       CRASH(36);
    }
  }
#endif

#if TIME
  getrusage(RUSAGE_SELF, &post);
#endif

  PRINTTIME((STDERR, "gc: mark (init:%d cycle:%ld stkoflw:%ld)"
            STATS_FORMAT
            " [%ld/%ld faults]: %ld\n", 
            inited_pages, iterations, 
            mark_stackoflw,
            STATS_ARGS
            post.ru_minflt - pre.ru_minflt, post.ru_majflt - pre.ru_majflt,
            GETTIMEREL()));

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

  zero_remaining_ephemerons(gc);
  zero_weak_boxes(gc);
  zero_weak_arrays(gc);

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

    prev = NULL;
    for (wl = fnl_weaks; wl; wl = next) {
      next = wl->next;
      if (!is_marked(gc, wl->p)) {
       /* Will be collected. Removed this link. */
       wl->p = NULL;
       if (prev)
         prev->next = next;
       else
         fnl_weaks = next;
       --fnl_weak_link_count;
      } else {
       prev = wl;
      }
    }
  }

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

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

#if USE_FREELIST
  {
    int j;

    for (j = 0; j < NUM_SETS; j++) {
      void **free_lists = sets[j]->free_lists;
      for (i = 0; i < FREE_LIST_ARRAY_SIZE; i++)
       free_lists[i] = NULL;
    }

    on_free_list = 0;
  }
#endif

  if (compact)
    compact_all_mpages();
#if USE_FREELIST
  else
    freelist_all_mpages(young);
#endif

#if TIME
  getrusage(RUSAGE_SELF, &post);
#endif

  PRINTTIME((STDERR, "gc: %s [%ld/%ld faults]: %ld\n", 
            compact ? "compact" : "freelist",
            post.ru_minflt - pre.ru_minflt, post.ru_majflt - pre.ru_majflt,
            GETTIMEREL()));

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

  promote_all_ages();

  if (compact) {
    for (i = 0; i < NUM_SETS; i++) {
      sets[i]->malloc_page = sets[i]->compact_page;
      sets[i]->low = sets[i]->compact_to + sets[i]->compact_to_offset;
      sets[i]->high = sets[i]->compact_to + MPAGE_WORDS;
      if (sets[i]->compact_to_offset < MPAGE_WORDS) {
       sets[i]->compact_page->age = 0;
       sets[i]->compact_page->refs_age = 0;
       sets[i]->compact_page->flags |= MFLAG_MODIFIED;
      }
    }

    reverse_propagate_new_age();
  } else {
    for (i = 0; i < NUM_SETS; i++) {
      if (sets[i]->malloc_page) {
       if (!(sets[i]->malloc_page->flags & COLOR_MASK)) {
         sets[i]->malloc_page= NULL;
         sets[i]->low = sets[i]->high = (void **)0;
       } else
         sets[i]->malloc_page->flags -= (sets[i]->malloc_page->flags & MFLAG_INITED);
      }
    }
  }

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

  resolve_for_fixup = 1;

  if (compact) {
#if CHECKS
    int fnl_count = 0;
#endif

    scanned_pages = 0;
    
    fixup_roots();

    {
      Fnl *f;
      for (f = GC->finalizers; f; f = f->next) {
#if CHECKS
       fnl_count++;
#endif
       fixup_finalizer(f);
      }
      for (f = run_queue; f; f = f->next) {
#if CHECKS
       fnl_count++;
#endif
       fixup_finalizer(f);
      }
#if CHECKS
      if (fnl_count != num_fnls)
       CRASH(38);
#endif
    }
    
    {
      Fnl_Weak_Link *wl;
      for (wl = fnl_weaks; wl; wl = wl->next)
       fixup_finalizer_weak_link(wl);
    }

    fixup_all_mpages();
    
#if TIME
    getrusage(RUSAGE_SELF, &post);
#endif
    
    PRINTTIME((STDERR, "gc: fixup (%d) [%ld/%ld faults]: %ld\n", 
              scanned_pages,
              post.ru_minflt - pre.ru_minflt, post.ru_majflt - pre.ru_majflt,
              GETTIMEREL()));
  }

  resolve_for_fixup = 0;

  /******************************************************/
  
  skipped_pages = scanned_pages = 0;

  free_unused_mpages();

  protect_old_mpages();

  reset_finalizer_tree(GC);

#if (COMPACTING == NEVER_COMPACT)
# define THRESH_FREE_LIST_DELTA (FREE_LIST_DELTA >> LOG_WORD_SIZE)
#else
# define THRESH_FREE_LIST_DELTA FREE_LIST_DELTA
#endif

  gc_threshold = (long)((GROW_FACTOR * (memory_in_use - THRESH_FREE_LIST_DELTA))
                     + GROW_ADDITION);

  if (compact) {
    for (i = 0; i < NUM_NONATOMIC_SETS; i++) {
      if (sets[i]->compact_to_offset < MPAGE_WORDS)
       memset(sets[i]->low, 0, (sets[i]->high - sets[i]->low) << LOG_WORD_SIZE);
    }
  }

#if TIME
  getrusage(RUSAGE_SELF, &post);
#endif

  memory_use_growth += (memory_in_use - prev_memory_in_use);
  prev_memory_in_use = memory_in_use;

  PRINTTIME((STDERR, "gc: done with %ld delta=%ld (free:%d cheap:%d) [%ld/%ld faults]: %ld >>\n",
            memory_in_use, memory_use_growth, skipped_pages, scanned_pages,
            post.ru_minflt - pre.ru_minflt, post.ru_majflt - pre.ru_majflt,
            GETTIMEREL()));

  during_gc = 0;

  if (young == 15) {
    cycle_count = 0;
    memory_use_growth = 0;
  } else {
    if ((cycle_count & 0x1) 
       || (memory_use_growth > INCREMENT_CYCLE_COUNT_GROWTH))
      cycle_count++;
  }
  gc_count++;

  if (GC_collect_start_callback)
    GC_collect_end_callback();

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

  /* Run Finalizations. Collections may happen */

  ran_final = 0;

  if (!running_finals) {
    running_finals = 1;

    /* Finalization might allocate, which might need park: */
    park_save[0] = park[0];
    park_save[1] = park[1];
    park[0] = NULL;
    park[1] = NULL;

    while (run_queue) {
      Fnl *f;
      void **gcs;
      
      ran_final++;
      
      f = run_queue;
      run_queue = run_queue->next;
      if (!run_queue)
       last_in_queue = NULL;
      --GC->num_fnls;

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

    running_finals = 0;

    park[0] = park_save[0];
    park[1] = park_save[1];
    park_save[0] = NULL;
    park_save[1] = NULL;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static MPage* get_page_rec ( void p,
mtype_t  mtype,
mflags_t  flags 
) [static]

Definition at line 3613 of file compact.c.

{
  unsigned long g, addr;
  MPage *map;

  g = ((unsigned long)p >> MAPS_SHIFT);
  
  if (!mpage_maps) {
    int i;
    mpage_maps = (MPage **)malloc_pages(sizeof(MPage *) * MAPS_SIZE, 0);
    if (!mpage_maps) {
      GCPRINT(GCOUTF, "Can't allocate map list\n");
      abort();
    }
    for (i = 0; i < MAPS_SIZE; i++)
      mpage_maps[i] = NULL;
  }

  map = mpage_maps[g];
  if (!map) {
    int i;

    map = (MPage *)malloc_pages_try_hard(sizeof(MPage) * MAP_SIZE, 0);
    for (i = 0; i < MAP_SIZE; i++) {
      map[i].type = 0;
      map[i].flags = 0;
    }

    mpage_maps[g] = map;
  }

  addr = (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);

#if NOISY
  {
    int c;
    if (!mtype)
      c = '.';
    else {
      if (mtype <= MTYPE_TAGGED)
       c = 't';
      else if (mtype == MTYPE_ATOMIC)
       c = 'a';
      else if (mtype == MTYPE_TAGGED_ARRAY)
       c = 'g';
      else
       c = 'v';

      if (flags & MFLAG_BIGBLOCK)
       c = c - ('a' - 'A');
    }
    GCPRINT(GCOUTF, "%c p = %lx, g = %lx, addr = %lx\n", c, (long)p, g, addr);
  }
#endif

  return map + addr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init ( void  ) [static]

Definition at line 2846 of file compact.c.

{
  if (!initialized) {
    GC_register_traversers(weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box, 1, 0);
    GC_register_traversers(ephemeron_tag, size_ephemeron, mark_ephemeron, fixup_ephemeron, 1, 0);
    GC_register_traversers(weak_array_tag, size_weak_array, mark_weak_array, fixup_weak_array, 0, 0);
#if USE_FREELIST
    GC_register_traversers(gc_on_free_list_tag, size_on_free_list, size_on_free_list, size_on_free_list, 0, 0);
#endif
    GC_add_roots(&GC->finalizers, (char *)&GC->finalizers + sizeof(GC->finalizers) + 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);
    GC_add_roots(&park_save, (char *)&park_save + sizeof(park_save) + 1);

    sets[0] = &tagged;
    sets[1] = &array;
    sets[2] = &tagged_array;
    sets[3] = &xtagged;
    sets[4] = &atomic;

    initialized = 1;

#if GENERATIONS
    initialize_signal_handler(GC);
#endif
  }
}

Here is the call graph for this function:

static void init_all_mpages ( int  young) [static]

Definition at line 880 of file compact.c.

{
  MPage *page;

  for (page = first; page; page = page->next) {
    int is_old = (page->age > young);
#if GENERATIONS
    void *p = page->block_start;
#endif
       
    if (!is_old && !(page->flags & MFLAG_MODIFIED)) {
#if GENERATIONS
      if (generations_available) {
       if (page->flags & MFLAG_BIGBLOCK)
         vm_protect_pages((void *)p, page->u.size, 1);
       else
         vm_protect_pages((void *)p, MPAGE_SIZE, 1);
      }
#endif
      page->flags |= MFLAG_MODIFIED;
    }

    if (is_old) {
      page->flags -= (page->flags & MFLAG_MARK);
      page->flags |= MFLAG_OLD;
    } else {
      page->flags -= (page->flags & MFLAG_OLD);
      page->flags |= MFLAG_MARK;
      young_pages++;
    }
      
    if (!(page->flags & MFLAG_INITED)) {
      void *p = page->block_start;

      if (page->flags & MFLAG_BIGBLOCK) {
       page->flags = (page->flags & NONCOLOR_MASK);
       page->flags |= MFLAG_INITED;
      } else {
       if (is_old) {
         if (page->type <= MTYPE_TAGGED)
           init_tagged_mpage((void **)p, page);
         else
           init_untagged_mpage((void **)p, page);
         page->flags |= MFLAG_INITED;
       } else {
         /* Young pages: initialize lazily as needed by `mark'.
            Not initialized means full page is garbage. */
         page->flags = (page->flags & NONCOLOR_MASK);
       }

       if (is_old) {
         skipped_pages++;
       }
      }
    } else {
       if (is_old) 
        skipped_pages++;
      /* Clear color flags: */
      page->flags = (page->flags & NONCOLOR_MASK);
    }

    if (is_old
       && ((page->refs_age <= young)
           || (page->flags & MFLAG_MODIFIED))
       && (page->type != MTYPE_ATOMIC)) {
      /* Offsets inited; need to set gray flag */
      page->flags |= MFLAG_GRAY;
      
      page->gray_next = gray_first;
      gray_first = page;
      
      page->gray_start = 0;
      page->gray_end = page->alloc_boundary - 2;

      if (!(page->flags & MFLAG_MODIFIED)) {
#if GENERATIONS
       if (generations_available) {
         if (page->flags & MFLAG_BIGBLOCK)
           vm_protect_pages((void *)p, page->u.size, 1);
         else
           vm_protect_pages((void *)p, MPAGE_SIZE, 1);
       }
#endif
       page->flags |= MFLAG_MODIFIED;
      }

      scanned_pages++;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void init_tagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 757 of file compact.c.

{
  OffsetTy offset = 0;
  OffsetArrTy *offsets;
  void **top;

  page->flags = (page->flags & NONCOLOR_MASK);
  offsets = page->u.offsets;
  top = p + MPAGE_WORDS;

  page->alloc_boundary = MPAGE_WORDS;
  
  while (p < top) {
    Type_Tag tag;
    long size;

    tag = *(Type_Tag *)p;

    if (tag == TAGGED_EOM) {
      /* Remember empty space for prop and compact:  */
      page->alloc_boundary = offset;
      break;
    }

#if ALIGN_DOUBLES
    if (tag == SKIP) {
      OFFSET_SET_SIZE_UNMASKED(offsets, offset, 1);
      offset++;
      p++;
    } else {
#endif

#if CHECKS
      if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
       GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p);
       GCFLUSHOUT();
       CRASH(7);
      }
      prev_prev_prev_prev_prev_ptr = prev_prev_prev_prev_ptr;
      prev_prev_prev_prev_ptr = prev_prev_prev_ptr;
      prev_prev_prev_ptr = prev_prev_ptr;
      prev_prev_ptr = prev_ptr;
      prev_ptr = p;
      prev_var_stack = GC_variable_stack;
#endif

      {
       Size_Proc size_proc;
       
       size_proc = size_table[tag];
       if (((long)size_proc) < 100)
         size = (long)size_proc;
       else
         size = size_proc(p);
      }

#if CHECKS
      if (size < 1) {
       CRASH(57);
      }
#endif

      OFFSET_SET_SIZE_UNMASKED(offsets, offset, size);
      offset += size;

#if CHECKS
      if (prev_var_stack != GC_variable_stack) {
       CRASH(8);
      }
#endif
      
      p += size;
#if ALIGN_DOUBLES
    }
#endif
  }

  inited_pages++;
}

Here is the caller graph for this function:

static void init_untagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 837 of file compact.c.

{
  OffsetTy offset = 0;
  OffsetArrTy *offsets;
  void **top;

  page->flags = (page->flags & NONCOLOR_MASK);
  offsets = page->u.offsets;
  page->alloc_boundary = MPAGE_WORDS;

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM) {
      /* Remember empty space for prop:  */
      page->alloc_boundary = offset;
      
      break;
    }

#if CHECKS
    if (0 && page->type == MTYPE_XTAGGED) {
      just_checking = 1;
      GC_mark_xtagged(p + 1);
      just_checking = 0;
    }

    the_size = size;
#endif

    OFFSET_SET_SIZE_UNMASKED(offsets, offset, 0);
    offset += size;

    p += size;
  } 

  inited_pages++;
}

Here is the caller graph for this function:

static int is_finalizable_page ( CompactGC gc,
void p 
) [static]

Definition at line 572 of file compact.c.

{
  MPage *page;
  page = find_page(p);
  return page && page->type;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int is_marked ( CompactGC gc,
void p 
) [static]

Definition at line 695 of file compact.c.

{
  unsigned long g = ((unsigned long)p >> MAPS_SHIFT);
  MPage *map;

  map = mpage_maps[g];
  if (map) {
    MPage *page;

    page = map + (((unsigned long)p & MAP_MASK) >> MAP_SHIFT);
#if DEFINE_MALLOC_FREE
    if (page->type == MTYPE_MALLOCFREE)
      return 1;
#endif
    if (page->flags & MFLAG_BIGBLOCK) {
      if (page->flags & MFLAG_CONTINUED)
        return is_marked(gc, page->o.bigblock_start);
      else
        return (page->flags & (COLOR_MASK | MFLAG_OLD));
    } else {
      if (page->flags & MFLAG_OLD)
        return 1;
      else if (page->flags & COLOR_MASK) {
        long offset = ((long)p & MPAGE_MASK) >> LOG_WORD_SIZE;

        if (page->type > MTYPE_TAGGED)
          offset -= 1;

        return OFFSET_COLOR(page->u.offsets, offset);
      } else if ((long)p & 0x1)
        return 1;
      else
        return 0;
    }
  }

  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* malloc_bigblock ( long  size_in_bytes,
mtype_t  mtype,
int  link 
) [static]

Definition at line 3718 of file compact.c.

{
  void *p, *mp;
  MPage *map;
  long s;

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

  if ((memory_in_use > gc_threshold) && link && !avoid_collection) {
    gcollect(0);
    return malloc_bigblock(size_in_bytes, mtype, 1);
  }
  
  p = (void *)malloc_pages_try_hard(size_in_bytes, MPAGE_SIZE);

  memory_in_use += size_in_bytes;

  map = get_page_rec(p, mtype, MFLAG_BIGBLOCK);
  
  map->type = mtype;
  map->flags = (MFLAG_BIGBLOCK | MFLAG_MODIFIED);
  map->u.size = size_in_bytes;
  map->block_start = p;
  map->age = 0;
  map->refs_age = 0;

  if (link) {
    map->next = NULL;
    map->prev = last;
    if (last)
      last->next = map;
    else
      first = map;
    last = map;
  } else {
    map->next = NULL;
    map->prev = NULL;
  }

  s = size_in_bytes;
  mp = p;
  while (s > MPAGE_SIZE) {
    mp = BYTEPTR(mp) + MPAGE_SIZE;
    s -= MPAGE_SIZE;
    map = get_page_rec(mp, 0, MFLAG_CONTINUED | MFLAG_BIGBLOCK);
    map->type = mtype;
    map->flags = MFLAG_CONTINUED | MFLAG_BIGBLOCK;
    map->o.bigblock_start = p;
  }

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

  return p;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* malloc_pages ( size_t  len,
size_t  alignment 
) [static]

Definition at line 430 of file compact.c.

{
  page_allocations += len;
  return vm_malloc_pages(GC->vm, len, alignment, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* malloc_pages_try_hard ( size_t  len,
size_t  alignment 
)

Definition at line 3587 of file compact.c.

{
  void *m;
  int i = 5;

  ran_final = 1;

  while (i--) {
    m = malloc_pages(len, alignment);
    if (m)
      return m;
    if (!ran_final)
      break;
    else
      gcollect(1);
  }

  if (GC_out_of_memory)
    GC_out_of_memory();

  GCPRINT(GCOUTF, "Out of memory\n");
  abort();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static gcINLINE void* malloc_untagged ( size_t  size_in_bytes,
mtype_t  mtype,
MSet set 
) [static]

Definition at line 3885 of file compact.c.

{
  size_t size_in_words;
  void **m, **naya;

#if CHECKS
  GC_check_variable_stack();
#endif

  if (!size_in_bytes)
    return zero_sized;

  size_in_words = ((size_in_bytes + 3) >> LOG_WORD_SIZE);

  if (size_in_words >= (BIGBLOCK_MIN_SIZE >> LOG_WORD_SIZE)) {
    return malloc_bigblock(size_in_words << LOG_WORD_SIZE, mtype, 1);
  }

#if USE_FREELIST
  m = (void *)set->free_lists[size_in_words];
  if (m) {
    int i;

    set->free_lists[size_in_words] = m[0];

    if (mtype != MTYPE_ATOMIC)
      memset(m, 0, size_in_words << LOG_WORD_SIZE);

    on_free_list -= size_in_words;
    
    return m;
  }
#endif

#if ALIGN_DOUBLES
  if (!(size_in_words & 0x1)) {
    /* Make sure memory is 8-aligned */
    if (!((long)set->low & 0x4)) {
      if (set->low == set->high) {
       new_page(mtype, 0, set, 1);
       return malloc_untagged(size_in_words << LOG_WORD_SIZE, mtype, set);
      }
      (set->low)[0] = 0;
      set->low += 1;
    }
  }
#endif

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

  m = set->low;
  naya = set->low + size_in_words + 1;
  if (naya >= set->high) {
    if (set->low < set->high)
      *(long *)set->low = UNTAGGED_EOM - 1;
    new_page(mtype, 0, set, 1);
    return malloc_untagged(size_in_words << LOG_WORD_SIZE, mtype, set);
  }
  set->low = naya;

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

  *(long *)m = size_in_words;

  return m + 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void mark_finalizer ( Fnl fnl) [static]

Definition at line 583 of file compact.c.

{
  gcMARK(fnl->next);
  gcMARK(fnl->data);
  /* !eager_level => queued for run: */
  if (!fnl->eager_level) {
    gcMARK(fnl->p);
  }
#if CHECKS
  if (!fnl->tagged && fnl->size < BIGBLOCK_MIN_SIZE) {
    if (((long *)fnl->p)[-1] != fnl->size)
      CRASH(2);
  }
#endif
}

Here is the caller graph for this function:

static void mark_finalizer_weak_link ( Fnl_Weak_Link wl) [static]

Definition at line 630 of file compact.c.

{
  gcMARK(wl->next);
}

Here is the caller graph for this function:

static void mark_roots ( ) [static]

Definition at line 2894 of file compact.c.

{
  Roots *roots = &GC->roots;
  ImmobileBox *ib;
  int i;

  for (i = 0; i < roots->count; i += 2) {
    void **s = (void **)roots->roots[i];
    void **e = (void **)roots->roots[i + 1];

    while (s < e) {
#if RECORD_MARK_SRC
      mark_src = s;
      mark_type = MTYPE_ROOT;
#endif
      gcMARK(*s);
      s++;
    }
  }

#if RECORD_MARK_SRC
  record_stack_source = 1;
#endif
  GC_mark_variable_stack(GC_variable_stack,
      0,
      (void *)(GC_get_thread_stack_base
        ? GC_get_thread_stack_base()
        : stack_base),
      NULL);
#if RECORD_MARK_SRC
  record_stack_source = 0;
#endif

  /* Do immobiles: */
  for (ib = immobile; ib; ib = ib->next) {
#if RECORD_MARK_SRC
    mark_src = ib;
    mark_type = MTYPE_IMMOBILE;
#endif
    gcMARK(ib->p);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void new_page ( mtype_t  mtype,
mflags_t  mflags,
MSet set,
int  link 
) [static]

Definition at line 3671 of file compact.c.

{
  void *p;
  MPage *map;
  OffsetArrTy *offsets;

  if ((memory_in_use > gc_threshold) && link && !avoid_collection) {
    gcollect(0);
    return;
  }
  
  p = (void *)malloc_pages_try_hard(MPAGE_SIZE, MPAGE_SIZE);
  offsets = (OffsetArrTy *)malloc_pages_try_hard(OPAGE_SIZE, 0);

  memory_in_use += MPAGE_SIZE;

  map = get_page_rec(p, mtype, mflags);

  map->type = mtype;
  map->flags = (mflags | MFLAG_MODIFIED);
  map->u.offsets = offsets;
  map->block_start = p;
  map->age = 0;
  map->refs_age = 0;

  if (link) {
    map->next = NULL;
    map->prev = last;
    if (last)
      last->next = map;
    else
      first = map;
    last = map;
  } else {
    map->next = map->prev = NULL;
  }

  set->malloc_page = map;

  set->low = (void **)p;
  set->high = (void **)(BYTEPTR(p) + MPAGE_SIZE);

#if KEEP_BACKPOINTERS
  map->backpointer_page = (void **)malloc_pages_try_hard(MPAGE_SIZE, 0);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2613 of file compact.c.

{
  MPage *page;

  for (page = first; page; page = page->next) {
    if (page->age < 15)
      page->age++;
    if (page->refs_age < 15)
      page->refs_age++;
  }
}

Here is the caller graph for this function:

static void propagate_all_mpages ( ) [static]

Definition at line 1626 of file compact.c.

{
  MPage *page;
  void *p;
  
  while (gray_first || mark_stack_pos) {
    iterations++;

    while (mark_stack_pos) {
      mtype_t type;
      
      p = mark_stack[--mark_stack_pos];
      type = mark_stack_type[mark_stack_pos];
# if RECORD_MARK_SRC
      current_mark_src = mark_src_stack[mark_stack_pos];
      current_mark_type = mark_src_type[mark_stack_pos];
# endif

      switch (type) {
      case MTYPE_TAGGED:
       {
         Type_Tag tag;
         tag = *(Type_Tag *)p;
       
#if ALIGN_DOUBLES
         if (tag != SKIP) {
#endif
         
#if CHECKS
           if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) {
             CRASH(18);
           }
#endif
#if RECORD_MARK_SRC
           mark_src = p;
           mark_type = MTYPE_TAGGED;
#endif

           old_tag = tag;
           old_p = p;
           mark_table[tag](p);
         
#if ALIGN_DOUBLES
         }
#endif
       }
       break;

      case MTYPE_XTAGGED:
#if RECORD_MARK_SRC
       mark_src = (void **)p + 1;
       mark_type = MTYPE_XTAGGED;
#endif
       GC_mark_xtagged((void **)p + 1);
       break;

      default: /* MTYPE_ARRAY */
       {
         long size, i;
         
         size = ((long *)p)[0];
         
#if RECORD_MARK_SRC
         mark_src = (void **)p + 1;
         mark_type = MTYPE_ARRAY;
#endif

         for (i = 1; i <= size; i++) {
           gcMARK(((void **)p)[i]);
         }
       }
      }
    }

    if (gray_first) {
      page = gray_first;
      gray_first = page->gray_next;
      
      page->flags = ((page->flags & NONCOLOR_MASK) | MFLAG_BLACK);
      p = page->block_start;
      
      if (page->flags & MFLAG_BIGBLOCK) {
       if (!(page->flags & MFLAG_CONTINUED))
         do_bigblock((void **)p, page, 0);
      } else {
       switch (page->type) {
       case MTYPE_ATOMIC:
         break;
       case MTYPE_TAGGED:
         if (page->flags & MFLAG_OLD)
           propagate_tagged_whole_mpage((void **)p, page);
         else
           propagate_tagged_mpage((void **)p, page);
         break;
       case MTYPE_TAGGED_ARRAY:
         if (page->flags & MFLAG_OLD)
           propagate_tagged_array_whole_mpage((void **)p, page);
         else
           propagate_tagged_array_mpage((void **)p, page);
         break;
       case MTYPE_XTAGGED:
         if (page->flags & MFLAG_OLD)
           propagate_xtagged_whole_mpage((void **)p, page);
         else
           propagate_xtagged_mpage((void **)p, page);
         break;
       case MTYPE_ARRAY:
       default:
         if (page->flags & MFLAG_OLD)
           propagate_array_whole_mpage((void **)p, page);
         else
           propagate_array_mpage((void **)p, page);
         break;
       }
      }
    }      
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void propagate_array_mpage ( void **  bottom,
MPage page 
) [static]

Definition at line 1274 of file compact.c.

{
  OffsetTy offset;
  OffsetArrTy *offsets;
  void **p, **top;

  offset = page->gray_start;
  p = bottom + offset;
  top = bottom + page->gray_end;
  offsets = page->u.offsets;

  while (p <= top) {
    OffsetArrTy v;
    long size;

    size = *(long *)p + 1;
       
#if CHECKS
    if ((size < 2) || (size > MPAGE_WORDS)) {
      CRASH(14);
    }
    prev_ptr = p;
#endif

    v = OFFSET_COLOR_UNMASKED(offsets, offset);
    if (v & MFLAG_GRAY) {
      int i;

#if RECORD_MARK_SRC
      mark_src = p + 1;
      mark_type = MTYPE_ARRAY;
#endif

      v -= MFLAG_GRAY;
      v |= MFLAG_BLACK;
      OFFSET_SET_COLOR_UNMASKED(offsets, offset, v);
      
      for (i = 1; i < size; i++) {
       gcMARK(p[i]);
      }
    }
    
    p += size;
    offset += size;

#if CHECKS
    if ((p > bottom + MPAGE_WORDS + 1) || (p < bottom)) {
      CRASH(15);
    }
#endif
  }
}

Here is the caller graph for this function:

static void propagate_array_whole_mpage ( void **  p,
MPage page 
) [static]

Definition at line 1327 of file compact.c.

{
  void **top;

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size, i;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM) {
      break;
    }

#if RECORD_MARK_SRC
    mark_src = p + 1;
    mark_type = MTYPE_ARRAY;
#endif

    for (i = 1; i < size; i++) {
      gcMARK(p[i]);
    }

    p += size;
  } 
}

Here is the caller graph for this function:

static void propagate_tagged_array_mpage ( void **  bottom,
MPage page 
) [static]

Definition at line 1355 of file compact.c.

{
  OffsetTy offset;
  OffsetArrTy *offsets;
  void **p, **top;

  offset = page->gray_start;
  p = bottom + offset;
  top = bottom + page->gray_end;
  offsets = page->u.offsets;

  while (p <= top) {
    OffsetArrTy v;
    int size;
    
    size = *(long *)p + 1;

    v = OFFSET_COLOR_UNMASKED(offsets, offset);
    if (v & MFLAG_GRAY) {
      v -= MFLAG_GRAY;
      v |= MFLAG_BLACK;
      OFFSET_SET_COLOR_UNMASKED(offsets, offset, v);

      {
       int i, elem_size;
       void **mp = p + 1;
       Type_Tag tag;
       Mark_Proc traverse;
       
#if RECORD_MARK_SRC
       mark_src = mp;
       mark_type = MTYPE_TAGGED_ARRAY;
#endif

       size--;
       tag = *(Type_Tag *)mp;

       traverse = mark_table[tag];
       elem_size = traverse(mp);
       mp += elem_size;
       for (i = elem_size; i < size; i += elem_size, mp += elem_size)
         traverse(mp);

       size++;
      }
    }
    
    p += size;
    offset += size;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void propagate_tagged_array_whole_mpage ( void **  p,
MPage page 
) [static]

Definition at line 1407 of file compact.c.

{
  void **top;

  top = p + MPAGE_WORDS;

  while (p < top) {
    int i, elem_size, size;
    void **mp;
    Type_Tag tag;
    Mark_Proc traverse;
    
    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM)
      break;
      
    mp = p + 1;
    p += size;
    size--;

    tag = *(Type_Tag *)mp;
      
#if RECORD_MARK_SRC
    mark_src = mp;
    mark_type = MTYPE_TAGGED_ARRAY;
#endif

    traverse = mark_table[tag];
    elem_size = traverse(mp);
    mp += elem_size;
    for (i = elem_size; i < size; i += elem_size, mp += elem_size)
      traverse(mp);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void propagate_tagged_mpage ( void **  bottom,
MPage page 
) [static]

Definition at line 1180 of file compact.c.

{
  OffsetTy offset;
  OffsetArrTy *offsets;
  void **p, **graytop;

  offsets = page->u.offsets;

  offset = page->gray_start;
  p = bottom + offset;
  graytop = bottom + page->gray_end;
  
  while (p <= graytop) {
    OffsetArrTy v;
    Type_Tag tag;
    long size;
    
    tag = *(Type_Tag *)p;

#if ALIGN_DOUBLES
    if (tag != SKIP) {
#endif

#if RECORD_MARK_SRC
      mark_src = p;
      mark_type = MTYPE_TAGGED;
#endif
      
      v = OFFSET_COLOR_UNMASKED(offsets, offset);
      size = OFFSET_SIZE(offsets, offset);
      if (v & MFLAG_GRAY) {
       v -= MFLAG_GRAY;
       v |= MFLAG_BLACK;
       OFFSET_SET_COLOR_UNMASKED(offsets, offset, v);
       mark_table[tag](p);
      }
       
#if ALIGN_DOUBLES
    } else
      size = 1;
#endif

    p += size;
    offset += size;
  }

#if MARK_STATS
  mark_many++;
#endif

#if MARK_STATS
  if (page->flags & MFLAG_GRAY) {
    mark_slow++;
  }
#endif
}

Here is the caller graph for this function:

static void propagate_tagged_whole_mpage ( void **  p,
MPage page 
) [static]

Definition at line 1237 of file compact.c.

{
  void **top;

  top = p + MPAGE_WORDS;
  
  while (p < top) {
    Type_Tag tag;
    long size;

    tag = *(Type_Tag *)p;

    if (tag == TAGGED_EOM) {
      break;
    }

#if ALIGN_DOUBLES
    if (tag == SKIP) {
      p++;
    } else {
#endif

#if RECORD_MARK_SRC
      mark_src = p;
      mark_type = MTYPE_TAGGED;
#endif

      size = mark_table[tag](p);

      p += size;

#if ALIGN_DOUBLES
    }
#endif
  }
}

Here is the caller graph for this function:

static void propagate_xtagged_mpage ( void **  bottom,
MPage page 
) [static]

Definition at line 1443 of file compact.c.

{
  OffsetTy offset;
  OffsetArrTy *offsets;
  void **p, **top;

  offset = page->gray_start;
  p = bottom + offset;
  top = bottom + page->gray_end;
  offsets = page->u.offsets;

  while (p <= top) {
    OffsetArrTy v;
    long size;

    size = *(long *)p + 1;
       
#if ALIGN_DOUBLES
    if (size > 1) {
#endif

      v = OFFSET_COLOR_UNMASKED(offsets, offset);
      if (v & MFLAG_GRAY) {
       v -= MFLAG_GRAY;
       v |= MFLAG_BLACK;
       OFFSET_SET_COLOR_UNMASKED(offsets, offset, v);
       
#if RECORD_MARK_SRC
       mark_src = p + 1;
       mark_type = MTYPE_XTAGGED;
#endif

       GC_mark_xtagged(p + 1);
      }

#if ALIGN_DOUBLES
    }
#endif
    
    p += size;
    offset += size;
  }
}

Here is the caller graph for this function:

static void propagate_xtagged_whole_mpage ( void **  p,
MPage page 
) [static]

Definition at line 1487 of file compact.c.

{
  void **top;

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM) {
      break;
    }

#if RECORD_MARK_SRC
    mark_src = p + 1;
    mark_type = MTYPE_XTAGGED;
#endif

#if ALIGN_DOUBLES
    if (size > 1) {
#endif

      GC_mark_xtagged(p + 1);

#if ALIGN_DOUBLES
    }
#endif

    p += size;
  } 
}

Here is the caller graph for this function:

Definition at line 2626 of file compact.c.

{
#if GENERATIONS
  MPage *page;

  if (generations_available) {
    for (page = first; page; page = page->next) {
      if (page->age && (page->type != MTYPE_ATOMIC)) {
       void *p;
      
       if (page->flags & MFLAG_MODIFIED) {
         page->flags -= MFLAG_MODIFIED;
      
         p = page->block_start;
         if (page->flags & MFLAG_BIGBLOCK)
           vm_protect_pages((void *)p, page->u.size, 0);
         else 
           vm_protect_pages((void *)p, MPAGE_SIZE, 0);
       }
      }
    }
  }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2304 of file compact.c.

{
  MPage *page;

  for (page = first; page; page = page->next) {
    if (!(page->flags & (MFLAG_BIGBLOCK | MFLAG_OLD))) {
      if (page->compact_boundary > 0) {
       MPage *page_to;
       page_to = find_page(page->o.compact_to);
       if (page_to->age < page->age)
         page->compact_to_age = page_to->age;
       else
         page->compact_to_age = page->age;
      } else
       page->compact_to_age = page->age;
    } else
      page->compact_to_age = page->age;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long scan_tagged_mpage ( void **  p,
MPage page,
short  trace_for_tag,
GC_for_each_found_proc  for_each_found 
) [static]

Definition at line 4331 of file compact.c.

{
  void **top, **bottom = p;

  top = p + MPAGE_WORDS;
  
  while (p < top) {
    Type_Tag tag;
    long size;

    tag = *(Type_Tag *)p;

    if (tag == TAGGED_EOM) {
      return (p - bottom);
    }

#if ALIGN_DOUBLES
    if (tag == SKIP) {
      p++;
    } else {
#endif      
      {
       Size_Proc size_proc;
       
       size_proc = size_table[tag];
       if (((long)size_proc) < 100)
         size = (long)size_proc;
       else
         size = size_proc(p);
      }

      dump_info_array[tag]++;
      dump_info_array[tag + NUMBER_OF_TAGS] += size;

      if (tag == trace_for_tag) {
#if KEEP_BACKPOINTERS
       register_traced_object(p);
#endif
       if (for_each_found)
         for_each_found(p);
      }

      p += size;
#if ALIGN_DOUBLES
    }
#endif
  }

  return MPAGE_WORDS;
}

Here is the caller graph for this function:

static long scan_untagged_mpage ( void **  p,
MPage page 
) [static]

Definition at line 4383 of file compact.c.

{
  void **top, **bottom = p;

  top = p + MPAGE_WORDS;

  while (p < top) {
    long size;

    size = *(long *)p + 1;

    if (size == UNTAGGED_EOM) {
      return (p - bottom);
    }

    dump_info_array[size - 1] += 1;

    p += size;
  } 

  return MPAGE_WORDS;
}

Here is the caller graph for this function:

static void set_ending_tags ( void  ) [static]

Definition at line 2830 of file compact.c.

{
  int i;

  for (i = 0; i < NUM_TAGGED_SETS; i++) {
    if (sets[i]->low < sets[i]->high)
      *(Type_Tag *)sets[i]->low = TAGGED_EOM;
  }
  for (i = NUM_TAGGED_SETS; i < NUM_SETS; i++) {
    if (sets[i]->low < sets[i]->high)
      *(long *)sets[i]->low = UNTAGGED_EOM - 1;
  }
}

Here is the caller graph for this function:


Variable Documentation

MSet array [static]

Definition at line 354 of file compact.c.

MSet atomic [static]

Definition at line 354 of file compact.c.

Definition at line 396 of file compact.c.

int compact_count = 0 [static]

Definition at line 374 of file compact.c.

int cycle_count = 0 [static]

Definition at line 374 of file compact.c.

Definition at line 4289 of file compact.c.

int during_gc [static]

Definition at line 396 of file compact.c.

Definition at line 175 of file compact.c.

MPage* first [static]

Definition at line 254 of file compact.c.

Definition at line 184 of file compact.c.

Definition at line 383 of file compact.c.

Definition at line 628 of file compact.c.

Definition at line 20 of file compact.c.

Definition at line 158 of file compact.c.

void(* GC_collect_inform_callback)(int major_gc, long pre_used, long post_used)

Definition at line 159 of file compact.c.

Definition at line 157 of file compact.c.

int gc_count = 0 [static]

Definition at line 374 of file compact.c.

Definition at line 165 of file compact.c.

unsigned long(* GC_get_thread_stack_base)(void)

Definition at line 162 of file compact.c.

Definition at line 164 of file compact.c.

Definition at line 160 of file compact.c.

Definition at line 161 of file compact.c.

long gc_threshold = GROW_ADDITION [static]

Definition at line 360 of file compact.c.

Definition at line 167 of file compact.c.

int generations_available = 1 [static]

Definition at line 370 of file compact.c.

MPage* gray_first [static]

Definition at line 257 of file compact.c.

ImmobileBox* immobile [static]

Definition at line 511 of file compact.c.

int inited_pages [static]

Definition at line 375 of file compact.c.

int initialized [static]

Definition at line 2844 of file compact.c.

long iterations [static]

Definition at line 377 of file compact.c.

MPage * last [static]

Definition at line 254 of file compact.c.

Fnl * last_in_queue [static]

Definition at line 581 of file compact.c.

Definition at line 126 of file compact.c.

long mark_stack_pos = 0 [static]

Definition at line 128 of file compact.c.

unsigned short mark_stack_type[MARK_STACK_MAX] [static]

Definition at line 127 of file compact.c.

Definition at line 183 of file compact.c.

long max_memory_use [static]

Definition at line 360 of file compact.c.

long memory_in_use [static]

Definition at line 360 of file compact.c.

Definition at line 361 of file compact.c.

Definition at line 2221 of file compact.c.

Definition at line 260 of file compact.c.

long num_seg_faults [static]

Definition at line 371 of file compact.c.

void* old_p [static]

Definition at line 1624 of file compact.c.

int old_tag [static]

Definition at line 1623 of file compact.c.

long page_allocations = 0 [static]

Definition at line 358 of file compact.c.

Definition at line 177 of file compact.c.

void* park[2] [static]

Definition at line 394 of file compact.c.

void * park_save[2] [static]

Definition at line 394 of file compact.c.

Definition at line 361 of file compact.c.

int ran_final [static]

Definition at line 385 of file compact.c.

int resolve_for_fixup = 0 [static]

Definition at line 398 of file compact.c.

Fnl* run_queue [static]

Definition at line 581 of file compact.c.

int running_finals [static]

Definition at line 386 of file compact.c.

int scanned_pages [static]

Definition at line 375 of file compact.c.

MSet* sets[NUM_SETS] [static]

Definition at line 355 of file compact.c.

Definition at line 182 of file compact.c.

int skipped_pages [static]

Definition at line 375 of file compact.c.

unsigned long stack_base [static]

Definition at line 446 of file compact.c.

MSet tagged [static]

Definition at line 354 of file compact.c.

MSet tagged_array [static]

Definition at line 354 of file compact.c.

Definition at line 176 of file compact.c.

Definition at line 174 of file compact.c.

MSet xtagged [static]

Definition at line 354 of file compact.c.

int young_pages [static]

Definition at line 375 of file compact.c.

char zero_sized[4] [static]

Definition at line 391 of file compact.c.