void
Perl_init_stacks(pTHX)
{
+ SSize_t size;
+
/* start with 128-item stack and 8K cxstack */
PL_curstackinfo = new_stackinfo(REASONABLE(128),
REASONABLE(8192/sizeof(PERL_CONTEXT) - 1));
PL_scopestack_ix = 0;
PL_scopestack_max = REASONABLE(32);
- Newx(PL_savestack,REASONABLE_but_at_least(128,SS_MAXPUSH),ANY);
+ size = REASONABLE_but_at_least(128,SS_MAXPUSH);
+ Newx(PL_savestack, size, ANY);
PL_savestack_ix = 0;
- PL_savestack_max = REASONABLE_but_at_least(128,SS_MAXPUSH);
+ /*PL_savestack_max lies: it always has SS_MAXPUSH more than it claims */
+ PL_savestack_max = size - SS_MAXPUSH;
}
#undef REASONABLE
void
Perl_savestack_grow(pTHX)
{
- PL_savestack_max = GROW(PL_savestack_max) + 4;
- Renew(PL_savestack, PL_savestack_max, ANY);
+ PL_savestack_max = GROW(PL_savestack_max);
+ /* Note that we allocate SS_MAXPUSH slots higher than ss_max
+ * so that SS_ADD_END(), SSGROW() etc can do a simper check */
+ Renew(PL_savestack, PL_savestack_max + SS_MAXPUSH, ANY);
}
void
Perl_savestack_grow_cnt(pTHX_ I32 need)
{
PL_savestack_max = PL_savestack_ix + need;
- Renew(PL_savestack, PL_savestack_max, ANY);
+ /* Note that we allocate SS_MAXPUSH slots higher than ss_max
+ * so that SS_ADD_END(), SSGROW() etc can do a simper check */
+ Renew(PL_savestack, PL_savestack_max + SS_MAXPUSH, ANY);
}
#undef GROW
* macros */
#define SS_MAXPUSH 4
-#define SSCHECK(need) if (UNLIKELY(PL_savestack_ix + (I32)(need) + SS_MAXPUSH > PL_savestack_max)) savestack_grow()
-#define SSGROW(need) if (UNLIKELY(PL_savestack_ix + (I32)(need) + SS_MAXPUSH > PL_savestack_max)) savestack_grow_cnt(need + SS_MAXPUSH)
+#define SSCHECK(need) if (UNLIKELY(PL_savestack_ix + (I32)(need) > PL_savestack_max)) savestack_grow()
+#define SSGROW(need) if (UNLIKELY(PL_savestack_ix + (I32)(need) > PL_savestack_max)) savestack_grow_cnt(need)
#define SSPUSHINT(i) (PL_savestack[PL_savestack_ix++].any_i32 = (I32)(i))
#define SSPUSHLONG(i) (PL_savestack[PL_savestack_ix++].any_long = (long)(i))
#define SSPUSHBOOL(p) (PL_savestack[PL_savestack_ix++].any_bool = (p))
* of the grow() can be done. These changes reduce the code of something
* like save_pushptrptr() to half its former size.
* Of course, doing the size check *after* pushing means we must always
- * ensure there are SS_MAXPUSH free slots on the savestack
+ * ensure there are SS_MAXPUSH free slots on the savestack. This ensured
+ * bt savestack_grow() and savestack_grow_cnt always allocating SS_MAXPUSH
+ * slots more than asked for, or that it sets PL_savestack_max to
*
* These are for internal core use only and are subject to change */
assert((need) <= SS_MAXPUSH); \
ix += (need); \
PL_savestack_ix = ix; \
- assert(ix <= PL_savestack_max); \
- if (UNLIKELY((ix + SS_MAXPUSH) > PL_savestack_max)) savestack_grow(); \
- assert(PL_savestack_ix + SS_MAXPUSH <= PL_savestack_max);
+ assert(ix <= PL_savestack_max + SS_MAXPUSH); \
+ if (UNLIKELY(ix > PL_savestack_max)) savestack_grow(); \
+ assert(PL_savestack_ix <= PL_savestack_max);
#define SS_ADD_INT(i) ((ssp++)->any_i32 = (I32)(i))
#define SS_ADD_LONG(i) ((ssp++)->any_long = (long)(i))