diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/mgcmark.go | 25 | ||||
| -rw-r--r-- | src/runtime/stack.go | 38 | ||||
| -rw-r--r-- | src/runtime/stkframe.go | 2 |
3 files changed, 13 insertions, 52 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 3a437ac8f8..6e2bd8b948 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -951,31 +951,12 @@ func scanstack(gp *g, gcw *gcWork) int64 { println() printunlock() } - gcdata := r.gcdata() - var s *mspan - if r.useGCProg() { - // This path is pretty unlikely, an object large enough - // to have a GC program allocated on the stack. - // We need some space to unpack the program into a straight - // bitmask, which we allocate/free here. - // TODO: it would be nice if there were a way to run a GC - // program without having to store all its bits. We'd have - // to change from a Lempel-Ziv style program to something else. - // Or we can forbid putting objects on stacks if they require - // a gc program (see issue 27447). - s = materializeGCProg(r.ptrdata(), gcdata) - gcdata = (*byte)(unsafe.Pointer(s.startAddr)) - } - + ptrBytes, gcData := r.gcdata() b := state.stack.lo + uintptr(obj.off) if conservative { - scanConservative(b, r.ptrdata(), gcdata, gcw, &state) + scanConservative(b, ptrBytes, gcData, gcw, &state) } else { - scanblock(b, r.ptrdata(), gcdata, gcw, &state) - } - - if s != nil { - dematerializeGCProg(s) + scanblock(b, ptrBytes, gcData, gcw, &state) } } diff --git a/src/runtime/stack.go b/src/runtime/stack.go index aef72d5117..8f11f54cce 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -722,22 +722,12 @@ func adjustframe(frame *stkframe, adjinfo *adjustinfo) { // we call into morestack.) continue } - ptrdata := obj.ptrdata() - gcdata := obj.gcdata() - var s *mspan - if obj.useGCProg() { - // See comments in mgcmark.go:scanstack - s = materializeGCProg(ptrdata, gcdata) - gcdata = (*byte)(unsafe.Pointer(s.startAddr)) - } - for i := uintptr(0); i < ptrdata; i += goarch.PtrSize { - if *addb(gcdata, i/(8*goarch.PtrSize))>>(i/goarch.PtrSize&7)&1 != 0 { + ptrBytes, gcData := obj.gcdata() + for i := uintptr(0); i < ptrBytes; i += goarch.PtrSize { + if *addb(gcData, i/(8*goarch.PtrSize))>>(i/goarch.PtrSize&7)&1 != 0 { adjustpointer(adjinfo, unsafe.Pointer(p+i)) } } - if s != nil { - dematerializeGCProg(s) - } } } } @@ -1288,24 +1278,14 @@ type stackObjectRecord struct { // if non-negative, offset from argp off int32 size int32 - _ptrdata int32 // ptrdata, or -ptrdata is GC prog is used + ptrBytes int32 gcdataoff uint32 // offset to gcdata from moduledata.rodata } -func (r *stackObjectRecord) useGCProg() bool { - return r._ptrdata < 0 -} - -func (r *stackObjectRecord) ptrdata() uintptr { - x := r._ptrdata - if x < 0 { - return uintptr(-x) - } - return uintptr(x) -} - -// gcdata returns pointer map or GC prog of the type. -func (r *stackObjectRecord) gcdata() *byte { +// gcdata returns the number of bytes that contain pointers, and +// a ptr/nonptr bitmask covering those bytes. +// Note that this bitmask might be larger than internal/abi.MaxPtrmaskBytes. +func (r *stackObjectRecord) gcdata() (uintptr, *byte) { ptr := uintptr(unsafe.Pointer(r)) var mod *moduledata for datap := &firstmoduledata; datap != nil; datap = datap.next { @@ -1318,7 +1298,7 @@ func (r *stackObjectRecord) gcdata() *byte { // you may have made a copy of a stackObjectRecord. // You must use the original pointer. res := mod.rodata + uintptr(r.gcdataoff) - return (*byte)(unsafe.Pointer(res)) + return uintptr(r.ptrBytes), (*byte)(unsafe.Pointer(res)) } // This is exported as ABI0 via linkname so obj can call it. diff --git a/src/runtime/stkframe.go b/src/runtime/stkframe.go index 2bab5a3a0e..b09320fa74 100644 --- a/src/runtime/stkframe.go +++ b/src/runtime/stkframe.go @@ -283,7 +283,7 @@ func stkobjinit() { methodValueCallFrameObjs[0] = stackObjectRecord{ off: -int32(alignUp(abiRegArgsType.Size_, 8)), // It's always the highest address local. size: int32(abiRegArgsType.Size_), - _ptrdata: int32(abiRegArgsType.PtrBytes), + ptrBytes: int32(abiRegArgsType.PtrBytes), gcdataoff: uint32(uintptr(unsafe.Pointer(abiRegArgsType.GCData)) - mod.rodata), } } |
