Normally, sub calls are compiled into a typeglob retrieval followed by a retrieval of the CV slot within that typeglob. The GV OP has a pointer to the GV associated with the name hard-baked in at compile time. The OP_GV pushes the GV on the stack, then the OP_ENTERSUB pops thes the GV off the stack, accesses its CV slot, calls the associated CV.
However as an optimisation, GVs which only have their CV slot used, are instead created as an RV to a CV. So for example, for
package FOO;
sub f { ... }
f()
at compile time, the value of the hash entry $FOO::{f} is created as an RV to the CV associated with f, rather than as a full typeglob. When the GV op is compiled, it points to that RV. When the GV op is called, it pushes that RV onto the stack. When the ENTERSUB is is called, it pops that value, notices that it's an RV rather than a GV, and extracts the CV as the thing referenced.
When things get more complex, the 'RV to a CV' SV is upgraded to a full GV with the CV in its code slot.
An 'RV to CV' is smaller and quicker than a full GV (a GV points to a GP which has a CV slot - so two allocations, two dereferences).
Dave. | [reply] [d/l] |
> Does B::Concise distinguish between these
Yes, for instance if a sub is not predefined in the STASH you'll see the
*main::g or rather *g form.
Also in (for me) random cases where it's predefined.
Update
~/perl $ perl -MO=Concise,-exec -e'g();'
1 <0> enter v
2 <;> nextstate(main 1 -e:1) v:{
3 <0> pushmark s
4 <#> gv[*g] s/EARLYCV
5 <1> entersub[t2] vKS/TARG
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
~/perl $
s/EARLYCV means the sub was unknown at compile time. | [reply] [d/l] [select] |
# Causes something akin to
# `*Foo::method = \&Base::method;`
$foo->method();
But it uses a counter system to invalidate the cache. The package's counter is incremented when the package is changed, making it so the counter in the cached entry no longer matches the package's, invalidating the cached entry.
Perhaps that same mechanism is used here. | [reply] [d/l] |
Well maybe
I tried to look into the code of pp_entersub but didn't understand much... 🤷🏻♂️
Personally when trying to implement this, I would try to use the original sub to link to the current one. Hence just a hop away.
| [reply] [d/l] |