From 8afa086ce67b44abb9c9639efca214db7acf7b3f Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Fri, 2 May 2014 17:39:25 +0100 Subject: [PATCH] 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 --- src/pkg/runtime/slice.goc | 14 +++++--------- 1 file 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 -- 2.50.0