develooper Front page | perl.perl5.porters | Postings from June 2003

Re: op_seq (was: Freeing code)

Thread Previous | Thread Next
Paul Johnson
June 20, 2003 12:11
Re: op_seq (was: Freeing code)
Message ID:
Stephen McCamant said:
>>>>>> "RG-S" == Rafael Garcia-Suarez <> writes:
> RG-S> op_seq seems to be used only as a flag : "has this OP been
> RG-S> optimized by now"
> ...
> RG-S> So we could theorically replace op_seq by two boolean flags, as
> RG-S> far as the core and the bytecode compiler backend are concerned.
> PJ> I use it in Devel::Cover in conjunction with the address of the op
> PJ> in order to (almost) uniquely identify the op.  Without this when
> PJ> ops get freed and the address is reused they cannot be told apart.
> PJ> I believe that Devel::Dprof also suffers from this problem, though
> PJ> maybe there is a better solution.
> I wonder how well a <address, checksum of all the OP's fields> pair
> would work. Not perfectly, in theory, but neither does op_seq, in
> theory, because of wrap-around.
> RG-S> B::Concise also uses it to identify ops.
> B::Concise's use could be replaced, though, and it would probably be a
> net improvement. We could just make another pass, and fill in a hash
> table mapping OP addresses to sequence numbers of our own devising (or
> <address, checksum> pairs, if it's important for B::Concise's output
> to be consistent over time as OPs are reallocated, which doesn't
> happen much in my use of it). This would avoid the ugly hack that we
> currently have to do to find the base of the sequence numbers we're
> using.
> If someone is feeling a bit ambitious, I think replacing op_seq with a
> few flags could be a significant win. Assuming it's only 2 bits, and
> recalling that op_type only needs 9 bits, I think we could squeeze
> op_type, op_seq, op_flags and op_private into 32 bits with some space
> left over. Assuming fields are naturally aligned, I think this would
> save a word per OP on most platforms, and OP flags are a high-demand
> resource it would be nice to have more of.

Here's a trivial patch which merges the op_type and the op_seq into 16
bits.  I've attached it too, but it's not for application in bleadperl
as is.

*** op.h.orig	Sat Jun  1 19:03:34 2002
--- op.h	Thu Jun 19 16:03:29 2003
*** 46,53 ****
      OP*		op_sibling;		\
      OP*		(CPERLscope(*op_ppaddr))(pTHX);		\
      PADOFFSET	op_targ;		\
!     OPCODE	op_type;		\
!     U16		op_seq;			\
      U8		op_flags;		\
      U8		op_private;
--- 46,53 ----
      OP*		op_sibling;		\
      OP*		(CPERLscope(*op_ppaddr))(pTHX);		\
      PADOFFSET	op_targ;		\
!     unsigned	op_type:9;		\
!     unsigned	op_seq:7;		\
      U8		op_flags;		\
      U8		op_private;

I've tested it on bleadperl on Linux i686 and all tests pass except for
a couple in File::Find.  I've not looked into that yet.  I've also
tested it on 5.8.0 on Solaris 2.8, where all tests pass except for
B::Concise, which is not surprising.  Both builds were with gcc 3.x.

I tested its effectiveness with the following program:

    $u = shift;

    for (1 .. $u)
        eval "sub s$_ { $_ + \$x++ }"

    for (1 .. $u)
        $t += &{"s$_"};

    print "$t\n";

    system "ps -el | grep $$";
    system "pmap -x $$";

On my Linux box the patch seemed to see a reduction of a little over 1%
in memory usage.  There was a smaller reduction on the Solaris box, but
it is less powerful and I ran a smaller test there.  Of course, the
change in memory usage is dependent on the number of ops allocated.

On Linux the differences in execution time were noise.  My Solaris box
was too heavily loaded to make a meaningful comparison.

So, my question is whether doing something like this has any downsides.
I'd be interested to know whether there are similar improvements in
memory usage on other architectures and compilers, and perhaps more
importantly whether there are any slowdowns.

If this looks like a plausible way forward then there are at least a
couple of other bits of code which will need to be altered (assumptions
about 16 bits).  The second part of the exercise will then be to turn
op_seq into two bits, and change any code which is looking for a number
there to do something else (which should probably be done anyway).  This
will then give us five spare bits per op with which we can do new and
exciting things.

Paul Johnson -

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About