start reworking op_ppaddr

op->op_ppaddr is basically a cached copy of PL_ppaddr[op->op_type]
dispatch-table entry.  Its deeper purpose however is to support
patching/customizing OPs (as is done by ext/arybase when $[ is
diddled, see b82b06b8).

Use of this OP-patching facility is however statistically exceedingly
rare.  Its worth examining whether we might be optimizing for the
wrong thing, and should be shrinking OPs instead and relying on a hot
cache of PL_ppaddr[].  OTOH, we might just thrash the L2, L3 cachees
harder on process preemption boundaries.  Point is we have no idea.

To test this, add a %patched_ops to interpreter, populate it in
Perl_linklist and mark op->op_patched (still op->op_spare for now)
when OP_IS_PATCHED(op) says so.

Once its possible (WIP) to actually drop the op_ppaddr field (perhaps
-DPERL_NO_PPADDR), we can devise some experiments to tease out the
performance effects.

The patch does as follows:

- add %patched_ops to interpvar.  I used a ptr-table arbitrarily (HV
  <-> pointer nested-conversion-macro phobia), and probly bugs lurk in
  lack of cloning, but its a line-in-the-sand.

- in Perl_linklist, use OP_IS_PATCHED to mark OPs (o->op_spare = 1,
  rename op_patched later), and store op_ppaddr to %patchedpp.  This
  appears to catch all in-core cases, particularly b82b06b8.

- in runloops, check o->op_spare, and fetch $patchpp{$op} when needed.
  hopefully a bit-test is cheap enough as to be unmeasurable.

NOTES:

For this patchset, Ive adopted an "OP-patching" terminology purposely
to avoid confusion with CUSTOM ops and all their implementation
details.  This patchset disregards the possibility that an
op->op_patched flag could signal a single lookup in a unified hash for
OP_CUSTOM ops too, instead of using PL_custom_ops.  Note that
PL_custom_op_names, PL_custom_op_descs dont need to have identical
keys, but rather some known super/subset relationship.

Devel::Cover is likely the highest profile and most sophisticated CPAN
user of OP-patching and op_ppaddr, its worth considering wrt viability
of this patchset.  DC has 2 OP-related techniques to apply:

- change PL_ppaddr[] entries to affect all OPs of that type (likely
  used for NEXTSTATE etc to take real control).
- change OP->op_ppaddr on per-OP basis.

These 2 techniques are available both before and after this patchset,
so modulo version branches, this is feasible in principle.  Managing
%patched_ops has extra overhead vs patching op_ppaddr, but toggling
op->op_spare and leaving 'disabled' entries is just as quick, and has
mnemonic value wrt disabled breakpoints.

TODO:

develop a benchmarking strategy. (ya, just like that ;-)
- need instrumentation to see cache effects.
- need to appreciate stochastics of any measurements.
- nice to leverage t/*, even if very suboptimal (tune what u can measure)
- perlbench - real runtimes, less overhead than core tests.

Add a -DOP_JUNK #ifdef to add an extra op_junk pointer in OP,
benchmark it to get costs (cache, footprint) of extra pointer, and
infer from that what the savings due to eliminating op_ppaddr might be
(caveats apply).

collect and analyse a lot of data.
missing patched might be causing extra failures, lessee
reset spare in CHANGE_TYPE, for op reuse
run-likely