summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc.goc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/malloc.goc')
-rw-r--r--src/pkg/runtime/malloc.goc17
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)