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.
This commit is contained in:
parent
7a631b3557
commit
cf6f353f20
|
@ -5,8 +5,8 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
#define INT_MARKER (1l << 63)
|
#define TOGGLE_MARK(n) ((uint64_t) n ^ ((uint64_t) 1 << 63))
|
||||||
#define IS_INT(n) ((uint64_t) n & INT_MARKER)
|
#define IS_MARKED(n) ((((uint64_t) n) ^ ((uint64_t) n << 1)) & ((uint64_t) 1 << 63))
|
||||||
|
|
||||||
struct node_base* alloc_node() {
|
struct node_base* alloc_node() {
|
||||||
struct node_base* new_node = malloc(sizeof(struct node_app));
|
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) {
|
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) {
|
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) {
|
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;
|
n->gc_reachable = 1;
|
||||||
|
|
||||||
if(n->tag == NODE_APP) {
|
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) {
|
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++;
|
g->gc_node_count++;
|
||||||
b->gc_next = g->gc_nodes;
|
b->gc_next = g->gc_nodes;
|
||||||
g->gc_nodes = b;
|
g->gc_nodes = b;
|
||||||
|
@ -210,7 +210,7 @@ void unwind(struct gmachine* g) {
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
struct node_base* peek = stack_peek(s, 0);
|
struct node_base* peek = stack_peek(s, 0);
|
||||||
if(IS_INT(peek)) {
|
if(IS_MARKED(peek)) {
|
||||||
break;
|
break;
|
||||||
} else if(peek->tag == NODE_APP) {
|
} else if(peek->tag == NODE_APP) {
|
||||||
struct node_app* n = (struct node_app*) peek;
|
struct node_app* n = (struct node_app*) peek;
|
||||||
|
@ -238,7 +238,7 @@ void unwind(struct gmachine* g) {
|
||||||
extern void f_main(struct gmachine* s);
|
extern void f_main(struct gmachine* s);
|
||||||
|
|
||||||
void print_node(struct node_base* n) {
|
void print_node(struct node_base* n) {
|
||||||
if(IS_INT(n)) {
|
if(IS_MARKED(n)) {
|
||||||
printf("%d", (int32_t) n);
|
printf("%d", (int32_t) n);
|
||||||
} else if(n->tag == NODE_APP) {
|
} else if(n->tag == NODE_APP) {
|
||||||
struct node_app* app = (struct node_app*) n;
|
struct node_app* app = (struct node_app*) n;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user