From cf6f353f20eabd73c46bdc83885707b5e4a88abf Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Thu, 17 Sep 2020 18:30:55 -0700 Subject: [PATCH] Change tagging to assume sign extension. ARM and x86_64 require "real" pointers to be sign-extended in their top bits. This means a working pointer is guaranteed to have either "11" as leading bits, or "00". So, to tag a "fake" pointer which is an unboxed 32-bit integer, we simply toggle the leading bit. --- code/compiler/13/runtime.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/code/compiler/13/runtime.c b/code/compiler/13/runtime.c index 7d3b7b2..8e2daf3 100644 --- a/code/compiler/13/runtime.c +++ b/code/compiler/13/runtime.c @@ -5,8 +5,8 @@ #include #include "runtime.h" -#define INT_MARKER (1l << 63) -#define IS_INT(n) ((uint64_t) n & INT_MARKER) +#define TOGGLE_MARK(n) ((uint64_t) n ^ ((uint64_t) 1 << 63)) +#define IS_MARKED(n) ((((uint64_t) n) ^ ((uint64_t) n << 1)) & ((uint64_t) 1 << 63)) struct node_base* alloc_node() { struct node_base* new_node = malloc(sizeof(struct node_app)); @@ -25,7 +25,7 @@ struct node_app* alloc_app(struct node_base* l, struct node_base* r) { } struct node_num* alloc_num(int32_t n) { - return (struct node_num*) (INT_MARKER | n); + return (struct node_num*) TOGGLE_MARK(n); } struct node_global* alloc_global(void (*f)(struct gmachine*), int32_t a) { @@ -50,7 +50,7 @@ void free_node_direct(struct node_base* n) { } void gc_visit_node(struct node_base* n) { - if(IS_INT(n) || n->gc_reachable) return; + if(IS_MARKED(n) || n->gc_reachable) return; n->gc_reachable = 1; if(n->tag == NODE_APP) { @@ -170,7 +170,7 @@ void gmachine_split(struct gmachine* g, size_t n) { } struct node_base* gmachine_track(struct gmachine* g, struct node_base* b) { - if(IS_INT(b)) return b; + if(IS_MARKED(b)) return b; g->gc_node_count++; b->gc_next = g->gc_nodes; g->gc_nodes = b; @@ -210,7 +210,7 @@ void unwind(struct gmachine* g) { while(1) { struct node_base* peek = stack_peek(s, 0); - if(IS_INT(peek)) { + if(IS_MARKED(peek)) { break; } else if(peek->tag == NODE_APP) { struct node_app* n = (struct node_app*) peek; @@ -238,7 +238,7 @@ void unwind(struct gmachine* g) { extern void f_main(struct gmachine* s); void print_node(struct node_base* n) { - if(IS_INT(n)) { + if(IS_MARKED(n)) { printf("%d", (int32_t) n); } else if(n->tag == NODE_APP) { struct node_app* app = (struct node_app*) n;