in reply to Re: Reference of constants and literals
in thread Reference of constants and literals

I think it's the symptom of an idea I planted in LanX' head yesterday, the idea of determining that the code is getting called from the same location because it gets passed the same (addresses of) variables. For arrays/hashes, it seems the code actually gets the same addresses of variables even though these are lexicals.

  • Comment on Re^2: Reference of constants and literals

Replies are listed 'Best First'.
Re^3: Reference of constants and literals
by moritz (Cardinal) on Nov 24, 2008 at 10:29 UTC
    That might be a nice idea for an obfuscation context, but certainly not for production code. It relies on an undocumented behaviour, here an optimization that might very well be changed in future.

    I think it's related to the optimization described in No garbage collection for my-variables (not sure though).

      I think it's related to the optimization described in No garbage collection for my-variables (not sure though).

      The linked post refers to the effect of the padsv (my $) operator. Neither padsv nor the underlying code (SAVECLEARSV) is involved here. Any resemblance is coincidental.

      In fact, I don't think there's any reuse of allocated memory involved. I think a new memory block just happens to be allocated at the same location as a previously allocated memory block. (Upd: That's indeed what happens, as show in Re^5: Reference of constants and literals )

      For example, the following code continually allocates memory blocks at the same two locations. This is not related to my since we're forcing my to continually reallocate SVs by keeping the refcount greater than 1. There is no reuse of allocated memory at all.

      >perl -le"sub f{ \my $x } print f() for 1..10;" SCALAR(0x236d40) SCALAR(0x236014) SCALAR(0x236d40) SCALAR(0x236014) SCALAR(0x236d40) SCALAR(0x236014) SCALAR(0x236d40) SCALAR(0x236014) SCALAR(0x236d40) SCALAR(0x236014)
        For example, the following code continually allocates memory blocks at the same two locations. This is not related to my since we're forcing my to continually reallocate SVs by keeping the refcount greater than 1. There is no reuse of allocated memory at all.
        perl -le"sub f{ \my $x } print f() for 1..10;"
        What refcount is kept greater than 1? After the print, the result of f() is no longer reference to. Hence the ref to $x goes out of scope, and since nothing is refering to $x, that one goes out of scope as well. Here's a slight variation that shows this:
        sub DESTROY {say "DESTROYED"} sub f{ bless \my $x } say f() for 1..10; __END__ main=SCALAR(0x9721530) DESTROYED main=SCALAR(0x9704c30) DESTROYED main=SCALAR(0x9721530) DESTROYED main=SCALAR(0x9704c30) DESTROYED main=SCALAR(0x9721530) DESTROYED main=SCALAR(0x9704c30) DESTROYED main=SCALAR(0x9721530) DESTROYED main=SCALAR(0x9704c30) DESTROYED main=SCALAR(0x9721530) DESTROYED main=SCALAR(0x9704c30) DESTROYED
        OTOH, if you do keep the refcount above 0, no address is reused:
        my @a; sub f{ push @a, \my $x; $a[-1] } say f() for 1..10; __END__ SCALAR(0x9c34108) SCALAR(0x9c33c1c) SCALAR(0x9c41f8c) SCALAR(0x9c33f50) SCALAR(0x9c341a8) SCALAR(0x9c34180) SCALAR(0x9c33f00) SCALAR(0x9c50534) SCALAR(0x9c5050c) SCALAR(0x9c504e4)