summaryrefslogtreecommitdiff
path: root/universal.c
diff options
context:
space:
mode:
authorSteffen Mueller <smueller@cpan.org>2012-10-22 20:56:45 +0200
committerSteffen Mueller <smueller@cpan.org>2012-10-22 20:56:45 +0200
commit2102d7a2adc27f86a21271a4721de2799b5158a0 (patch)
treea0ad9894b9a21ac7ce25f1b6fe50590f362c187b /universal.c
parent855ea7c74bf7bb29e7655147ec501fcdb53b07cd (diff)
downloadperl-2102d7a2adc27f86a21271a4721de2799b5158a0.tar.gz
Move more X's off the PUSH into EXTEND's
Generally speaking, if there's branching and each branch may contain a varying number of PUSH operations, EXTENDing to the longest number of items should generally be more efficient since the stack will eventually grow to a relatively steady state, but the extra branching incurred by the X's will cost every time.
Diffstat (limited to 'universal.c')
-rw-r--r--universal.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/universal.c b/universal.c
index 9f632eee3e..055d8ab176 100644
--- a/universal.c
+++ b/universal.c
@@ -1035,40 +1035,41 @@ XS(XS_PerlIO_get_layers)
const bool argok = argsvp && *argsvp && SvPOK(*argsvp);
const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
+ EXTEND(SP, 3); /* Three is the max in all branches: better check just once */
if (details) {
/* Indents of 5? Yuck. */
/* We know that PerlIO_get_layers creates a new SV for
the name and flags, so we can just take a reference
and "steal" it when we free the AV below. */
- XPUSHs(namok
+ PUSHs(namok
? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
: &PL_sv_undef);
- XPUSHs(argok
+ PUSHs(argok
? newSVpvn_flags(SvPVX_const(*argsvp),
SvCUR(*argsvp),
(SvUTF8(*argsvp) ? SVf_UTF8 : 0)
| SVs_TEMP)
: &PL_sv_undef);
- XPUSHs(flgok
+ PUSHs(flgok
? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
: &PL_sv_undef);
nitem += 3;
}
else {
if (namok && argok)
- XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
+ PUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
SVfARG(*namsvp),
SVfARG(*argsvp))));
else if (namok)
- XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
+ PUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
else
- XPUSHs(&PL_sv_undef);
+ PUSHs(&PL_sv_undef);
nitem++;
if (flgok) {
const IV flags = SvIVX(*flgsvp);
if (flags & PERLIO_F_UTF8) {
- XPUSHs(newSVpvs_flags("utf8", SVs_TEMP));
+ PUSHs(newSVpvs_flags("utf8", SVs_TEMP));
nitem++;
}
}
@@ -1234,13 +1235,14 @@ XS(XS_re_regnames)
av = MUTABLE_AV(SvRV(ret));
length = av_len(av);
+ EXTEND(SP, length+1); /* better extend stack just once */
for (i = 0; i <= length; i++) {
entry = av_fetch(av, i, FALSE);
if (!entry)
Perl_croak(aTHX_ "NULL array element in re::regnames()");
- mXPUSHs(SvREFCNT_inc_simple_NN(*entry));
+ mPUSHs(SvREFCNT_inc_simple_NN(*entry));
}
SvREFCNT_dec(ret);
@@ -1311,8 +1313,9 @@ XS(XS_re_regexp_pattern)
(RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
/* return the pattern and the modifiers */
- XPUSHs(pattern);
- XPUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
+ EXTEND(SP, 2);
+ PUSHs(pattern);
+ PUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
XSRETURN(2);
} else {
/* Scalar, so use the string that Perl would return */