runtime: update docs, code for SetFinalizer

At last minute before 1.3 we relaxed SetFinalizer to avoid
crashes when you pass the result of a global alloc to it.
This avoids the crash but makes SetFinalizer a bit too relaxed.

Document that the finalizer of a global allocation may not run.

Tighten the SetFinalizer check to ignore a global allocation but
not ignore everything else.

Fixes #7656.

LGTM=r, iant
R=golang-codereviews, iant, r
CC=dvyukov, golang-codereviews, khr, rlh
https://golang.org/cl/145930043
diff --git a/src/runtime/mfinal_test.go b/src/runtime/mfinal_test.go
index 6b53888..d2cead2 100644
--- a/src/runtime/mfinal_test.go
+++ b/src/runtime/mfinal_test.go
@@ -44,10 +44,17 @@
 		{func(x *int) interface{} { return (*Tint)(x) }, func(v Tinter) { finalize((*int)(v.(*Tint))) }},
 	}
 
-	for _, tt := range finalizerTests {
+	for i, tt := range finalizerTests {
 		done := make(chan bool, 1)
 		go func() {
-			v := new(int)
+			// allocate struct with pointer to avoid hitting tinyalloc.
+			// Otherwise we can't be sure when the allocation will
+			// be freed.
+			type T struct {
+				v int
+				p unsafe.Pointer
+			}
+			v := &new(T).v
 			*v = 97531
 			runtime.SetFinalizer(tt.convert(v), tt.finalizer)
 			v = nil
@@ -58,7 +65,7 @@
 		select {
 		case <-ch:
 		case <-time.After(time.Second * 4):
-			t.Errorf("finalizer for type %T didn't run", tt.finalizer)
+			t.Errorf("#%d: finalizer for type %T didn't run", i, tt.finalizer)
 		}
 	}
 }