diff --git a/lib/simulate.lpc b/lib/simulate.lpc index 80b96aac1be9381bcd90e4ce9385cd6a14e0d1c1..985735cf8d62adfb6a623e4fa23c4bb61d5be745 100644 --- a/lib/simulate.lpc +++ b/lib/simulate.lpc @@ -5,27 +5,9 @@ inherit "/precompiled/regexp"; string current_file, current_mode; -static int open(string file, string how) -{ - if(file == current_file && how == current_mode) - { - seek(0); - return 1; - }else{ - if(file::open(file,how)) - { - current_file=file; - current_mode=how; - return 1; - }else{ - current_file=current_mode=0; - return 0; - } - } -} - string read_bytes(string filename,void|int start,void|int len) { + string ret; if(!open(filename,"r")) error("Couldn't open file "+filename+".\n"); @@ -37,16 +19,20 @@ string read_bytes(string filename,void|int start,void|int len) case 3: seek(start); } - return read(len); + ret=read(len); + close(); + return ret; } int write_file(string filename,string what) { - if(!open(filename,"wc")) + int ret; + if(!open(filename,"awc")) error("Couldn't open file "+filename+".\n"); - seek(-1); - return write(what); + ret=write(what); + close(); + return ret; } mixed *map_array(mixed *arr, mixed fun, mixed ... args) diff --git a/src/ChangeLog b/src/ChangeLog index 482ff040beb73e8387f8c986bdf12320640a4cb9..6e349ca19ee5eba384af994294b872508e647867 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +Sat Feb 24 04:12:52 1996 Fredrik Hubinette <hubbe@tymin.signum.se> + + * program.c, array.c, object.c, gc.c: + Added routines to remove cyclic structures. + Sat Feb 17 23:05:24 1996 Fredrik Hubinette <hubbe@sparky.signum.se> * sprintf: added support for %2c diff --git a/src/Makefile.in b/src/Makefile.in index aae59ad77d578911ee4266c27ff0d923a354a939..fbfd057af6a905fd05479c34eee0d9c5e3d2bed8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -72,7 +72,7 @@ OBJ=language.o add_efun.o array.o builtin_efuns.o backend.o \ fsort.o hashtable.o interpret.o lex.o las.o list.o \ lpc_types.o main.o mapping.o memory.o module.o object.o \ opcodes.o operators.o port.o program.o rusage.o stralloc.o \ - stuff.o svalue.o debug.o callback.o lpc_signal.o @EXTRA_OBJS@ + stuff.o svalue.o gc.o callback.o lpc_signal.o @EXTRA_OBJS@ # MODULES=@subdirs@ @@ -145,11 +145,11 @@ TAGS: verify_manual: $(RUNULPC) $(SRCDIR)/test/verifymanual.lpc $(TMP_DOCDIR) -verify: +verify: $(SRCDIR)/test/testsuite $(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite # verify / debug verbose -verbose_verify: +verbose_verify: $(SRCDIR)/test/testsuite $(RUNULPC) $(SRCDIR)/test/test_lpc.lpc $(SRCDIR)/test/testsuite --verbose # verify & debug VERBOSE @@ -214,250 +214,423 @@ $(SRCDIR)/test/testsuite: $(SRCDIR)/test/create_testsuite #Dependencies begin here, DO NOT REMOVE THIS LINE!!!! language.o: language.c global.h machine.h \ - config.h debug.h \ - port.h interpret.h \ - program.h array.h \ - las.h svalue.h \ - dynamic_buffer.h object.h \ - stralloc.h lex.h \ - lpc_types.h add_efun.h \ - hashtable.h macros.h \ - error.h docode.h -add_efun.o: add_efun.c add_efun.h \ - svalue.h types.h machine.h \ - hashtable.h las.h \ - config.h dynamic_buffer.h \ - program.h macros.h \ - memory.h lpc_types.h \ - stralloc.h interpret.h + config.h \ + port.h \ + interpret.h \ + program.h \ + array.h las.h \ + svalue.h \ + dynamic_buffer.h \ + object.h \ + stralloc.h \ + lex.h \ + lpc_types.h \ + add_efun.h \ + hashtable.h \ + macros.h \ + error.h \ + docode.h +add_efun.o: add_efun.c \ + add_efun.h \ + svalue.h \ + types.h machine.h \ + hashtable.h \ + las.h \ + config.h \ + dynamic_buffer.h \ + program.h \ + macros.h \ + memory.h \ + lpc_types.h \ + stralloc.h \ + interpret.h alloca.o: alloca.c -array.o: array.c global.h \ - machine.h config.h debug.h \ - port.h svalue.h \ +array.o: array.c \ + global.h machine.h \ + config.h \ + port.h \ + svalue.h \ array.h las.h \ - dynamic_buffer.h program.h \ - object.h stralloc.h \ - interpret.h language.h error.h \ - lpc_types.h fsort.h \ - builtin_efuns.h -backend.o: backend.c global.h \ - machine.h config.h debug.h \ - port.h interpret.h \ - program.h object.h \ - svalue.h error.h \ - call_out.h backend.h \ - fd_control.h main.h \ - callback.h array.h \ - las.h dynamic_buffer.h + dynamic_buffer.h \ + program.h \ + object.h \ + stralloc.h \ + interpret.h language.h \ + error.h \ + lpc_types.h \ + fsort.h \ + builtin_efuns.h \ + gc.h builtin_efuns.o: builtin_efuns.c \ - global.h machine.h config.h \ - debug.h port.h \ - interpret.h program.h \ - svalue.h macros.h \ - object.h array.h \ - las.h dynamic_buffer.h \ - error.h add_efun.h \ - hashtable.h mapping.h \ - stralloc.h lex.h \ - list.h lpc_types.h \ - rusage.h operators.h \ - fsort.h call_out.h \ - callback.h -call_out.o: call_out.c global.h \ - machine.h config.h debug.h \ - port.h array.h \ - las.h svalue.h \ - dynamic_buffer.h program.h \ - call_out.h object.h \ - interpret.h error.h \ - builtin_efuns.h main.h -callback.o: callback.c macros.h \ - memory.h types.h machine.h \ - callback.h array.h \ - las.h config.h \ - svalue.h dynamic_buffer.h \ + global.h machine.h \ + config.h \ + port.h \ + interpret.h \ + program.h \ + svalue.h \ + macros.h \ + object.h \ + array.h las.h \ + dynamic_buffer.h \ + error.h \ + add_efun.h \ + hashtable.h \ + mapping.h \ + stralloc.h \ + lex.h list.h \ + lpc_types.h \ + rusage.h \ + operators.h \ + fsort.h \ + call_out.h \ + callback.h \ + gc.h +call_out.o: call_out.c \ + global.h machine.h \ + config.h \ + port.h \ + array.h las.h \ + svalue.h \ + dynamic_buffer.h \ + program.h \ + call_out.h \ + object.h \ + interpret.h \ + error.h \ + builtin_efuns.h \ + main.h +callback.o: callback.c \ + macros.h \ + memory.h \ + types.h machine.h \ + callback.h \ + array.h las.h \ + config.h \ + svalue.h \ + dynamic_buffer.h \ program.h -debug.o: debug.c global.h \ - machine.h config.h debug.h \ - port.h -docode.o: docode.c global.h \ - machine.h config.h debug.h \ +docode.o: docode.c \ + global.h machine.h \ + config.h \ port.h las.h \ - svalue.h dynamic_buffer.h \ + svalue.h \ + dynamic_buffer.h \ program.h language.h \ - lpc_types.h stralloc.h \ - interpret.h add_efun.h \ - hashtable.h array.h \ - macros.h error.h \ + lpc_types.h \ + stralloc.h \ + interpret.h \ + add_efun.h \ + hashtable.h \ + array.h \ + macros.h \ + error.h \ main.h lex.h \ builtin_efuns.h dynamic_buffer.o: dynamic_buffer.c \ - global.h machine.h config.h \ - debug.h port.h \ - dynamic_buffer.h stralloc.h \ - error.h svalue.h -error.o: error.c global.h \ - machine.h config.h debug.h \ - port.h macros.h \ - error.h svalue.h \ - interpret.h program.h \ - stralloc.h builtin_efuns.h \ + global.h machine.h \ + config.h \ + port.h \ + dynamic_buffer.h \ + stralloc.h \ + error.h \ + svalue.h +error.o: error.c \ + global.h machine.h \ + config.h \ + port.h \ + macros.h \ + error.h \ + svalue.h \ + interpret.h \ + program.h \ + stralloc.h \ + builtin_efuns.h \ array.h las.h \ - dynamic_buffer.h object.h + dynamic_buffer.h \ + object.h fd_control.o: fd_control.c \ - fd_control.h global.h \ - machine.h config.h debug.h \ + fd_control.h \ + global.h machine.h \ + config.h \ port.h -fsort.o: fsort.c global.h \ - machine.h config.h debug.h \ - port.h fsort.h -hashtable.o: hashtable.c global.h \ - machine.h config.h debug.h \ - port.h hashtable.h \ - stralloc.h stuff.h \ - error.h svalue.h -interpret.o: interpret.c global.h \ - machine.h config.h debug.h \ - port.h interpret.h \ - program.h object.h \ - svalue.h array.h \ - las.h dynamic_buffer.h \ - mapping.h error.h language.h \ - stralloc.h add_efun.h \ - hashtable.h macros.h \ - list.h backend.h \ - operators.h opcodes.h \ +fsort.o: fsort.c \ + global.h machine.h \ + config.h \ + port.h \ + fsort.h +gc.o: gc.c \ + global.h machine.h \ + config.h \ + port.h gc.h \ + main.h +hashtable.o: hashtable.c \ + global.h machine.h \ + config.h \ + port.h \ + hashtable.h \ + stralloc.h \ + stuff.h \ + error.h \ + svalue.h +interpret.o: interpret.c \ + global.h machine.h \ + config.h \ + port.h \ + interpret.h \ + program.h \ + object.h \ + svalue.h \ + array.h las.h \ + dynamic_buffer.h \ + mapping.h \ + error.h language.h \ + stralloc.h \ + add_efun.h \ + hashtable.h \ + macros.h \ + list.h \ + backend.h \ + operators.h \ + opcodes.h \ main.h lex.h \ - builtin_efuns.h lpc_signal.h -las.o: las.c global.h machine.h \ - config.h debug.h \ - port.h language.h interpret.h \ - program.h las.h \ - svalue.h dynamic_buffer.h \ - array.h object.h \ - stralloc.h lex.h \ - lpc_types.h add_efun.h \ - hashtable.h mapping.h \ - list.h error.h \ - docode.h main.h -lex.o: lex.c global.h machine.h \ - config.h debug.h \ - port.h language.h array.h \ - las.h svalue.h \ - dynamic_buffer.h program.h \ - lex.h stralloc.h \ - add_efun.h hashtable.h \ - stuff.h interpret.h \ - error.h object.h \ - operators.h opcodes.h \ - builtin_efuns.h macros.h -list.o: list.c global.h \ - machine.h config.h debug.h \ - port.h array.h \ - las.h svalue.h \ - dynamic_buffer.h program.h \ - list.h macros.h \ - error.h interpret.h \ + builtin_efuns.h \ + lpc_signal.h +las.o: las.c \ + global.h machine.h \ + config.h \ + port.h language.h \ + interpret.h \ + program.h \ + las.h \ + svalue.h \ + dynamic_buffer.h \ + array.h \ + object.h \ + stralloc.h \ + lex.h \ + lpc_types.h \ + add_efun.h \ + hashtable.h \ + mapping.h \ + list.h \ + error.h \ + docode.h \ + main.h +lex.o: lex.c \ + global.h machine.h \ + config.h \ + port.h language.h \ + array.h las.h \ + svalue.h \ + dynamic_buffer.h \ + program.h \ + lex.h \ + stralloc.h \ + add_efun.h \ + hashtable.h \ + stuff.h \ + interpret.h \ + error.h \ + object.h \ + operators.h \ + opcodes.h \ + builtin_efuns.h \ + macros.h +list.o: list.c \ + global.h machine.h \ + config.h \ + port.h \ + array.h las.h \ + svalue.h \ + dynamic_buffer.h \ + program.h \ + list.h \ + macros.h \ + error.h \ + interpret.h \ builtin_efuns.h lpc_signal.o: lpc_signal.c \ - global.h machine.h config.h \ - debug.h port.h \ - svalue.h interpret.h \ - program.h stralloc.h \ - add_efun.h hashtable.h \ - las.h dynamic_buffer.h \ - macros.h backend.h -lpc_types.o: lpc_types.c global.h \ - machine.h config.h debug.h \ - port.h svalue.h \ - lpc_types.h stralloc.h \ - stuff.h array.h \ - las.h dynamic_buffer.h \ - program.h add_efun.h \ - hashtable.h object.h \ - list.h mapping.h \ - macros.h error.h -main.o: main.c global.h \ - machine.h config.h debug.h \ - port.h backend.h \ - module.h object.h \ - svalue.h lex.h \ - lpc_types.h builtin_efuns.h \ + global.h machine.h \ + config.h \ + port.h \ + svalue.h \ + interpret.h \ + program.h \ + stralloc.h \ + add_efun.h \ + hashtable.h \ + las.h \ + dynamic_buffer.h \ + macros.h \ + backend.h +lpc_types.o: lpc_types.c \ + global.h machine.h \ + config.h \ + port.h \ + svalue.h \ + lpc_types.h \ + stralloc.h \ + stuff.h \ + array.h las.h \ + dynamic_buffer.h \ + program.h \ + add_efun.h \ + hashtable.h \ + object.h \ + list.h \ + mapping.h \ + macros.h \ + error.h +main.o: main.c \ + global.h machine.h \ + config.h \ + port.h \ + backend.h \ + module.h \ + object.h \ + svalue.h \ + lex.h \ + lpc_types.h \ + builtin_efuns.h \ array.h las.h \ - dynamic_buffer.h program.h \ - stralloc.h interpret.h \ - error.h macros.h \ - callback.h lpc_signal.h -mapping.o: mapping.c global.h \ - machine.h config.h debug.h \ - port.h mapping.h \ - las.h svalue.h \ - dynamic_buffer.h program.h \ - array.h macros.h language.h \ - error.h interpret.h -memory.o: memory.c global.h \ - machine.h config.h debug.h \ - port.h error.h \ + dynamic_buffer.h \ + program.h \ + stralloc.h \ + interpret.h \ + error.h \ + macros.h \ + callback.h \ + lpc_signal.h +mapping.o: mapping.c \ + global.h machine.h \ + config.h \ + port.h \ + mapping.h \ + las.h \ + svalue.h \ + dynamic_buffer.h \ + program.h \ + array.h \ + macros.h language.h \ + error.h \ + interpret.h +memory.o: memory.c \ + global.h machine.h \ + config.h \ + port.h \ + error.h \ svalue.h -module.o: module.c module.h \ - types.h machine.h macros.h \ - memory.h error.h \ +module.o: module.c \ + module.h \ + types.h machine.h \ + macros.h \ + memory.h \ + error.h \ svalue.h modlist.h -object.o: object.c global.h \ - machine.h config.h debug.h \ - port.h object.h \ - svalue.h dynamic_buffer.h \ - interpret.h program.h \ - stralloc.h macros.h \ - error.h main.h -opcodes.o: opcodes.c global.h \ - machine.h config.h debug.h \ - port.h interpret.h \ - program.h svalue.h \ +object.o: object.c \ + global.h machine.h \ + config.h \ + port.h \ + object.h \ + svalue.h \ + dynamic_buffer.h \ + interpret.h \ + program.h \ + stralloc.h \ + macros.h \ + error.h \ + main.h \ + array.h las.h \ + gc.h +opcodes.o: opcodes.c \ + global.h machine.h \ + config.h \ + port.h \ + interpret.h \ + program.h \ + svalue.h \ array.h las.h \ - dynamic_buffer.h stralloc.h \ - mapping.h list.h \ - opcodes.h object.h \ - error.h lpc_types.h -operators.o: operators.c global.h \ - machine.h config.h debug.h \ - port.h interpret.h \ - program.h svalue.h \ + dynamic_buffer.h \ + stralloc.h \ + mapping.h \ + list.h \ + opcodes.h \ + object.h \ + error.h \ + lpc_types.h +operators.o: operators.c \ + global.h machine.h \ + config.h \ + port.h \ + interpret.h \ + program.h \ + svalue.h \ list.h las.h \ - dynamic_buffer.h mapping.h \ - array.h stralloc.h \ - opcodes.h operators.h \ - language.h error.h -port.o: port.c global.h \ - machine.h config.h debug.h \ - port.h macros.h -program.o: program.c global.h \ - machine.h config.h debug.h \ - port.h program.h \ - object.h svalue.h \ - dynamic_buffer.h lpc_types.h \ - stralloc.h las.h language.h \ - lex.h macros.h \ - fsort.h error.h \ - docode.h interpret.h \ - hashtable.h compilation.h -rusage.o: rusage.c global.h \ - machine.h config.h debug.h \ - port.h rusage.h -stralloc.o: stralloc.c global.h \ - machine.h config.h debug.h \ - port.h stralloc.h \ - macros.h dynamic_buffer.h \ - error.h svalue.h -stuff.o: stuff.c stuff.h \ + dynamic_buffer.h \ + mapping.h \ + array.h \ + stralloc.h \ + opcodes.h \ + operators.h language.h \ + error.h \ + docode.h \ + add_efun.h \ + hashtable.h +port.o: port.c \ + global.h machine.h \ + config.h \ + port.h \ + macros.h +program.o: program.c \ + global.h machine.h \ + config.h \ + port.h \ + program.h \ + object.h \ + svalue.h \ + dynamic_buffer.h \ + lpc_types.h \ + stralloc.h \ + las.h language.h \ + lex.h \ + macros.h \ + fsort.h \ + error.h \ + docode.h \ + interpret.h \ + hashtable.h \ + main.h gc.h \ + compilation.h +rusage.o: rusage.c \ + global.h machine.h \ + config.h \ + port.h \ + rusage.h +stralloc.o: stralloc.c \ + global.h machine.h \ + config.h \ + port.h \ + stralloc.h \ + macros.h \ + dynamic_buffer.h \ + error.h \ + svalue.h +stuff.o: stuff.c \ + stuff.h \ types.h machine.h -svalue.o: svalue.c global.h \ - machine.h config.h debug.h \ - port.h svalue.h \ - stralloc.h array.h \ - las.h dynamic_buffer.h \ - program.h mapping.h \ - list.h object.h \ - add_efun.h hashtable.h \ +svalue.o: svalue.c \ + global.h machine.h \ + config.h \ + port.h \ + svalue.h \ + stralloc.h \ + array.h las.h \ + dynamic_buffer.h \ + program.h \ + mapping.h \ + list.h \ + object.h \ + add_efun.h \ + hashtable.h \ error.h ualarm.o: ualarm.c diff --git a/src/array.c b/src/array.c index e2e2a865926220e948c692a0f625123ef08cc6ac..2697bdeb8bc8d560ba06877f1b4ac0cf474f0fe7 100644 --- a/src/array.c +++ b/src/array.c @@ -16,6 +16,7 @@ #include "fsort.h" #include "builtin_efuns.h" #include "memory.h" +#include "gc.h" struct array empty_array= { @@ -46,10 +47,13 @@ struct array *allocate_array_no_init(INT32 size,INT32 extra_space) return &empty_array; } + GC_ALLOC(); + v=(struct array *)malloc(sizeof(struct array)+ (size+extra_space-1)*sizeof(struct svalue)); if(!v) error("Couldn't allocate array, out of memory.\n"); + /* for now, we don't know what will go in here */ v->type_field=BIT_MIXED; @@ -94,6 +98,8 @@ static void array_free_no_free(struct array *v) v->next->prev=prev; free((char *)v); + + GC_FREE(); } /* @@ -1245,138 +1251,111 @@ void array_replace(struct array *a, while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to); } -#ifdef GC - -void array_gc_clear_mark() -{ - struct array *a; - a=&empty_array; - do - { - a->flags &=~ ARRAY_FLAG_MARK; - check_array(a, pass); - - a=a->next; - #ifdef DEBUG - if(!a) fatal("Null pointer in array list.\n"); -#endif - } while (a != & empty_array); -} - -void array_gc_mark(struct array *a) +void check_array(struct array *a) { INT32 e; - if(a->flags & ARRAY_FLAG_MARK) return; - a->flags |= ARRAY_FLAG_MARK; - if(!(a->type_field & ~(BIT_STRING|BIT_INT|BIT_FLOAT))) - return 0; + if(a->next->prev != a) + fatal("Array check: a->next->prev != a\n"); - for(e=0;e<a->size;e++) svalue_gc_sweep(ITEM(a) + e); -} + if(a->size > a->malloced_size) + fatal("Array is larger than malloced block!\n"); -void array_gc_sweep() -{ - struct array *a, *next; + if(a->refs <=0 ) + fatal("Array has zero refs.\n"); - a=&empty_array; - do + for(e=0;e<a->size;e++) { - a->refs++; - - if(!(a->flags & ARRAY_FLAG_MARK)) - { - free_svalues(ITEM(a), a->size, a->type_field); - a->size=0; /* Don't free them again */ - } + if(! ( (1 << ITEM(a)[e].type) & (a->type_field) )) + fatal("Type field lies.\n"); - next=a->next; - free_array(a); - - a=next; -#ifdef DEBUG - if(!a) fatal("Null pointer in array list.\n"); -#endif - } while (a != & empty_array); + check_svalue(ITEM(a)+e); + } } - -#ifdef DEBUG -void array_gc_sweep2() +void check_all_arrays() { struct array *a; - if(!d_flag) return; a=&empty_array; do { - if(!(a->flags & ARRAY_FLAG_MARK)) - fatal("Array ref count incorrect!\n"); + check_array(a); - a=a->next - -#ifdef DEBUG - if(!a) fatal("Null pointer in array list.\n"); -#endif + a=a->next; + if(!a) + fatal("Null pointer in array list.\n"); } while (a != & empty_array); } #endif /* DEBUG */ -#endif /* GC */ +#ifdef GC2 -#ifdef DEBUG -void check_array(struct array *a, int pass) +void gc_check_array(struct array *a) { - INT32 e; - if(pass) - { - e=checked((void *)a,0); - if(e!=a->refs) - { - simple_describe_array(a); - fatal("Above array has wrong number of references. (%ld != %ld)\n", - (long)e,(long)a->refs); - } - return; - } - - if(a->next->prev != a) - fatal("Array check: a->next->prev != a\n"); + if(a == gc_ptr) gc_refs++; + if(a->flags & GC_MARK) return; + a->flags |= GC_MARK; + if(!(a->type_field & BIT_COMPLEX)) return; + gc_check_svalues(ITEM(a), a->size); +} - if(a->size > a->malloced_size) - fatal("Array is larger than malloced block!\n"); - if(a->refs <=0 ) - fatal("Array has zero refs.\n"); +void gc_check_all_arrays() +{ + struct array *a,*n; - for(e=0;e<a->size;e++) + a=&empty_array; + do { - if(! ( (1 << ITEM(a)[e].type) & (a->type_field) )) - fatal("Type field lies.\n"); - - check_svalue(ITEM(a)+e); - } + if(!(a->flags & GC_MARK) && a->type_field & BIT_COMPLEX) + { + gc_ptr=a; + gc_refs=0; + + gc_check_array(a); + + a->refs++; + + if(gc_refs == a->refs) + { + /* This structure contains as many references to itself as + * it has referenes, which means that it is circular and + * should be destroyed, so please go away. + */ + + free_svalues(ITEM(a), a->size, a->type_field); + + a->size=0; + + } + + if(!(n=a->next)) + fatal("Null pointer in array list.\n"); + + free_array(a); + a=n; + }else{ + a=a->next; + } + } while (a != & empty_array); } -void check_all_arrays(int pass) +void gc_clear_array_marks() { struct array *a; a=&empty_array; do { - check_array(a, pass); - + a->flags &=~ GC_MARK; a=a->next; - if(!a) - fatal("Null pointer in array list.\n"); - } while (a != & empty_array); - if(!pass) - { - checked((void *)&empty_array,1); - } + } while (a != & empty_array); } -#endif /* DEBUG */ + + + +#endif /* GC2 */ diff --git a/src/array.h b/src/array.h index 34f74e4baab7cf09d2c0d5b3040ada29ed436c57..758fc6cbad1414fcfdfc21b02845b52f7785b53f 100644 --- a/src/array.h +++ b/src/array.h @@ -117,12 +117,11 @@ struct array *reverse_array(struct array *a); void array_replace(struct array *a, struct svalue *from, struct svalue *to); -void array_gc_clear_mark(); -void array_gc_mark(struct array *a); -void array_gc_sweep(); -void array_gc_sweep2(); -void check_array(struct array *a, int pass); -void check_all_arrays(int pass); +void check_array(struct array *a); +void check_all_arrays(); +void gc_check_array(struct array *a); +void gc_check_all_arrays(); +void gc_clear_array_marks(); /* Prototypes end here */ diff --git a/src/backend.c b/src/backend.c index f3a47a4d036a83a35dc66af00932052a742e9260..f8cb88b7af848a66a7b8b5d1198ac9e9db9182ef 100644 --- a/src/backend.c +++ b/src/backend.c @@ -157,40 +157,22 @@ void *query_write_callback_data(int fd) } #ifdef DEBUG -void do_debug(int check_refs) +void do_debug() { - extern void check_all_arrays(int); - extern void check_all_mappings(int); - extern void check_all_programs(int); - extern void check_all_objects(int); - extern void verify_shared_strings_tables(int); - extern void slow_check_stack(int); - -#if 0 - if(d_flag>1) - init_checked(); -#endif - - slow_check_stack(0); - check_all_arrays(0); - check_all_mappings(0); - check_all_programs(0); - verify_all_objects(0); - verify_shared_strings_tables(0); + extern void check_all_arrays(); + extern void check_all_mappings(); + extern void check_all_programs(); + extern void check_all_objects(); + extern void verify_shared_strings_tables(); + extern void slow_check_stack(); + + slow_check_stack(); + check_all_arrays(); + check_all_mappings(); + check_all_programs(); + verify_all_objects(); + verify_shared_strings_tables(); verify_all_call_outs(); - -#if 0 - if(d_flag>1) - { - check_all_arrays(1); - check_all_mappings(1); - check_all_programs(1); - verify_all_objects(1); - verify_shared_strings_tables(1); - exit_checked(); - } -#endif - } #endif @@ -263,7 +245,7 @@ void backend() alloca(0); /* Do garbage collect */ #ifdef DEBUG if(d_flag > 1) - do_debug(1); + do_debug(); #endif } diff --git a/src/backend.h b/src/backend.h index b69daeb74c97fd73537675309b3be5025a47a36e..a80179d81ded3e5fa637bd3e33cf340952b1caf1 100644 --- a/src/backend.h +++ b/src/backend.h @@ -26,7 +26,7 @@ callback query_read_callback(int fd); callback query_write_callback(int fd); void *query_read_callback_data(int fd); void *query_write_callback_data(int fd); -void do_debug(int check_refs); +void do_debug(); void backend(); int write_to_stderr(char *a, INT32 len); /* Prototypes end here */ diff --git a/src/builtin_efuns.c b/src/builtin_efuns.c index aa094a6853eb609b693ce2cdb0eb4256d8416039..e5428f0b44296f36c6769636ba5a864fd5e8d0f1 100644 --- a/src/builtin_efuns.c +++ b/src/builtin_efuns.c @@ -22,6 +22,7 @@ #include "fsort.h" #include "call_out.h" #include "callback.h" +#include "gc.h" #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif @@ -1210,6 +1211,15 @@ void f_sleep(INT32 args) } } +void f_gc(INT32 args) +{ + INT32 tmp; + pop_n_elems(args); + tmp=num_objects; + do_gc(); + push_int(tmp - num_objects); +} + #ifdef TYPEP #undef TYPEP #endif @@ -1296,6 +1306,7 @@ void init_builtin_efuns() add_efun("upper_case",f_upper_case,"function(string:string)",0); add_efun("values",f_values,"function(string|list:int*)|function(array|mapping|object:mixed*)",0); add_efun("zero_type",f_zero_type,"function(int:int)",0); + add_efun("gc",f_gc,"function(:int)",OPT_SIDE_EFFECT); } diff --git a/src/call_out.c b/src/call_out.c index cfda6cc07156adb29adeea114c9278f04eadf418..f596c0ce30e2b410ce7e759c883d70d1bf968bcb 100644 --- a/src/call_out.c +++ b/src/call_out.c @@ -308,12 +308,6 @@ time_t get_next_call_out() #ifdef DEBUG void verify_all_call_outs() { - int e; verify_call_outs(); - for(e=0;e<num_pending_calls;e++) - { - checked((void *)pending_calls[e]->caller,1); - checked((void *)pending_calls[e]->args,1); - } } #endif diff --git a/src/config.h b/src/config.h index fcb99f4b9ab47993a6e74af777c87fbae55d8762..d905a755de9f2ddb1e75645488916210c2703b45 100644 --- a/src/config.h +++ b/src/config.h @@ -32,6 +32,11 @@ * Define the size of the cache that is used for method lookup. */ #define FIND_FUNCTION_HASHSIZE 4711 + +/* + * Undefine this to disable garabge collection + */ +#define GC2 /* diff --git a/src/debug.c b/src/debug.c deleted file mode 100644 index c11c55f0825eb9abfbd59a0f65b3a2d6595c0dff..0000000000000000000000000000000000000000 --- a/src/debug.c +++ /dev/null @@ -1,125 +0,0 @@ -/*\ -||| This file a part of uLPC, and is copyright by Fredrik Hubinette -||| uLPC is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#include "global.h" -#include "types.h" -#include "memory.h" - -#define MARKER_CHUNK_SIZE 4096 -#define REHASH_LIMIT 16 -#define REHASH_FORMULA(X) ((X)*4-1) - -struct marker -{ - struct marker *next; - void *marked; - INT32 refs; -}; - -struct marker_chunk -{ - struct marker_chunk *next; - struct marker markers[MARKER_CHUNK_SIZE]; -}; - -static struct marker_chunk *chunk=0; -static int markers_left_in_chunk=0; - -static struct marker *new_marker() -{ - if(!markers_left_in_chunk) - { - struct marker_chunk *m; - m=(struct marker_chunk *)xalloc(sizeof(struct marker_chunk)); - m->next=chunk; - chunk=m; - markers_left_in_chunk=MARKER_CHUNK_SIZE; - } - markers_left_in_chunk--; - - return chunk->markers + markers_left_in_chunk; -} - -static struct marker **hash=0; -static int hashsize=0; -static int hashed=0; - -INT32 checked(void *a,INT32 delta) -{ - int hashval; - struct marker *m; - - if(!hash) return 0; - - hashval=((long)a)%hashsize; - - for(m=hash[hashval];m;m=m->next) - { - if(m->marked == a) - { - m->refs+=delta; - return m->refs; - } - } - if(!delta) return 0; - - m=new_marker(); - m->marked=a; - m->next=hash[hashval]; - m->refs=delta; - hash[hashval]=m; - - hashed++; - if(hashed / REHASH_LIMIT > hashsize) - { - struct marker **new_hash,*next; - int new_hashsize; - int e; - - new_hashsize=REHASH_FORMULA(hashsize); - new_hash=(struct marker **)xalloc(sizeof(struct marker **)*new_hashsize); - memset((char *)new_hash,0,sizeof(struct marker **)*new_hashsize); - - for(e=0;e<hashsize;e++) - { - for(m=hash[e];m;m=next) - { - next=m->next; - m->next=new_hash[((long)m->marked)%new_hashsize]; - new_hash[((long)m->marked)%new_hashsize]=m; - } - } - - free((char *)hash); - hash=new_hash; - hashsize=new_hashsize; - } - - return m->refs; -} - -void init_checked() -{ - /* init hash*/ - hashsize=4711; - hashed=0; - hash=(struct marker **)xalloc(sizeof(struct marker **)*hashsize); - memset((char *)hash,0,sizeof(struct marker **)*hashsize); - markers_left_in_chunk=0; -} - -void exit_checked() -{ - struct marker_chunk *m; - - if(!hash) return; - free((char *)hash); - while(m=chunk) - { - chunk=m->next; - free((char *)m); - } - hash=0; -} diff --git a/src/debug.h b/src/debug.h deleted file mode 100644 index 7e482708e773dec0d9c3dcfb7199bc07720e458c..0000000000000000000000000000000000000000 --- a/src/debug.h +++ /dev/null @@ -1,19 +0,0 @@ -/*\ -||| This file a part of uLPC, and is copyright by Fredrik Hubinette -||| uLPC is distributed as GPL (General Public License) -||| See the files COPYING and DISCLAIMER for more information. -\*/ -#ifndef DEBUG_H -#define DEBUG_H - -#include "types.h" - -/* Prototypes begin here */ -struct marker; -struct marker_chunk; -INT32 checked(void *a,INT32 delta); -void init_checked(); -void exit_checked(); -/* Prototypes end here */ - -#endif diff --git a/src/global.h b/src/global.h index 7eca62d6c8978880663061fcac16e0c861e35d8a..e8be108dbfb013f052ecdfa7cb0e1f2a9ff22dc5 100644 --- a/src/global.h +++ b/src/global.h @@ -66,10 +66,6 @@ char *alloca (); #include <memory.h> #endif -#ifdef DEBUG -#include "debug.h" -#endif - #if defined(__GNUC__) && !defined(DEBUG) && !defined(lint) #define INLINE inline #else diff --git a/src/mapping.c b/src/mapping.c index de252f7fbf13fcd8e2f357c117a8e1b32491eade..b23d2bdff5355ca6e7f97728164d7932547e0f35 100644 --- a/src/mapping.c +++ b/src/mapping.c @@ -411,15 +411,8 @@ void mapping_search_no_free(struct svalue *to, #ifdef DEBUG -void check_mapping(struct mapping *m,int pass) +void check_mapping(struct mapping *m) { - if(pass) - { - if(checked((void *)m,0) != m->refs) - fatal("Mapping has wrong number of refs.\n"); - return; - } - if(m->refs <=0) fatal("Mapping has zero refs.\n"); @@ -434,17 +427,12 @@ void check_mapping(struct mapping *m,int pass) if(first_mapping != m) fatal("Mapping ->prev == 0 but first_mapping != mapping.\n"); } - checked((void *)m->ind,1); - checked((void *)m->val,1); } -void check_all_mappings(int pass) +void check_all_mappings() { struct mapping *m; for(m=first_mapping;m;m=m->next) - check_mapping(m,pass); - - if(!pass) - checked((void *)first_mapping,1); + check_mapping(m); } #endif diff --git a/src/mapping.h b/src/mapping.h index 9a9132cb14296fa3db368201d0111f2edc5c11a0..8eb88ae8732822dc959257a27dc4e08e5ad00f81 100644 --- a/src/mapping.h +++ b/src/mapping.h @@ -53,5 +53,7 @@ void mapping_search_no_free(struct svalue *to, struct mapping *m, struct svalue *look_for, struct svalue *start); +void check_mapping(struct mapping *m); +void check_all_mappings(); /* Prototypes end here */ #endif diff --git a/src/modules/efuns.c b/src/modules/efuns.c deleted file mode 100644 index 16fb213bb3fa33a6f19458de6c7b7e9e7c7f814a..0000000000000000000000000000000000000000 --- a/src/modules/efuns.c +++ /dev/null @@ -1,47 +0,0 @@ - -/* function *get_function_list(object); */ -void f_get_function_list(int num_arg,struct svalue *argp) -{ - int e; - int funs; - struct program *p; - struct vector *v; - struct object *o; - o=argp[0].u.ob; - - p=o->prog; - for(funs=e=0;e<p->num_funindex;e++) - if(!(p->function_ptrs[e].type & TYPE_MOD_STATIC)) - funs++; - - v=allocate_array_no_init(funs,0); - funs=0; - - for(e=0;e<p->num_funindex;e++) - { - if(!(p->function_ptrs[e].type & TYPE_MOD_STATIC)) - { - v->item[funs].type=T_FUNCTION; - v->item[funs].u.ob=o; - v->item[funs].subtype=e; - add_ref(o,"get_function_list"); - funs++; - } - } - v->types=BIT_FUNCTION; - free_svalue(argp); - argp->type=T_ARRAY; - argp->u.vec=v; -} - -/* int function_args(function); */ -void f_function_args(int num_arg,struct svalue *argp) -{ - int i; - i=FUNC(argp[0].u.ob->prog,argp[0].subtype)->num_arg; - free_svalue(argp); - argp->type=T_INT; - argp->subtype=0; - argp->u.number=i; -} - diff --git a/src/modules/files/Makefile.in b/src/modules/files/Makefile.in index cee0d455844eda7ca83bcf4f1dcf078221572501..9df921c43f36eb6af0039d6e75dbbe9ab6380ed7 100644 --- a/src/modules/files/Makefile.in +++ b/src/modules/files/Makefile.in @@ -21,9 +21,9 @@ depend: #Dependencies begin here, DO NOT REMOVE THIS LINE!!!! datagram.o: datagram.c efuns.o: efuns.c \ - global.h machine.h \ + global.h \ + machine.h \ config.h \ - debug.h \ port.h \ interpret.h \ program.h \ @@ -34,11 +34,12 @@ efuns.o: efuns.c \ dynamic_buffer.h \ mapping.h \ macros.h \ - fd_control.h file_machine.h + fd_control.h \ + file_machine.h file.o: file.c \ - global.h machine.h \ + global.h \ + machine.h \ config.h \ - debug.h \ port.h \ interpret.h \ program.h \ @@ -50,14 +51,14 @@ file.o: file.c \ object.h \ macros.h \ backend.h \ - fd_control.h file_machine.h \ - file.h \ + fd_control.h \ + file_machine.h file.h \ error.h \ lpc_signal.h socket.o: socket.c \ - global.h machine.h \ + global.h \ + machine.h \ config.h \ - debug.h \ port.h \ interpret.h \ program.h \ @@ -69,5 +70,5 @@ socket.o: socket.c \ object.h \ macros.h \ backend.h \ - fd_control.h file_machine.h \ - file.h + fd_control.h \ + file_machine.h file.h diff --git a/src/modules/regexp/Makefile.in b/src/modules/regexp/Makefile.in index d2bc317acdf146b93a18476bacd5a5f1251b2549..f3a73a2b6c6d5c7c4d7447decdb242937568fbd2 100644 --- a/src/modules/regexp/Makefile.in +++ b/src/modules/regexp/Makefile.in @@ -19,9 +19,9 @@ depend: #Dependencies begin here, DO NOT REMOVE THIS LINE!!!! glue.o: glue.c \ - global.h machine.h \ + global.h \ + machine.h \ config.h \ - debug.h \ port.h \ interpret.h \ program.h \ @@ -33,9 +33,9 @@ glue.o: glue.c \ object.h \ macros.h regexp.o: regexp.c \ - global.h machine.h \ + global.h \ + machine.h \ config.h \ - debug.h \ port.h \ regexp.h \ error.h \ diff --git a/src/modules/sprintf/Makefile.in b/src/modules/sprintf/Makefile.in index 5ace6c5549a2de0443099b1cb62997cd78c6f1c0..56de303c762dc620fa81cd15bda65ef166dd9264 100644 --- a/src/modules/sprintf/Makefile.in +++ b/src/modules/sprintf/Makefile.in @@ -19,9 +19,9 @@ depend: #Dependencies begin here, DO NOT REMOVE THIS LINE!!!! sprintf.o: sprintf.c \ - global.h machine.h \ + global.h \ + machine.h \ config.h \ - debug.h \ port.h \ error.h \ svalue.h \ diff --git a/src/object.c b/src/object.c index 7f24245964e1a7433b7b1d44722f924b510ffe0e..9d6e0ff0876f9a54d9937de3d1cb016c4baa737b 100644 --- a/src/object.c +++ b/src/object.c @@ -15,6 +15,7 @@ #include "error.h" #include "main.h" #include "array.h" +#include "gc.h" struct object *master_object = 0; struct object *first_object; @@ -34,6 +35,8 @@ struct object *clone(struct program *p, int args) struct object *o; struct frame frame; + GC_ALLOC(); + o=(struct object *)xalloc(sizeof(struct object)-1+p->storage_needed); o->prog=p; @@ -231,6 +234,8 @@ void really_free_object(struct object *o) if(o->next) o->next->prev=o->prev; free((char *)o); + + GC_FREE(); } void object_index_no_free(struct svalue *to, @@ -463,22 +468,13 @@ union anything *object_get_item_ptr(struct object *o, } #ifdef DEBUG -void verify_all_objects(int pass) +void verify_all_objects() { struct object *o; struct frame frame; for(o=first_object;o;o=o->next) { - if(pass) - { - if(checked((void *)o, 0) != o->refs) - { - fatal("Object has wrong number of refs.\n"); - } - continue; - } - if(o->next && o->next->prev !=o) fatal("Object check: o->next->prev != o\n"); @@ -537,9 +533,6 @@ void verify_all_objects(int pass) frame.context=o->prog->inherits[e]; frame.context.prog->refs++; frame.current_storage=o->storage+frame.context.storage_offset; - - if(frame.context.prog->checkrefs) - frame.context.prog->checkrefs(frame.current_storage,o,pass); } free_object(frame.current_object); @@ -647,19 +640,14 @@ struct array *object_values(struct object *o) return a; } -#ifdef GC -void object_gc_clear_mark() -{ - struct object *o; - for(o=first_object;o;o=o->next) - o->flags &=~ OBJECT_FLAG_MARK; -} +#ifdef GC2 -void object_gc_mark(struct object *o) +void gc_check_object(struct object *o) { INT32 e; - if(o->flags & OBJECT_FLAG_MARK) return; - a->flags |= OBJECT_FLAG_MARK; + if(o == gc_ptr) gc_refs++; + if(o->flags & GC_MARK) return; + o->flags |= GC_MARK; if(!o->prog) return; @@ -673,36 +661,41 @@ void object_gc_mark(struct object *o) if(i->run_time_type == T_MIXED) { - svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i)); + gc_check_svalues((struct svalue *)LOW_GET_GLOBAL(o,e,i),1); }else{ - short_svalue_gc_sweep((struct svalue *)LOW_GET_GLOBAL(o,e,i), + gc_check_short_svalue((struct svalue *)LOW_GET_GLOBAL(o,e,i), i->run_time_type); } } } -void object_gc_sweep() +void gc_check_all_objects() { struct object *o, *next; for(o=first_object;o;o=next) { - o->refs++; - if(!(o->flags & OBJECT_FLAG_MARK)) destruct(o); - next=o->next; - free_object(o); + if(!(o->flags & GC_MARK)) + { + gc_ptr=o; + gc_refs=0; + + o->refs++; + + if(gc_refs == o->refs) destruct(o); + + next=o->next; + free_object(o); + }else{ + next=o->next; + } } } -#ifdef DEBUG -void object_gc_sweep2() +void gc_clear_object_marks() { struct object *o; - if(!d_flag) return; - - for(o=first_object;o;o=o->next) - if(!(o->flags & OBJECT_FLAG_MARK)) - fatal("Object ref count incorrect.\n"); + for(o=first_object;o;o=o->next) o->flags &=~ GC_MARK; } -#endif /* DEBUG */ -#endif /* GC */ + +#endif /* GC2 */ diff --git a/src/object.h b/src/object.h index 8d67f15dd0a0a6d6bf484205a6b9c839978002dc..32608e56ed1024f3e9f0caa00ee2d7c8b3802238 100644 --- a/src/object.h +++ b/src/object.h @@ -14,7 +14,9 @@ struct object { INT32 refs; /* Reference count, must be first. */ +#ifdef GC2 INT16 flags; +#endif struct program *prog; struct object *next; struct object *prev; @@ -55,11 +57,14 @@ union anything *object_low_get_item_ptr(struct object *o, union anything *object_get_item_ptr(struct object *o, struct svalue *index, TYPE_T type); -void verify_all_objects(int pass); +void verify_all_objects(); int object_equal_p(struct object *a, struct object *b, struct processing *p); void cleanup_objects(); struct array *object_indices(struct object *o); struct array *object_values(struct object *o); +void gc_check_object(struct object *o); +void gc_check_all_objects(); +void gc_clear_object_marks(); /* Prototypes end here */ #endif /* OBJECT_H */ diff --git a/src/program.c b/src/program.c index 274f1e34a344ad1012fb2877674ea7e24a54480f..85de0f4f961d7ac359d02faba3b4d28f4c29ceba 100644 --- a/src/program.c +++ b/src/program.c @@ -19,6 +19,7 @@ #include "interpret.h" #include "hashtable.h" #include "main.h" +#include "gc.h" #include <stdio.h> #include <fcntl.h> @@ -156,6 +157,8 @@ void really_free_program(struct program *p) p->next->prev=p->prev; free((char *)p); + + GC_FREE(); } #ifdef DEBUG @@ -214,19 +217,11 @@ void toss_current_program() } #ifdef DEBUG -void check_program(struct program *p, int pass) +void check_program(struct program *p) { INT32 size,e; unsigned INT32 checksum; - if(pass) - { - if(checked((void *)p,0) != p->refs) - fatal("Program has wrong number of references.\n"); - - return; - } - if(p->refs <=0) fatal("Program has zero refs.\n"); @@ -333,10 +328,7 @@ void check_program(struct program *p, int pass) { if(p->inherits[e].storage_offset < 0) fatal("Inherit->storage_offset is wrong.\n"); - - checked((void *)p->inherits[e].prog,1); } - checked((void *)p,-1); /* One too many were added above */ } #endif @@ -466,7 +458,7 @@ struct program *end_program() first_program=prog; #ifdef DEBUG - check_program(prog,0); + check_program(prog); if(l_flag) dump_program_desc(prog); #endif @@ -1190,12 +1182,15 @@ struct program *compile_file(struct lpc_string *file_name) { int fd; struct program *p; - + fd=open(file_name->str,O_RDONLY); if(fd < 0) error("Couldn't open file '%s'.\n",file_name->str); + GC_ALLOC(); + + #define FILE_STATE #define PUSH #include "compilation.h" @@ -1226,6 +1221,8 @@ struct program *compile_string(struct lpc_string *prog, #include "compilation.h" #undef PUSH + GC_ALLOC(); + start_new_string(prog->str,prog->len,name); start_new_program(); compile(); @@ -1281,23 +1278,11 @@ void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags) } #ifdef DEBUG -void check_all_programs(int pass) +void check_all_programs() { struct program *p; for(p=first_program;p;p=p->next) - check_program(p,pass); - -#ifdef FIND_FUNCTION_HASHSIZE - if(!pass) - { - int e; - for(e=0;e<FIND_FUNCTION_HASHSIZE;e++) - { - if(cache[e].name) - checked((void *)cache[e].name,1); - } - } -#endif + check_program(p); } #endif @@ -1315,3 +1300,47 @@ void cleanup_program() } #endif } + +#ifdef GC2 + +void gc_check_program(struct program *p) +{ + if(p==gc_ptr) gc_refs++; + if(p->flags & GC_MARK) return; + p->flags |= GC_MARK; + gc_check_svalues(p->constants, p->num_constants); +} + +void gc_check_all_programs() +{ + struct program *p, *next; + for(p=first_program;p;p=next) + { + if(!(p->flags & GC_MARK)) + { + gc_ptr=p; + gc_refs=0; + + gc_check_program(p); + + p->refs++; + + if(gc_refs == p->refs) + free_svalues(p->constants, p->num_constants, -1); + + next=p->next; + free_program(p); + }else{ + next=p->next; + } + } +} + +void gc_clear_program_marks() +{ + struct program *p; + + for(p=first_program;p;p=p->next) p->flags &=~ GC_MARK; +} + +#endif /* GC2 */ diff --git a/src/program.h b/src/program.h index 0204f525483e6c88de5ca4bee9f2cc9e00a432d0..fe1c265aab35c35d732104281544b06c8e80ae27 100644 --- a/src/program.h +++ b/src/program.h @@ -111,7 +111,6 @@ struct program void (*init)(char *,struct object *); void (*exit)(char *,struct object *); #ifdef DEBUG - void (*checkrefs)(char *,struct object *,int pass); unsigned INT32 checksum; #endif @@ -145,7 +144,7 @@ void start_new_program(); void really_free_program(struct program *p); void dump_program_desc(struct program *p); void toss_current_program(); -void check_program(struct program *p, int pass); +void check_program(struct program *p); struct program *end_program(); SIZE_T add_storage(SIZE_T size); void set_init_callback(void (*init)(char *,struct object *)); @@ -181,8 +180,11 @@ struct program *compile_string(struct lpc_string *prog, struct lpc_string *name); struct program *end_c_program(char *name); void add_function(char *name,void (*cfun)(INT32),char *type,INT16 flags); -void check_all_programs(int pass); +void check_all_programs(); void cleanup_program(); +void gc_check_program(struct program *p); +void gc_check_all_programs(); +void gc_clear_program_marks(); /* Prototypes end here */ diff --git a/src/stralloc.c b/src/stralloc.c index c915693f90adc7e411e0686b517ec94177569e99..8c3d1317c5df0d1302e72159c702f1eeea999775 100644 --- a/src/stralloc.c +++ b/src/stralloc.c @@ -30,11 +30,9 @@ void check_string(struct lpc_string *s) if(s->str[s->len]) fatal("Shared string is not zero terminated properly.\n"); - - checked((void *)s,1); } -void verify_shared_strings_tables(int pass) +void verify_shared_strings_tables() { unsigned int e, h; struct lpc_string *s; @@ -44,14 +42,6 @@ void verify_shared_strings_tables(int pass) h=0; for(s=base_table[e];s;s=s->next) { - if(pass) - { - if(checked((void *)s,0)!=s->refs) - { - fatal("Shared string has wrong number of refs '%s'.\n",s->str); - } - continue; - } h++; if(s->len < 0) fatal("Shared string shorter than zero bytes.\n"); diff --git a/src/stralloc.h b/src/stralloc.h index a2b626193549de54786fd04373525047918d3481..7da0aa5e98cc17ba27c85d4df92a3c3ff2a4d8bc 100644 --- a/src/stralloc.h +++ b/src/stralloc.h @@ -33,7 +33,7 @@ struct lpc_string *debug_findstring(const struct lpc_string *foo); /* Prototypes begin here */ void check_string(struct lpc_string *s); -void verify_shared_strings_tables(int pass); +void verify_shared_strings_tables(); struct lpc_string *findstring(const char *foo); struct lpc_string *debug_findstring(const struct lpc_string *foo); struct lpc_string *begin_shared_string(int len); diff --git a/src/svalue.c b/src/svalue.c index 04af973f0bdce8b8cadba257d3cf1bca207aa318..612ab00302229ed296953c159a555c9ca85971f7 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -639,11 +639,6 @@ void check_short_svalue(union anything *u,TYPE_T type) check_refs2(u,type); if(!u->refs) return; - if(type <= MAX_REF_TYPE) - { - checked((void *) u->refs,1); - } - switch(type) { case T_STRING: @@ -660,3 +655,56 @@ void check_svalue(struct svalue *s) } #endif + +#ifdef GC2 +void gc_check_svalues(struct svalue *s, int num) +{ + INT32 e; + for(e=0;e<num;e++,s++) + { + switch(s->type) + { + case T_ARRAY: gc_check_array(s->u.array); break; + case T_LIST: + gc_check_array(s->u.list->ind); + break; + case T_MAPPING: + gc_check_array(s->u.mapping->ind); + gc_check_array(s->u.mapping->val); + break; + case T_OBJECT: + if(s->u.object->prog) + { + gc_check_object(s->u.object); + }else{ + free_svalue(s); + } + break; + case T_PROGRAM: gc_check_program(s->u.program); break; + } + } +} + +void gc_check_short_svalue(union anything *u, TYPE_T type) +{ + if(!u->refs) return; + switch(type) + { + case T_ARRAY: gc_check_array(u->array); break; + case T_LIST: gc_check_array(u->list->ind); break; + case T_MAPPING: + gc_check_array(u->mapping->ind); + gc_check_array(u->mapping->val); + break; + case T_OBJECT: + if(u->object->prog) + { + gc_check_object(u->object); + }else{ + free_short_svalue(u,T_OBJECT); + } + break; + case T_PROGRAM: gc_check_program(u->program); break; + } +} +#endif /* GC2 */ diff --git a/src/svalue.h b/src/svalue.h index 09780754785a7177ba860bb5120eb47ffc4e3751..9e536ff2f14ca6db4848639f5ff48241ef7cb008 100644 --- a/src/svalue.h +++ b/src/svalue.h @@ -75,6 +75,9 @@ struct svalue #define BIT_NOTHING 0 #define BIT_MIXED 0xffff +#define BIT_BASIC (BIT_INT|BIT_FLOAT|BIT_STRING) +#define BIT_COMPLEX (BIT_ARRAY|BIT_LIST|BIT_OBJECT|BIT_PROGRAM|BIT_MAPPING) + /* Max type with ref count */ #define MAX_REF_TYPE T_STRING /* Max type handled by svalue primitives */ diff --git a/src/test/create_testsuite b/src/test/create_testsuite index 18261c1d2398a49ea3c04d93563212685b15ce6c..5dbe7f6a33dbbce2e2a82fc073575b6c101739a7 100755 --- a/src/test/create_testsuite +++ b/src/test/create_testsuite @@ -63,6 +63,8 @@ test_compile([[while(0)if(0)continue;else;]]) test_program([[int b=1,c; int a() { c=b+2; return c==3; }]]) test_true([[ ("foobar"/"o") & ({ "foo" }) ]]) test_any([[ array a="foo bar"/" "; return sizeof(a & ({"foo"}))]],1) +test_true(intp(gc())); +test_any([[ gc(); array a=({0}); a[0]=a; a=0; return gc() > 0; ]],1); test_eq("\377"[0],255) test_do(add_efun("foo",clone(class {int i;})))