John Tobey <[EMAIL PROTECTED]> writes:
>Nick Ing-Simmons <[EMAIL PROTECTED]> wrote:
>> John Tobey <[EMAIL PROTECTED]> writes:
>> >Dan Sugalski <[EMAIL PROTECTED]> wrote:
>> >> Yup, and I realized one of my big problems to GCs that move memory
>> >> (references that are pointers and such) really isn't, if we keep the
>> >> two-level variable structure that we have now. The 'main' SV structure
>> >> won't move, while the guts that the equivalent of sv_any points to can
>> >> without a problem.
>> >
>> >I certainly hope this data layout factoid is still subject to change.
>>
>> Having an SV have a fixed address is handy for C extensions.
>> The 'entity' has got to have some 'handle' to defines its existance.
>> If not the SV* data structure then what is it that defines the thing?
>
>Just like in Perl, if you want a reference to it, put it somewhere and
>use a pointer. Otherwise, use it by value. (three words, or two if
>flags are dropped, or four if vptr is added, or one if everything is
>crammed into a pointer with low bits commandeered).
So what exactly is your point here ?
We currently (perl5) have the "token" being:
struct sv {
void* sv_any; /* pointer to something */
U32 sv_refcnt; /* how many references to us */
U32 sv_flags; /* what we are */
};
3 words (which is a "funny" number in a binary world.
(With the type hiding in flags as a small int.)
Current perl6 "token" proposed by RFC 35 is:
struct {
IV GC_data; // REFCNT
void *variable_data; // sv_any, possibly used for IV, RV
IV flags; // sv_flags
vtable_t *vtable; // _new_ - explcit type
void *sync_data; // _new_ - for threads etc.
}
5 words (which is if anything a slighty worse number...)
I think I would make it 4 or 8 words:
struct {
vtable_t *vtable; // _new_ - explcit type
IV flags_and_GC; // sv_flags
void *sync_data; // _new_ - for threads etc.
void *variable_data; // sv_any, possibly used for IV, RV
}
That squeezes flags and GC into a word - no big deal for 'mark' bit
but if we have a REFCNT it had better be 8 or 16 bits or update will
be too many cycles.
So my own favourite right now allows a little more - to keep data and token
together for cache, and to avoid extra malloc() in simple cases.
Some variant like:
struct {
vtable_t *vtable; // _new_ - explcit type
IV flags; // sv_flags
void *sync_data; // _new_ - for threads etc.
IV GC_data; // REFCNT
void *ptr; // SvPV, SvRV
IV iv; // SvIV, SvCUR/SvOFF
NV nv; // SvNV
}
The other extreme might be just a pointer with LS 3 bits snaffled for
"mark" and two "vital" flags - but that just means above lives via the
pointer and everything is one more de-ref away _AND_ needs masking
except for "all flags zero" case (which had better be the common one).
As I recall my LISP it has two pointers + flags
--
Nick Ing-Simmons