enhanced object hash handling

This commit is contained in:
hyunghwan.chung 2019-09-19 14:10:00 +00:00
parent e1e577ec22
commit e0c116ecd4
4 changed files with 25 additions and 20 deletions

View File

@ -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;
}

View File

@ -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 */

View File

@ -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; \