I'm writing a simple language to embody the concept of copy-on-write, and
so that I can learn how to implement it.  The language is called COW and
it's at

  http://japhy.perlmonk.org/COW/

Ben Tilly suggested I contact the Perl6 Internals folk and let you know
that this is an important feature that we should try to incorporate into
Perl 6.  The main reason I bring this up is because I am a regex fanatic,
and I hate that damned $& poison.

  $_ = "_" x 100_000;
  while (/./g) {  }  # runs fast

But then...!

  1 if $&;  # ooh, I just set PL_sawampersand, a hideous global flag!
  $_ = "_" x 100_000;
  while (/./g) { ... }  # runs real REAL slow

The reason the second code is slow is because PL_sawampersand being TRUE
makes the regex engine COPY THE STRING it is matched against, so it can
provide $`, $&, and $'.

COPYING 100,000 byte strings SUCKS.

If PL_sawampersand is FALSE, the string is not copied, but a pointer to it
is used.  This is "dangerous", but since PL_sawampersand is FALSE, it
"should" be "safe".  Now I'll make it unsafe:

  $_ = "japhy";
  /../;
  $_ = "tilly";
  eval q{ print $& };  # ooh, eval '' hides the $& from compile-time!

That prints "ti" instead of "ja", due to the use of pointers.  We're lucky
the pointer was still valid. :/

So what's copy-on-write?  Basically, it's the use of a pointer until that
use becomes unsafe.

  # COW code -- you might need to read the
  # cow.pod documentation to fully grok this

  # v_strncpy(dst,src,len) ABSOLUTELY copies
  # len bytes from src to dst, regardless of
  # null bytes

  x = "japhy";  # v_strncpy(SvSTR(sv_x), "japhy", 5)

  y = cow x;    # this does a lot of stuff...
                # SvCOW_on(sv_x)                # copy-on-write
                # SvDEPa(sv_x, sv_y)            # add a dependent
                #
                # SvMAGIC_on(sv_y)              # y is magical
                # SvMGs(sv_y, MGt_COW, sv_x)    # type=COW, obj=sv_x
                # SvSTR(sv_y) = SvSTR(sv_x)     # use of a pointer

  print y;      # access SvSTR(y) which is a pointer to SvSTR(x)

  x = "tilly";  # since SvCOW(sv_x) is true...
                # SvCOW_off(sv_x)
                # v_strncpy(SvSTR(sv_y), SvSTR(sv_x), SvSTRLEN(sv_x))
                # SvDEPr(sv_x, sv_y)            # remove dependent
                # v_strncpy(SvSTR(sv_x), "tilly", 5)
                #
                # SvMAGIC_off(sv_y)             # remove magic flag
                # SvMGc(sv_y)                   # clear magic

And that's that.  The language will take me a while to develop and all,
but I'm interested in helping out as much as I can to integrate COW in
Perl 6 -- it'll be a good idea, I feel.

-- 
japhy, perl hacker unordinaire!


Reply via email to