]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: efence support for growable stacks
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 12 Mar 2014 06:21:34 +0000 (10:21 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 12 Mar 2014 06:21:34 +0000 (10:21 +0400)
1. Fix the bug that shrinkstack returns memory to heap.
   This causes growslice to misbehave (it manually initialized
   blocks, and in efence mode shrinkstack's free leads to
   partially-initialized blocks coming out of growslice.
   Which in turn causes GC to crash while treating the garbage
   as Eface/Iface.
2. Enable efence for stack segments.

LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews, khr
https://golang.org/cl/74080043

src/pkg/runtime/stack.c

index 4d699f1101ac0c68f1686228344f58f4bf3d511e..4bdc24107c82543e943f00ae9913b1a878596e5d 100644 (file)
@@ -102,7 +102,7 @@ runtime·stackalloc(G *gp, uint32 n)
                runtime·printf("stackalloc %d\n", n);
 
        gp->stacksize += n;
-       if(StackFromSystem)
+       if(runtime·debug.efence || StackFromSystem)
                return runtime·SysAlloc(ROUND(n, PageSize), &mstats.stacks_sys);
 
        // Minimum-sized stacks are allocated with a fixed-size free-list allocator,
@@ -143,8 +143,8 @@ runtime·stackfree(G *gp, void *v, Stktop *top)
        if(StackDebug >= 1)
                runtime·printf("stackfree %p %d\n", v, (int32)n);
        gp->stacksize -= n;
-       if(StackFromSystem) {
-               if(StackFaultOnFree)
+       if(runtime·debug.efence || StackFromSystem) {
+               if(runtime·debug.efence || StackFaultOnFree)
                        runtime·SysFault(v, n);
                else
                        runtime·SysFree(v, n, &mstats.stacks_sys);
@@ -819,7 +819,15 @@ runtime·shrinkstack(G *gp)
                gp->stack0 = (uintptr)oldstk + newsize;
        gp->stacksize -= oldsize - newsize;
 
-       // Free bottom half of the stack.  First, we trick malloc into thinking
+       // Free bottom half of the stack.
+       if(runtime·debug.efence || StackFromSystem) {
+               if(runtime·debug.efence || StackFaultOnFree)
+                       runtime·SysFault(oldstk, newsize);
+               else
+                       runtime·SysFree(oldstk, newsize, &mstats.stacks_sys);
+               return;
+       }
+       // First, we trick malloc into thinking
        // we allocated the stack as two separate half-size allocs.  Then the
        // free() call does the rest of the work for us.
        if(oldsize == PageSize) {