memory management change, allocating primitives call gc directly

cvs
Slava Pestov 2004-10-13 03:49:43 +00:00
parent 9c2166b0be
commit be8eb34102
31 changed files with 351 additions and 200 deletions

View File

@ -1,5 +1,5 @@
CC = gcc CC = gcc
DEFAULT_CFLAGS = -Os -Wall -export-dynamic -fomit-frame-pointer DEFAULT_CFLAGS = -Os -Wall -export-dynamic -fomit-frame-pointer $(SITE_CFLAGS)
DEFAULT_LIBS = -lm DEFAULT_LIBS = -lm
STRIP = strip STRIP = strip
@ -22,6 +22,7 @@ default:
@echo "Run 'make' with one of the following parameters:" @echo "Run 'make' with one of the following parameters:"
@echo "" @echo ""
@echo "bsd" @echo "bsd"
@echo "bsd-nopthread - on FreeBSD 4, if you want to use profiling"
@echo "linux" @echo "linux"
@echo "solaris" @echo "solaris"
@echo "" @echo ""
@ -36,6 +37,11 @@ bsd:
CFLAGS="$(DEFAULT_CFLAGS) -DFFI -pthread" \ CFLAGS="$(DEFAULT_CFLAGS) -DFFI -pthread" \
LIBS="$(DEFAULT_LIBS)" LIBS="$(DEFAULT_LIBS)"
bsd-nopthread:
$(MAKE) f \
CFLAGS="$(DEFAULT_CFLAGS) -DFFI" \
LIBS="$(DEFAULT_LIBS)"
linux: linux:
$(MAKE) f \ $(MAKE) f \
CFLAGS="$(DEFAULT_CFLAGS) -DFFI" \ CFLAGS="$(DEFAULT_CFLAGS) -DFFI" \

View File

@ -74,7 +74,6 @@ DEFER: os-env
DEFER: type DEFER: type
DEFER: size DEFER: size
DEFER: address DEFER: address
DEFER: dump
DEFER: heap-stats DEFER: heap-stats
IN: strings IN: strings
@ -357,7 +356,6 @@ IN: image
(random-int) (random-int)
type type
size size
dump
cwd cwd
cd cd
compiled-offset compiled-offset

View File

@ -209,7 +209,6 @@ USE: words
[ allot-profiling | " depth -- " ] [ allot-profiling | " depth -- " ]
[ allot-count | " word -- n " ] [ allot-count | " word -- n " ]
[ set-allot-count | " n word -- n " ] [ set-allot-count | " n word -- n " ]
[ dump | " obj -- " ]
[ cwd | " -- dir " ] [ cwd | " -- dir " ]
[ cd | " dir -- " ] [ cd | " dir -- " ]
[ compiled-offset | " -- ptr " ] [ compiled-offset | " -- ptr " ]

View File

@ -36,8 +36,9 @@ USE: stack
USE: words USE: words
USE: vectors USE: vectors
! The variable "profile-top-only" toggles between ! The variable "only-top" toggles between
! culminative counts, and top of call stack counts. ! culminative counts, and top of call stack counts.
SYMBOL: only-top
: reset-counts ( -- ) : reset-counts ( -- )
[ 0 over set-call-count 0 swap set-allot-count ] each-word ; [ 0 over set-call-count 0 swap set-allot-count ] each-word ;
@ -47,11 +48,7 @@ USE: vectors
: call-count, ( word -- ) : call-count, ( word -- )
#! Add to constructing list if call count is non-zero. #! Add to constructing list if call count is non-zero.
dup call-count dup 0 = [ dup call-count dup 0 = [ 2drop ] [ cons , ] ifte ;
2drop
] [
cons ,
] ifte ;
: counts. ( alist -- ) : counts. ( alist -- )
sort-counts [ . ] each ; sort-counts [ . ] each ;
@ -61,27 +58,21 @@ USE: vectors
[, [ call-count, ] each-word ,] counts. ; [, [ call-count, ] each-word ,] counts. ;
: profile-depth ( -- n ) : profile-depth ( -- n )
"profile-top-only" get [ only-top get [ -1 ] [ callstack vector-length ] ifte ;
-1
] [
callstack vector-length
] ifte ;
: call-profile ( quot -- ) : (call-profile) ( quot -- )
#! Execute a quotation with the CPU profiler enabled.
reset-counts reset-counts
profile-depth call-profiling profile-depth call-profiling
call call
f call-profiling f call-profiling ;
call-counts. ;
: call-profile ( quot -- )
#! Execute a quotation with the CPU profiler enabled.
(call-profile) call-counts. ;
: allot-count, ( word -- ) : allot-count, ( word -- )
#! Add to constructing list if allot count is non-zero. #! Add to constructing list if allot count is non-zero.
dup allot-count dup 0 = [ dup allot-count dup 0 = [ 2drop ] [ cons , ] ifte ;
2drop
] [
cons ,
] ifte ;
: allot-counts. ( -- alist ) : allot-counts. ( -- alist )
#! Print word/allot count pairs. #! Print word/allot count pairs.

View File

