use MSB of tt as mark bit

This commit is contained in:
Yuichi Nishiwaki 2017-04-09 19:14:02 +09:00
parent 287e7473b4
commit 960029841e
3 changed files with 28 additions and 16 deletions

View File

@ -202,13 +202,13 @@ pic_alloca(pic_state *pic, size_t n)
static bool
is_marked(pic_state *PIC_UNUSED(pic), struct object *obj)
{
return obj->u.basic.gc_mark == 1;
return obj->u.basic.tt & GC_MARK;
}
static void
mark(pic_state *PIC_UNUSED(pic), struct object *obj)
{
obj->u.basic.gc_mark = 1;
obj->u.basic.tt |= GC_MARK;
}
#else
@ -322,7 +322,7 @@ gc_mark_object(pic_state *pic, struct object *obj)
#define LOOP(o) obj = (struct object *)(o); goto loop
switch (obj->u.basic.tt) {
switch (obj_type(pic, obj)) {
case PIC_TYPE_PAIR: {
gc_mark(pic, obj->u.pair.car);
if (obj_p(pic, obj->u.pair.cdr)) {
@ -494,7 +494,7 @@ gc_mark_phase(pic_state *pic)
static void
gc_finalize_object(pic_state *pic, struct object *obj)
{
switch (obj->u.basic.tt) {
switch (obj_type(pic, obj)) {
case PIC_TYPE_VECTOR: {
pic_free(pic, obj->u.vec.data);
break;
@ -651,8 +651,8 @@ gc_sweep_page(pic_state *pic, struct heap_page *page)
goto escape;
}
obj = (struct object *)(p + 1);
if (obj->u.basic.gc_mark == 1) {
obj->u.basic.gc_mark = 0;
if (obj->u.basic.tt & GC_MARK) {
obj->u.basic.tt &= ~GC_MARK;
alive += p->s.size;
} else {
if (head == NULL) {
@ -849,9 +849,6 @@ pic_obj_alloc_unsafe(pic_state *pic, size_t size, int type)
pic_panic(pic, "GC memory exhausted");
}
}
#if !PIC_BITMAP_GC
obj->u.basic.gc_mark = 0;
#endif
obj->u.basic.tt = type;
return obj;

View File

@ -70,14 +70,14 @@ pic_int(pic_state *PIC_UNUSED(pic), pic_value v)
PIC_STATIC_INLINE double
pic_float(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_float_p(v));
assert(pic_float_p(pic, v));
return v.u.f;
}
PIC_STATIC_INLINE char
pic_char(pic_state *PIC_UNUSED(pic), pic_value v)
{
assert(pic_char_p(v));
assert(pic_char_p(pic, v));
return v.u.c;
}

View File

@ -16,8 +16,11 @@ extern "C" {
unsigned char tt;
#else
# define OBJECT_HEADER \
unsigned char tt; \
char gc_mark;
unsigned char tt;
#endif
#if !PIC_BITMAP_GC
# define GC_MARK 0x80
#endif
struct object; /* defined in gc.c */
@ -174,12 +177,24 @@ struct error {
if (tolen - at < e - s) pic_error(pic, "invalid range", 0); \
} while (0)
#if PIC_BITMAP_GC
PIC_STATIC_INLINE int
obj_tt(pic_state *PIC_UNUSED(pic), void *ptr)
obj_type(pic_state *PIC_UNUSED(pic), void *ptr)
{
return ((struct basic *)ptr)->tt;
}
#else
PIC_STATIC_INLINE int
obj_type(pic_state *PIC_UNUSED(pic), void *ptr)
{
return ((struct basic *)ptr)->tt & ~GC_MARK;
}
#endif
#if !PIC_NAN_BOXING
PIC_STATIC_INLINE struct object *
@ -197,7 +212,7 @@ obj_p(pic_state *PIC_UNUSED(pic), pic_value v)
PIC_STATIC_INLINE pic_value
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
{
pic_value v = pic_make_value(obj_tt(pic, ptr));
pic_value v = pic_make_value(obj_type(pic, ptr));
v.u.data = ptr;
return v;
}
@ -219,7 +234,7 @@ obj_p(pic_state *PIC_UNUSED(pic), pic_value v)
PIC_STATIC_INLINE pic_value
obj_value(pic_state *PIC_UNUSED(pic), void *ptr)
{
pic_value v = pic_make_value(obj_tt(pic, ptr));
pic_value v = pic_make_value(obj_type(pic, ptr));
v.v |= 0x3ffffffffffful & ((uint64_t)ptr >> 2);
return v;
}