| Store | Cart

Should multideref be disabled if OP_EXISTS/OP_DELETE custom check functions are set?

From: Vincent Pit (VPIT) <p...@profvince.com>
Sat, 25 Apr 2015 22:13:54 -0300
Hello,

While porting autovivification.pm to the new multideref optimization, I 
realized that while the module was loaded the OP_MULTIDEREF ops were 
actually pretty rare :

$ perl5.21.11-dbg-psn-shr-thr-64 -Mblib -MO=Concise -M-autovivification 
-e'my $x; $x->{a}{b}{c}'
f  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 183 -e:1) v:%,{ ->3
3     <0> padsv[$x:183,184] vM/LVINTRO ->4
4     <;> nextstate(main 184 -e:1) v:%,{ ->5
e     <2> helem vK/2 ->f
c        <1> rv2hv sKR/1 ->d
b           <2> helem sKM/LVDEFER,2 ->c
9              <1> rv2hv sKR/1 ->a
8                 <2> helem sKM/LVDEFER,2 ->9
6                    <1> rv2hv sKR/1 ->7
5                       <0> padsv[$x:183,184] sM/STATE ->6
7                    <$> const[PV "a"] s/BARE ->8
a              <$> const[PV "b"] s/BARE ->b
d        <$> const[PV "c"] s/BARE ->e
-e syntax OK

$ perl5.21.11-dbg-psn-shr-thr-64 -Mblib -MO=Concise -M-autovivification 
-e'my $x; exists $x->{a}{b}{c}'
d  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 183 -e:1) v:%,{ ->3
3     <0> padsv[$x:183,184] vM/LVINTRO ->4
4     <;> nextstate(main 184 -e:1) v:%,{ ->5
-     <1> ex-exists vK/1 ->d
c        <+> multideref(->{"c"}) vK/EXISTS ->d
-           <1> ex-rv2hv sKR/1 ->c
b              <2> helem sKM/LVDEFER,2 ->c
9                 <1> rv2hv sKR/1 ->a
8                    <2> helem sKM/LVDEFER,2 ->9
6                       <1> rv2hv sKR/1 ->7
5                          <0> padsv[$x:183,184] sM/STATE ->6
7                       <$> const[PV "a"] s/BARE ->8
a                 <$> const[PV "b"] s/BARE ->b
-e syntax OK

$ perl5.21.11-dbg-psn-shr-thr-64 -Mblib -MO=Concise -M-autovivification 
-e'my $x; delete $x->{a}{b}{c}'
d  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 183 -e:1) v:%,{ ->3
3     <0> padsv[$x:183,184] vM/LVINTRO ->4
4     <;> nextstate(main 184 -e:1) v:%,{ ->5
-     <1> ex-delete vK ->d
c        <+> multideref(->{"c"}) vK/DELETE ->d
-           <1> ex-rv2hv sKR/1 ->c
b              <2> helem sKM/LVDEFER,2 ->c
9                 <1> rv2hv sKR/1 ->a
8                    <2> helem sKM/LVDEFER,2 ->9
6                       <1> rv2hv sKR/1 ->7
5                          <0> padsv[$x:183,184] sM/STATE ->6
7                       <$> const[PV "a"] s/BARE ->8
a                 <$> const[PV "b"] s/BARE ->b
-e syntax OK

Basically, they only happen for exists and delete constructs, and just 
for the last dereferencing. What causes this is this conditional in 
S_maybe_multideref() :

             /* if something like arybase (a.k.a $[ ) is in scope,
              * abandon optimisation attempt */
             if (  (o->op_type == OP_AELEM || o->op_type == OP_HELEM)
                && PL_check[o->op_type] != Perl_ck_null)
                 return;

This makes a lot of sense, but I wonder if this shouldn't be extended to 
topmost OP_EXISTS and OP_DELETE, so that the multideref optimization is 
also disabled when they define their own check functions. This would 
make autovivification.pm automatically work with multideref, since it 
would de facto disable the few optimizations left by the existing checks 
for OP_AELEM/OP_HELEM (autovivification.pm hijacks the check functions 
of all these ops).

Note that this is not a request ; I've fixed the module with regard to 
the current implementation.

What are your thoughts about this?


Vincent

Recent Messages in this Thread
Vincent Pit (VPIT) Apr 26, 2015 01:13 am
Dave Mitchell Apr 27, 2015 12:31 pm
Vincent Pit (VPIT) Apr 27, 2015 12:50 pm
Messages in this thread