@ -2,24 +2,29 @@ IN: scratchpad
USE: kernel USE: kernel
USE: math USE: math
USE: test USE: test
USE: real-math
[ 4.0 ] [ 16 ] [ sqrt ] test-word ! Lets get the argument order correct, eh?
[ #{ 0 4.0 } ] [ -16 ] [ sqrt ] test-word [ 0.0 ] [ 0 1 fatan2 ] unit-test
[ 0.25 ] [ 2 -2 fpow ] unit-test
[ 4.0 ] [ 2 2 ] [ ^ ] test-word [ 4.0 ] [ 16 sqrt ] unit-test
[ 0.25 ] [ 2 -2 ] [ ^ ] test-word [ #{ 0 4.0 } ] [ -16 sqrt ] unit-test
[ t ] [ 2 0.5 ^ 2 ^ ] [ 2 2.00001 between? ] test-word
[ t ] [ e pi i * ^ real ] [ -1.0 = ] test-word
[ t ] [ e pi i * ^ imaginary ] [ -0.00001 0.00001 between? ] test-word
[ 1.0 ] [ 0 ] [ cosh ] test-word [ 4.0 ] [ 2 2 ^ ] unit-test
[ 0.0 ] [ 1 ] [ acosh ] test-word [ 0.25 ] [ 2 -2 ^ ] unit-test
[ t ] [ 2 0.5 ^ 2 ^ 2 2.00001 between? ] unit-test
[ t ] [ e pi i * ^ real -1.0 = ] unit-test
[ t ] [ e pi i * ^ imaginary -0.00001 0.00001 between? ] unit-test
[ 1.0 ] [ 0 ] [ cos ] test-word [ 1.0 ] [ 0 cosh ] unit-test
[ 0.0 ] [ 1 ] [ acos ] test-word [ 0.0 ] [ 1 acosh ] unit-test
[ 0.0 ] [ 0 ] [ sinh ] test-word [ 1.0 ] [ 0 cos ] unit-test
[ 0.0 ] [ 0 ] [ asinh ] test-word [ 0.0 ] [ 1 acos ] unit-test
[ 0.0 ] [ 0 ] [ sin ] test-word [ 0.0 ] [ 0 sinh ] unit-test
[ 0.0 ] [ 0 ] [ asin ] test-word [ 0.0 ] [ 0 asinh ] unit-test
[ 0.0 ] [ 0 sin ] unit-test
[ 0.0 ] [ 0 asin ] unit-test

View File

@ -55,6 +55,7 @@ ARRAY* to_bignum(CELL tagged)
void primitive_to_bignum(void) void primitive_to_bignum(void)
{ {
maybe_garbage_collection();
drepl(tag_object(to_bignum(dpeek()))); drepl(tag_object(to_bignum(dpeek())));
} }
@ -65,38 +66,39 @@ void primitive_bignum_eq(void)
dpush(tag_boolean(s48_bignum_equal_p(x,y))); dpush(tag_boolean(s48_bignum_equal_p(x,y)));
} }
#define GC_AND_POP_BIGNUMS(x,y) \
ARRAY *x, *y; \
maybe_garbage_collection(); \
y = to_bignum(dpop()); \
x = to_bignum(dpop());
void primitive_bignum_add(void) void primitive_bignum_add(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_add(x,y))); dpush(tag_object(s48_bignum_add(x,y)));
} }
void primitive_bignum_subtract(void) void primitive_bignum_subtract(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_subtract(x,y))); dpush(tag_object(s48_bignum_subtract(x,y)));
} }
void primitive_bignum_multiply(void) void primitive_bignum_multiply(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_multiply(x,y))); dpush(tag_object(s48_bignum_multiply(x,y)));
} }
void primitive_bignum_divint(void) void primitive_bignum_divint(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_quotient(x,y))); dpush(tag_object(s48_bignum_quotient(x,y)));
} }
void primitive_bignum_divfloat(void) void primitive_bignum_divfloat(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(make_float( dpush(tag_object(make_float(
s48_bignum_to_double(x) / s48_bignum_to_double(x) /
s48_bignum_to_double(y)))); s48_bignum_to_double(y))));
@ -104,9 +106,8 @@ void primitive_bignum_divfloat(void)
void primitive_bignum_divmod(void) void primitive_bignum_divmod(void)
{ {
ARRAY* y = to_bignum(dpop());
ARRAY* x = to_bignum(dpop());
ARRAY *q, *r; ARRAY *q, *r;
GC_AND_POP_BIGNUMS(x,y);
s48_bignum_divide(x,y,&q,&r); s48_bignum_divide(x,y,&q,&r);
dpush(tag_object(q)); dpush(tag_object(q));
dpush(tag_object(r)); dpush(tag_object(r));
@ -114,36 +115,35 @@ void primitive_bignum_divmod(void)
void primitive_bignum_mod(void) void primitive_bignum_mod(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_remainder(x,y))); dpush(tag_object(s48_bignum_remainder(x,y)));
} }
void primitive_bignum_and(void) void primitive_bignum_and(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_bitwise_and(x,y))); dpush(tag_object(s48_bignum_bitwise_and(x,y)));
} }
void primitive_bignum_or(void) void primitive_bignum_or(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_bitwise_ior(x,y))); dpush(tag_object(s48_bignum_bitwise_ior(x,y)));
} }
void primitive_bignum_xor(void) void primitive_bignum_xor(void)
{ {
ARRAY* y = to_bignum(dpop()); GC_AND_POP_BIGNUMS(x,y);
ARRAY* x = to_bignum(dpop());
dpush(tag_object(s48_bignum_bitwise_xor(x,y))); dpush(tag_object(s48_bignum_bitwise_xor(x,y)));
} }
void primitive_bignum_shift(void) void primitive_bignum_shift(void)
{ {
FIXNUM y = to_fixnum(dpop()); FIXNUM y;
ARRAY* x = to_bignum(dpop()); ARRAY* x;
maybe_garbage_collection();
y = to_fixnum(dpop());
x = to_bignum(dpop());
dpush(tag_object(s48_bignum_arithmetic_shift(x,y))); dpush(tag_object(s48_bignum_arithmetic_shift(x,y)));
} }
@ -207,6 +207,7 @@ void primitive_bignum_greatereq(void)
void primitive_bignum_not(void) void primitive_bignum_not(void)
{ {
maybe_garbage_collection();
drepl(tag_object(s48_bignum_bitwise_not( drepl(tag_object(s48_bignum_bitwise_not(
untag_bignum(dpeek())))); untag_bignum(dpeek()))));
} }

