summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorNicolas R <atoomic@cpan.org>2017-09-26 18:07:47 -0500
committerTony Cook <tony@develop-help.com>2017-10-05 09:09:40 +1100
commit0cbfaef69bb7fd07d9ececee9c76bd53c15eb888 (patch)
treee6fb72a6324f4440a583c60921080bbfc42802fa /pp_ctl.c
parente63f47ca6d8204615d2baf90b04e8749b1260472 (diff)
downloadperl-0cbfaef69bb7fd07d9ececee9c76bd53c15eb888.tar.gz
pp_require: return earlier when module is already loaded
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 5f3cfdf23f..1ef7fb463d 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -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;