aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2014-05-02 17:39:25 +0100
committerDmitriy Vyukov <dvyukov@google.com>2014-05-02 17:39:25 +0100
commit8afa086ce67b44abb9c9639efca214db7acf7b3f (patch)
tree0ef03554b60d166ee6590f72ee887d245249b9d9 /src/pkg/runtime
parent350a8fcde14e936a4af33560b5365b18e822477a (diff)
downloadgo-8afa086ce67b44abb9c9639efca214db7acf7b3f.tar.xz
runtime: do not set m->locks around memory allocation
If slice append is the only place where a program allocates, then it will consume all available memory w/o triggering GC. This was demonstrated in the issue. Fixes #7922. LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews, iant, khr https://golang.org/cl/91010048
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/slice.goc14
1 files changed, 5 insertions, 9 deletions
diff --git a/src/pkg/runtime/slice.goc b/src/pkg/runtime/slice.goc
index 6112639e02..2a14dafab5 100644
--- a/src/pkg/runtime/slice.goc
+++ b/src/pkg/runtime/slice.goc
@@ -118,21 +118,17 @@ growslice1(SliceType *t, Slice x, intgo newcap, Slice *ret)
if(newcap1 > MaxMem/typ->size)
runtime·panicstring("growslice: cap out of range");
capmem = runtime·roundupsize(newcap1*typ->size);
- flag = FlagNoZero;
+ flag = 0;
+ // Can't use FlagNoZero w/o FlagNoScan, because otherwise GC can scan unitialized memory.
if(typ->kind&KindNoPointers)
- flag |= FlagNoScan;
- // Here we allocate with FlagNoZero but potentially w/o FlagNoScan,
- // GC must not see this blocks until memclr below.
- m->locks++;
+ flag = FlagNoScan|FlagNoZero;
ret->array = runtime·mallocgc(capmem, (uintptr)typ|TypeInfo_Array, flag);
ret->len = x.len;
ret->cap = capmem/typ->size;
lenmem = x.len*typ->size;
runtime·memmove(ret->array, x.array, lenmem);
- runtime·memclr(ret->array+lenmem, capmem-lenmem);
- m->locks--;
- if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack
- g->stackguard0 = StackPreempt;
+ if(typ->kind&KindNoPointers)
+ runtime·memclr(ret->array+lenmem, capmem-lenmem);
}
#pragma textflag NOSPLIT