Commit aed86103 authored by Rick Hudson's avatar Rick Hudson

[dev.garbage] runtime: add stackfreelist

The freelist for normal objects and the freelist
for stacks share the same mspan field for holding
the list head but are operated on by different code
sequences. This overloading complicates the use of bit
vectors for allocation of normal objects. This change
refactors the use of the stackfreelist out from the
use of freelist.

Change-Id: I5b155b5b8a1fcd8e24c12ee1eb0800ad9b6b4fa0
Reviewed-on: https://go-review.googlesource.com/19315Reviewed-by: 's avatarAustin Clements <austin@google.com>
parent 2ac8bdc5
...@@ -552,7 +552,7 @@ func (h *mheap) allocStack(npage uintptr) *mspan { ...@@ -552,7 +552,7 @@ func (h *mheap) allocStack(npage uintptr) *mspan {
s := h.allocSpanLocked(npage) s := h.allocSpanLocked(npage)
if s != nil { if s != nil {
s.state = _MSpanStack s.state = _MSpanStack
s.freelist = 0 s.stackfreelist = 0
s.ref = 0 s.ref = 0
memstats.stacks_inuse += uint64(s.npages << _PageShift) memstats.stacks_inuse += uint64(s.npages << _PageShift)
} }
......
...@@ -194,23 +194,23 @@ func stackpoolalloc(order uint8) gclinkptr { ...@@ -194,23 +194,23 @@ func stackpoolalloc(order uint8) gclinkptr {
if s.ref != 0 { if s.ref != 0 {
throw("bad ref") throw("bad ref")
} }
if s.freelist.ptr() != nil { if s.stackfreelist.ptr() != nil {
throw("bad freelist") throw("bad stackfreelist")
} }
for i := uintptr(0); i < _StackCacheSize; i += _FixedStack << order { for i := uintptr(0); i < _StackCacheSize; i += _FixedStack << order {
x := gclinkptr(uintptr(s.start)<<_PageShift + i) x := gclinkptr(uintptr(s.start)<<_PageShift + i)
x.ptr().next = s.freelist x.ptr().next = s.stackfreelist
s.freelist = x s.stackfreelist = x
} }
list.insert(s) list.insert(s)
} }
x := s.freelist x := s.stackfreelist
if x.ptr() == nil { if x.ptr() == nil {
throw("span has no free stacks") throw("span has no free stacks")
} }
s.freelist = x.ptr().next s.stackfreelist = x.ptr().next
s.ref++ s.ref++
if s.freelist.ptr() == nil { if s.stackfreelist.ptr() == nil {
// all stacks in s are allocated. // all stacks in s are allocated.
list.remove(s) list.remove(s)
} }
...@@ -223,12 +223,12 @@ func stackpoolfree(x gclinkptr, order uint8) { ...@@ -223,12 +223,12 @@ func stackpoolfree(x gclinkptr, order uint8) {
if s.state != _MSpanStack { if s.state != _MSpanStack {
throw("freeing stack not in a stack span") throw("freeing stack not in a stack span")
} }
if s.freelist.ptr() == nil { if s.stackfreelist.ptr() == nil {
// s will now have a free stack // s will now have a free stack
stackpool[order].insert(s) stackpool[order].insert(s)
} }
x.ptr().next = s.freelist x.ptr().next = s.stackfreelist
s.freelist = x s.stackfreelist = x
s.ref-- s.ref--
if gcphase == _GCoff && s.ref == 0 { if gcphase == _GCoff && s.ref == 0 {
// Span is completely free. Return it to the heap // Span is completely free. Return it to the heap
...@@ -247,7 +247,7 @@ func stackpoolfree(x gclinkptr, order uint8) { ...@@ -247,7 +247,7 @@ func stackpoolfree(x gclinkptr, order uint8) {
// //
// By not freeing, we prevent step #4 until GC is done. // By not freeing, we prevent step #4 until GC is done.
stackpool[order].remove(s) stackpool[order].remove(s)
s.freelist = 0 s.stackfreelist = 0
mheap_.freeStack(s) mheap_.freeStack(s)
} }
} }
...@@ -1138,6 +1138,7 @@ func freeStackSpans() { ...@@ -1138,6 +1138,7 @@ func freeStackSpans() {
if s.ref == 0 { if s.ref == 0 {
list.remove(s) list.remove(s)
s.freelist = 0 s.freelist = 0
s.stackfreelist = 0
mheap_.freeStack(s) mheap_.freeStack(s)
} }
s = next s = next
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment