That's a follow up to Refresh a Module

Consider the following code

~ $ perl -w -e'sub g{1}; my $cr=\&g; eval q(sub g{2}); print g(); pr +int $cr->();' Subroutine g redefined at (eval 1) line 1. 21~ $
As you can see is the sub g dynamically redefined and the calls work.

Looking in the optree reveals that the compiler did some optimisation when compiling the code, and stored the reference \&main::g inside the call. (See OP "e" )

~ $ perl -MO=Concise,-exec -w -e'sub g{1}; my $cr=\&g; eval q(sub g{2 +}); print g(); print $cr->();' 1 <0> enter v 2 <;> nextstate(main 3 -e:1) v:{ 3 <#> gv[IV \&main::g] s 4 <1> rv2cv[t3] lKRM/AMPER,TARG 5 <1> srefgen sK/1 6 <0> padsv[$cr:3,4] sRM*/LVINTRO 7 <2> sassign vKS/2 8 <;> nextstate(main 4 -e:1) v:{ 9 <$> const[PV "sub g{2}"] s a <1> entereval[t256] vK/1 b <;> nextstate(main 4 -e:1) v:{ c <0> pushmark s d <0> pushmark s e <#> gv[IV \&main::g] s f <1> entersub lKS g <@> print vK h <;> nextstate(main 4 -e:1) v:{ i <0> pushmark s j <0> pushmark s k <0> padsv[$cr:3,4] s l <1> entersub[t4] lKS/TARG m <@> print vK n <@> leave[1 ref] vKP/REFC -e syntax OK

This reference must be obviously going to the first g(), because the second wasn't known at compile time. But calling the first g() can't be right.

Now, how was Perl able to fix this optimisation?

I did a Devel::Peek of both subs, and couldn't see any data hinting to "forwarding".

Looking up the Symbol table wouldn't make sense, because it's making the optimisation useless

Am I misreading the op-tree and there is no optimisation?

I found an SO thread where Tom Christiansen explicitly states this optimisation is happening.

I'm curious, how is it implemented? What am I missing?

For completeness, here the output from Devel::Peek

~ $ perl -w -e'sub g{1}; my $cr=\&g; eval q(sub g{2}); print g(); pri +nt $cr->();use Devel::Peek; Dump($cr);Dump(\&g);' Subroutine g redefined at (eval 2) line 1. SV = IV(0xb40000715c6827e8) at 0xb40000715c6827f8 REFCNT = 1 FLAGS = (ROK) RV = 0xb40000715c682810 SV = PVCV(0xb40000715c6812d8) at 0xb40000715c682810 REFCNT = 1 FLAGS = (DYNFILE) COMP_STASH = 0xb40000715c60c6c0 "main" START = 0xb40000715c699698 ===> 1 ROOT = 0xb40000715c699620 GVGV::GV = 0xb40000715c682858 "main" :: "g" FILE = "-e" DEPTH = 0 FLAGS = 0x1000 OUTSIDE_SEQ = 1 PADLIST = 0xb40000715c63b480 PADNAME = 0xb40000715c693bd0(0xb40000715c605510) PAD = 0xb40000715 +c682828(0xb40000715c63b4a0) OUTSIDE = 0xb40000715c60c9d8 (MAIN) SV = IV(0xb40000715c682038) at 0xb40000715c682048 REFCNT = 1 FLAGS = (TEMP,ROK) RV = 0xb40000715c682078 SV = PVCV(0xb40000715c6e2548) at 0xb40000715c682078 REFCNT = 2 FLAGS = (DYNFILE) COMP_STASH = 0xb40000715c60c6c0 "main" START = 0xb40000715c699b98 ===> 2 ROOT = 0xb40000715c699b20 GVGV::GV = 0xb40000715c682858 "main" :: "g" FILE = "(eval 2)" DEPTH = 0 FLAGS = 0x1000 OUTSIDE_SEQ = 213 PADLIST = 0xb40000715c63b4e0 PADNAME = 0xb40000715c693c90(0xb40000715c605670) PAD = 0xb40000715 +c682120(0xb40000715c720260) OUTSIDE = 0xb40000715c60c6a8 (UNIQUE) 21~ $

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

Update

FWIW: The redefine mechanism is related to the symbol table, because if I delete the symbol the full redefine partly fails and the old g() is called when the coderef was stored.

~ $ perl -w -e'sub g{1}; my $cr=\&g; delete $::{g}; eval q(sub g{2}); + print g(); print $cr->();' 11~ $

Which makes sense, because a symbol can't be redefined if it doesn't exist.

Update

I just discovered that a subroutine which isn't redefined carries a flag NAMED , like

FLAGS = (DYNFILE,NAMED)

so probably this is checked, and if the flag is missing, the symbol table entry becomes the fall back.


In reply to How is redefining a sub internally done? by LanX

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.