summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorNicolas R <atoomic@cpan.org>2016-10-31 09:55:05 -0600
committerTony Cook <tony@develop-help.com>2017-09-05 09:37:43 +1000
commitf8ac814f18bfea140da870d907324b308d182202 (patch)
tree5a2721892e41d4ee5f9dde6fd6df50a2e280983a /gv.c
parent97fcda75b598695644a4ad496e090941f5b7dcbc (diff)
downloadperl-f8ac814f18bfea140da870d907324b308d182202.tar.gz
Reduce malloc&free for S_parse_gv_stash_name
S_parse_gv_stash_name was using multiple malloc and free when using ' as package separator. We can malloc & free only once the tmpbuffer as we know the size max. This is also sligthly improving iterations when using :: as we do not need to check if we need to free the tmp buffer. This is also saving an extra '*gv && *gv != (const GV *)&PL_sv_undef' check.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/gv.c b/gv.c
index afddfe48a8..4bb534b6f1 100644
--- a/gv.c
+++ b/gv.c
@@ -1595,6 +1595,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
STRLEN *len, const char *nambeg, STRLEN full_len,
const U32 is_utf8, const I32 add)
{
+ char *tmpbuf = NULL;
const char *name_cursor;
const char *const name_end = nambeg + full_len;
const char *const name_em1 = name_end - 1;
@@ -1627,9 +1628,9 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
key = *name;
*len += 2;
}
- else {
- char *tmpbuf;
- Newx(tmpbuf, *len+2, char);
+ else { /* using ' for package separator */
+ if (tmpbuf == NULL) /* only malloc&free once, a little more than needed */
+ Newx(tmpbuf, full_len+2, char);
Copy(*name, tmpbuf, *len, char);
tmpbuf[(*len)++] = ':';
tmpbuf[(*len)++] = ':';
@@ -1637,16 +1638,15 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
}
gvp = (GV**)hv_fetch(*stash, key, is_utf8 ? -((I32)*len) : (I32)*len, add);
*gv = gvp ? *gvp : NULL;
- if (*gv && *gv != (const GV *)&PL_sv_undef) {
- if (SvTYPE(*gv) != SVt_PVGV)
- gv_init_pvn(*gv, *stash, key, *len, (add & GV_ADDMULTI)|is_utf8);
- else
- GvMULTI_on(*gv);
- }
- if (key != *name)
- Safefree(key);
- if (!*gv || *gv == (const GV *)&PL_sv_undef)
+ if (!*gv || *gv == (const GV *)&PL_sv_undef) {
+ Safefree(tmpbuf);
return FALSE;
+ }
+ /* here we know that *gv && *gv != &PL_sv_undef */
+ if (SvTYPE(*gv) != SVt_PVGV)
+ gv_init_pvn(*gv, *stash, key, *len, (add & GV_ADDMULTI)|is_utf8);
+ else
+ GvMULTI_on(*gv);
if (!(*stash = GvHV(*gv))) {
*stash = GvHV(*gv) = newHV();
@@ -1681,6 +1681,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name,
MUTABLE_HV(SvREFCNT_inc_simple(PL_defstash));
}
}
+ Safefree(tmpbuf);
return TRUE;
}
}