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 {