diff options
author | Russ Cox <rsc@golang.org> | 2014-11-16 16:53:53 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-11-16 16:53:53 -0500 |
commit | fb002ba0ea389cd183fbee72a2a34fbbd6a89279 (patch) | |
tree | ce93ce3968180fd76a47a084bc0219cd8b233841 /src/runtime/malloc.go | |
parent | 5012c68de6a62a5adb006f2820a4435c9c349efc (diff) | |
parent | 8b46a22b652d6e7a4a69b9523d57aff12f9dc945 (diff) | |
download | go-fb002ba0ea389cd183fbee72a2a34fbbd6a89279.tar.gz |
[dev.garbage] all: merge dev.cc (723ca3789b88) into dev.garbage
Brings in Linux time signature fixes. Should fix build.
TBR=austin
CC=golang-codereviews
https://codereview.appspot.com/176870043
Diffstat (limited to 'src/runtime/malloc.go')
-rw-r--r-- | src/runtime/malloc.go | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index 20cb6818d..f90a8f84a 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -241,6 +241,8 @@ func mallocgc(size uintptr, typ *_type, flags uint32) unsafe.Pointer { masksize = masksize * pointersPerByte / 8 // 4 bits per word masksize++ // unroll flag in the beginning if masksize > maxGCMask && typ.gc[1] != 0 { + // write barriers have not been updated to deal with this case yet. + gothrow("maxGCMask too small for now") // If the mask is too large, unroll the program directly // into the GC bitmap. It's 7 times slower than copying // from the pre-unrolled mask, but saves 1/16 of type size @@ -295,6 +297,17 @@ func mallocgc(size uintptr, typ *_type, flags uint32) unsafe.Pointer { } } marked: + + // GCmarkterminate allocates black + // All slots hold nil so no scanning is needed. + // This may be racing with GC so do it atomically if there can be + // a race marking the bit. + if gcphase == _GCmarktermination { + systemstack(func() { + gcmarknewobject_m(uintptr(x)) + }) + } + if raceenabled { racemalloc(x, size) } @@ -335,6 +348,36 @@ marked: return x } +func loadPtrMask(typ *_type) []uint8 { + var ptrmask *uint8 + nptr := (uintptr(typ.size) + ptrSize - 1) / ptrSize + if typ.kind&kindGCProg != 0 { + masksize := nptr + if masksize%2 != 0 { + masksize *= 2 // repeated + } + masksize = masksize * pointersPerByte / 8 // 4 bits per word + masksize++ // unroll flag in the beginning + if masksize > maxGCMask && typ.gc[1] != 0 { + // write barriers have not been updated to deal with this case yet. + gothrow("maxGCMask too small for now") + } + ptrmask = (*uint8)(unsafe.Pointer(uintptr(typ.gc[0]))) + // Check whether the program is already unrolled + // by checking if the unroll flag byte is set + maskword := uintptr(atomicloadp(unsafe.Pointer(ptrmask))) + if *(*uint8)(unsafe.Pointer(&maskword)) == 0 { + systemstack(func() { + unrollgcprog_m(typ) + }) + } + ptrmask = (*uint8)(add(unsafe.Pointer(ptrmask), 1)) // skip the unroll flag byte + } else { + ptrmask = (*uint8)(unsafe.Pointer(typ.gc[0])) // pointer to unrolled mask + } + return (*[1 << 30]byte)(unsafe.Pointer(ptrmask))[:(nptr+1)/2] +} + // implementation of new builtin func newobject(typ *_type) unsafe.Pointer { flags := uint32(0) @@ -429,7 +472,21 @@ func gogc(force int32) { mp = acquirem() mp.gcing = 1 releasem(mp) + systemstack(stoptheworld) + systemstack(finishsweep_m) // finish sweep before we start concurrent scan. + if false { // To turn on concurrent scan and mark set to true... + systemstack(starttheworld) + // Do a concurrent heap scan before we stop the world. + systemstack(gcscan_m) + systemstack(stoptheworld) + systemstack(gcinstallmarkwb_m) + systemstack(starttheworld) + systemstack(gcmark_m) + systemstack(stoptheworld) + systemstack(gcinstalloffwb_m) + } + if mp != acquirem() { gothrow("gogc: rescheduled") } @@ -445,17 +502,21 @@ func gogc(force int32) { if debug.gctrace > 1 { n = 2 } + eagersweep := force >= 2 for i := 0; i < n; i++ { if i > 0 { startTime = nanotime() } // switch to g0, call gc, then switch back - eagersweep := force >= 2 systemstack(func() { gc_m(startTime, eagersweep) }) } + systemstack(func() { + gccheckmark_m(startTime, eagersweep) + }) + // all done mp.gcing = 0 semrelease(&worldsema) @@ -470,6 +531,14 @@ func gogc(force int32) { } } +func GCcheckmarkenable() { + systemstack(gccheckmarkenable_m) +} + +func GCcheckmarkdisable() { + systemstack(gccheckmarkdisable_m) +} + // GC runs a garbage collection. func GC() { gogc(2) |