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 if (rcv == moo->_false) hv = 2;
else else
{ {
int type;
MOO_ASSERT (moo, MOO_OOP_IS_POINTER(rcv)); MOO_ASSERT (moo, MOO_OOP_IS_POINTER(rcv));
type = MOO_OBJ_GET_FLAGS_TYPE(rcv); switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
switch (type)
{ {
case MOO_OBJ_TYPE_BYTE: case MOO_OBJ_TYPE_BYTE:
hv = moo_hash_bytes(MOO_OBJ_GET_BYTE_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv)); 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: default:
/* MOO_OBJ_TYPE_OOP, ... */ /* 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)) switch (MOO_OBJ_GET_FLAGS_HASH(rcv))
{ {
case 0: case MOO_OBJ_FLAGS_HASH_UNUSED:
MOO_OBJ_SET_FLAGS_HASH (rcv, 1); /* 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 */ /* fall thru */
case 1: case MOO_OBJ_FLAGS_HASH_CALLED:
hv = (moo_oow_t)rcv; hv = ((moo_oow_t)rcv) % (MOO_SMOOI_MAX + 1);
break; 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)); hv = *(moo_oow_t*)((moo_uint8_t*)rcv + MOO_SIZEOF(moo_obj_t) + moo_getobjpayloadbytes(moo, rcv) - MOO_SIZEOF(moo_oow_t));
break; break;
} }

View File

@ -743,8 +743,9 @@ moo_oow_t moo_getobjpayloadbytes (moo_t* moo, moo_oop_t oop)
* | X | * | X |
* | X | * | X |
* | Y | <-- it may exist if EXTRA is set in _flags. * | 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_TYPE(oop) == MOO_OBJ_TYPE_OOP);
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_UNIT(oop) == MOO_SIZEOF(moo_oow_t)); 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)); 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)); MOO_STATIC_ASSERT (MOO_SIZEOF(moo_oop_t) == MOO_SIZEOF(moo_oow_t));
nbytes += 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); 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 */ MOO_STATIC_ASSERT (MOO_SIZEOF(moo_oop_t) == MOO_SIZEOF(moo_oow_t));
extra_bytes = MOO_SIZEOF(moo_oow_t); /* MOO_ALIGN(MOO_SIZEOF(moo_oow_t), MOO_SIZEOF(moo_oop_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 */ /* 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) if (extra_bytes)
{ {
MOO_OBJ_SET_FLAGS_HASH (tmp, 2); 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_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 */ /* 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_IMMATURE 1
#define MOO_OBJ_FLAGS_KERNEL_MATURE 2 #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 \ #define MOO_OBJ_HEADER \
moo_oow_t _flags; \ moo_oow_t _flags; \
moo_oow_t _size; \ moo_oow_t _size; \

View File

@ -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_oop_t rcv, obj;
MOO_ASSERT (moo, nargs == 0); 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; if (!obj) return MOO_PF_FAILURE;
MOO_STACK_SETRET (moo, nargs, obj); MOO_STACK_SETRET (moo, nargs, obj);