2004-07-16 02:26:21 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
void dump_generations(void)
|
2004-12-10 21:39:45 -05:00
|
|
|
{
|
2005-05-10 22:30:58 -04:00
|
|
|
int i;
|
|
|
|
for(i = 0; i < GC_GENERATIONS; i++)
|
|
|
|
{
|
|
|
|
fprintf(stderr,"Generation %d: base=%d, size=%d, here=%d\n",
|
|
|
|
i,
|
|
|
|
generations[i].base,
|
|
|
|
generations[i].limit - generations[i].base,
|
|
|
|
generations[i].here);
|
|
|
|
}
|
2004-12-10 21:39:45 -05:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
fprintf(stderr,"Semispace: base=%d, size=%d, here=%d\n",
|
|
|
|
prior.base,
|
|
|
|
prior.limit - prior.base,
|
|
|
|
prior.here);
|
2004-12-10 21:39:45 -05:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
fprintf(stderr,"Cards: base=%d, size=%d\n",cards,cards_end - cards);
|
|
|
|
}
|
2004-12-10 21:39:45 -05:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
CELL init_zone(ZONE *z, CELL size, CELL base)
|
|
|
|
{
|
|
|
|
z->base = z->here = base;
|
|
|
|
z->limit = z->base + size;
|
|
|
|
z->alarm = z->base + (size * 3) / 4;
|
|
|
|
return z->limit;
|
2004-12-10 21:39:45 -05:00
|
|
|
}
|
2005-05-10 22:30:58 -04:00
|
|
|
|
|
|
|
/* input parameters must be 8 byte aligned */
|
|
|
|
void init_arena(CELL young_size, CELL aging_size)
|
2004-08-12 01:07:22 -04:00
|
|
|
{
|
2005-05-10 22:30:58 -04:00
|
|
|
CELL total_size = (GC_GENERATIONS - 1) * young_size + 2 * aging_size;
|
|
|
|
CELL cards_size = total_size / CARD_SIZE;
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
heap_start = (CELL)alloc_guarded(total_size);
|
|
|
|
cards = alloc_guarded(cards_size);
|
|
|
|
cards_end = cards + cards_size;
|
|
|
|
clear_cards();
|
2004-08-12 23:40:28 -04:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
int i;
|
|
|
|
CELL alloter = heap_start;
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
if(heap_start == 0)
|
|
|
|
fatal_error("Cannot allocate data heap",total_size);
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
alloter = init_zone(&generations[TENURED],aging_size,alloter);
|
|
|
|
alloter = init_zone(&prior,aging_size,alloter);
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2005-05-10 22:30:58 -04:00
|
|
|
for(i = 0; i < GC_GENERATIONS - 1; i++)
|
|
|
|
alloter = init_zone(&generations[i],young_size,alloter);
|
|
|
|
|
|
|
|
if(alloter != heap_start + total_size)
|
|
|
|
fatal_error("Oops",alloter);
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-29 03:20:19 -04:00
|
|
|
allot_profiling = false;
|
|
|
|
gc_in_progress = false;
|
2005-02-17 21:19:27 -05:00
|
|
|
heap_scan = false;
|
2004-12-25 02:55:03 -05:00
|
|
|
gc_time = 0;
|
2005-05-10 22:30:58 -04:00
|
|
|
|
|
|
|
dump_generations();
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
2004-08-29 03:20:19 -04:00
|
|
|
void allot_profile_step(CELL a)
|
|
|
|
{
|
|
|
|
CELL depth = (cs - cs_bot) / CELLS;
|
|
|
|
int i;
|
|
|
|
CELL obj;
|
|
|
|
|
|
|
|
if(gc_in_progress)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for(i = profile_depth; i < depth; i++)
|
|
|
|
{
|
|
|
|
obj = get(cs_bot + i * CELLS);
|
2005-01-14 19:51:38 -05:00
|
|
|
if(type_of(obj) == WORD_TYPE)
|
2004-08-29 03:20:19 -04:00
|
|
|
untag_word(obj)->allot_count += a;
|
|
|
|
}
|
|
|
|
|
2004-12-31 02:38:58 -05:00
|
|
|
if(in_zone(&prior,executing))
|
|
|
|
critical_error("executing in prior zone",executing);
|
|
|
|
untag_word_fast(executing)->allot_count += a;
|
2004-08-29 03:20:19 -04:00
|
|
|
}
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
void flip_zones()
|
|
|
|
{
|
2004-09-01 21:04:16 -04:00
|
|
|
ZONE z = active;
|
2004-08-31 20:31:16 -04:00
|
|
|
active = prior;
|
|
|
|
prior = z;
|
2005-01-25 19:40:57 -05:00
|
|
|
active.here = active.base;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
2004-07-24 00:54:57 -04:00
|
|
|
void primitive_room(void)
|
|
|
|
{
|
2005-03-28 23:45:13 -05:00
|
|
|
box_signed_cell(compiling.limit - compiling.here);
|
|
|
|
box_signed_cell(compiling.limit - compiling.base);
|
|
|
|
box_signed_cell(active.limit - active.here);
|
|
|
|
box_signed_cell(active.limit - active.base);
|
2004-07-24 00:54:57 -04:00
|
|
|
}
|
2004-08-29 03:20:19 -04:00
|
|
|
|
|
|
|
void primitive_allot_profiling(void)
|
|
|
|
{
|
|
|
|
CELL d = dpop();
|
|
|
|
if(d == F)
|
|
|
|
allot_profiling = false;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allot_profiling = true;
|
|
|
|
profile_depth = to_fixnum(d);
|
|
|
|
}
|
|
|
|
}
|
2004-09-06 22:39:12 -04:00
|
|
|
|
2004-09-18 22:29:29 -04:00
|
|
|
void primitive_address(void)
|
2004-09-06 22:39:12 -04:00
|
|
|
{
|
2005-02-18 20:37:01 -05:00
|
|
|
drepl(tag_bignum(s48_ulong_to_bignum(dpeek())));
|
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_size(void)
|
|
|
|
{
|
|
|
|
drepl(tag_fixnum(object_size(dpeek())));
|
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_begin_scan(void)
|
|
|
|
{
|
|
|
|
primitive_gc();
|
|
|
|
heap_scan_ptr = active.base;
|
|
|
|
heap_scan_end = active.here;
|
|
|
|
heap_scan = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_next_object(void)
|
|
|
|
{
|
|
|
|
CELL value = get(heap_scan_ptr);
|
|
|
|
CELL obj = heap_scan_ptr;
|
|
|
|
CELL size, type;
|
|
|
|
|
|
|
|
if(!heap_scan)
|
|
|
|
general_error(ERROR_HEAP_SCAN,F);
|
|
|
|
|
|
|
|
if(heap_scan_ptr >= heap_scan_end)
|
|
|
|
{
|
|
|
|
dpush(F);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(headerp(value))
|
|
|
|
{
|
|
|
|
size = align8(untagged_object_size(heap_scan_ptr));
|
|
|
|
type = untag_header(value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size = CELLS * 2;
|
|
|
|
type = CONS_TYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
heap_scan_ptr += size;
|
|
|
|
|
|
|
|
if(type < HEADER_TYPE)
|
|
|
|
dpush(RETAG(obj,type));
|
|
|
|
else
|
|
|
|
dpush(RETAG(obj,OBJECT_TYPE));
|
|
|
|
}
|
|
|
|
|
|
|
|
void primitive_end_scan(void)
|
|
|
|
{
|
|
|
|
heap_scan = false;
|
2004-09-06 22:39:12 -04:00
|
|
|
}
|