reflect: make unsafe use of SliceHeader gc-friendly

Revert workaround in compiler and
revert test for compiler workaround.

Tested that the 386 build continues to fail if
the gc change is made without the reflect change.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5312041
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
index 056704f..9ddbee0 100644
--- a/src/pkg/reflect/value.go
+++ b/src/pkg/reflect/value.go
@@ -1424,11 +1424,17 @@
 		typ = iv.typ.toType()
 		base = (*SliceHeader)(iv.addr).Data
 	}
-	s := new(SliceHeader)
+
+	// Declare slice so that gc can see the base pointer in it.
+	var x []byte
+
+	// Reinterpret as *SliceHeader to edit.
+	s := (*SliceHeader)(unsafe.Pointer(&x))
 	s.Data = base + uintptr(beg)*typ.Elem().Size()
 	s.Len = end - beg
-	s.Cap = cap - beg
-	return valueFromAddr(iv.flag&flagRO, typ, unsafe.Pointer(s))
+	s.Cap = end - beg
+
+	return valueFromAddr(iv.flag&flagRO, typ, unsafe.Pointer(&x))
 }
 
 // String returns the string v's underlying value, as a string.
@@ -1654,12 +1660,17 @@
 	if typ.Kind() != Slice {
 		panic("reflect: MakeSlice of non-slice type")
 	}
-	s := &SliceHeader{
-		Data: uintptr(unsafe.NewArray(typ.Elem(), cap)),
-		Len:  len,
-		Cap:  cap,
-	}
-	return valueFromAddr(0, typ, unsafe.Pointer(s))
+
+	// Declare slice so that gc can see the base pointer in it.
+	var x []byte
+
+	// Reinterpret as *SliceHeader to edit.
+	s := (*SliceHeader)(unsafe.Pointer(&x))
+	s.Data = uintptr(unsafe.NewArray(typ.Elem(), cap))
+	s.Len = len
+	s.Cap = cap
+
+	return valueFromAddr(0, typ, unsafe.Pointer(&x))
 }
 
 // MakeChan creates a new channel with the specified type and buffer size.