[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: tolua++ porting to 5.2
- From: Ross Bencina <rossb-lists@...>
- Date: Tue, 15 Jan 2013 14:49:59 +1100
On 15/01/2013 11:33 AM, Jay Carlson wrote:
The fix for this would involve C-side deallocation turning Lua-side
references into tombstones, and I don't see an obvious way to
implement tombstones other than something that works out to be Tim's
serial numbers.
How about this for an eager alternative to the counting thing. I haven't
tried this. I don't think it's better (aside from avoiding the page
fault issue). I'm mentioning it as a model to think about options:
Any pointer to a C object in Lua could be represented by a struct:
struct TrackedLuaCPointerNode{
TrackedLuaCPointer *next;
void *cobject; // pointer to c object
}
In C/C++ wrap/intercept the allocator so that there is a
TrackedLuaCPointerNode* stored just before the allocated C/C++ memory
region. This pointer is used as the head of a linked list of
TrackedLuaCPointerNodes that point to the region.
Use TrackedLuaCPointerNode to represent C/C++ pointers in Lua. Whenever
you want to create a new Lua pointer, the object pointer goes in
p.cobject and the TrackedLuaCPointerNode gets linked into the linked list.
When the C/C++ object memory region is beeing released, walk the linked
list:
- TrackedLuaCPointerNodes with non-NULL cobject fields are still
referenced in Lua. set cobject to NULL.
- TrackedLuaCPointerNodes with NULL cobject fields have already been
finalised in Lua. In this case free the TrackedLuaCPointerNode.
When Lua finalises a TrackedLuaCPointerNode:
- TrackedLuaCPointerNodes with non-NULL cobject fields are still
allocated in C, set cobject field to NULL.
- If cobject is NULL, free TrackedLuaCPointerNode.
This scheme will work whenever you can intercept the memory allocator
used for C/C++ objects (eg. overload operator new/delete). It assumes
C/C++ pointers are to the start of the allocation region: objectPointer
- sizeof(TrackedLuaCPointer*) will give a pointer to the linked list
head -- that's good because it means you can cheaply make a
TrackedLuaCPointerNode out of any pointer.
A similar scheme could be used intrusively with C++ objects or some kind
of smart pointer thing.
It could also be made to work with embedded subobjects (since deleting
the outer object deletes all fields, they could share a single linked
list) but you'd need a way to get the list head when making a new
TrackedLuaCPointerNode.
I've described it so that creating a pointer and finalising a pointer
are constant time operations at the cost of keeping the nodes around
until the C++ region is freed (and then an O(n) operation to free the
nodes). I can think of a way to make the release O(1) too using a
trampoline and an incremental reclamation list, but its more complicated.
Ross.