diff --git a/libgst/dict.inl b/libgst/dict.inl index 29cee4d..87deff6 100644 --- a/libgst/dict.inl +++ b/libgst/dict.inl @@ -132,6 +132,33 @@ static inline gst_object new_instance (OOP class_oop, any variance in size (such as a string that's shorter than a word boundary). */ static inline gst_object +instantiate_numbytes_from_space (gst_object (*func) (size_t, OOP *), + OOP class_oop, + OOP *p_oop, + intptr_t instanceSpec, + size_t numBytes); + +/* Returns a new, initialized instance of CLASS_OOP with + NUMINDEXFIELDS indexable fields. If the instance contains + pointers, they are initialized to _gst_nil_oop, else they are set + to the SmallInteger 0. The pointer to the object data is returned, + the OOP is stored in P_OOP. The OOP is adjusted to reflect any + variance in size (such as a string that's shorter than a word + boundary). */ +static inline gst_object +instantiate_with_from_space (gst_object (*func) (size_t, OOP *), + OOP class_oop, + size_t numIndexFields, + OOP *p_oop); + +/* Returns a new, initialized instance of CLASS_OOP within an + object of size NUMBYTES. INSTANCESPEC is used to find the + number of fixed instance variables and initialize them to + _gst_nil_oop. The pointer to the object data is returned, + the OOP is stored in P_OOP. The OOP is not adjusted to reflect + any variance in size (such as a string that's shorter than a word + boundary). */ +static inline gst_object instantiate_numbytes (OOP class_oop, OOP *p_oop, intptr_t instanceSpec, @@ -156,6 +183,25 @@ static inline gst_object instantiate_with (OOP class_oop, static inline gst_object instantiate (OOP class_oop, OOP *p_oop); +/* Create and return a new instance of class CLASS_OOP. CLASS_OOP + must be a class with no indexable fields. The named instance + variables of the new instance are initialized to _gst_nil_oop, + since fixed-field-only objects can only have pointers. The pointer + to the object data is returned, the OOP is stored in P_OOP. */ +static inline gst_object instantiate_fixed (OOP class_oop, + OOP *p_oop); + +/* Returns a new, initialized instance of CLASS_OOP with + NUMINDEXFIELDS indexable fields. If the instance contains + pointers, they are initialized to _gst_nil_oop, else they are set + to the SmallInteger 0. The pointer to the object data is returned, + the OOP is stored in P_OOP. The OOP is adjusted to reflect any + variance in size (such as a string that's shorter than a word + boundary). */ +static inline gst_object instantiate_fixed_with (OOP class_oop, + size_t numIndexFields, + OOP *p_oop); + /* Return the Character object for the Unicode value C. */ static inline OOP char_new (unsigned codePoint); @@ -711,10 +757,10 @@ new_instance (OOP class_oop, return p_instance; } - gst_object -instantiate_numbytes (OOP class_oop, - OOP *p_oop, +instantiate_numbytes_from_space (gst_object (*func) (size_t, OOP *), + OOP class_oop, + OOP *p_oop, intptr_t instanceSpec, size_t numBytes) { @@ -722,7 +768,7 @@ instantiate_numbytes (OOP class_oop, int n; OOP src, *dest; - p_instance = _gst_alloc_obj (numBytes, p_oop); + p_instance = func (numBytes, p_oop); p_instance->objClass = class_oop; (*p_oop)->flags |= (class_oop->flags & F_UNTRUSTED); @@ -753,9 +799,10 @@ instantiate_numbytes (OOP class_oop, } gst_object -instantiate_with (OOP class_oop, - size_t numIndexFields, - OOP *p_oop) +instantiate_with_from_space (gst_object (*func) (size_t, OOP *), + OOP class_oop, + size_t numIndexFields, + OOP *p_oop) { size_t numBytes, indexedBytes, alignedBytes; intptr_t instanceSpec; @@ -775,28 +822,46 @@ instantiate_with (OOP class_oop, if COMMON ((instanceSpec & ISP_INDEXEDVARS) == GST_ISP_POINTER) { - p_instance = _gst_alloc_obj (numBytes, p_oop); + p_instance = func (numBytes, p_oop); p_instance->objClass = class_oop; (*p_oop)->flags |= (class_oop->flags & F_UNTRUSTED); nil_fill (p_instance->data, - (instanceSpec >> ISP_NUMFIXEDFIELDS) + numIndexFields); + (instanceSpec >> ISP_NUMFIXEDFIELDS) + numIndexFields); } else { alignedBytes = ROUNDED_BYTES (numBytes); - p_instance = instantiate_numbytes (class_oop, + p_instance = instantiate_numbytes_from_space (func, + class_oop, p_oop, instanceSpec, alignedBytes); INIT_UNALIGNED_OBJECT (*p_oop, alignedBytes - numBytes); memset (&p_instance->data[instanceSpec >> ISP_NUMFIXEDFIELDS], 0, - indexedBytes); + indexedBytes); } return p_instance; } gst_object +instantiate_numbytes (OOP class_oop, + OOP *p_oop, + intptr_t instanceSpec, + size_t numBytes) +{ + return instantiate_numbytes_from_space (_gst_alloc_obj, class_oop, p_oop, instanceSpec, numBytes); +} + +gst_object +instantiate_with (OOP class_oop, + size_t numIndexFields, + OOP *p_oop) +{ + return instantiate_with_from_space (_gst_alloc_obj, class_oop, numIndexFields, p_oop); +} + +gst_object instantiate (OOP class_oop, OOP *p_oop) { @@ -810,6 +875,30 @@ instantiate (OOP class_oop, p_oop, instanceSpec, numBytes); } + +gst_object +instantiate_fixed (OOP class_oop, + OOP *p_oop) +{ + size_t numBytes; + intptr_t instanceSpec; + + instanceSpec = CLASS_INSTANCE_SPEC (class_oop); + numBytes = sizeof (gst_object_header) + + SIZE_TO_BYTES(instanceSpec >> ISP_NUMFIXEDFIELDS); + return instantiate_numbytes_from_space (_gst_alloc_fixed_obj, + class_oop, + p_oop, + instanceSpec, numBytes); +} + +gst_object +instantiate_fixed_with (OOP class_oop, + size_t numIndexFields, + OOP *p_oop) +{ + return instantiate_with_from_space (_gst_alloc_fixed_obj, class_oop, numIndexFields, p_oop); +} OOP * diff --git a/libgst/oop.c b/libgst/oop.c index ea52d4e..860cfd3 100644 --- a/libgst/oop.c +++ b/libgst/oop.c @@ -765,7 +765,7 @@ _gst_alloc_obj (size_t size, newAllocPtr = _gst_mem.eden.allocPtr + BYTES_TO_SIZE (size); if UNCOMMON (size >= _gst_mem.big_object_threshold) - return _gst_alloc_old_obj (size, p_oop); + return _gst_alloc_fixed_obj (size, p_oop); if UNCOMMON (newAllocPtr >= _gst_mem.eden.maxPtr) { @@ -782,25 +782,25 @@ _gst_alloc_obj (size_t size, } gst_object -_gst_alloc_old_obj (size_t size, +_gst_alloc_fixed_obj (size_t size, OOP *p_oop) { gst_object p_instance; size = ROUNDED_BYTES (size); - /* If the object is big enough, we put it directly in oldspace. */ - p_instance = (gst_object) _gst_mem_alloc (_gst_mem.old, size); + /* If the object is big enough, we put it directly in fixedspace. */ + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size); if COMMON (p_instance) goto ok; _gst_global_gc (size); - p_instance = (gst_object) _gst_mem_alloc (_gst_mem.old, size); + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size); if COMMON (p_instance) goto ok; _gst_compact (0); - p_instance = (gst_object) _gst_mem_alloc (_gst_mem.old, size); + p_instance = (gst_object) _gst_mem_alloc (_gst_mem.fixed, size); if UNCOMMON (!p_instance) { /* !!! do something more reasonable in the future */ @@ -809,7 +809,7 @@ _gst_alloc_old_obj (size_t size, } ok: - *p_oop = alloc_oop (p_instance, F_OLD); + *p_oop = alloc_oop (p_instance, F_FIXED | F_OLD); p_instance->objSize = FROM_INT (BYTES_TO_SIZE (size)); return p_instance; } diff --git a/libgst/oop.h b/libgst/oop.h index c20dfc3..f732d87 100644 --- a/libgst/oop.h +++ b/libgst/oop.h @@ -415,8 +415,8 @@ extern gst_object _gst_alloc_obj (size_t size, OOP *p_oop) ATTRIBUTE_HIDDEN; -/* The same, but for an oldspace object */ -extern gst_object _gst_alloc_old_obj (size_t size, +/* The same, but for an fixedspace object */ +extern gst_object _gst_alloc_fixed_obj (size_t size, OOP *p_oop) ATTRIBUTE_HIDDEN; diff --git a/libgst/prims.def b/libgst/prims.def index 131dc8c..60d764a 100644 --- a/libgst/prims.def +++ b/libgst/prims.def @@ -4564,8 +4564,7 @@ primitive VMpr_Behavior_basicNewFixed [succeed,fail] if (!CLASS_IS_INDEXABLE (oop1)) { OOP result; - instantiate (oop1, &result); - _gst_make_oop_fixed (result); + instantiate_fixed (oop1, &result); SET_STACKTOP (result); PRIM_SUCCEEDED; } @@ -4591,8 +4590,7 @@ primitive VMpr_Behavior_basicNewFixedColon [succeed,fail] if (arg2 >= 0) { OOP result; - instantiate_with (oop1, arg2, &result); - _gst_make_oop_fixed (result); + instantiate_fixed_with (oop1, arg2, &result); SET_STACKTOP (result); PRIM_SUCCEEDED; }