diff options
author | Nicolas R <atoomic@cpan.org> | 2017-09-26 18:07:47 -0500 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2017-10-05 09:09:40 +1100 |
commit | 0cbfaef69bb7fd07d9ececee9c76bd53c15eb888 (patch) | |
tree | e6fb72a6324f4440a583c60921080bbfc42802fa /pp_ctl.c | |
parent | e63f47ca6d8204615d2baf90b04e8749b1260472 (diff) | |
download | perl-0cbfaef69bb7fd07d9ececee9c76bd53c15eb888.tar.gz |
pp_require: return earlier when module is already loaded
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 14 |
1 files changed, 12 insertions, 2 deletions
@@ -3752,6 +3752,7 @@ S_require_file(pTHX_ SV *sv) I32 old_savestack_ix; const bool op_is_require = PL_op->op_type == OP_REQUIRE; const char *const op_name = op_is_require ? "require" : "do"; + SV ** svp_cached = NULL; assert(op_is_require || PL_op->op_type == OP_DOFILE); @@ -3761,6 +3762,15 @@ S_require_file(pTHX_ SV *sv) if (!(name && len > 0 && *name)) DIE(aTHX_ "Missing or undefined argument to %s", op_name); +#ifndef VMS + /* try to return earlier (save the SAFE_PATHNAME check) if INC already got the name */ + if (op_is_require) { + /* can optimize to only perform one single lookup */ + svp_cached = hv_fetch(GvHVn(PL_incgv), (char*) name, len, 0); + if ( svp_cached && *svp_cached != &PL_sv_undef ) RETPUSHYES; + } +#endif + if (!IS_SAFE_PATHNAME(name, len, op_name)) { if (!op_is_require) { CLEAR_ERRSV(); @@ -3799,8 +3809,8 @@ S_require_file(pTHX_ SV *sv) unixlen = len; } if (op_is_require) { - SV * const * const svp = hv_fetch(GvHVn(PL_incgv), - unixname, unixlen, 0); + /* reuse the previous hv_fetch result if possible */ + SV * const * const svp = svp_cached ? svp_cached : hv_fetch(GvHVn(PL_incgv), unixname, unixlen, 0); if ( svp ) { if (*svp != &PL_sv_undef) RETPUSHYES; |