Front page | perl.perl5.porters |
Postings from July 2011
Re: Mutable constant-expression values
Thread Previous
|
Thread Next
From:
Nicholas Clark
Date:
July 23, 2011 03:58
Subject:
Re: Mutable constant-expression values
Message ID:
20110723105825.GD23881@plum.flirble.org
On Fri, Jul 22, 2011 at 02:02:43PM +0200, Aristotle Pagaltzis wrote:
> Something just occurred to me. In another thread I had an
> exchange with Chip, and we got to this point:
>
> * Reverend Chip <rev.chip@gmail.com> in <4E1E6E83.7030606@gmail.com> [2011-07-14 06:25]:
> > On 7/13/2011 5:35 PM, Aristotle Pagaltzis wrote:
> > > If you write ++${\10} that should yield 11 no matter how
> > > often you evaluate it. You should get a copy (or rather, via
> > > CoW, a potential copy) when you evaluate a constant....
> >
> > I appreciate the purity & consistency of this position, but I'm
> > not fond of it, because I foresee it costing a lot of
> > performance for absolutely no practical gain. Its only payoff
> > is ideological bragging rights, which don't motivate me.
>
> But now that I think of it, not only does this need no CoW, it
> should not even cost any performance at all (even without CoW!).
> After all, throwing ???Modification of a read-only value attempted???
> already requires a check. The only thing that would have to be
> done to implement the above change is to change most instances
> of `Perl_croak_no_modify` to check for a real constant and make
> a mutable copy of the value to operate on and return instead of
> always throwing the error.
>
> I.e. constants would be copied to a mutable SV at the point in
> time at which someone attempts to mutate them. The impact (and
> performance hit) on all other operations would be *zero*.
>
> Am I missing anything here? Is that all? (Conceptually speaking.
> The implementation would take some work.)
One can't do it trivially that way without breaking existing semantics.
Internally, scalars are passed around as (RVALUE) pointers to (LVALUE)
SV structures. Effectively, at the C level, everything is a form of
reference, and C code has to work on the scalar in place.
Currently the C code croaks if what is has been passed is read-only.
If one wanted to change to the C code to on-demand create a new read-write
copy of a read-only value, then every function would have to have a way to
return a new SV * address of each of its operand that "moved".
If instead one wanted to keep the current C APIs, and replace the "croak on
read only" check with a "cheap COW copy of the value", keeping the same
SV * address, then one would have to change how constants are put onto the
Perl stack. Currently the address of the SV stored in the optree (1 pointer)
is placed on the Perl stack, without any refcounting:
PP(pp_const)
{
dVAR;
dSP;
XPUSHs(cSVOP_sv);
RETURN;
}
To allow mutation, even by copy-on-write, then the above code would have to
change to allocate a new SV * (each time), which would be quite a performance
hit, given that each newly allocated SV would also have to be stored on the
mortal stack to ensure that it was cleaned up at the end of the statement.
Nicholas Clark
Thread Previous
|
Thread Next