I have some questions and suggestions regarding PMCs, Buffers and memory
management/internal data structures.
First and foremost, is there any compelling reason, to have totally
different structures for PMCs and Buffers?
- Both have a ->data aka ->bufstart
- Both have ->flags, that have vastly the same meaning.
This separation means two different routines for marking in DOD,
separated allocation and so on - a lot of code duplication, which
is IMHO not necessary.
Finally they are both SmallObjects and handled as these in the deep
inyards of arenas.
DOD considerations
We have currently:
- buffer_lives -> BUFFER_live_FLAG
- mark_used -> PMC_live_flag + next_for_GC
If PMC and Buffers are unified, it should be possible to mark them in
one recursive process:
mark(buffer) {
if (life_flag) // already done
return
set life_flag
if (buffer_is_buffer_ptr)
mark(buffer->data)
else if(buffer_is_array_of_buffers)
mark(...) for (buffer->data[..])
else if(has_custom_mark)
((PMC*)buffer)->vtable->mark()
}
Above mark routined called for each register/stack entry/whatever,
where now PMCs & Buffers are marked, should catch _all_ entries. No need
for next_for_GC, 2 different subroutines and a second pass for PMCs.
I propose to unify these structure, i.e. make PMC a buffer_like
structure, unify the flags, and treat them vastly the same.
2)
What is PMCs member:
SYNC *synchronize; /* undocumented + unused */
3)
What are: arena_base->extra_buffer_headers;
4)
Is there any deeper reason that the sized_small_object pool allocates
unused slots for intermediate object sizes?
Finally, if we ever have multiple interpreters, which can be built
dynamically, _all_ structures including the interpreter itself and
it's internal data structures should have to be derived from a Buffer
object (or have to manage there own destroy method). If not, these
interpreters will leak memory like the current one, and this is more
then a bunch of sieves.
Comments welcome,
leo