Open GWRon opened 1 year ago
It seems not many modules use this code but it seems some could use it!
Eg. Brl.MaxLua/lua_object.c has this code:
struct BBObjectContainer {
BBObject * o;
};
void lua_boxobject( lua_State *L,BBObject *obj ){
void *p;
struct BBObjectContainer * uc = (struct BBObjectContainer *)GC_MALLOC_UNCOLLECTABLE(sizeof(struct BBObjectContainer));
uc->o = obj;
p=lua_newuserdata( L, sizeof(struct BBObjectContainer) );
*(struct BBObjectContainer**)p=uc;
}
Means it wraps a container around an exposed object. This container was maybe introduced before NG. (see edit)
It is no longer needed. We might simply "BBRetain(obj)":
void lua_boxobject( lua_State *L,BBObject *obj ){
BBRETAIN(obj);
void *p;
p=lua_newuserdata( L, sizeof(BBObject) );
*(BBObject**)p = obj;
}
While this change would get rid of the "in all cases" kept GC_MALLOC_UNCOLLECTABLE
it would at least temporary affect the GC even if in most cases not needed (exposing existing BlitzMax objects VS passing new and nowhere referenced BlitzMax objects).
Edit: Seems @woollybah exactly did the opposite already there: https://github.com/bmx-ng/brl.mod/commit/badcdc0582cfb845b14a510c26408e98114802ee
Maybe you (@woollybah ) could explain to me why this was needed?
The same "allocate but free if already existing" thing can be seen in brl.map/map.c
void bmx_map_intmap_insert( int key, BBObject *value, struct avl_root ** root ) {
struct intmap_node * node = (struct intmap_node *)GC_malloc_uncollectable(sizeof(struct intmap_node));
node->key = key;
node->value = value;
struct intmap_node * old_node = (struct intmap_node *)avl_map(&node->link, compare_intmap_nodes, root);
if (&node->link != &old_node->link) {
// key already exists. Store the value in this node.
old_node->value = value;
// delete the new node, since we don't need it
GC_FREE(node);
}
}
so any duplicated insert allocated gc managed memory - and frees it.
While looking at the GC stuff-code I saw this in blitz.mod/blitz_gc.c:
And I wondered, why we allocate GC managed memory even if we later find out, that we might not need the new "node" as there was already something referencing it.
Now compare this to bbGCRelease():
There we do NOT affect the GC just to allow the lookup.
As creating the "simple" struct might be less heavy .. isn't it possible to only call the GC stuff if really needed?
Edit: It seems to be made for "C(++) code" which wants to mark specific objects as "to keep". So it might only be used rarely (yet it could be ... redone avoiding GC affection)