Perl/perl5 — pull request #4 by syberrus (2014-07-24 19:12:12+00:00)
Title: Large commit with very significant speedup of class/object method calls ...

...and several more features:

1) Added hashmap.h - extremely fast low-level C hash to use for perl code needs (see below).

2) Speeding up stash cache, make gv_stash* use the cache and by this make all of perl core and XS modules use
this cache, not only S_method_common.
- Change PL_stashcache from HV* to SVMAP* (hashmap of SVMAP_ENT values)
- The lowest-level function is now gv_stashent which receives precomputed hash64 value for class name
and searches the cache. If nothing found, calls slow S_gv_stashpvn (former Perl_gv_stashpvn) and
fills the cache.
- gv_stashpvn is now a wrapper for gv_stashent, computing hash value.
- add API functions to clear stash cache locally (1 class) and globally. Make use of them.
- added one more flag to gv_stash* - GV_CACHE_ONLY which returns stash only if found in cache,
otherwise NULL. Required for correct behaviour of rule "IO globs take precedence over class names".
- use private hash function PERL_HASH64 for computing hash values for class names. This function is
much faster than PERL_HASH function (especially for long keys, which is likely for full class names)
and returns a 64bit value. It doesn't use randomization because stash cache is a private core data,
not a user data.

3) Speeding up method cache and super method cache, make gv_fetchmeth*/gv_fetchmethod* use the cache.
- store method cache in meta->mro_method instead of package stash's HV itself.
- rename meta->mro_super -> meta->mro_supermethod
- meta->mro_method & meta->mro_supermethod are both SVMAP*
- The lowest-level function for gv_fetchmeth* is now gv_fetchmeth_ent which receives precomputed
hash value for method name.
- gv_fetchmeth_pvn is now a wrapper for gv_fetchmeth_ent, computing hash64 value.
- The lowest-level function for gv_fetchmethod* is now gv_fetchmethod_ent which receives precomputed
hash value for method name. Method cannot contain '::', gv_fetchmethod_ent doesn't search for '::'.
- gv_fetchmethod_pvn is now a wrapper for gv_fetchmethod_ent, searching for '::', changing method name
(and possibly stash, flags) and computing hash64 value.
- new flag for gv_fetchmethod_pvn - GV_METHOD_SIMPLE, which means gv_fetchmethod_pvn doesn't need to scan
for '::' in method name.

4) Precomputing hash64 values for perl code.
- added 2 more op types:
- OP_METHOD_SUPER "$proto->SUPER::func()"
- OP_METHOD_REDIR "$proto->OtherClass::func()" or "$proto->OtherClass::SUPER::func()"
- added new op struct type - struct methop (typedef METHOP).
It actually behaves like UNOP for OP_METHOD and like SVOP for OP_METHOD_* and fully compatible with
them for backward compability. It contains additional fields:
- hash for method name (for OP_METHOD_*). Method name SV and targ are still in ->op_sv and ->op_targ
- hash, sv and targ for class name (for all types)
- hash, sv and targ for redirect class name (for OP_METHOD_REDIR)
- ck_method detects const method name, fills hash and sv, and creates OP_METHOD_NAMED
- ck_method detects const method name with SUPER keyword, fills hash and sv, and creates OP_METHOD_SUPER
- ck_method detects const method name with class redirect (possibly with SUPER keyword),
fills hash, sv, rclass hash and rclass sv and creates OP_METHOD_REDIR
- ck_subr now detects if left operand is a const (MyClass->method()), and stores the data (class hash and sv)
in underlying OP_METHOD* op.
- all of these infos are used in runtime to greatly speedup pp_method* calls

5) OOP context for XSUBs.
Calculated stash HV of left operand (object/class/IO/etc) is now saved in PL_methstash for later use by XSUBS.
This prevents double caclucation of stash's HV for such functions as UNIVERSAL::can and so on and speeds up them
a lot.
Moreover it has one more usage: pp_entersub sets PL_methstash to NULL if CV is called as function, and sets
PL_methstash to object/class/IO/etc stash's HV if CV is called as class/object/etc method.
This makes it possible for XS code to detect if it is called as funtion or method in case if user wants to implement
separate behaviour for those cases.
For example if (PL_methstash) { ... called as method, object/class/etc stash is in PL_methstash }
else { ... called as function }
Additionaly for XSUBs like UNIVERSAL::can which always want to interpret its calls as method calls (i.e. first arg is
object/class/etc), there is a macro dMETHSTASH which defines variable 'HV* stash' and either sets it to PL_methstash
(if called as method) or (if called as function) calculate stash in the same way as pp_method* would do in case of
real method call.
Note that PL_methstash is not stacked (to not introduce any overheat), that means you have to either use it
before you made a new perl CV call or save it to a variable.

6) Bring B, B::Deparse and B::Concise in consistency with new ops.

7) misc:
- bugfix in Opcode.xs: _safe_call_sv (and therefore module Safe) had critical vulnerability
which made it possible for code in $safe->reval("...") to hack your entire program.
- Remove "local's" unneccesary overheat. ("local GLOB = GLOB" - OK, "local GLOB = CODEREF" - OVERHEAT)
{
local *MyClass::func = sub {...}; # LINE A
...
} # LINE B
This example caused global method cache reset at both lines A and B because glob_assign_ref and leave_scope
thought that GV's GP refcnt was 2 (because of saving to Save Stack).
Issue has been fixed (added gp_flags and new GP flag LOCALIZED, if flag is set then 1 refcnt from save stack is
not counted in gv_method_changed calls).
- bugfix in dump.c : sv_dump(stash) (where stash is HV* - someone's stash) crashes if stash has cached destructor -
sv_dump thought that it was a stash and tried to dump CV* as HV*.
- UNIVERSAL::can (in universal.c) is rewritten to make use of PL_methstash and runs much faster now.