Skip to content

Commit 0d09226

Browse files
committed
hv.c: Check for being %ENV hash by comparing to GvHV(PL_envgv) rather than looking for PERL_MAGIC_env
Previous code would invoke an entire `mg_find()` call just to check if the given HV happens to have `PERL_MAGIC_env`. This is a more expensive lookup than simply comparing the pointer to the HV slot of the *ENV glob. In addition, it hardcodes in knowledge of the `PERL_MAGIC_env` type in a lot of places that don't really care about it.
1 parent 82a05dc commit 0d09226

File tree

2 files changed

+11
-12
lines changed

2 files changed

+11
-12
lines changed

hv.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,8 @@ Perl_hv_common_key_len(pTHX_ HV *hv, const char *key, I32 klen_i32,
481481
return hv_common(hv, NULL, key, klen, flags, action, val, hash);
482482
}
483483

484+
#define hv_is_env(hv) ((hv) == GvHV(PL_envgv))
485+
484486
void *
485487
Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
486488
int flags, int action, SV *val, U32 hash)
@@ -604,7 +606,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
604606
return (void *) entry;
605607
}
606608
#ifdef ENV_IS_CASELESS
607-
else if (mg_find((const SV *)hv, PERL_MAGIC_env)) {
609+
else if (hv_is_env(hv)) {
608610
U32 i;
609611
for (i = 0; i < klen; ++i)
610612
if (isLOWER(key[i])) {
@@ -669,7 +671,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
669671
return SvTRUE_NN(svret) ? (void *)hv : NULL;
670672
}
671673
#ifdef ENV_IS_CASELESS
672-
else if (mg_find((const SV *)hv, PERL_MAGIC_env)) {
674+
else if (hv_is_env(hv)) {
673675
/* XXX This code isn't UTF8 clean. */
674676
char * const keysave = (char * const)key;
675677
/* Will need to free this, so set FREEKEY flag. */
@@ -714,7 +716,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
714716
return NULL;
715717
}
716718
#ifdef ENV_IS_CASELESS
717-
else if (mg_find((const SV *)hv, PERL_MAGIC_env)) {
719+
else if (hv_is_env(hv)) {
718720
/* XXX This code isn't UTF8 clean. */
719721
const char *keysave = key;
720722
/* Will need to free this, so set FREEKEY flag. */
@@ -737,8 +739,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
737739
if (!HvARRAY(hv)) {
738740
if ((action & (HV_FETCH_LVALUE | HV_FETCH_ISSTORE))
739741
#ifdef DYNAMIC_ENV_FETCH /* if it's an %ENV lookup, we may get it on the fly */
740-
|| (SvRMAGICAL((const SV *)hv)
741-
&& mg_find((const SV *)hv, PERL_MAGIC_env))
742+
|| (SvRMAGICAL((const SV *)hv) && hv_is_env(hv))
742743
#endif
743744
) {
744745
char *array;
@@ -946,7 +947,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
946947
#ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */
947948
if (!(action & HV_FETCH_ISSTORE)
948949
&& SvRMAGICAL((const SV *)hv)
949-
&& mg_find((const SV *)hv, PERL_MAGIC_env)) {
950+
&& hv_is_env(hv)) {
950951
unsigned long len;
951952
const char * const env = PerlEnv_ENVgetenv_len(key,&len);
952953
if (env) {
@@ -1196,7 +1197,7 @@ Perl_hv_pushkv(pTHX_ HV *hv, U32 flags)
11961197
HE *entry;
11971198
bool tied = SvRMAGICAL(hv) && (mg_find(MUTABLE_SV(hv), PERL_MAGIC_tied)
11981199
#ifdef DYNAMIC_ENV_FETCH /* might not know number of keys yet */
1199-
|| mg_find(MUTABLE_SV(hv), PERL_MAGIC_env)
1200+
|| hv_is_env(hv)
12001201
#endif
12011202
);
12021203
PERL_ARGS_ASSERT_HV_PUSHKV;
@@ -1348,7 +1349,7 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
13481349
return NULL; /* element cannot be deleted */
13491350
}
13501351
#ifdef ENV_IS_CASELESS
1351-
else if (mg_find((const SV *)hv, PERL_MAGIC_env)) {
1352+
else if (hv_is_env(hv)) {
13521353
/* XXX This code isn't UTF8 clean. */
13531354
keysv = newSVpvn_flags(key, klen, SVs_TEMP);
13541355
if (k_flags & HVhek_FREEKEY) {
@@ -3063,8 +3064,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
30633064
}
30643065
}
30653066
#if defined(DYNAMIC_ENV_FETCH) && defined(VMS) /* set up %ENV for iteration */
3066-
if (!entry && SvRMAGICAL((const SV *)hv)
3067-
&& mg_find((const SV *)hv, PERL_MAGIC_env)) {
3067+
if (!entry && SvRMAGICAL((const SV *)hv) && hv_is_env(hv)) {
30683068
prime_env_iter();
30693069
}
30703070
#endif

pp_hot.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -2267,8 +2267,7 @@ S_padhv_rv2hv_common(pTHX_ HV *hv, U8 gimme, bool is_keys, bool has_targ)
22672267
keys then check its length, and whether we do either with or without
22682268
an %ENV lookup first. prime_env_iter() returns quickly if nothing
22692269
needs doing. */
2270-
if (SvRMAGICAL((const SV *)hv)
2271-
&& mg_find((const SV *)hv, PERL_MAGIC_env)) {
2270+
if (SvRMAGICAL((const SV *)hv) && (hv == GvHV(PL_envgv)) {
22722271
prime_env_iter();
22732272
}
22742273
#endif

0 commit comments

Comments
 (0)