factor/native/memory.c

154 lines
2.9 KiB
C
Raw Normal View History

2004-07-16 02:26:21 -04:00
#include "factor.h"
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 */
2005-05-12 01:02:39 -04:00
/* the heap layout is important:
- two semispaces: tenured and prior
- younger generations follow */
2005-05-10 22:30:58 -04:00
void init_arena(CELL young_size, CELL aging_size)
{
2005-05-12 01:02:39 -04:00
int i;
CELL alloter;
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;
2005-05-10 22:30:58 -04:00
heap_start = (CELL)alloc_guarded(total_size);
2005-05-12 01:02:39 -04:00
heap_end = heap_start + total_size;
2005-05-10 22:30:58 -04:00
cards = alloc_guarded(cards_size);
cards_end = cards + cards_size;
2004-08-12 23:40:28 -04:00
2005-05-12 01:02:39 -04:00
alloter = heap_start;
2005-05-10 22:30:58 -04:00
if(heap_start == 0)
fatal_error("Cannot allocate data heap",total_size);
2005-05-11 00:43:52 -04:00
alloter = init_zone(&tenured,aging_size,alloter);
2005-05-10 22:30:58 -04:00
alloter = init_zone(&prior,aging_size,alloter);
2005-05-12 01:02:39 -04:00
for(i = GC_GENERATIONS - 2; i >= 0; i--)
2005-05-10 22:30:58 -04:00
alloter = init_zone(&generations[i],young_size,alloter);
2005-05-12 01:02:39 -04:00
clear_cards(TENURED,NURSERY);
2005-05-10 22:30:58 -04:00
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;
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;
for(i = profile_depth; i < depth; i++)
{
obj = get(cs_bot + i * CELLS);
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
untag_word_fast(executing)->allot_count += a;
2004-08-29 03:20:19 -04:00
}
2004-07-24 00:54:57 -04:00
void primitive_room(void)
{
2005-05-11 00:43:52 -04:00
CELL list = F;
int gen;
box_signed_cell(compiling.limit - compiling.here);
box_signed_cell(compiling.limit - compiling.base);
2005-05-11 00:52:27 -04:00
box_signed_cell(cards_end - cards);
box_signed_cell(prior.limit - prior.base);
2005-05-11 00:43:52 -04:00
for(gen = GC_GENERATIONS - 1; gen >= 0; gen--)
{
ZONE *z = &generations[gen];
list = cons(cons(
tag_fixnum(z->limit - z->here),
tag_fixnum(z->limit - z->base)),
list);
}
dpush(list);
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-18 22:29:29 -04:00
void primitive_address(void)
{
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)
{
2005-05-12 01:02:39 -04:00
garbage_collection(TENURED);
2005-05-11 00:43:52 -04:00
heap_scan_ptr = tenured.base;
heap_scan_end = tenured.here;
2005-02-18 20:37:01 -05:00
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;
}