]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: do not set m->locks around memory allocation
authorDmitriy Vyukov <dvyukov@google.com>
Fri, 2 May 2014 16:39:25 +0000 (17:39 +0100)
committerDmitriy Vyukov <dvyukov@google.com>
Fri, 2 May 2014 16:39:25 +0000 (17:39 +0100)
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

index 6112639e02a7357181681c3386021069a47322a3..2a14dafab5b52531fe4caf0eccd324da54a39adf 100644 (file)
@@ -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