diff options
Diffstat (limited to 'gv.c')
-rw-r--r-- | gv.c | 19 |
1 files changed, 14 insertions, 5 deletions
@@ -1595,10 +1595,11 @@ 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; + char *tmpfullbuf = NULL; /* only malloc one big chunk of memory when the smallbuff is not large enough */ const char *name_cursor; const char *const name_end = nambeg + full_len; const char *const name_em1 = name_end - 1; + char smallbuf[64]; /* small buffer to avoid a malloc when possible */ PERL_ARGS_ASSERT_PARSE_GV_STASH_NAME; @@ -1629,8 +1630,16 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, *len += 2; } else { /* using ' for package separator */ - if (tmpbuf == NULL) /* only malloc&free once, a little more than needed */ - Newx(tmpbuf, full_len+2, char); + /* use our pre-allocated buffer when possible to save a malloc */ + char *tmpbuf; + if ( *len+2 <= sizeof smallbuf) + tmpbuf = smallbuf; + else { + /* only malloc once if needed */ + if (tmpfullbuf == NULL) /* only malloc&free once, a little more than needed */ + Newx(tmpfullbuf, full_len+2, char); + tmpbuf = tmpfullbuf; + } Copy(*name, tmpbuf, *len, char); tmpbuf[(*len)++] = ':'; tmpbuf[(*len)++] = ':'; @@ -1639,7 +1648,7 @@ 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) { - Safefree(tmpbuf); + Safefree(tmpfullbuf); /* free our tmpfullbuf if it was used */ return FALSE; } /* here we know that *gv && *gv != &PL_sv_undef */ @@ -1681,7 +1690,7 @@ S_parse_gv_stash_name(pTHX_ HV **stash, GV **gv, const char **name, MUTABLE_HV(SvREFCNT_inc_simple(PL_defstash)); } } - Safefree(tmpbuf); + Safefree(tmpfullbuf); /* free our tmpfullbuf if it was used */ return TRUE; } } |