Permalink
Browse files

Change the tagging scheme slightly to catch more bugs.

  • Loading branch information...
1 parent 43e13de commit b9212887b6b6a262471b79cf71d89369ddbbe631 @nelhage committed Jan 2, 2009
Showing with 43 additions and 23 deletions.
  1. +9 −8 gc.c
  2. +26 −7 gc.h
  3. +8 −8 scgc.c
View
17 gc.c
@@ -18,8 +18,8 @@ static uintptr_t mem_size;
static int in_gc = 0;
#endif
-static gc_handle gc_root_stack = NIL;
-static gc_handle gc_root_hooks = NIL;
+static gc_handle gc_root_stack;
+static gc_handle gc_root_hooks;
static uint32_t gc_n_temp_roots = 0;
static gc_handle *gc_temp_roots[MAX_EXTERNAL_ROOTS_FRAME];
@@ -30,7 +30,7 @@ void *_gc_try_alloc(uint32_t n) {
free_ptr += n;
return h;
}
- return NIL;
+ return NULL;
}
void* _gc_alloc(uint32_t n) {
@@ -84,6 +84,7 @@ void gc_init() {
gc_root_hooks = NIL;
gc_root_stack = NIL;
+ gc_n_temp_roots = 0;
gc_register_gc_root_hook(gc_relocate_root);
}
@@ -171,7 +172,7 @@ void gc_register_roots(gc_handle* root0, ...) {
frame->next_frame = gc_root_stack;
- gc_root_stack = TAG_POINTER(frame);
+ gc_root_stack = gc_tag_pointer(frame);
}
void gc_pop_roots() {
@@ -200,17 +201,17 @@ static struct gc_ops gc_root_hook_ops = {
void gc_register_gc_root_hook(gc_hook *hook_fun) {
gc_root_hook *hook = (gc_root_hook*)gc_alloc(&gc_root_hook_ops, 3);
- hook->next = TAG_POINTER(gc_root_hooks);
+ hook->next = gc_root_hooks;
hook->hook = hook_fun;
- gc_root_hooks = TAG_POINTER(hook);
+ gc_root_hooks = gc_tag_pointer(hook);
}
void gc_relocate(gc_handle *v) {
int len;
uintptr_t *reloc;
gc_chunk *val;
- if(NUMBERP(*v))
+ if(gc_numberp(*v))
return;
val = UNTAG_PTR(*v, gc_chunk);
@@ -231,7 +232,7 @@ void gc_relocate(gc_handle *v) {
reloc = _gc_alloc(len);
memcpy(reloc, val, sizeof(uintptr_t) * len);
val->ops = BROKEN_HEART;
- *v = val->data[0] = TAG_POINTER(reloc);
+ *v = val->data[0] = gc_tag_pointer(reloc);
}
void gc_relocate_root() {
View
33 gc.h
@@ -46,15 +46,34 @@ void gc_pop_roots();
void gc_register_gc_root_hook(gc_hook *);
+#define TAG_BITS 2
+#define TAG_MASK 0x03
+#define NUMBER_TAG 0x01
+#define POINTER_TAG 0x02
+
/* Here be demons */
-#define TAG_NUMBER(x) ((gc_handle)((x)<<1 | 0x1))
-#define TAG_POINTER(x) ((gc_handle)(x))
+static inline gc_handle gc_tag_number(gc_int n) {
+ return (n << TAG_BITS) | NUMBER_TAG;
+}
+
+static inline gc_handle gc_tag_pointer(void *p) {
+ assert(!(((gc_int)p) & TAG_MASK));
+ return (gc_handle)((gc_int)p) | POINTER_TAG;
+}
+
+static inline int gc_numberp(gc_handle h) {
+ return (h & TAG_MASK) == NUMBER_TAG;
+}
+
+static inline int gc_pointerp(gc_handle h) {
+ return (h & TAG_MASK) == POINTER_TAG;
+}
-#define NUMBERP(x) ((uintptr_t)(x)&0x1)
-#define POINTERP(x) (!NUMBERP(x))
+static inline gc_int gc_untag_number(gc_handle h) {
+ return (h >> TAG_BITS);
+}
-#define UNTAG_PTR(c, t) ((t*)c)
-#define UNTAG_NUMBER(c) (((gc_int)(c))>>1)
+#define UNTAG_PTR(c, t) ((t*)(c & ~TAG_MASK))
#define MAX(a,b) \
({ typeof (a) _a = (a); \
@@ -75,7 +94,7 @@ void gc_register_gc_root_hook(gc_hook *);
(typeof(a)) (ROUNDDOWN((uint32_t) (a) + __n - 1, __n)); \
})
-#define NIL (TAG_POINTER(NULL))
+#define NIL (gc_tag_pointer(NULL))
#define NILP(x) ((x) == NIL)
#endif /* !defined(__MINISCHEME_GC__)*/
View
16 scgc.c
@@ -114,11 +114,11 @@ uint32_t sc_strlen(gc_handle c) {
gc_int sc_number(gc_handle n) {
assert(sc_numberp(n));
- return UNTAG_NUMBER(n);
+ return gc_untag_number(n);
}
gc_handle sc_make_number(gc_int n) {
- return (gc_handle)TAG_NUMBER(n);
+ return gc_tag_number(n);
}
uint32_t sc_vector_len(gc_handle v) {
@@ -140,7 +140,7 @@ void sc_vector_set(gc_handle v, uint32_t n, gc_handle x) {
/* Predicates */
static inline int sc_pointer_typep(gc_handle c, gc_ops *type) {
- return POINTERP(c)
+ return gc_pointerp(c)
&& !NILP(c)
&& UNTAG_PTR(c, gc_chunk)->ops == type;
}
@@ -162,21 +162,21 @@ int sc_vectorp(gc_handle c) {
}
int sc_numberp(gc_handle c) {
- return NUMBERP(c);
+ return gc_numberp(c);
}
/* Memory allocation */
gc_handle sc_alloc_cons() {
sc_cons *cons = (sc_cons*)gc_alloc(&sc_cons_ops, 3);
cons->car = cons->cdr = NIL;
- return TAG_POINTER(cons);
+ return gc_tag_pointer(cons);
}
gc_handle sc_alloc_string(uint32_t len) {
sc_string *str = (sc_string*)gc_alloc(&sc_string_ops, STRLEN2CELLS(len) + 2);
str->strlen = len;
- return TAG_POINTER(str);
+ return gc_tag_pointer(str);
}
gc_handle sc_alloc_vector(uint32_t len) {
@@ -186,13 +186,13 @@ gc_handle sc_alloc_vector(uint32_t len) {
for(i = 0; i < len; i++) {
vec->vector[i] = NIL;
}
- return TAG_POINTER(vec);
+ return gc_tag_pointer(vec);
}
gc_handle sc_alloc_symbol(uint32_t len) {
sc_symbol *sym = (sc_string*)gc_alloc(&sc_symbol_ops, STRLEN2CELLS(len) + 2);
sym->strlen = len;
- return TAG_POINTER(sym);
+ return gc_tag_pointer(sym);
}
gc_handle sc_make_string(char *string) {

0 comments on commit b921288

Please sign in to comment.