From 991e5aabd4e9a57713a9fb58fdef803c8ff7b587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Tue, 28 Apr 1998 19:45:22 -0700 Subject: [PATCH] garbage collector now uses a queue instead of recursion Rev: src/Makefile.in:1.85 Rev: src/gc.c:1.37 Rev: src/gc.h:1.18 Rev: src/queue.c:1.1 Rev: src/queue.h:1.1 Rev: src/svalue.c:1.31 --- src/Makefile.in | 3 ++- src/gc.c | 8 +++++++- src/gc.h | 4 +++- src/queue.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ src/queue.h | 20 +++++++++++++++++++ src/svalue.c | 31 +++++++++++++++++++++++------ 6 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 src/queue.c create mode 100644 src/queue.h diff --git a/src/Makefile.in b/src/Makefile.in index b4af76d5ff..c1839d2067 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 c2fcd93845..056dbb1a49 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 4e72c2f0bf..4a0400fed1 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 0000000000..f2dc7fca66 --- /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 0000000000..2dc43f261b --- /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 cd18e902dd..4fe027eb39 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; -- GitLab