Skip to content

Commit

Permalink
Inlined newSV_type(SVt_NULL) leaner than non-inlined newSV(0)
Browse files Browse the repository at this point in the history
When a function outside of sv.c creates a SV via newSV(0):
 * There is a call to Perl_newSV
 * A SV head is uprooted and its flags set
 * A runtime check is made to effectively see if 0 > 0
 * The new SV* is returned

Replacing newSV(0) with newSV_type(SVt_NULL) should be more efficient,
because (assuming there are SV heads to uproot), the only step is:
 * A SV head is uprooted and its flags set
  • Loading branch information
richardleach committed Feb 14, 2022
1 parent ede6625 commit 83babae
Show file tree
Hide file tree
Showing 14 changed files with 43 additions and 43 deletions.
6 changes: 3 additions & 3 deletions av.c
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ Perl_av_fetch(pTHX_ AV *av, SSize_t key, I32 lval)

if (!AvARRAY(av)[key]) {
emptyness:
return lval ? av_store(av,key,newSV(0)) : NULL;
return lval ? av_store(av,key,newSV_type(SVt_NULL)) : NULL;
}

return &AvARRAY(av)[key];
Expand Down Expand Up @@ -473,7 +473,7 @@ Perl_av_make(pTHX_ SSize_t size, SV **strp)

