static void before_collection( young_heap_t *heap ) { young_data_t *data = DATA(heap); word *globals = data->globals; flush_stack( heap ); heap->maximum = data->heapsize; heap->allocated = heap->maximum - free_space( heap ); if (!data->havestats) { data->havestats = TRUE; data->los_live = bytes2words(los_bytes_used( heap->collector->los, data->gen_no )); data->stack_live = bytes2words(globals[G_STKBOT] - globals[G_STKP]); data->not_used = bytes2words(globals[G_STKP] - globals[G_ETOP]); } }
young_heap_t * create_nursery( int gen_no, gc_t *gc, /* the owning GC */ nursery_info_t *info, /* creation parameters */ word *globals /* the globals array (not in heap) */ ) { int size_bytes = info->size_bytes; young_data_t *data; young_heap_t *heap; heap = allocate_nursery( gen_no, gc ); data = heap->data; assert( size_bytes >= GC_LARGE_OBJECT_LIMIT + MAX_STACK_FRAME ); size_bytes = roundup_page( size_bytes ); data->globals = globals; data->heapsize = size_bytes; again2: data->heapbot = (word*)gclib_alloc_heap( size_bytes, data->gen_no ); if (data->heapbot == 0) { memfail( MF_HEAP, "young-heap: Could not allocate heap data area." ); goto again2; } data->heaplim = data->heapbot + bytes2words(size_bytes); /* Setup heap pointers needed by RTS */ globals[ G_EBOT ] = (word)(data->heapbot); globals[ G_ETOP ] = (word)(data->heapbot); globals[ G_ELIM ] = (word)(data->heaplim); /* Must be set up before stack can be initialized */ globals[ G_STKP ] = globals[ G_ELIM ]; globals[ G_STKUFLOW ] = 0; heap->maximum = DATA(heap)->heapsize; heap->allocated = 0; return heap; }
static bool fill_from_los_stack( msgc_context_t *context ) { int next, k, n, i; word obj; if (context->los_stack.stkp == context->los_stack.stkbot) { /* underflow */ if (!pop_segment( &context->los_stack )) return FALSE; } obj = *--context->los_stack.stkp; next = (int)*--context->los_stack.stkp; n = bytes2words( sizefield( *ptrof(obj) ) ); k = min( n-next, LARGE_OBJECT_LIMIT ); for ( i=0 ; i < k ; i++ ) PUSH( context, vector_ref( obj, i+next ) ); if (next+k < n) LOS_PUSH( context, next+k, obj ); return TRUE; }
static int push_constituents( msgc_context_t *context, word w ) { int i, n; switch (tagof(w)) { case PAIR_TAG : PUSH( context, pair_cdr( w ) ); /* Do the CDR last */ PUSH( context, pair_car( w ) ); /* Do the CAR first */ return 2; case VEC_TAG : case PROC_TAG : n = bytes2words( sizefield(*ptrof(w)) ); if (n > LARGE_OBJECT_LIMIT) LOS_PUSH( context, 0, w ); /* Treat large objects specially */ else for ( i=0 ; i < n ; i++ ) PUSH( context, vector_ref( w, i ) ); return n+1; default : return 0; } }
static void stats( young_heap_t *heap ) { young_data_t *data = DATA(heap); gen_stats_t gen_stats; gc_stats_t gc_stats; assert( data->havestats ); memset( &gen_stats, 0, sizeof(gen_stats) ); gen_stats.target = bytes2words(data->heapsize); gen_stats.allocated = gen_stats.target + data->los_live; gen_stats.used = gen_stats.allocated - data->not_used; stats_add_gen_stats( data->self, &gen_stats ); memset( &gc_stats, 0, sizeof( gc_stats ) ); gc_stats.allocated = gen_stats.used - data->stack_live; stats_add_gc_stats( &gc_stats ); data->los_live = 0; data->stack_live = 0; data->not_used = 0; data->havestats = FALSE; }
static int push_constituents( msgc_context_t *context, word w ) { int i, n; switch (tagof(w)) { case PAIR_TAG : return push_pair_constiuents( context, w ); case VEC_TAG : case PROC_TAG : assert2_tag_hdr_consistency( context, w ); n = bytes2words( sizefield(*ptrof(w)) ); if (n > LARGE_OBJECT_LIMIT) LOS_PUSH( context, 0, w ); /* Treat large objects specially */ else { assert2_object_contents_mapped( context, w, n ); for ( i=0 ; i < n ; i++ ) { PUSH( context, vector_ref( w, i ), w, i+1 ); } } return n+1; default : return 0; } }