diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 2babeea..a3184d1 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -2196,11 +2196,8 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) else if (rcv == moo->_false) hv = 2; else { - int type; - MOO_ASSERT (moo, MOO_OOP_IS_POINTER(rcv)); - type = MOO_OBJ_GET_FLAGS_TYPE(rcv); - switch (type) + switch (MOO_OBJ_GET_FLAGS_TYPE(rcv)) { case MOO_OBJ_TYPE_BYTE: hv = moo_hash_bytes(MOO_OBJ_GET_BYTE_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv)); @@ -2220,17 +2217,18 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) default: /* MOO_OBJ_TYPE_OOP, ... */ - moo_seterrbfmt(moo, MOO_ENOIMPL, "no builtin hash implemented for %O", rcv); /* TODO: better error code? */ switch (MOO_OBJ_GET_FLAGS_HASH(rcv)) { - case 0: - MOO_OBJ_SET_FLAGS_HASH (rcv, 1); + case MOO_OBJ_FLAGS_HASH_UNUSED: + /* the object in the permanent space doesn't need this. but never mind */ + /*if (!MOO_OBJ_GET_FLAGS_PERM(rcv)) */ + MOO_OBJ_SET_FLAGS_HASH (rcv, MOO_OBJ_FLAGS_HASH_CALLED); /* fall thru */ - case 1: - hv = (moo_oow_t)rcv; + case MOO_OBJ_FLAGS_HASH_CALLED: + hv = ((moo_oow_t)rcv) % (MOO_SMOOI_MAX + 1); break; - case 2: + case MOO_OBJ_FLAGS_HASH_STORED: hv = *(moo_oow_t*)((moo_uint8_t*)rcv + MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, rcv) - MOO_SIZEOF(moo_oow_t)); break; } diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 3c99489..cc375de 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -743,8 +743,9 @@ moo_oow_t moo_getobjpayloadbytes (moo_t* moo, moo_oop_t oop) * | X | * | X | * | Y | <-- it may exist if EXTRA is set in _flags. - * | Z | <-- if TRAILER is set, it is the number of bytes in the trailer - * | | | | | + * | Z | <-- if TRAILER is set, it is a word indicating the number of bytes in the trailer + * | | | | | <-- trailer bytes. it's aligned to a word boundary. + * | hash | <-- if HASH is set to 2 in _flags, a word is used to store a hash value */ MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP); MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_UNIT(oop) == MOO_SIZEOF(moo_oow_t)); @@ -759,7 +760,7 @@ moo_oow_t moo_getobjpayloadbytes (moo_t* moo, moo_oop_t oop) } nbytes = MOO_ALIGN(nbytes, MOO_SIZEOF(moo_oop_t)); - if (MOO_OBJ_GET_FLAGS_HASH(oop) == 2) + if (MOO_OBJ_GET_FLAGS_HASH(oop) == MOO_OBJ_FLAGS_HASH_STORED) { MOO_STATIC_ASSERT (MOO_SIZEOF(moo_oop_t) == MOO_SIZEOF(moo_oow_t)); nbytes += MOO_SIZEOF(moo_oow_t); @@ -793,10 +794,12 @@ moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop) nbytes_aligned = moo_getobjpayloadbytes(moo, oop); - if (MOO_OBJ_GET_FLAGS_HASH(oop) == 1) + if (MOO_OBJ_GET_FLAGS_HASH(oop) == MOO_OBJ_FLAGS_HASH_CALLED) { - MOO_STATIC_ASSERT (MOO_SIZEOF(moo_oop_t) == MOO_SIZEOF(moo_oow_t)); /* don't need explicit alignment */ - extra_bytes = MOO_SIZEOF(moo_oow_t); /* MOO_ALIGN(MOO_SIZEOF(moo_oow_t), MOO_SIZEOF(moo_oop_t)); */ + MOO_STATIC_ASSERT (MOO_SIZEOF(moo_oop_t) == MOO_SIZEOF(moo_oow_t)); + /* don't need explicit alignment since oop and oow have the same size + extra_bytes = MOO_ALIGN(MOO_SIZEOF(moo_oow_t), MOO_SIZEOF(moo_oop_t)); */ + extra_bytes = MOO_SIZEOF(moo_oow_t); } /* allocate space in the new heap */ @@ -824,8 +827,8 @@ moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop) if (extra_bytes) { - MOO_OBJ_SET_FLAGS_HASH (tmp, 2); - *(moo_oow_t*)((moo_uint8_t*)tmp + MOO_SIZEOF(moo_obj_t) + nbytes_aligned) = (moo_oow_t)oop; + MOO_OBJ_SET_FLAGS_HASH (tmp, MOO_OBJ_FLAGS_HASH_STORED); + *(moo_oow_t*)((moo_uint8_t*)tmp + MOO_SIZEOF(moo_obj_t) + nbytes_aligned) = (moo_oow_t)oop % (MOO_SMOOI_MAX + 1); } /* return the new object */ diff --git a/moo/lib/moo.h b/moo/lib/moo.h index dd06a74..94a060a 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -373,6 +373,10 @@ typedef enum moo_gcfin_t moo_gcfin_t; #define MOO_OBJ_FLAGS_KERNEL_IMMATURE 1 #define MOO_OBJ_FLAGS_KERNEL_MATURE 2 +#define MOO_OBJ_FLAGS_HASH_UNUSED 0 /* the hash method has never been invoked */ +#define MOO_OBJ_FLAGS_HASH_CALLED 1 /* the hash method has been invoked for this object */ +#define MOO_OBJ_FLAGS_HASH_STORED 2 /* the object with hash invoke has been moved by GC */ + #define MOO_OBJ_HEADER \ moo_oow_t _flags; \ moo_oow_t _size; \ diff --git a/moo/lib/pf-basic.c b/moo/lib/pf-basic.c index 93f4c44..ab29074 100644 --- a/moo/lib/pf-basic.c +++ b/moo/lib/pf-basic.c @@ -244,9 +244,9 @@ moo_pfrc_t moo_pf_shallow_copy (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) moo_oop_t rcv, obj; MOO_ASSERT (moo, nargs == 0); - rcv = MOO_STACK_GETRCV (moo, nargs); + rcv = MOO_STACK_GETRCV(moo, nargs); - obj = moo_shallowcopy (moo, rcv); + obj = moo_shallowcopy(moo, rcv); if (!obj) return MOO_PF_FAILURE; MOO_STACK_SETRET (moo, nargs, obj);