SvGETMAGIC(*strp); /* before newSV, in case it dies */
AvFILLp(av)++;
ary[i] = newSV(0);
ary[i] = newSV_type(SVt_NULL);
sv_setsv_flags(ary[i], *strp,
SV_DO_COW_SVSETSV|SV_NOSTEAL);
strp++;
Expand Down Expand Up @@ -1124,7 +1124,7 @@ Perl_av_iter_p(pTHX_ AV *av) {

SV *
Perl_av_nonelem(pTHX_ AV *av, SSize_t ix) {
SV * const sv = newSV(0);
SV * const sv = newSV_type(SVt_NULL);
PERL_ARGS_ASSERT_AV_NONELEM;
if (!av_store(av,ix,sv))
return sv_2mortal(sv); /* has tie magic */
Expand Down
2 changes: 1 addition & 1 deletion dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -2674,7 +2674,7 @@ S_append_gv_name(pTHX_ GV *gv, SV *out)
sv_catpvs_nomg(out, "<NULLGV>");
return;
}
sv = newSV(0);
sv = newSV_type(SVt_NULL);
gv_fullname4(sv, gv, NULL, FALSE);
Perl_sv_catpvf(aTHX_ out, "$%" SVf, SVfARG(sv));
SvREFCNT_dec_NN(sv);
Expand Down
10 changes: 5 additions & 5 deletions gv.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Perl_newGP(pTHX_ GV *const gv)
Newxz(gp, 1, GP);
gp->gp_egv = gv; /* allow compiler to reuse gv after this */
#ifndef PERL_DONT_CREATE_GVSV
gp->gp_sv = newSV(0);
gp->gp_sv = newSV_type(SVt_NULL);
#endif

/* PL_curcop may be null here. E.g.,
Expand Down Expand Up @@ -294,7 +294,7 @@ Perl_cvgv_from_hek(pTHX_ CV *cv)
if (!CvSTASH(cv)) return NULL;
ASSUME(CvNAME_HEK(cv));
svp = hv_fetchhek(CvSTASH(cv), CvNAME_HEK(cv), 0);
gv = MUTABLE_GV(svp && *svp ? *svp : newSV(0));
gv = MUTABLE_GV(svp && *svp ? *svp : newSV_type(SVt_NULL));
if (!isGV(gv))
gv_init_pvn(gv, CvSTASH(cv), HEK_KEY(CvNAME_HEK(cv)),
HEK_LEN(CvNAME_HEK(cv)),
Expand Down Expand Up @@ -580,7 +580,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
ampable = FALSE;
}
if (!gv) {
gv = (GV *)newSV(0);
gv = (GV *)newSV_type(SVt_NULL);
gv_init(gv, stash, name, len, TRUE);
}
GvMULTI_on(gv);
Expand Down Expand Up @@ -1359,7 +1359,7 @@ Perl_gv_autoload_pvn(pTHX_ HV *stash, const char *name, STRLEN len, U32 flags)
if (!isGV(vargv)) {
gv_init_pvn(vargv, varstash, S_autoload, S_autolen, 0);
#ifdef PERL_DONT_CREATE_GVSV
GvSV(vargv) = newSV(0);
GvSV(vargv) = newSV_type(SVt_NULL);
#endif
}
LEAVE;
Expand Down Expand Up @@ -2516,7 +2516,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
/* By this point we should have a stash and a name */
gvp = (GV**)hv_fetch(stash,name,is_utf8 ? -(I32)len : (I32)len,add);
if (!gvp || *gvp == (const GV *)&PL_sv_undef) {
if (addmg) gv = (GV *)newSV(0); /* tentatively */
if (addmg) gv = (GV *)newSV_type(SVt_NULL); /* tentatively */
else return NULL;
}
else gv = *gvp, addmg = 0;
Expand Down
8 changes: 4 additions & 4 deletions hv.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
HV_FETCH_ISSTORE
| HV_DISABLE_UVAR_XKEY
| return_svp,
newSV(0), hash);
newSV_type(SVt_NULL), hash);
} else {
if (flags & HVhek_FREEKEY)
Safefree(key);
Expand Down Expand Up @@ -739,7 +739,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
break;
}
/* LVAL fetch which actually needs a store. */
val = newSV(0);
val = newSV_type(SVt_NULL);
HvPLACEHOLDERS(hv)--;
} else {
/* store */
Expand Down Expand Up @@ -793,7 +793,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
return NULL;
}
if (action & HV_FETCH_LVALUE) {
val = action & HV_FETCH_EMPTY_HE ? NULL : newSV(0);
val = action & HV_FETCH_EMPTY_HE ? NULL : newSV_type(SVt_NULL);
if (SvMAGICAL(hv)) {
/* At this point the old hv_fetch code would call to hv_store,
which in turn might do some tied magic. So we need to make that
Expand Down Expand Up @@ -3247,7 +3247,7 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he)

switch(he->refcounted_he_data[0] & HVrhek_typemask) {
case HVrhek_undef:
value = newSV(0);
value = newSV_type(SVt_NULL);
break;
case HVrhek_delete:
value = &PL_sv_placeholder;
Expand Down
2 changes: 1 addition & 1 deletion inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Perl_av_fetch_simple(pTHX_ AV *av, SSize_t key, I32 lval)
assert(key > -1);

if ( (key > AvFILLp(av)) || !AvARRAY(av)[key]) {
return lval ? av_store_simple(av,key,newSV(0)) : NULL;
return lval ? av_store_simple(av,key,newSV_type(SVt_NULL)) : NULL;
} else {
return &AvARRAY(av)[key];
}
Expand Down
6 changes: 3 additions & 3 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -10964,7 +10964,7 @@ S_op_const_sv(pTHX_ const OP *o, CV *cv, bool allow_lex)
if (type == OP_CONST && cSVOPo->op_sv)
sv = cSVOPo->op_sv;
else if (type == OP_UNDEF && !o->op_private) {
sv = newSV(0);
sv = newSV_type(SVt_NULL);
SAVEFREESV(sv);
}
else if (allow_lex && type == OP_PADSV) {
Expand Down Expand Up @@ -13623,7 +13623,7 @@ Perl_ck_glob(pTHX_ OP *o)
LEAVE;
}
#endif /* !PERL_EXTERNAL_GLOB */
gv = (GV *)newSV(0);
gv = (GV *)newSV_type(SVt_NULL);
gv_init(gv, 0, "", 0, 0);
gv_IOadd(gv);
op_append_elem(OP_GLOB, o, newGVOP(OP_GV, 0, gv));
Expand Down Expand Up @@ -13689,7 +13689,7 @@ Perl_ck_index(pTHX_ OP *o)
if ( (!SvPOK(sv) || SvNIOKp(sv) || isREGEXP(sv))
&& SvOK(sv) && !SvROK(sv))
{
sv = newSV(0);
sv = newSV_type(SVt_NULL);
sv_copypv(sv, kSVOP->op_sv);
SvREFCNT_dec_NN(kSVOP->op_sv);
kSVOP->op_sv = sv;
Expand Down
16 changes: 8 additions & 8 deletions pad.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ Perl_pad_alloc(pTHX_ I32 optype, U32 tmptype)
pad_reset();
if (tmptype == SVs_PADMY) { /* Not & because this ‘flag’ is 0. */
/* For a my, simply push a null SV onto the end of PL_comppad. */
sv = *av_store_simple(PL_comppad, AvFILLp(PL_comppad) + 1, newSV(0));
sv = *av_store_simple(PL_comppad, AvFILLp(PL_comppad) + 1, newSV_type(SVt_NULL));
retval = (PADOFFSET)AvFILLp(PL_comppad);
}
else {
Expand Down Expand Up @@ -1565,7 +1565,7 @@ Perl_pad_swipe(pTHX_ PADOFFSET po, bool refadjust)
/* if pad tmps aren't shared between ops, then there's no need to
* create a new tmp when an existing op is freed */
#ifdef USE_PAD_RESET
PL_curpad[po] = newSV(0);
PL_curpad[po] = newSV_type(SVt_NULL);
SvPADTMP_on(PL_curpad[po]);
#else
PL_curpad[po] = NULL;
Expand Down Expand Up @@ -2030,7 +2030,7 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned,
else if (sigil == '%')
sv = MUTABLE_SV(newHV());
else
sv = newSV(0);
sv = newSV_type(SVt_NULL);
/* reset the 'assign only once' flag on each state var */
if (sigil != '&' && SvPAD_STATE(namesv))
SvPADSTALE_on(sv);
Expand All @@ -2041,7 +2041,7 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, HV *cloned,
sv = SvREFCNT_inc_NN(ppad[ix]);
}
else {
sv = newSV(0);
sv = newSV_type(SVt_NULL);
SvPADTMP_on(sv);
}
PL_curpad[ix] = sv;
Expand Down Expand Up @@ -2435,15 +2435,15 @@ Perl_pad_push(pTHX_ PADLIST *padlist, int depth)
else if (sigil == '%')
sv = MUTABLE_SV(newHV());
else
sv = newSV(0);
sv = newSV_type(SVt_NULL);
}
}
else if (PadnamePV(names[ix])) {
sv = SvREFCNT_inc_NN(oldpad[ix]);
}
else {
/* save temporaries on recursion? */
sv = newSV(0);
sv = newSV_type(SVt_NULL);
SvPADTMP_on(sv);
}
AvARRAY(newpad)[ix] = sv;
Expand Down Expand Up @@ -2543,7 +2543,7 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
else if (sigil == '%')
sv = MUTABLE_SV(newHV());
else
sv = newSV(0);
sv = newSV_type(SVt_NULL);
pad1a[ix] = sv;
}
}
Expand All @@ -2554,7 +2554,7 @@ Perl_padlist_dup(pTHX_ PADLIST *srcpad, CLONE_PARAMS *param)
}
else {
/* save temporaries on recursion? */
SV * const sv = newSV(0);
SV * const sv = newSV_type(SVt_NULL);
pad1a[ix] = sv;

/* SvREFCNT(oldpad[ix]) != 1 for some code in threads.xs
Expand Down
18 changes: 9 additions & 9 deletions pp.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ S_rv2gv(pTHX_ SV *sv, const bool vivify_sv, const bool strict,
HV *stash;
if (SvREADONLY(sv))
Perl_croak_no_modify();
gv = MUTABLE_GV(newSV(0));
gv = MUTABLE_GV(newSV_type(SVt_NULL));
stash = CopSTASH(PL_curcop);
if (SvTYPE(stash) != SVt_PVHV) stash = NULL;
if (cUNOP->op_targ) {
Expand Down Expand Up @@ -938,7 +938,7 @@ PP(pp_undef)
Newxz(gp, 1, GP);
GvGP_set(sv, gp_ref(gp));
#ifndef PERL_DONT_CREATE_GVSV
GvSV(sv) = newSV(0);
GvSV(sv) = newSV_type(SVt_NULL);
#endif
GvLINE(sv) = CopLINE(PL_curcop);
GvEGV(sv) = MUTABLE_GV(sv);
Expand Down Expand Up @@ -3499,7 +3499,7 @@ PP(pp_index)

/* At this point, pv is a malloc()ed string. So donate it to temp
to ensure it will get free()d */
little = temp = newSV(0);
little = temp = newSV_type(SVt_NULL);
sv_usepvn(temp, pv, llen);
little_p = SvPVX(little);
} else {
Expand Down Expand Up @@ -5534,13 +5534,13 @@ PP(pp_anonhash)
{
MARK++;
SvGETMAGIC(*MARK);
val = newSV(0);
val = newSV_type(SVt_NULL);
sv_setsv_nomg(val, *MARK);
}
else
{
Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "Odd number of elements in anonymous hash");
val = newSV(0);
val = newSV_type(SVt_NULL);
}
(void)hv_store_ent(hv,key,val,0);
}
Expand Down Expand Up @@ -5791,7 +5791,7 @@ PP(pp_push)
for (++MARK; MARK <= SP; MARK++) {
SV *sv;
if (*MARK) SvGETMAGIC(*MARK);
sv = newSV(0);
sv = newSV_type(SVt_NULL);
if (*MARK)
sv_setsv_nomg(sv, *MARK);
av_store(ary, AvFILLp(ary)+1, sv);
Expand Down Expand Up @@ -7026,7 +7026,7 @@ PP(pp_argelem)
SV *tmpsv;
SV **svp = av_fetch(defav, ix + i, FALSE);
SV *val = svp ? *svp : &PL_sv_undef;
tmpsv = newSV(0);
tmpsv = newSV_type(SVt_NULL);
sv_setsv(tmpsv, val);
av_store((AV*)targ, i++, tmpsv);
TAINT_NOT;
Expand All @@ -7042,7 +7042,7 @@ PP(pp_argelem)
/* see "target should usually be empty" comment above */
for (i = 0; i < argc; i++) {
SV **svp = av_fetch(defav, ix + i, FALSE);
SV *newsv = newSV(0);
SV *newsv = newSV_type(SVt_NULL);
sv_setsv_flags(newsv,
svp ? *svp : &PL_sv_undef,
(SV_DO_COW_SVSETSV|SV_NOSTEAL));
Expand Down Expand Up @@ -7071,7 +7071,7 @@ PP(pp_argelem)
argc -= 2;
if (UNLIKELY(SvGMAGICAL(key)))
key = sv_mortalcopy(key);
tmpsv = newSV(0);
tmpsv = newSV_type(SVt_NULL);
sv_setsv(tmpsv, val);
hv_store_ent((HV*)targ, key, tmpsv, 0);
TAINT_NOT;
Expand Down
2 changes: 1 addition & 1 deletion pp_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4386,7 +4386,7 @@ S_require_file(pTHX_ SV *sv)
than hanging another SV from it. In turn, filter_add() optionally
takes the SV to use as the filter (or creates a new SV if passed
NULL), so simply pass in whatever value filter_cache has. */
SV * const fc = filter_cache ? newSV(0) : NULL;
SV * const fc = filter_cache ? newSV_type(SVt_NULL) : NULL;
SV *datasv;
if (fc) sv_copypv(fc, filter_cache);
datasv = filter_add(S_run_user_filter, fc);
Expand Down
4 changes: 2 additions & 2 deletions pp_hot.c
Original file line number Diff line number Diff line change
Expand Up @@ -4895,7 +4895,7 @@ Perl_leave_adjust_stacks(pTHX_ SV **from_sp, SV **to_sp, U8 gimme, int pass)
* ++PL_tmps_ix, moving the previous occupant there
* instead.
*/
SV *newsv = newSV(0);
SV *newsv = newSV_type(SVt_NULL);

PL_tmps_stack[++PL_tmps_ix] = *tmps_basep;
/* put it on the tmps stack early so it gets freed if we die */
Expand Down Expand Up @@ -5510,7 +5510,7 @@ Perl_vivify_ref(pTHX_ SV *sv, U32 to_what)
prepare_SV_for_RV(sv);
switch (to_what) {
case OPpDEREF_SV:
SvRV_set(sv, newSV(0));
SvRV_set(sv, newSV_type(SVt_NULL));
break;
case OPpDEREF_AV:
SvRV_set(sv, MUTABLE_SV(newAV()));
Expand Down
2 changes: 1 addition & 1 deletion regexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -3712,7 +3712,7 @@ Perl_regexec_flags(pTHX_ REGEXP * const rx, char *stringarg, char *strend,
magic belonging to this SV.
Not newSVsv, either, as it does not COW.
*/
reginfo->sv = newSV(0);
reginfo->sv = newSV_type(SVt_NULL);
SvSetSV_nosteal(reginfo->sv, sv);
SAVEFREESV(reginfo->sv);
}
Expand Down
4 changes: 2 additions & 2 deletions scope.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ S_save_scalar_at(pTHX_ SV **sptr, const U32 flags)
if (flags & SAVEf_KEEPOLDELEM)
sv = osv;
else {
sv = (*sptr = newSV(0));
sv = (*sptr = newSV_type(SVt_NULL));
if (SvTYPE(osv) >= SVt_PVMG && SvMAGIC(osv))
mg_localize(osv, sv, cBOOL(flags & SAVEf_SETMAGIC));
}
Expand Down Expand Up @@ -1264,7 +1264,7 @@ Perl_leave_scope(pTHX_ I32 base)
CvLEXICAL_on(*svp);
break;
}
default: *svp = newSV(0); break;
default: *svp = newSV_type(SVt_NULL); break;
}
SvREFCNT_dec_NN(sv); /* Cast current value to the winds. */
/* preserve pad nature, but also mark as not live
Expand Down
4 changes: 2 additions & 2 deletions sv.c
Original file line number Diff line number Diff line change
Expand Up @@ -8361,7 +8361,7 @@ Perl_sv_collxfrm_flags(pTHX_ SV *const sv, STRLEN *const nxp, const I32 flags)
static char *
S_sv_gets_append_to_utf8(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
{
SV * const tsv = newSV(0);
SV * const tsv = newSV_type(SVt_NULL);
ENTER;
SAVEFREESV(tsv);
sv_gets(tsv, fp, 0);
Expand Down Expand Up @@ -16308,7 +16308,7 @@ Perl_varname(pTHX_ const GV *const gv, const char gvtype, PADOFFSET targ,
}

if (subscript_type == FUV_SUBSCRIPT_HASH) {
SV * const sv = newSV(0);
SV * const sv = newSV_type(SVt_NULL);
STRLEN len;
const char * const pv = SvPV_nomg_const((SV*)keyname, len);

Expand Down
2 changes: 1 addition & 1 deletion toke.c
Original file line number Diff line number Diff line change
Expand Up @@ -2382,7 +2382,7 @@ S_force_strict_version(pTHX_ char *s)
s++;

if (is_STRICT_VERSION(s,&errstr)) {
SV *ver = newSV(0);
SV *ver = newSV_type(SVt_NULL);
s = (char *)scan_version(s, ver, 0);
version = newSVOP(OP_CONST, 0, ver);
}
Expand Down

0 comments on commit 83babae

Please sign in to comment.