View File

@ -62,8 +62,12 @@ void primitive_to_rect(void)
void primitive_from_rect(void) void primitive_from_rect(void)
{ {
CELL imaginary = dpop(); CELL imaginary, real;
CELL real = dpop();
maybe_garbage_collection();
imaginary = dpop();
real = dpop();
if(!realp(imaginary)) if(!realp(imaginary))
type_error(REAL_TYPE,imaginary); type_error(REAL_TYPE,imaginary);

View File

@ -10,8 +10,10 @@ CELL cons(CELL car, CELL cdr)
void primitive_cons(void) void primitive_cons(void)
{ {
CELL cdr = dpop(); CELL car, cdr;
CELL car = dpop(); maybe_garbage_collection();
cdr = dpop();
car = dpop();
dpush(cons(car,cdr)); dpush(cons(car,cdr));
} }

View File

@ -69,8 +69,8 @@ void type_error(CELL type, CELL tagged)
general_error(ERROR_TYPE,c); general_error(ERROR_TYPE,c);
} }
void range_error(CELL tagged, CELL index, CELL max) void range_error(CELL tagged, FIXNUM index, CELL max)
{ {
CELL c = cons(tagged,cons(tag_fixnum(index),cons(tag_fixnum(max),F))); CELL c = cons(tagged,cons(tag_integer(index),cons(tag_cell(max),F)));
general_error(ERROR_RANGE,c); general_error(ERROR_RANGE,c);
} }

View File

@ -21,4 +21,4 @@ void throw_error(CELL object);
void general_error(CELL error, CELL tagged); void general_error(CELL error, CELL tagged);
void type_error(CELL type, CELL tagged); void type_error(CELL type, CELL tagged);
void primitive_throw(void); void primitive_throw(void);
void range_error(CELL tagged, CELL index, CELL max); void range_error(CELL tagged, FIXNUM index, CELL max);

View File

@ -33,6 +33,11 @@
typedef unsigned long int CELL; typedef unsigned long int CELL;
#define CELLS ((signed)sizeof(CELL)) #define CELLS ((signed)sizeof(CELL))
#define FIXNUM_MAX (LONG_MAX >> TAG_BITS)
#define FIXNUM_MIN (LONG_MIN >> TAG_BITS)
#define FIXNUM long int /* unboxed */
#define WORD_SIZE (CELLS*8) #define WORD_SIZE (CELLS*8)
#define HALF_WORD_SIZE (CELLS*4) #define HALF_WORD_SIZE (CELLS*4)
#define HALF_WORD_MASK (((unsigned long)1<<HALF_WORD_SIZE)-1) #define HALF_WORD_MASK (((unsigned long)1<<HALF_WORD_SIZE)-1)
@ -46,7 +51,7 @@ typedef unsigned char BYTE;
/* Memory heap size */ /* Memory heap size */
#define DEFAULT_ARENA (64 * 1024 * 1024) #define DEFAULT_ARENA (64 * 1024 * 1024)
#define COMPILE_ZONE_SIZE (5 * 1024 * 1024) #define COMPILE_ZONE_SIZE (4 * 1024 * 1024)
#define STACK_SIZE 16384 #define STACK_SIZE 16384

View File

