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>
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
}
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)
}
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
if s == nil {
throw("out of memory")
}
+ s.elemsize = uintptr(n)
}
v = unsafe.Pointer(s.base())
}