runtime: clean up GC code
Remove C version of GC.
Convert freeOSMemory to Go.
Restore g0 check in GC.
Remove unknownGCPercent check in GC,
it's initialized explicitly now.
LGTM=rsc
R=golang-codereviews, rsc
CC=golang-codereviews, khr
https://golang.org/cl/139910043
diff --git a/src/pkg/runtime/malloc.go b/src/pkg/runtime/malloc.go
index 7f344c9..e95bdbb 100644
--- a/src/pkg/runtime/malloc.go
+++ b/src/pkg/runtime/malloc.go
@@ -407,33 +407,19 @@
// force = 1 - do GC regardless of current heap usage
// force = 2 - go GC and eager sweep
func gogc(force int32) {
- if !memstats.enablegc {
- return
- }
-
- // TODO: should never happen? Only C calls malloc while holding a lock?
+ // The gc is turned off (via enablegc) until the bootstrap has completed.
+ // Also, malloc gets called in the guts of a number of libraries that might be
+ // holding locks. To avoid deadlocks during stoptheworld, don't bother
+ // trying to run gc while holding a lock. The next mallocgc without a lock
+ // will do the gc instead.
mp := acquirem()
- if mp.locks > 1 {
+ if gp := getg(); gp == mp.g0 || mp.locks > 1 || !memstats.enablegc || panicking != 0 || gcpercent < 0 {
releasem(mp)
return
}
releasem(mp)
mp = nil
- if panicking != 0 {
- return
- }
- if gcpercent == gcpercentUnknown {
- lock(&mheap_.lock)
- if gcpercent == gcpercentUnknown {
- gcpercent = readgogc()
- }
- unlock(&mheap_.lock)
- }
- if gcpercent < 0 {
- return
- }
-
semacquire(&worldsema, false)
if force == 0 && memstats.heap_alloc < memstats.next_gc {