adding the hash flag field to the object to support generic object hash with a moving gc

This commit is contained in:
hyunghwan.chung 2019-09-16 14:16:55 +00:00
parent a640650b67
commit ee9064bf8f
5 changed files with 58 additions and 45 deletions

View File

@ -640,7 +640,7 @@ int moo_ignite (moo_t* moo, moo_oow_t heapsz)
moo->_nil = moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t)); moo->_nil = moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t));
if (!moo->_nil) goto oops; if (!moo->_nil) goto oops;
moo->_nil->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 1, moo->igniting, 0, 0, 0); moo->_nil->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 1, moo->igniting, 0, 0, 0, 0);
moo->_nil->_size = 0; moo->_nil->_size = 0;
if (ignite_1(moo) <= -1 || ignite_2(moo) <= -1 || ignite_3(moo)) goto oops;; if (ignite_1(moo) <= -1 || ignite_2(moo) <= -1 || ignite_3(moo)) goto oops;;
@ -728,12 +728,10 @@ static void compact_symbol_table (moo_t* moo, moo_oop_t _nil)
static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop) static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop)
{ {
moo_oow_t nbytes_aligned; moo_oow_t nbytes;
if (MOO_OBJ_GET_FLAGS_TRAILER(oop)) if (MOO_OBJ_GET_FLAGS_TRAILER(oop))
{ {
moo_oow_t nbytes;
/* only an OOP object can have the trailer. /* only an OOP object can have the trailer.
* *
* | _flags | * | _flags |
@ -751,15 +749,17 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop)
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(oop) == 0); /* no 'extra' for an OOP object */ MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(oop) == 0); /* no 'extra' for an OOP object */
nbytes = MOO_OBJ_BYTESOF(oop) + MOO_SIZEOF(moo_oow_t) + MOO_OBJ_GET_TRAILER_SIZE(oop); nbytes = MOO_OBJ_BYTESOF(oop) + MOO_SIZEOF(moo_oow_t) + MOO_OBJ_GET_TRAILER_SIZE(oop);
nbytes_aligned = MOO_ALIGN (nbytes, MOO_SIZEOF(moo_oop_t));
} }
else else
{ {
/* calculate the payload size in bytes */ /* calculate the payload size in bytes */
nbytes_aligned = MOO_ALIGN(MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t)); nbytes = MOO_OBJ_BYTESOF(oop);
} }
return nbytes_aligned; if (MOO_OBJ_GET_FLAGS_HASH(oop) == 2) nbytes += MOO_SIZEOF(moo_oow_t);
return MOO_ALIGN(nbytes, MOO_SIZEOF(moo_oop_t));
} }
moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop) moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop)
@ -828,6 +828,16 @@ static moo_uint8_t* scan_heap_space (moo_t* moo, moo_uint8_t* ptr, moo_uint8_t**
nbytes_aligned = get_payload_bytes(moo, oop); nbytes_aligned = get_payload_bytes(moo, oop);
/*
if (MOO_OBJ_GET_HASH_FLAGS(oop) == 1)
{
TODO: use the unaligned bytes and align after this addition
nbytes_aligned += MOO_SIZEOF(moo_oow_t);
change the hash flags to 2.
store the existing address to the extra hash field
}
*/
tmp = moo_moveoop(moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop)); tmp = moo_moveoop(moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop));
MOO_OBJ_SET_CLASS (oop, tmp); MOO_OBJ_SET_CLASS (oop, tmp);
@ -1096,28 +1106,13 @@ moo_oop_t moo_shallowcopy (moo_t* moo, moo_oop_t oop)
{ {
if (MOO_OOP_IS_POINTER(oop) && MOO_OBJ_GET_CLASS(oop) != moo->_symbol) if (MOO_OOP_IS_POINTER(oop) && MOO_OBJ_GET_CLASS(oop) != moo->_symbol)
{ {
#if 0
moo_oop_t z;
moo_oop_class_t c;
c = MOO_OBJ_GET_CLASS(oop);
moo_pushvolat (moo, &oop);
z = moo_instantiate(moo, (moo_oop_t)c, MOO_NULL, MOO_OBJ_GET_SIZE(oop) - MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(c->spec)));
moo_popvolat(moo);
if (!z) return z;
/* copy the payload */
MOO_MEMCPY (z + 1, oop + 1, get_payload_bytes(moo, oop));
MOO_OBJ_SET_FLAGS_RDONLY (z, 0); /* a copied object is not read-only */
return z;
#else
moo_oop_t z; moo_oop_t z;
moo_oow_t total_bytes; moo_oow_t total_bytes;
total_bytes = MOO_SIZEOF(moo_obj_t) + get_payload_bytes(moo, oop); total_bytes = MOO_SIZEOF(moo_obj_t) + get_payload_bytes(moo, oop);
/* TODO: exclude trailer and hash space? exclde hash space at least? */
moo_pushvolat (moo, &oop); moo_pushvolat (moo, &oop);
z = (moo_oop_t)moo_allocbytes(moo, total_bytes); z = (moo_oop_t)moo_allocbytes(moo, total_bytes);
moo_popvolat(moo); moo_popvolat(moo);
@ -1125,14 +1120,12 @@ moo_oop_t moo_shallowcopy (moo_t* moo, moo_oop_t oop)
MOO_MEMCPY (z, oop, total_bytes); MOO_MEMCPY (z, oop, total_bytes);
MOO_OBJ_SET_FLAGS_RDONLY (z, 0); /* a copied object is not read-only */ MOO_OBJ_SET_FLAGS_RDONLY (z, 0); /* a copied object is not read-only */
return z; return z;
#endif
} }
return oop; return oop;
} }
int moo_regfinalizable (moo_t* moo, moo_oop_t oop) int moo_regfinalizable (moo_t* moo, moo_oop_t oop)
{ {
moo_finalizable_t* x; moo_finalizable_t* x;

View File

@ -969,7 +969,22 @@ int moo_setclasstrsize (moo_t* moo, moo_oop_class_t _class, moo_oow_t size, moo_
moo_oow_t spec; moo_oow_t spec;
MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class); MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class);
MOO_ASSERT (moo, size <= MOO_SMOOI_MAX); /*MOO_ASSERT (moo, size <= MOO_SMOOI_MAX);
MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(trgc));*/
if (size > MOO_SMOOI_MAX)
{
moo_seterrbfmt (moo, MOO_EINVAL, "trailer size %zu too large for the %.*js class",
size, MOO_OBJ_GET_SIZE(_class->name), MOO_OBJ_GET_CHAR_SLOT(_class->name));
return -1;
}
if (!MOO_IN_SMPTR_RANGE(trgc))
{
moo_seterrbfmt (moo, MOO_EINVAL, "trailer gc pointer %p not SMPTR compatible for the %.*js class",
trgc, MOO_OBJ_GET_SIZE(_class->name), MOO_OBJ_GET_CHAR_SLOT(_class->name));
return -1;
}
if (_class == moo->_method) if (_class == moo->_method)
{ {

View File

@ -300,6 +300,7 @@ typedef enum moo_gcfin_t moo_gcfin_t;
#define MOO_OBJ_FLAGS_RDONLY_BITS 1 #define MOO_OBJ_FLAGS_RDONLY_BITS 1
#define MOO_OBJ_FLAGS_GCFIN_BITS 4 #define MOO_OBJ_FLAGS_GCFIN_BITS 4
#define MOO_OBJ_FLAGS_TRAILER_BITS 1 #define MOO_OBJ_FLAGS_TRAILER_BITS 1
#define MOO_OBJ_FLAGS_HASH_BITS 2
#define MOO_OBJ_FLAGS_TYPE_SHIFT (MOO_OBJ_FLAGS_UNIT_BITS + MOO_OBJ_FLAGS_UNIT_SHIFT) #define MOO_OBJ_FLAGS_TYPE_SHIFT (MOO_OBJ_FLAGS_UNIT_BITS + MOO_OBJ_FLAGS_UNIT_SHIFT)
#define MOO_OBJ_FLAGS_UNIT_SHIFT (MOO_OBJ_FLAGS_EXTRA_BITS + MOO_OBJ_FLAGS_EXTRA_SHIFT) #define MOO_OBJ_FLAGS_UNIT_SHIFT (MOO_OBJ_FLAGS_EXTRA_BITS + MOO_OBJ_FLAGS_EXTRA_SHIFT)
@ -310,7 +311,8 @@ typedef enum moo_gcfin_t moo_gcfin_t;
#define MOO_OBJ_FLAGS_PROC_SHIFT (MOO_OBJ_FLAGS_RDONLY_BITS + MOO_OBJ_FLAGS_RDONLY_SHIFT) #define MOO_OBJ_FLAGS_PROC_SHIFT (MOO_OBJ_FLAGS_RDONLY_BITS + MOO_OBJ_FLAGS_RDONLY_SHIFT)
#define MOO_OBJ_FLAGS_RDONLY_SHIFT (MOO_OBJ_FLAGS_GCFIN_BITS + MOO_OBJ_FLAGS_GCFIN_SHIFT) #define MOO_OBJ_FLAGS_RDONLY_SHIFT (MOO_OBJ_FLAGS_GCFIN_BITS + MOO_OBJ_FLAGS_GCFIN_SHIFT)
#define MOO_OBJ_FLAGS_GCFIN_SHIFT (MOO_OBJ_FLAGS_TRAILER_BITS + MOO_OBJ_FLAGS_TRAILER_SHIFT) #define MOO_OBJ_FLAGS_GCFIN_SHIFT (MOO_OBJ_FLAGS_TRAILER_BITS + MOO_OBJ_FLAGS_TRAILER_SHIFT)
#define MOO_OBJ_FLAGS_TRAILER_SHIFT (0) #define MOO_OBJ_FLAGS_TRAILER_SHIFT (MOO_OBJ_FLAGS_HASH_BITS + MOO_OBJ_FLAGS_HASH_SHIFT)
#define MOO_OBJ_FLAGS_HASH_SHIFT (0)
#define MOO_OBJ_GET_FLAGS_TYPE(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS) #define MOO_OBJ_GET_FLAGS_TYPE(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS)
#define MOO_OBJ_GET_FLAGS_UNIT(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS) #define MOO_OBJ_GET_FLAGS_UNIT(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS)
@ -322,6 +324,7 @@ typedef enum moo_gcfin_t moo_gcfin_t;
#define MOO_OBJ_GET_FLAGS_RDONLY(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS) #define MOO_OBJ_GET_FLAGS_RDONLY(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS)
#define MOO_OBJ_GET_FLAGS_GCFIN(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS) #define MOO_OBJ_GET_FLAGS_GCFIN(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS)
#define MOO_OBJ_GET_FLAGS_TRAILER(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS) #define MOO_OBJ_GET_FLAGS_TRAILER(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS)
#define MOO_OBJ_GET_FLAGS_HASH(oop) MOO_GETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_HASH_SHIFT, MOO_OBJ_FLAGS_HASH_BITS)
#define MOO_OBJ_SET_FLAGS_TYPE(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS, v) #define MOO_OBJ_SET_FLAGS_TYPE(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TYPE_SHIFT, MOO_OBJ_FLAGS_TYPE_BITS, v)
#define MOO_OBJ_SET_FLAGS_UNIT(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS, v) #define MOO_OBJ_SET_FLAGS_UNIT(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_UNIT_SHIFT, MOO_OBJ_FLAGS_UNIT_BITS, v)
@ -333,6 +336,7 @@ typedef enum moo_gcfin_t moo_gcfin_t;
#define MOO_OBJ_SET_FLAGS_RDONLY(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS, v) #define MOO_OBJ_SET_FLAGS_RDONLY(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_RDONLY_SHIFT, MOO_OBJ_FLAGS_RDONLY_BITS, v)
#define MOO_OBJ_SET_FLAGS_GCFIN(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS, v) #define MOO_OBJ_SET_FLAGS_GCFIN(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_GCFIN_SHIFT, MOO_OBJ_FLAGS_GCFIN_BITS, v)
#define MOO_OBJ_SET_FLAGS_TRAILER(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS, v) #define MOO_OBJ_SET_FLAGS_TRAILER(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS, v)
#define MOO_OBJ_SET_FLAGS_HASH(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_HASH_SHIFT, MOO_OBJ_FLAGS_HASH_BITS, v)
#define MOO_OBJ_GET_SIZE(oop) ((oop)->_size) #define MOO_OBJ_GET_SIZE(oop) ((oop)->_size)
#define MOO_OBJ_GET_CLASS(oop) ((moo_oop_class_t)((oop)->_class)) #define MOO_OBJ_GET_CLASS(oop) ((moo_oop_class_t)((oop)->_class))
@ -353,15 +357,16 @@ typedef enum moo_gcfin_t moo_gcfin_t;
/* [NOTE] this macro doesn't check the range of the actual value. /* [NOTE] this macro doesn't check the range of the actual value.
* make sure that the value of each bit fields given falls within the * make sure that the value of each bit fields given falls within the
* possible range of the defined bits */ * possible range of the defined bits */
#define MOO_OBJ_MAKE_FLAGS(t,u,e,k,p,m,g,r) ( \ #define MOO_OBJ_MAKE_FLAGS(_ty,_u,_e,_k,_p,_m,_g,_tr,_h) ( \
(((moo_oow_t)(t)) << MOO_OBJ_FLAGS_TYPE_SHIFT) | \ (((moo_oow_t)(_ty)) << MOO_OBJ_FLAGS_TYPE_SHIFT) | \
(((moo_oow_t)(u)) << MOO_OBJ_FLAGS_UNIT_SHIFT) | \ (((moo_oow_t)(_u)) << MOO_OBJ_FLAGS_UNIT_SHIFT) | \
(((moo_oow_t)(e)) << MOO_OBJ_FLAGS_EXTRA_SHIFT) | \ (((moo_oow_t)(_e)) << MOO_OBJ_FLAGS_EXTRA_SHIFT) | \
(((moo_oow_t)(k)) << MOO_OBJ_FLAGS_KERNEL_SHIFT) | \ (((moo_oow_t)(_k)) << MOO_OBJ_FLAGS_KERNEL_SHIFT) | \
(((moo_oow_t)(p)) << MOO_OBJ_FLAGS_PERM_SHIFT) | \ (((moo_oow_t)(_p)) << MOO_OBJ_FLAGS_PERM_SHIFT) | \
(((moo_oow_t)(m)) << MOO_OBJ_FLAGS_MOVED_SHIFT) | \ (((moo_oow_t)(_m)) << MOO_OBJ_FLAGS_MOVED_SHIFT) | \
(((moo_oow_t)(g)) << MOO_OBJ_FLAGS_PROC_SHIFT) | \ (((moo_oow_t)(_g)) << MOO_OBJ_FLAGS_PROC_SHIFT) | \
(((moo_oow_t)(r)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) \ (((moo_oow_t)(_tr)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) | \
(((moo_oow_t)(_h)) << MOO_OBJ_FLAGS_HASH_SHIFT) \
) )
#define MOO_OBJ_FLAGS_KERNEL_USER 0 #define MOO_OBJ_FLAGS_KERNEL_USER 0

View File

@ -76,7 +76,7 @@ moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size)
hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned);
if (!hdr) return MOO_NULL; if (!hdr) return MOO_NULL;
hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 0); hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 0, 0);
MOO_OBJ_SET_SIZE (hdr, size); MOO_OBJ_SET_SIZE (hdr, size);
MOO_OBJ_SET_CLASS (hdr, moo->_nil); MOO_OBJ_SET_CLASS (hdr, moo->_nil);
@ -102,7 +102,7 @@ moo_oop_t moo_allocoopobjwithtrailer (moo_t* moo, moo_oow_t size, const moo_oob_
hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); hdr = (moo_oop_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned);
if (!hdr) return MOO_NULL; if (!hdr) return MOO_NULL;
hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 1); /* TRAILER bit -> 1 */ hdr->_flags = MOO_OBJ_MAKE_FLAGS(MOO_OBJ_TYPE_OOP, MOO_SIZEOF(moo_oop_t), 0, 0, moo->igniting, 0, 0, 1, 0); /* TRAILER bit -> 1 */
MOO_OBJ_SET_SIZE (hdr, size); MOO_OBJ_SET_SIZE (hdr, size);
MOO_OBJ_SET_CLASS (hdr, moo->_nil); MOO_OBJ_SET_CLASS (hdr, moo->_nil);
@ -149,7 +149,7 @@ static MOO_INLINE moo_oop_t alloc_numeric_array (moo_t* moo, const void* ptr, mo
hdr = (moo_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned); hdr = (moo_oop_t)moo_allocbytes(moo, MOO_SIZEOF(moo_obj_t) + nbytes_aligned);
if (!hdr) return MOO_NULL; if (!hdr) return MOO_NULL;
hdr->_flags = MOO_OBJ_MAKE_FLAGS(type, unit, extra, 0, moo->igniting, 0, 0, 0); /* TODO: review. ngc and perm flags seems to conflict with each other ... the diff is that ngc is malloc() and perm is allocated in the perm heap */ hdr->_flags = MOO_OBJ_MAKE_FLAGS(type, unit, extra, 0, moo->igniting, 0, 0, 0, 0); /* TODO: review. ngc and perm flags seems to conflict with each other ... the diff is that ngc is malloc() and perm is allocated in the perm heap */
hdr->_size = len; hdr->_size = len;
MOO_OBJ_SET_SIZE (hdr, len); MOO_OBJ_SET_SIZE (hdr, len);
MOO_OBJ_SET_CLASS (hdr, moo->_nil); MOO_OBJ_SET_CLASS (hdr, moo->_nil);

View File

@ -223,7 +223,7 @@ moo_pfrc_t moo_pf_basic_new (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize)) if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize))
{ {
obj = moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize)); obj = moo_instantiatewithtrailer(moo, _class, size, MOO_NULL, MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize));
} }
else else
{ {