@ -12,10 +12,15 @@ DLL* untag_dll(CELL tagged)
void primitive_dlopen(void) void primitive_dlopen(void)
{ {
#ifdef FFI #ifdef FFI
char* path = unbox_c_string(); char* path;
void* dllptr = dlopen(path,RTLD_LAZY); void* dllptr;
DLL* dll; DLL* dll;
maybe_garbage_collection();
path = unbox_c_string();
dllptr = dlopen(path,RTLD_LAZY);
if(dllptr == NULL) if(dllptr == NULL)
{ {
general_error(ERROR_FFI,tag_object( general_error(ERROR_FFI,tag_object(
@ -81,7 +86,9 @@ void primitive_alien(void)
#ifdef FFI #ifdef FFI
CELL length = unbox_integer(); CELL length = unbox_integer();
CELL ptr = unbox_integer(); CELL ptr = unbox_integer();
ALIEN* alien = allot_object(ALIEN_TYPE,sizeof(ALIEN)); ALIEN* alien;
maybe_garbage_collection();
alien = allot_object(ALIEN_TYPE,sizeof(ALIEN));
alien->ptr = ptr; alien->ptr = ptr;
alien->length = length; alien->length = length;
alien->local = false; alien->local = false;
@ -95,8 +102,11 @@ void primitive_local_alien(void)
{ {
#ifdef FFI #ifdef FFI
CELL length = unbox_integer(); CELL length = unbox_integer();
ALIEN* alien = allot_object(ALIEN_TYPE,sizeof(ALIEN)); ALIEN* alien;
STRING* local = string(length / CHARS,'\0'); STRING* local;
maybe_garbage_collection();
alien = allot_object(ALIEN_TYPE,sizeof(ALIEN));
local = string(length / CHARS,'\0');
alien->ptr = (CELL)local + sizeof(STRING); alien->ptr = (CELL)local + sizeof(STRING);
alien->length = length; alien->length = length;
alien->local = true; alien->local = true;

View File

@ -4,9 +4,13 @@ void primitive_open_file(void)
{ {
bool write = untag_boolean(dpop()); bool write = untag_boolean(dpop());
bool read = untag_boolean(dpop()); bool read = untag_boolean(dpop());
char* path = unbox_c_string();
int mode; char* path;
int fd; int mode, fd;
maybe_garbage_collection();
path = unbox_c_string();
if(read && write) if(read && write)
mode = O_RDWR | O_CREAT; mode = O_RDWR | O_CREAT;
@ -28,7 +32,11 @@ void primitive_open_file(void)
void primitive_stat(void) void primitive_stat(void)
{ {
struct stat sb; struct stat sb;
STRING* path = untag_string(dpop()); STRING* path;
maybe_garbage_collection();
path = untag_string(dpop());
if(stat(to_c_string(path),&sb) < 0) if(stat(to_c_string(path),&sb) < 0)
dpush(F); dpush(F);
else else
@ -50,14 +58,19 @@ void primitive_stat(void)
void primitive_read_dir(void) void primitive_read_dir(void)
{ {
STRING* path = untag_string(dpop()); STRING* path;
DIR* dir = opendir(to_c_string(path)); DIR* dir;
CELL result = F; CELL result = F;
maybe_garbage_collection();
path = untag_string(dpop());
dir = opendir(to_c_string(path));
if(dir != NULL) if(dir != NULL)
{ {
struct dirent* file; struct dirent* file;
while(file = readdir(dir)) while((file = readdir(dir)) != NULL)
{ {
CELL name = tag_object(from_c_string( CELL name = tag_object(from_c_string(
file->d_name)); file->d_name));
@ -73,6 +86,7 @@ void primitive_read_dir(void)
void primitive_cwd(void) void primitive_cwd(void)
{ {
char wd[MAXPATHLEN]; char wd[MAXPATHLEN];
maybe_garbage_collection();
if(getcwd(wd,MAXPATHLEN) < 0) if(getcwd(wd,MAXPATHLEN) < 0)
io_error(__FUNCTION__); io_error(__FUNCTION__);
box_c_string(wd); box_c_string(wd);
@ -80,5 +94,6 @@ void primitive_cwd(void)
void primitive_cd(void) void primitive_cd(void)
{ {
maybe_garbage_collection();
chdir(unbox_c_string()); chdir(unbox_c_string());
} }

View File

@ -1,8 +1,3 @@
#define FIXNUM_MAX (LONG_MAX >> TAG_BITS)
#define FIXNUM_MIN (LONG_MIN >> TAG_BITS)
#define FIXNUM long int /* unboxed */
INLINE FIXNUM untag_fixnum_fast(CELL tagged) INLINE FIXNUM untag_fixnum_fast(CELL tagged)
{ {
return ((FIXNUM)tagged) >> TAG_BITS; return ((FIXNUM)tagged) >> TAG_BITS;

View File

@ -27,15 +27,22 @@ double to_float(CELL tagged)
void primitive_to_float(void) void primitive_to_float(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(to_float(dpeek())))); drepl(tag_object(make_float(to_float(dpeek()))));
} }
void primitive_str_to_float(void) void primitive_str_to_float(void)
{ {
STRING* str = untag_string(dpeek()); STRING* str;
char* c_str = to_c_string(str); char *c_str, *end;
char* end = c_str; double f;
double f = strtod(c_str,&end);
maybe_garbage_collection();
str = untag_string(dpeek());
c_str = to_c_string(str);
end = c_str;
f = strtod(c_str,&end);
if(end != c_str + str->capacity) if(end != c_str + str->capacity)
general_error(ERROR_FLOAT_FORMAT,tag_object(str)); general_error(ERROR_FLOAT_FORMAT,tag_object(str));
drepl(tag_object(make_float(f))); drepl(tag_object(make_float(f)));
@ -44,6 +51,9 @@ void primitive_str_to_float(void)
void primitive_float_to_str(void) void primitive_float_to_str(void)
{ {
char tmp[33]; char tmp[33];
maybe_garbage_collection();
snprintf(tmp,32,"%.16g",to_float(dpop())); snprintf(tmp,32,"%.16g",to_float(dpop()));
tmp[32] = '\0'; tmp[32] = '\0';
box_c_string(tmp); box_c_string(tmp);
@ -51,43 +61,49 @@ void primitive_float_to_str(void)
void primitive_float_to_bits(void) void primitive_float_to_bits(void)
{ {
double f = untag_float(dpeek()); double f;
long long f_raw = *(long long*)&f; long long f_raw;
maybe_garbage_collection();
f = untag_float(dpeek());
f_raw = *(long long*)&f;
drepl(tag_object(s48_long_long_to_bignum(f_raw))); drepl(tag_object(s48_long_long_to_bignum(f_raw)));
} }
#define GC_AND_POP_FLOATS(x,y) \
double x, y; \
maybe_garbage_collection(); \
y = to_float(dpop()); \
x = to_float(dpop());
void primitive_float_eq(void) void primitive_float_eq(void)
{ {
double y = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double x = to_float(dpop());
dpush(tag_boolean(x == y)); dpush(tag_boolean(x == y));
} }
void primitive_float_add(void) void primitive_float_add(void)
{ {
double y = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double x = to_float(dpop());
dpush(tag_object(make_float(x + y))); dpush(tag_object(make_float(x + y)));
} }
void primitive_float_subtract(void) void primitive_float_subtract(void)
{ {
double y = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double x = to_float(dpop());
dpush(tag_object(make_float(x - y))); dpush(tag_object(make_float(x - y)));
} }
void primitive_float_multiply(void) void primitive_float_multiply(void)
{ {
double y = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double x = to_float(dpop());
dpush(tag_object(make_float(x * y))); dpush(tag_object(make_float(x * y)));
} }
void primitive_float_divfloat(void) void primitive_float_divfloat(void)
{ {
double y = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double x = to_float(dpop());
dpush(tag_object(make_float(x / y))); dpush(tag_object(make_float(x / y)));
} }
@ -121,64 +137,72 @@ void primitive_float_greatereq(void)
void primitive_facos(void) void primitive_facos(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(acos(to_float(dpeek()))))); drepl(tag_object(make_float(acos(to_float(dpeek())))));
} }
void primitive_fasin(void) void primitive_fasin(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(asin(to_float(dpeek()))))); drepl(tag_object(make_float(asin(to_float(dpeek())))));
} }
void primitive_fatan(void) void primitive_fatan(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(atan(to_float(dpeek()))))); drepl(tag_object(make_float(atan(to_float(dpeek())))));
} }
void primitive_fatan2(void) void primitive_fatan2(void)
{ {
double x = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double y = to_float(dpop()); dpush(tag_object(make_float(atan2(x,y))));
dpush(tag_object(make_float(atan2(y,x))));
} }
void primitive_fcos(void) void primitive_fcos(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(cos(to_float(dpeek()))))); drepl(tag_object(make_float(cos(to_float(dpeek())))));
} }
void primitive_fexp(void) void primitive_fexp(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(exp(to_float(dpeek()))))); drepl(tag_object(make_float(exp(to_float(dpeek())))));
} }
void primitive_fcosh(void) void primitive_fcosh(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(cosh(to_float(dpeek()))))); drepl(tag_object(make_float(cosh(to_float(dpeek())))));
} }
void primitive_flog(void) void primitive_flog(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(log(to_float(dpeek()))))); drepl(tag_object(make_float(log(to_float(dpeek())))));
} }
void primitive_fpow(void) void primitive_fpow(void)
{ {
double x = to_float(dpop()); GC_AND_POP_FLOATS(x,y);
double y = to_float(dpop()); dpush(tag_object(make_float(pow(x,y))));
dpush(tag_object(make_float(pow(y,x))));
} }
void primitive_fsin(void) void primitive_fsin(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(sin(to_float(dpeek()))))); drepl(tag_object(make_float(sin(to_float(dpeek())))));
} }
void primitive_fsinh(void) void primitive_fsinh(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(sinh(to_float(dpeek()))))); drepl(tag_object(make_float(sinh(to_float(dpeek())))));
} }
void primitive_fsqrt(void) void primitive_fsqrt(void)
{ {
maybe_garbage_collection();
drepl(tag_object(make_float(sqrt(to_float(dpeek()))))); drepl(tag_object(make_float(sqrt(to_float(dpeek())))));
} }

