diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2014-05-02 17:39:25 +0100 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2014-05-02 17:39:25 +0100 |
| commit | 8afa086ce67b44abb9c9639efca214db7acf7b3f (patch) | |
| tree | 0ef03554b60d166ee6590f72ee887d245249b9d9 /src/pkg/runtime | |
| parent | 350a8fcde14e936a4af33560b5365b18e822477a (diff) | |
| download | go-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.goc | 14 |
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 |
