On Mon, Aug 4, 2014 at 2:42 AM, Nick Wellnhofer <[email protected]> wrote:
> OK, then let's discuss the immortal flag.
>
> To protect against refcount races on the Perl side, objects are shared using
> SvSHARE, right? So if a host object is created and the immortal flag is set,
> it could be shared automatically. This eliminates the need to override
> To_Host.
>
> To set the immortal flag, a simple function like Obj_make_immortal would be
> enough. This should be called immediately after object creation. We wouldn't
> even need a flag but only a special value like -1 in ref.count.
>
> Shouldn't be hard to implement.
Using a special value in `ref.count` such as -1 prevents us from caching a
host object in `ref.host_obj` and thus has the consequence that a Clownfish
object may be associated with multiple Perl objects during the course of its
lifetime. That means we need to account for the fact that the Perl-space
DESTROY may be called an arbitrary number of times for a given Clownfish
object.
For various reasons (including incompatibility with inside-out member vars),
modern Clownfish avoids this pattern and tries to ensure that only a single
Perl object is ever associated with a Clownfish object during its lifetime --
but let's imagine breaking that discipline for the sake of argument.
For Class, all of whose instances are immortal, we could override Perl-space
DESTROY to do nothing. (This would preclude using inside-out member vars with
Class, but it isn't designed to be subclassed so that's not a deal-killer.)
But for String, we can't do that -- so what would it mean to call
`Obj_make_immortal(klass->name)`?
What I'd like Obj_make_immortal() to do is cache a host object and set an
"immortal" flag on *that*, yielding the behavior that Perl exhibits with
regards to SVs which are SvIMMORTAL.
http://perl5.git.perl.org/perl.git/blob/dee28d0dbca2d9719243e3e17392dcd12d011104:/sv.c#l6615
Unfortunately, `SvIMMORTAL` (which is not public) isn't a flag -- membership is
limited to a whitelist of Perl-internal SVs.
http://perl5.git.perl.org/perl.git/blob/dee28d0dbca2d9719243e3e17392dcd12d011104:/sv.h#l2101
So what I'm left with is the unsatisfying suggestion that Obj_make_immortal()
be implemented in Perl by caching a host object and setting its refcount to
half of the maximum. In the absence of additional refcounting bugs, that
yields immortality in practice. But if there are refcounting bugs, the
failure mode is bad: only long-running processes would be affected, making it
hard to reproduce.
Marvin Humphrey