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,
|
|
|
|
PROT_READ | PROT_WRITE,MAP_ANON | MAP_PRIVATE,-1,0);
|
|
|
|
|
|
|
|
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-12 02:13:43 -04:00
|
|
|
ZONE* zalloc(CELL size)
|
2004-07-16 02:26:21 -04:00
|
|
|
{
|
|
|
|
ZONE* z = (ZONE*)malloc(sizeof(ZONE));
|
|
|
|
if(z == 0)
|
|
|
|
fatal_error("Cannot allocate zone header",size);
|
|
|
|
z->base = z->here = (CELL)malloc(size);
|
|
|
|
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);
|
|
|
|
return z;
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_arena(CELL size)
|
|
|
|
{
|
|
|
|
z1 = zalloc(size);
|
|
|
|
z2 = zalloc(size);
|
|
|
|
active = z1;
|
|
|
|
}
|
|
|
|
|
2004-08-04 22:43:58 -04:00
|
|
|
void* allot(CELL a)
|
2004-07-16 02:26:21 -04:00
|
|
|
{
|
|
|
|
CELL h = active->here;
|
|
|
|
active->here = align8(active->here + a);
|
2004-07-29 17:18:41 -04:00
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
if(active->here > active->limit)
|
2004-07-24 00:54:57 -04:00
|
|
|
{
|
|
|
|
printf("Out of memory\n");
|
2004-07-28 19:02:24 -04:00
|
|
|
printf("active->base = %ld\n",active->base);
|
|
|
|
printf("active->here = %ld\n",active->here);
|
|
|
|
printf("active->limit = %ld\n",active->limit);
|
|
|
|
printf("request = %ld\n",a);
|
2004-07-24 00:54:57 -04:00
|
|
|
exit(1);
|
|
|
|
}
|
2004-07-29 17:18:41 -04:00
|
|
|
else if(active->here > active->alarm)
|
|
|
|
{
|
|
|
|
/* Execute the 'garbage-collection' word */
|
|
|
|
cpush(env.cf);
|
|
|
|
env.cf = env.user[GC_ENV];
|
|
|
|
}
|
|
|
|
|
2004-08-04 22:43:58 -04:00
|
|
|
return (void*)h;
|
2004-07-16 02:26:21 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void flip_zones()
|
|
|
|
{
|
|
|
|
if(active == z1)
|
|
|
|
{
|
|
|
|
prior = z1;
|
|
|
|
active = z2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prior = z2;
|
|
|
|
active = z1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 */
|
|
|
|
dpush(tag_fixnum(active->limit - active->here));
|
2004-08-12 17:36:36 -04:00
|
|
|
dpush(tag_fixnum(active->limit - active->base));
|
2004-07-24 00:54:57 -04:00
|
|
|
}
|