View File

@ -132,6 +132,7 @@ void collect_roots(void)
void primitive_gc(void) void primitive_gc(void)
{ {
fprintf(stderr,"GC!\n");
gc_in_progress = true; gc_in_progress = true;
flip_zones(); flip_zones();
@ -149,3 +150,23 @@ void primitive_gc(void)
gc_in_progress = false; gc_in_progress = false;
} }
/* WARNING: only call this from a context where all local variables
are also reachable via the GC roots. */
void maybe_garbage_collection(void)
{
if(active.here > active.alarm)
{
if(active.here > active.limit)
{
fprintf(stderr,"Out of memory\n");
fprintf(stderr,"active.base = %ld\n",active.base);
fprintf(stderr,"active.here = %ld\n",active.here);
fprintf(stderr,"active.limit = %ld\n",active.limit);
fflush(stderr);
exit(1);
}
else
primitive_gc();
}
}

View File

@ -7,3 +7,4 @@ void collect_object(void);
void collect_next(void); void collect_next(void);
void collect_roots(void); void collect_roots(void);
void primitive_gc(void); void primitive_gc(void);
void maybe_garbage_collection(void);

View File

@ -36,7 +36,6 @@ void init_arena(CELL size)
init_zone(&prior,size); init_zone(&prior,size);
allot_profiling = false; allot_profiling = false;
gc_in_progress = false; gc_in_progress = false;
gc_protect = false;
} }
void allot_profile_step(CELL a) void allot_profile_step(CELL a)
@ -58,25 +57,6 @@ void allot_profile_step(CELL a)
executing->allot_count += a; executing->allot_count += a;
} }
void garbage_collection_later(void)
{
if(gc_protect)
return;
if(active.here > active.limit)
{
fprintf(stderr,"Out of memory\n");
fprintf(stderr,"active.base = %ld\n",active.base);
fprintf(stderr,"active.here = %ld\n",active.here);
fprintf(stderr,"active.limit = %ld\n",active.limit);
fflush(stderr);
exit(1);
}
/* Execute the 'garbage-collection' word */
call(userenv[GC_ENV]);
}
void flip_zones() void flip_zones()
{ {
ZONE z = active; ZONE z = active;

View File

@ -10,15 +10,11 @@ ZONE prior;
bool allot_profiling; bool allot_profiling;
/* we can temporarily disable GC */
bool gc_protect;
void* alloc_guarded(CELL size); void* alloc_guarded(CELL size);
void init_zone(ZONE* zone, CELL size); void init_zone(ZONE* zone, CELL size);
void init_arena(CELL size); void init_arena(CELL size);
void flip_zones(); void flip_zones();
void garbage_collection_later(void);
void allot_profile_step(CELL a); void allot_profile_step(CELL a);
INLINE CELL align8(CELL a) INLINE CELL align8(CELL a)
@ -32,8 +28,6 @@ INLINE void* allot(CELL a)
active.here += align8(a); active.here += align8(a);
if(allot_profiling) if(allot_profiling)
allot_profile_step(align8(a)); allot_profile_step(align8(a));
if(active.here > active.alarm)
garbage_collection_later();
return (void*)h; return (void*)h;
} }

