runtime: initialize more fields of stack spans

Stack spans don't internally use many of the fields of the mspan,
which means things like the size class and element size get left over
from whatever last used the mspan. This can lead to confusing crashes
and debugging.

Zero these fields or initialize them to something reasonable. This
also lets us simplify some code that currently has to distinguish
between heap and stack spans.

Change-Id: I9bd114e76c147bb32de497045b932f8bf1988bbf
Reviewed-on: https://go-review.googlesource.com/38573
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
diff --git a/src/runtime/mheap.go b/src/runtime/mheap.go
index 6888406..df62154 100644
--- a/src/runtime/mheap.go
+++ b/src/runtime/mheap.go
@@ -326,10 +326,8 @@
 		return false
 	}
 	switch s.state {
-	case mSpanInUse:
+	case mSpanInUse, _MSpanStack:
 		return b < s.limit
-	case _MSpanStack:
-		return b < s.base()+s.npages<<_PageShift
 	default:
 		return false
 	}
@@ -653,6 +651,10 @@
 		s.state = _MSpanStack
 		s.stackfreelist = 0
 		s.allocCount = 0
+		s.sizeclass = 0
+		s.nelems = 0
+		s.elemsize = 0
+		s.limit = s.base() + s.npages<<_PageShift
 		memstats.stacks_inuse += uint64(s.npages << _PageShift)
 	}
 
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
index 830316b..e81bb5b 100644
--- a/src/runtime/stack.go
+++ b/src/runtime/stack.go
@@ -196,7 +196,8 @@
 		if s.stackfreelist.ptr() != nil {
 			throw("bad stackfreelist")
 		}
-		for i := uintptr(0); i < _StackCacheSize; i += _FixedStack << order {
+		s.elemsize = _FixedStack << order
+		for i := uintptr(0); i < _StackCacheSize; i += s.elemsize {
 			x := gclinkptr(s.base() + i)
 			x.ptr().next = s.stackfreelist
 			s.stackfreelist = x
@@ -393,6 +394,7 @@
 			if s == nil {
 				throw("out of memory")
 			}
+			s.elemsize = uintptr(n)
 		}
 		v = unsafe.Pointer(s.base())
 	}