enhanced object hash handling
This commit is contained in:
parent
e1e577ec22
commit
e0c116ecd4
@ -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;
|
||||
}
|
||||
|
19
moo/lib/gc.c
19
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 */
|
||||
|
@ -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; \
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user