2004-07-16 02:26:21 -04:00
|
|
|
#include "factor.h"
|
|
|
|
|
2004-08-12 23:40:28 -04:00
|
|
|
/* set up guard pages to check for under/overflow.
|
|
|
|
size must be a multiple of the page size */
|
2004-08-12 01:07:22 -04:00
|
|
|
void* alloc_guarded(CELL size)
|
|
|
|
{
|
2004-08-12 23:40:28 -04:00
|
|
|
int pagesize = getpagesize();
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2004-08-12 23:40:28 -04:00
|
|
|
char* array = mmap((void*)0,pagesize + size + pagesize,
|
2004-09-11 15:26:24 -04:00
|
|
|
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
|
|
MAP_ANON | MAP_PRIVATE,-1,0);
|
2004-08-12 23:40:28 -04:00
|
|
|
|
|
|
|
if(mprotect(array,pagesize,PROT_NONE) == -1)
|
2004-08-12 02:13:43 -04:00
|
|
|
fatal_error("Cannot allocate low guard page",(CELL)array);
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2004-08-12 23:40:28 -04:00
|
|
|
if(mprotect(array + pagesize + size,pagesize,PROT_NONE) == -1)
|
2004-08-12 02:13:43 -04:00
|
|
|
fatal_error("Cannot allocate high guard page",(CELL)array);
|
2004-08-12 01:07:22 -04:00
|
|
|
|
2004-08-12 02:13:43 -04:00
|
|
|
/* return bottom of actual array */
|
2004-08-12 23:40:28 -04:00
|
|
|
return array + pagesize;
|
2004-08-12 01:07:22 -04:00
|
|
|
}
|
|
|
|
|
2004-08-31 20:31:16 -04:00
|
|
|
void init_zone(ZONE* z, CELL size)
|
2004-07-16 02:26:21 -04:00
|
|
|
{
|
2004-09-06 02:32:04 -04:00
|
|
|
z->base = z->here = align8((CELL)alloc_guarded(size));
|
2004-07-16 02:26:21 -04:00
|
|
|
if(z->base == 0)
|
|
|
|
fatal_error("Cannot allocate zone",size);
|
|
|
|
z->limit = z->base + size;
|
2004-07-29 17:18:41 -04:00
|
|
|
z->alarm = z->base + (size * 3) / 4;
|
2004-07-16 02:26:21 -04:00
|
|
|
z->base = align8(z->base);
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_arena(CELL size)
|
|
|
|
{
|
2004-08-31 20:31:16 -04:00
|
|
|
init_zone(&active,size);
|
|
|
|
init_zone(&prior,size);
|
2004-08-29 03:20:19 -04:00
|
|
|
allot_profiling = false;
|
|
|
|
gc_in_progress = false;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
2004-08-29 03:20:19 -04:00
|
|
|
#ifdef FACTOR_PROFILER
|
|
|
|
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);
|
|
|
|
if(TAG(obj) == WORD_TYPE)
|
|
|
|
untag_word(obj)->allot_count += a;
|
|
|
|
}
|
|
|
|
|
|
|
|
executing->allot_count += a;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2004-08-16 20:42:30 -04:00
|
|
|
void check_memory(void)
|
2004-07-16 02:26:21 -04:00
|
|
|
{
|
2004-08-31 20:31:16 -04:00
|
|
|
if(active.here > active.alarm)
|
2004-07-29 17:18:41 -04:00
|
|
|
{
|
2004-08-31 20:31:16 -04:00
|
|
|
if(active.here > active.limit)
|
2004-08-16 20:42:30 -04:00
|
|
|
{
|
2004-08-26 22:21:17 -04:00
|
|
|
fprintf(stderr,"Out of memory\n");
|
2004-08-31 20:31:16 -04:00
|
|
|
fprintf(stderr,"active.base = %ld\n",active.base);
|
|
|
|
fprintf(stderr,"active.here = %ld\n",active.here);
|
|
|
|
fprintf(stderr,"active.limit = %ld\n",active.limit);
|
2004-08-26 22:21:17 -04:00
|
|
|
fflush(stderr);
|
2004-08-16 20:42:30 -04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2004-07-29 17:18:41 -04:00
|
|
|
/* Execute the 'garbage-collection' word */
|
2004-08-23 01:13:09 -04:00
|
|
|
call(userenv[GC_ENV]);
|
2004-07-29 17:18:41 -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;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool in_zone(ZONE* z, CELL pointer)
|
|
|
|
{
|
|
|
|
return pointer >= z->base && pointer < z->limit;
|
|
|
|
}
|
2004-07-24 00:54:57 -04:00
|
|
|
|
|
|
|
void primitive_room(void)
|
|
|
|
{
|
2004-08-01 19:26:43 -04:00
|
|
|
/* push: free total */
|
2004-08-31 20:31:16 -04:00
|
|
|
dpush(tag_integer(active.limit - active.here));
|
|
|
|
dpush(tag_integer(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)
|
|
|
|
{
|
|
|
|
#ifndef FACTOR_PROFILER
|
|
|
|
general_error(ERROR_PROFILING_DISABLED,F);
|
|
|
|
#else
|
|
|
|
CELL d = dpop();
|
|
|
|
if(d == F)
|
|
|
|
allot_profiling = false;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allot_profiling = true;
|
|
|
|
profile_depth = to_fixnum(d);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
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
|
|
|
{
|
|
|
|
dpush(tag_object(s48_ulong_to_bignum(dpop())));
|
|
|
|
}
|