Commit 8afa086c authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

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
parent 350a8fcd
...@@ -118,21 +118,17 @@ growslice1(SliceType *t, Slice x, intgo newcap, Slice *ret) ...@@ -118,21 +118,17 @@ growslice1(SliceType *t, Slice x, intgo newcap, Slice *ret)
if(newcap1 > MaxMem/typ->size) if(newcap1 > MaxMem/typ->size)
runtime·panicstring("growslice: cap out of range"); runtime·panicstring("growslice: cap out of range");
capmem = runtime·roundupsize(newcap1*typ->size); 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) if(typ->kind&KindNoPointers)
flag |= FlagNoScan; flag = FlagNoScan|FlagNoZero;
// Here we allocate with FlagNoZero but potentially w/o FlagNoScan,
// GC must not see this blocks until memclr below.
m->locks++;
ret->array = runtime·mallocgc(capmem, (uintptr)typ|TypeInfo_Array, flag); ret->array = runtime·mallocgc(capmem, (uintptr)typ|TypeInfo_Array, flag);
ret->len = x.len; ret->len = x.len;
ret->cap = capmem/typ->size; ret->cap = capmem/typ->size;
lenmem = x.len*typ->size; lenmem = x.len*typ->size;
runtime·memmove(ret->array, x.array, lenmem); runtime·memmove(ret->array, x.array, lenmem);
runtime·memclr(ret->array+lenmem, capmem-lenmem); if(typ->kind&KindNoPointers)
m->locks--; runtime·memclr(ret->array+lenmem, capmem-lenmem);
if(m->locks == 0 && g->preempt) // restore the preemption request in case we've cleared it in newstack
g->stackguard0 = StackPreempt;
} }
#pragma textflag NOSPLIT #pragma textflag NOSPLIT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment