diff --git a/src/Makefile.in b/src/Makefile.in index b4af76d5ff995af137dfb9f7b4de8eaf295df826..c1839d20673dbad9f5349afa388e925d02533f2a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.84 1998/04/27 15:18:09 grubba Exp $ +# $Id: Makefile.in,v 1.85 1998/04/29 02:45:21 hubbe Exp $ # # This line is needed on some machines. @@ -121,6 +121,7 @@ OBJ= \ stuff.o \ threads.o \ version.o \ + queue.o \ svalue.o @EXTRA_OBJS@ # diff --git a/src/gc.c b/src/gc.c index c2fcd938454433bca982577a4c50770f20f3c314..056dbb1a49c839960ff08964ac838216795b5bae 100644 --- a/src/gc.c +++ b/src/gc.c @@ -25,7 +25,7 @@ struct callback *gc_evaluator_callback=0; #include "main.h" #include <math.h> -RCSID("$Id: gc.c,v 1.36 1998/04/24 00:32:08 hubbe Exp $"); +RCSID("$Id: gc.c,v 1.37 1998/04/29 02:45:21 hubbe Exp $"); /* Run garbage collect approximate every time we have * 20 percent of all arrays, objects and programs is @@ -42,6 +42,7 @@ INT32 num_objects =0; INT32 num_allocs =0; INT32 alloc_threshold = MIN_ALLOC_THRESHOLD; static int in_gc = 0; +struct queue gc_mark_queue; static double objects_alloced = 0.0; static double objects_freed = 0.0; @@ -609,10 +610,15 @@ void do_gc(void) /* Next we mark anything with external references */ gc_mark_all_arrays(); + run_queue(&gc_mark_queue); gc_mark_all_multisets(); + run_queue(&gc_mark_queue); gc_mark_all_mappings(); + run_queue(&gc_mark_queue); gc_mark_all_programs(); + run_queue(&gc_mark_queue); gc_mark_all_objects(); + run_queue(&gc_mark_queue); if(d_flag) gc_mark_all_strings(); diff --git a/src/gc.h b/src/gc.h index 4e72c2f0bf4ddf0906c8ca774fcb894261e5b133..4a0400fed17c42b343ed5f3a6ba35895808331c2 100644 --- a/src/gc.h +++ b/src/gc.h @@ -1,12 +1,14 @@ /* - * $Id: gc.h,v 1.17 1998/04/06 04:25:27 hubbe Exp $ + * $Id: gc.h,v 1.18 1998/04/29 02:45:22 hubbe Exp $ */ #ifndef GC_H #define GC_H #include "global.h" #include "callback.h" +#include "queue.h" +extern struct queue gc_mark_queue; extern INT32 num_objects; extern INT32 num_allocs; extern INT32 alloc_threshold; diff --git a/src/queue.c b/src/queue.c new file mode 100644 index 0000000000000000000000000000000000000000..f2dc7fca66b51c5815c78a6ee81ef8b60be9626c --- /dev/null +++ b/src/queue.c @@ -0,0 +1,53 @@ +#include "global.h" +#include "pike_macros.h" +#include "queue.h" + +struct queue_entry +{ + queue_call call; + void *data; +}; + +#define QUEUE_ENTRIES 8192 + +struct queue_block +{ + struct queue_block *next; + int used; + struct queue_entry entries[QUEUE_ENTRIES]; +}; + +void run_queue(struct queue *q) +{ + struct queue_block *b; + while((b=q->first)) + { + int e; + for(e=0;e<b->used;e++) + b->entries[e].call(b->entries[e].data); + + q->first=b->next; + free((char *)b); + } + q->last=0; +} + +void enqueue(struct queue *q, queue_call call, void *data) +{ + struct queue_block *b=q->last; + if(!b || b->used >= QUEUE_ENTRIES) + { + b=ALLOC_STRUCT(queue_block); + b->used=0; + b->next=0; + if(q->first) + q->last->next=b; + else + q->first=b; + q->last=b; + } + + b->entries[b->used].call=call; + b->entries[b->used].data=data; + b->used++; +} diff --git a/src/queue.h b/src/queue.h new file mode 100644 index 0000000000000000000000000000000000000000..2dc43f261b6216cf28b7c3e07bc5471fc96e4b2f --- /dev/null +++ b/src/queue.h @@ -0,0 +1,20 @@ +#ifndef QUEUE_H +#define QUEUE_H + +struct queue; +typedef void (*queue_call)(void *data); + +/* Prototypes begin here */ +struct queue_entry; +struct queue_block; +void run_queue(struct queue *q); +void enqueue(struct queue *q, queue_call call, void *data); +/* Prototypes end here */ + +struct queue +{ + struct queue_block *first, *last; +}; + + +#endif /* QUEUE_H */ diff --git a/src/svalue.c b/src/svalue.c index cd18e902dd472be37cbef5eadd6efee205b1ed4a..4fe027eb39775a2ae0f4d99971c1f51c2a738317 100644 --- a/src/svalue.c +++ b/src/svalue.c @@ -19,8 +19,9 @@ #include "gc.h" #include "pike_macros.h" #include <ctype.h> +#include "queue.h" -RCSID("$Id: svalue.c,v 1.30 1998/04/28 22:34:18 hubbe Exp $"); +RCSID("$Id: svalue.c,v 1.31 1998/04/29 02:45:22 hubbe Exp $"); struct svalue dest_ob_zero = { T_INT, 0 }; @@ -1066,10 +1067,26 @@ void gc_mark_svalues(struct svalue *s, int num) { switch(s->type) { - case T_ARRAY: gc_mark_array_as_referenced(s->u.array); break; - case T_MULTISET: gc_mark_multiset_as_referenced(s->u.multiset); break; - case T_MAPPING: gc_mark_mapping_as_referenced(s->u.mapping); break; - case T_PROGRAM: gc_mark_program_as_referenced(s->u.program); break; + case T_ARRAY: + enqueue(&gc_mark_queue, + (queue_call)gc_mark_array_as_referenced, + s->u.array); + break; + case T_MULTISET: + enqueue(&gc_mark_queue, + (queue_call)gc_mark_multiset_as_referenced, + s->u.multiset); + break; + case T_MAPPING: + enqueue(&gc_mark_queue, + (queue_call)gc_mark_mapping_as_referenced, + s->u.mapping); + break; + case T_PROGRAM: + enqueue(&gc_mark_queue, + (queue_call)gc_mark_program_as_referenced, + s->u.program); + break; case T_FUNCTION: if(s->subtype == FUNCTION_BUILTIN) break; @@ -1077,7 +1094,9 @@ void gc_mark_svalues(struct svalue *s, int num) case T_OBJECT: if(s->u.object->prog) { - gc_mark_object_as_referenced(s->u.object); + enqueue(&gc_mark_queue, + (queue_call)gc_mark_object_as_referenced, + s->u.object); }else{ free_svalue(s); s->type=T_INT;