Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df7a37e

Browse files
committed
[release-branch.go1.3] runtime: fix GC bitmap corruption
««« CL 103640044 / d2f256096d8d runtime: fix GC bitmap corruption Fixes #8299. R=golang-codereviews CC=golang-codereviews, khr, rsc https://golang.org/cl/103640044 »»» TBR=r, rsc CC=golang-codereviews https://golang.org/cl/125150044
1 parent 1657de2 commit df7a37e

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

src/pkg/runtime/mgc0.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2760,7 +2760,7 @@ runtime·markscan(void *v)
27602760
void
27612761
runtime·markfreed(void *v)
27622762
{
2763-
uintptr *b, off, shift;
2763+
uintptr *b, off, shift, xbits;
27642764

27652765
if(0)
27662766
runtime·printf("markfreed %p\n", v);
@@ -2771,7 +2771,18 @@ runtime·markfreed(void *v)
27712771
off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start; // word offset
27722772
b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
27732773
shift = off % wordsPerBitmapWord;
2774-
*b = (*b & ~(bitMask<<shift)) | (bitAllocated<<shift);
2774+
if(!g->m->gcing || work.nproc == 1) {
2775+
// During normal operation (not GC), the span bitmap is not updated concurrently,
2776+
// because either the span is cached or accesses are protected with MCentral lock.
2777+
*b = (*b & ~(bitMask<<shift)) | (bitAllocated<<shift);
2778+
} else {
2779+
// During GC other threads concurrently mark heap.
2780+
for(;;) {
2781+
xbits = *b;
2782+
if(runtime·casp((void**)b, (void*)xbits, (void*)((xbits & ~(bitMask<<shift)) | (bitAllocated<<shift))))
2783+
break;
2784+
}
2785+
}
27752786
}
27762787

27772788
// check that the block at v of size n is marked freed.

0 commit comments

Comments
 (0)