Fix STRESS_REALLOC after 3caf0269d
authorFather Chrysostomos <sprout@cpan.org>
Sat, 21 May 2016 18:36:56 +0000 (11:36 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 21 May 2016 18:57:24 +0000 (11:57 -0700)
This commit:

commit 3caf0269dd4c609b8c2bc22b54598c642ba63ed8
Author: David Mitchell <davem@iabyn.com>
Date:   Sun Dec 27 14:07:02 2015 +0000

    offset PL_savestack_max by SS_MAXPUSH

stopped savestack_grow from adding 4 to the allocated amount, which
broke builds with -Accflags=-DSTRESS_REALLOC.

savestack_grow accepts no arguments.  The callers have no way to
tell it how much to allocate; they just assume that it will allocate
enough.  By default, in increases the stack size by 50%, and the stack
starts out at 128 elements, so everything works fine.

Under STRESS_REALLOC, introduced by commit 2ce36478e5 in ’98, the
savestack started out at 1 (later, SS_MAXPUSH; as of 3caf0269d,
PL_savestack_max is 0 initially, though the actual stack size is
SS_MAXPUSH).  And the stack-growing functions in scope.h that default
to 50% instead add 1 element to the stack.

Anything that calls savestack_grow assumes it will allocate enough for
the savestack elements pushed.  The most elements ever pushed at once
is 4, so 2ce36478e5 added a +4 to the size in savestack_grow.

3caf0269d removed that +4, so the stack is only incremented by 1, and
this assertion at the end of scope.h:SS_ADD_END failed:

    if (UNLIKELY(ix > PL_savestack_max)) savestack_grow();      \
    assert(PL_savestack_ix <= PL_savestack_max);

3caf0269d was right in removing the +4, since it is unnecessary for
normal builds.  For STRESS_REALLOC, which is designed to grow stacks
as little as possible, we were allocating one more element than neces-
sary.  So this commit just explicitly grows the stack by SS_MAXPUSH
(the new name for 4) in savestack_grow if STRESS_REALLOC is defined.

scope.c

diff --git a/scope.c b/scope.c
index 78a465b..55f801a 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -140,7 +140,11 @@ Perl_markstack_grow(pTHX)
 void
 Perl_savestack_grow(pTHX)
 {
+#ifdef STRESS_REALLOC
+    PL_savestack_max += SS_MAXPUSH;
+#else
     PL_savestack_max = GROW(PL_savestack_max);
+#endif
     /* 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);