From fb859880d92974382f8a0f916b8b5c9d2aec4005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Thu, 26 Nov 1998 15:46:24 +0100 Subject: [PATCH] Started on gc. Rev: src/io.c:1.29 Rev: src/lsh_types.h:1.18 Rev: src/service.h:1.8 Rev: src/xalloc.c:1.10 Rev: src/xalloc.h:1.10 --- src/io.c | 8 ++--- src/lsh_types.h | 29 ++++++++++++++++++- src/service.h | 11 +++++++ src/xalloc.c | 77 ++++++++++++++++++++++++++++++------------------- src/xalloc.h | 4 --- 5 files changed, 91 insertions(+), 38 deletions(-) diff --git a/src/io.c b/src/io.c index 5e76ab86..431b8cbc 100644 --- a/src/io.c +++ b/src/io.c @@ -61,10 +61,10 @@ int io_iter(struct io_backend *b) * and unlinks any fd:s that should be closed, and also counts how * many fd:s there are. */ - struct lsh_fd **_fd; + struct lsh_fd **fd_p; struct lsh_fd *fd; - for(_fd = &b->files; (fd = *_fd); ) + for(fd_p = &b->files; (fd = *fd_p); ) { if (!fd->close_now && fd->prepare) PREPARE_FD(fd); @@ -91,11 +91,11 @@ int io_iter(struct io_backend *b) close(fd->fd); } /* Unlink this fd */ - *_fd = fd->next; + *fd_p = fd->next; continue; } nfds++; - _fd = &fd->next; + fd_p = &fd->next; } } diff --git a/src/lsh_types.h b/src/lsh_types.h index f8c5b123..a7f17c1e 100644 --- a/src/lsh_types.h +++ b/src/lsh_types.h @@ -66,14 +66,41 @@ do { \ #define LSH_ALLOC_STATIC 1 #define LSH_ALLOC_STACK 2 +struct lsh_class; + +struct lsh_object +{ + /* Objects are chained together, for the sweep phase of the gc. */ + struct lsh_object *next; + struct lsh_class *isa; + + char alloc_method; + char marked; +}; + +struct lsh_class +{ + struct lsh_object *super; + struct lsh_class *super_class; + size_t size; + + struct lsh_object *(*mark_instance)(struct lsh_object *instance, + void (*mark)(struct lsh_object *o)); + void (*free_instance)(struct lsh_object *instance); + + /* Particular classes may add their own methods here */ +}; + #ifdef DEBUG_ALLOC - + +#if 0 struct lsh_object { int size; /* Zero for objects that are not allocated on the heap. */ char alloc_method; char marked; }; +#endif struct lsh_string_header { diff --git a/src/service.h b/src/service.h index 7f09989e..fde69ffd 100644 --- a/src/service.h +++ b/src/service.h @@ -31,12 +31,23 @@ * in a SSH_MSG_SERVICE_REQUEST or SSH_MSG_USERAUTH_REQUEST) and for * any other stuff that needs initialization at some later time. */ +#include "service.h.x" + +#if 0 struct ssh_service { struct lsh_object header; int (*init)(struct ssh_service *self, struct ssh_connection *c); }; +#endif + +/* CLASS: + ((name ssh_service) + (vars + (method + int "(*init)(struct ssh_service *self, struct ssh_connection *c)"))) +*/ #define SERVICE_INIT(s, c) ((s)->init((s), (c))) diff --git a/src/xalloc.c b/src/xalloc.c index c56e6010..e2db0218 100644 --- a/src/xalloc.c +++ b/src/xalloc.c @@ -116,6 +116,30 @@ void lsh_string_free(struct lsh_string *s) lsh_free(s); } +struct lsh_object *lsh_object_alloc(struct lsh_class *class) +{ + struct lsh_object *self = xalloc(class->size); + self->class = class; + self->alloc_method = LSH_ALLOC_HEAP; + + gc_register(o); + + return o; +} + +/* Should be called *only* by the gc */ +void lsh_object_free(struct lsh_object *o) +{ + if (o->alloc_method != LSH_ALLOC_HEAP) + fatal("lsh_object_free: Object not allocated on the heap!\n"); + + if (o->isa->free_instance) + o->isa->free_instance(o); + + lsh_free(o); +}; + +#if 0 void *lsh_object_alloc(size_t size) { struct lsh_object *self = xalloc(size); @@ -133,43 +157,38 @@ void lsh_object_free(void *p) fatal("lsh_object_free: Object not allocated on the heap!\n"); lsh_free(p); }; +#endif #ifdef DEBUG_ALLOC -void lsh_object_check(void *p, size_t size) +void lsh_object_check(struct lsh_object *instance, struct lsh_class *class) { - struct lsh_object *self = (struct lsh_object *) p; + if (instance->marked) + fatal("lsh_object_check: Unexpected marked object!\n"); - switch(self->alloc_method) - { - case LSH_ALLOC_HEAP: - if (self->size != size) - fatal("Type error!\n"); - break; - case LSH_ALLOC_STATIC: - case LSH_ALLOC_STACK: - break; - default: - fatal("Type error!\n"); - } + if (instance->dead) + fatal("lsh_object_check: Reference to dead object!\n"); + + if (instance->class != class) + fatal("lsh_object_check: Type error!\n"); } -void lsh_object_check_subtype(void *p, size_t size) +void lsh_object_check_subtype(struct lsh_object *instance, + struct lsh_class *class) { - struct lsh_object *self = (struct lsh_object *) p; - switch(self->alloc_method) - { - case LSH_ALLOC_HEAP: - if (self->size < size) - fatal("Type error!\n"); - break; - case LSH_ALLOC_STATIC: - case LSH_ALLOC_STACK: - break; - default: - fatal("Type error!\n"); - } -} + struct lsh_class *type; + + if (instance->marked) + fatal("lsh_object_check: Unexpected marked object!\n"); + + if (instance->dead) + fatal("lsh_object_check: Reference to dead object!\n"); + for (type = instance->class; type; type=type->super_class) + if (type == class) + return; + + fatal("lsh_object_check_subtype: Unexpected marked object!\n"); +} #endif /* DEBUG_ALLOC */ #ifdef DEBUG_ALLOC diff --git a/src/xalloc.h b/src/xalloc.h index da9ba1d1..3bd4ab67 100644 --- a/src/xalloc.h +++ b/src/xalloc.h @@ -29,10 +29,6 @@ #include "lsh_types.h" #include -#if 0 -void *xalloc(size_t size); -#endif - /* Allocation */ /* The memory allocation model (for strings) is as follows: -- GitLab