diff options
author | Nicolas R <atoomic@cpan.org> | 2016-10-31 09:55:05 -0600 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2017-09-05 09:37:43 +1000 |
commit | f8ac814f18bfea140da870d907324b308d182202 (patch) | |
tree | 5a2721892e41d4ee5f9dde6fd6df50a2e280983a /gv.c | |
parent | 97fcda75b598695644a4ad496e090941f5b7dcbc (diff) | |
download | perl-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.c | 25 |
1 files changed, 13 insertions, 12 deletions
@@ -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; } } |