diff options
Diffstat (limited to 'src/pkg/runtime/malloc.goc')
-rw-r--r-- | src/pkg/runtime/malloc.goc | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc index 70b85d68d..41060682e 100644 --- a/src/pkg/runtime/malloc.goc +++ b/src/pkg/runtime/malloc.goc @@ -8,6 +8,7 @@ package runtime #include "runtime.h" +#include "stack.h" #include "malloc.h" #include "defs.h" #include "type.h" @@ -146,6 +147,9 @@ runtime·free(void *v) // Large object. size = s->npages<<PageShift; *(uintptr*)(s->start<<PageShift) = 1; // mark as "needs to be zeroed" + // Must mark v freed before calling unmarkspan and MHeap_Free: + // they might coalesce v into other spans and change the bitmap further. + runtime·markfreed(v, size); runtime·unmarkspan(v, 1<<PageShift); runtime·MHeap_Free(&runtime·mheap, s, 1); } else { @@ -154,10 +158,13 @@ runtime·free(void *v) size = runtime·class_to_size[sizeclass]; if(size > sizeof(uintptr)) ((uintptr*)v)[1] = 1; // mark as "needs to be zeroed" + // Must mark v freed before calling MCache_Free: + // it might coalesce v and other blocks into a bigger span + // and change the bitmap further. + runtime·markfreed(v, size); mstats.by_size[sizeclass].nfree++; runtime·MCache_Free(c, v, sizeclass, size); } - runtime·markfreed(v, size); mstats.alloc -= size; if(prof) runtime·MProf_Free(v, size); @@ -379,7 +386,7 @@ static struct { } stacks; enum { - FixedStack = StackBig + StackExtra + FixedStack = StackMin, }; void* @@ -387,6 +394,12 @@ runtime·stackalloc(uint32 n) { void *v; + // Stackalloc must be called on scheduler stack, so that we + // never try to grow the stack during the code that stackalloc runs. + // Doing so would cause a deadlock (issue 1547). + if(g != m->g0) + runtime·throw("stackalloc not on scheduler stack"); + if(m->mallocing || m->gcing || n == FixedStack) { runtime·lock(&stacks); if(stacks.size == 0) |