View File

@ -7,8 +7,12 @@ void primitive_exit(void)
void primitive_os_env(void) void primitive_os_env(void)
{ {
char* name = unbox_c_string(); char *name, *value;
char* value = getenv(name);
maybe_garbage_collection();
name = unbox_c_string();
value = getenv(name);
if(value == NULL) if(value == NULL)
dpush(F); dpush(F);
else else
@ -24,6 +28,7 @@ void primitive_millis(void)
{ {
struct timeval t; struct timeval t;
gettimeofday(&t,NULL); gettimeofday(&t,NULL);
maybe_garbage_collection();
dpush(tag_object(s48_long_long_to_bignum( dpush(tag_object(s48_long_long_to_bignum(
(long long)t.tv_sec * 1000 + t.tv_usec/1000))); (long long)t.tv_sec * 1000 + t.tv_usec/1000)));
} }
@ -41,15 +46,6 @@ void primitive_init_random(void)
void primitive_random_int(void) void primitive_random_int(void)
{ {
maybe_garbage_collection();
dpush(tag_object(s48_long_to_bignum(random()))); dpush(tag_object(s48_long_to_bignum(random())));
} }
void primitive_dump(void)
{
/* Take an object, and print its memory. Later, return a vector */
CELL obj = dpop();
CELL size = object_size(obj);
int i;
for(i = 0; i < size; i += CELLS)
fprintf(stderr,"%lx\n",get(UNTAG(obj) + i));
}

View File

@ -4,4 +4,3 @@ void primitive_eq(void);
void primitive_millis(void); void primitive_millis(void);
void primitive_init_random(void); void primitive_init_random(void);
void primitive_random_int(void); void primitive_random_int(void);
void primitive_dump(void);

View File

@ -169,7 +169,6 @@ XT primitives[] = {
primitive_random_int, primitive_random_int,
primitive_type, primitive_type,
primitive_size, primitive_size,
primitive_dump,
primitive_cwd, primitive_cwd,
primitive_cd, primitive_cd,
primitive_compiled_offset, primitive_compiled_offset,

View File

@ -4,8 +4,12 @@
library implementation, to avoid breaking invariants. */ library implementation, to avoid breaking invariants. */
void primitive_from_fraction(void) void primitive_from_fraction(void)
{ {
CELL denominator = dpop(); CELL numerator, denominator;
CELL numerator = dpop();
maybe_garbage_collection();
denominator = dpop();
numerator = dpop();
if(zerop(denominator)) if(zerop(denominator))
raise(SIGFPE); raise(SIGFPE);
if(onep(denominator)) if(onep(denominator))

View File

@ -107,8 +107,12 @@ void primitive_can_read_line(void)
void primitive_add_read_line_io_task(void) void primitive_add_read_line_io_task(void)
{ {
CELL callback = dpop(); CELL callback, port;
CELL port = dpop();
maybe_garbage_collection();
callback = dpop();
port = dpop();
add_io_task(IO_TASK_READ_LINE,port,F,callback, add_io_task(IO_TASK_READ_LINE,port,F,callback,
read_io_tasks,&read_fd_count); read_io_tasks,&read_fd_count);
@ -140,7 +144,11 @@ bool perform_read_line_io_task(PORT* port)
void primitive_read_line_8(void) void primitive_read_line_8(void)
{ {
PORT* port = untag_port(dpeek()); PORT* port;
maybe_garbage_collection();
port = untag_port(dpeek());
pending_io_error(port); pending_io_error(port);
@ -199,16 +207,27 @@ bool can_read_count(PORT* port, FIXNUM count)
void primitive_can_read_count(void) void primitive_can_read_count(void)
{ {
PORT* port = untag_port(dpop()); PORT* port;
FIXNUM len = to_fixnum(dpop()); FIXNUM len;
maybe_garbage_collection();
port = untag_port(dpop());
len = to_fixnum(dpop());
dpush(tag_boolean(can_read_count(port,len))); dpush(tag_boolean(can_read_count(port,len)));
} }
void primitive_add_read_count_io_task(void) void primitive_add_read_count_io_task(void)
{ {
CELL callback = dpop(); CELL callback;
PORT* port = untag_port(dpop()); PORT* port;
FIXNUM count = to_fixnum(dpop()); FIXNUM count;
maybe_garbage_collection();
callback = dpop();
port = untag_port(dpop());
count = to_fixnum(dpop());
add_io_task(IO_TASK_READ_COUNT, add_io_task(IO_TASK_READ_COUNT,
tag_object(port),F,callback, tag_object(port),F,callback,
read_io_tasks,&read_fd_count); read_io_tasks,&read_fd_count);
@ -233,8 +252,13 @@ bool perform_read_count_io_task(PORT* port)
void primitive_read_count_8(void) void primitive_read_count_8(void)
{ {
PORT* port = untag_port(dpop()); PORT* port;
FIXNUM len = to_fixnum(dpop()); FIXNUM len;
maybe_garbage_collection();
port = untag_port(dpop());
len = to_fixnum(dpop());
if(port->count != len) if(port->count != len)
critical_error("read# counts don't match",tag_object(port)); critical_error("read# counts don't match",tag_object(port));

View File

@ -10,6 +10,7 @@ SBUF* sbuf(FIXNUM capacity)
void primitive_sbuf(void) void primitive_sbuf(void)
{ {
maybe_garbage_collection();
drepl(tag_object(sbuf(to_fixnum(dpeek())))); drepl(tag_object(sbuf(to_fixnum(dpeek()))));
} }
@ -20,8 +21,13 @@ void primitive_sbuf_length(void)
void primitive_set_sbuf_length(void) void primitive_set_sbuf_length(void)
{ {
SBUF* sbuf = untag_sbuf(dpop()); SBUF* sbuf;
FIXNUM length = to_fixnum(dpop()); FIXNUM length;
maybe_garbage_collection();
sbuf = untag_sbuf(dpop());
length = to_fixnum(dpop());
if(length < 0) if(length < 0)
range_error(tag_object(sbuf),length,sbuf->top); range_error(tag_object(sbuf),length,sbuf->top);
sbuf->top = length; sbuf->top = length;
@ -61,9 +67,15 @@ void set_sbuf_nth(SBUF* sbuf, CELL index, CHAR value)
void primitive_set_sbuf_nth(void) void primitive_set_sbuf_nth(void)
{ {
SBUF* sbuf = untag_sbuf(dpop()); SBUF* sbuf;
FIXNUM index = to_fixnum(dpop()); FIXNUM index;
CELL value = dpop(); CELL value;
maybe_garbage_collection();
sbuf = untag_sbuf(dpop());
index = to_fixnum(dpop());
value = dpop();
set_sbuf_nth(sbuf,index,value); set_sbuf_nth(sbuf,index,value);
} }
@ -79,8 +91,14 @@ void sbuf_append_string(SBUF* sbuf, STRING* string)
void primitive_sbuf_append(void) void primitive_sbuf_append(void)
{ {
SBUF* sbuf = untag_sbuf(dpop()); SBUF* sbuf;
CELL object = dpop(); CELL object;
maybe_garbage_collection();
sbuf = untag_sbuf(dpop());
object = dpop();
switch(type_of(object)) switch(type_of(object))
{ {
case FIXNUM_TYPE: case FIXNUM_TYPE:
@ -98,8 +116,13 @@ void primitive_sbuf_append(void)
void primitive_sbuf_to_string(void) void primitive_sbuf_to_string(void)
{ {
SBUF* sbuf = untag_sbuf(dpeek()); SBUF* sbuf;
STRING* s = string_clone(sbuf->string,sbuf->top); STRING* s;
maybe_garbage_collection();
sbuf = untag_sbuf(dpeek());
s = string_clone(sbuf->string,sbuf->top);
rehash_string(s); rehash_string(s);
drepl(tag_object(s)); drepl(tag_object(s));
} }
@ -112,8 +135,14 @@ void primitive_sbuf_reverse(void)
void primitive_sbuf_clone(void) void primitive_sbuf_clone(void)
{ {
SBUF* s = untag_sbuf(dpeek()); SBUF* s;
SBUF* new_s = sbuf(s->top); SBUF* new_s;
maybe_garbage_collection();
s = untag_sbuf(dpeek());
new_s = sbuf(s->top);
sbuf_append_string(new_s,s->string); sbuf_append_string(new_s,s->string);
drepl(tag_object(new_s)); drepl(tag_object(new_s));
} }

View File

@ -45,8 +45,14 @@ int make_client_socket(const char* hostname, uint16_t port)
void primitive_client_socket(void) void primitive_client_socket(void)
{ {
uint16_t p = (uint16_t)to_fixnum(dpop()); uint16_t p = (uint16_t)to_fixnum(dpop());
char* host = unbox_c_string(); char* host;
int sock = make_client_socket(host,p); int sock;
maybe_garbage_collection();
host = unbox_c_string();
sock = make_client_socket(host,p);
dpush(tag_object(port(PORT_RECV,sock))); dpush(tag_object(port(PORT_RECV,sock)));
dpush(tag_object(port(PORT_WRITE,sock))); dpush(tag_object(port(PORT_WRITE,sock)));
} }
@ -91,13 +97,16 @@ int make_server_socket(uint16_t port)
void primitive_server_socket(void) void primitive_server_socket(void)
{ {
uint16_t p = (uint16_t)to_fixnum(dpop()); uint16_t p = (uint16_t)to_fixnum(dpop());
maybe_garbage_collection();
dpush(tag_object(port(PORT_SPECIAL,make_server_socket(p)))); dpush(tag_object(port(PORT_SPECIAL,make_server_socket(p))));
} }
void primitive_add_accept_io_task(void) void primitive_add_accept_io_task(void)
{ {
CELL callback = dpop(); CELL callback, port;
CELL port = dpop(); maybe_garbage_collection();
callback = dpop();
port = dpop();
add_io_task(IO_TASK_ACCEPT,port,F,callback, add_io_task(IO_TASK_ACCEPT,port,F,callback,
read_io_tasks,&read_fd_count); read_io_tasks,&read_fd_count);
} }
@ -131,7 +140,9 @@ CELL accept_connection(PORT* p)
void primitive_accept_fd(void) void primitive_accept_fd(void)
{ {
PORT* p = untag_port(dpop()); PORT* p;
maybe_garbage_collection();
p = untag_port(dpop());
dpush(p->client_host); dpush(p->client_host);
dpush(p->client_port); dpush(p->client_port);
dpush(tag_object(port(PORT_RECV,p->client_socket))); dpush(tag_object(port(PORT_RECV,p->client_socket)));

View File

@ -94,15 +94,14 @@ VECTOR* stack_to_vector(CELL bottom, CELL top)
void primitive_datastack(void) void primitive_datastack(void)
{ {
maybe_garbage_collection();
dpush(tag_object(stack_to_vector(ds_bot,ds))); dpush(tag_object(stack_to_vector(ds_bot,ds)));
} }
void primitive_callstack(void) void primitive_callstack(void)
{ {
/* we don't want gc word to end up on callstack. */ maybe_garbage_collection();
gc_protect = true;
dpush(tag_object(stack_to_vector(cs_bot,cs))); dpush(tag_object(stack_to_vector(cs_bot,cs)));
gc_protect = false;
} }
/* Returns top of stack */ /* Returns top of stack */

View File

@ -274,9 +274,14 @@ INLINE STRING* substring(CELL start, CELL end, STRING* string)
/* start end string -- string */ /* start end string -- string */
void primitive_substring(void) void primitive_substring(void)
{ {
STRING* string = untag_string(dpop()); STRING* string;
CELL end = to_fixnum(dpop()); CELL end, start;
CELL start = to_fixnum(dpop());
maybe_garbage_collection();
string = untag_string(dpop());
end = to_fixnum(dpop());
start = to_fixnum(dpop());
dpush(tag_object(substring(start,end,string))); dpush(tag_object(substring(start,end,string)));
} }
@ -305,7 +310,11 @@ STRING* string_clone(STRING* s, int len)
void primitive_string_reverse(void) void primitive_string_reverse(void)
{ {
STRING* s = untag_string(dpeek()); STRING* s;
maybe_garbage_collection();
s = untag_string(dpeek());
s = string_clone(s,s->capacity); s = string_clone(s,s->capacity);
string_reverse(s,s->capacity); string_reverse(s,s->capacity);
rehash_string(s); rehash_string(s);

View File

@ -10,6 +10,7 @@ VECTOR* vector(FIXNUM capacity)
void primitive_vector(void) void primitive_vector(void)
{ {
maybe_garbage_collection();
drepl(tag_object(vector(to_fixnum(dpeek())))); drepl(tag_object(vector(to_fixnum(dpeek()))));
} }
@ -20,8 +21,13 @@ void primitive_vector_length(void)
void primitive_set_vector_length(void) void primitive_set_vector_length(void)
{ {
VECTOR* vector = untag_vector(dpop()); VECTOR* vector;
FIXNUM length = to_fixnum(dpop()); FIXNUM length;
maybe_garbage_collection();
vector = untag_vector(dpop());
length = to_fixnum(dpop());
if(length < 0) if(length < 0)
range_error(tag_object(vector),length,vector->top); range_error(tag_object(vector),length,vector->top);
vector->top = length; vector->top = length;
@ -51,9 +57,15 @@ void vector_ensure_capacity(VECTOR* vector, CELL index)
void primitive_set_vector_nth(void) void primitive_set_vector_nth(void)
{ {
VECTOR* vector = untag_vector(dpop()); VECTOR* vector;
FIXNUM index = to_fixnum(dpop()); FIXNUM index;
CELL value = dpop(); CELL value;
maybe_garbage_collection();
vector = untag_vector(dpop());
index = to_fixnum(dpop());
value = dpop();
if(index < 0) if(index < 0)
range_error(tag_object(vector),index,vector->top); range_error(tag_object(vector),index,vector->top);

View File

@ -25,9 +25,13 @@ void update_xt(WORD* word)
/* <word> ( primitive parameter plist -- word ) */ /* <word> ( primitive parameter plist -- word ) */
void primitive_word(void) void primitive_word(void)
{ {
CELL plist = dpop(); CELL plist, parameter;
FIXNUM primitive; FIXNUM primitive;
CELL parameter = dpop();
maybe_garbage_collection();
plist = dpop();
parameter = dpop();
primitive = to_fixnum(dpop()); primitive = to_fixnum(dpop());
dpush(tag_word(word(primitive,parameter,plist))); dpush(tag_word(word(primitive,parameter,plist)));
} }

View File

@ -38,16 +38,25 @@ bool can_write(PORT* port, FIXNUM len)
void primitive_can_write(void) void primitive_can_write(void)
{ {
PORT* port = untag_port(dpop()); PORT* port;
FIXNUM len = to_fixnum(dpop()); FIXNUM len;
maybe_garbage_collection();
port = untag_port(dpop());
len = to_fixnum(dpop());
pending_io_error(port); pending_io_error(port);
dpush(tag_boolean(can_write(port,len))); dpush(tag_boolean(can_write(port,len)));
} }
void primitive_add_write_io_task(void) void primitive_add_write_io_task(void)
{ {
CELL callback = dpop(); CELL callback, port;
CELL port = dpop();
maybe_garbage_collection();
callback = dpop();
port = dpop();
add_io_task(IO_TASK_WRITE,port,F,callback, add_io_task(IO_TASK_WRITE,port,F,callback,
write_io_tasks,&write_fd_count); write_io_tasks,&write_fd_count);
} }
@ -107,12 +116,17 @@ void write_string_8(PORT* port, STRING* str)
void primitive_write_8(void) void primitive_write_8(void)
{ {
PORT* port = untag_port(dpop()); PORT* port;
CELL text, type;
CELL text = dpop();
CELL type = type_of(text);
STRING* str; STRING* str;
maybe_garbage_collection();
port = untag_port(dpop());
text = dpop();
type = type_of(text);
pending_io_error(port); pending_io_error(port);
switch(type) switch(type)