Commit 4de46862 authored by Austin Clements's avatar Austin Clements

runtime: use spanOf* more widely

The logic in the spanOf* functions is open-coded in a lot of places
right now. Replace these with calls to the spanOf* functions.

Change-Id: I3cc996aceb9a529b60fea7ec6fef22008c012978
Reviewed-on: https://go-review.googlesource.com/85880
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent a90f9a00
...@@ -125,9 +125,7 @@ func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) { ...@@ -125,9 +125,7 @@ func cgoCheckTypedBlock(typ *_type, src unsafe.Pointer, off, size uintptr) {
} }
} }
aoff := uintptr(src) - mheap_.arena_start s := spanOfUnchecked(uintptr(src))
idx := aoff >> _PageShift
s := mheap_.spans[idx]
if s.state == _MSpanManual { if s.state == _MSpanManual {
// There are no heap bits for value stored on the stack. // There are no heap bits for value stored on the stack.
// For a channel receive src might be on the stack of some // For a channel receive src might be on the stack of some
......
...@@ -381,15 +381,8 @@ func heapBitsForSpan(base uintptr) (hbits heapBits) { ...@@ -381,15 +381,8 @@ func heapBitsForSpan(base uintptr) (hbits heapBits) {
// in which the pointer p was found and the byte offset at which it // in which the pointer p was found and the byte offset at which it
// was found. These are used for error reporting. // was found. These are used for error reporting.
func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, objIndex uintptr) { func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, objIndex uintptr) {
arenaStart := mheap_.arena_start s = spanOf(p)
if p < arenaStart || p >= mheap_.arena_used { // If p is a bad pointer, it may not be in s's bounds.
return
}
off := p - arenaStart
idx := off >> _PageShift
// p points into the heap, but possibly to the middle of an object.
// Consult the span table to find the block beginning.
s = mheap_.spans[idx]
if s == nil || p < s.base() || p >= s.limit || s.state != mSpanInUse { if s == nil || p < s.base() || p >= s.limit || s.state != mSpanInUse {
if s == nil || s.state == _MSpanManual { if s == nil || s.state == _MSpanManual {
// If s is nil, the virtual address has never been part of the heap. // If s is nil, the virtual address has never been part of the heap.
...@@ -416,7 +409,7 @@ func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, objIndex ui ...@@ -416,7 +409,7 @@ func findObject(p, refBase, refOff uintptr) (base uintptr, s *mspan, objIndex ui
} else { } else {
print(" to unused region of span") print(" to unused region of span")
} }
print(" idx=", hex(idx), " span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", s.state, "\n") print(" span.base()=", hex(s.base()), " span.limit=", hex(s.limit), " span.state=", s.state, "\n")
if refBase != 0 { if refBase != 0 {
print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n") print("runtime: found in object at *(", hex(refBase), "+", hex(refOff), ")\n")
gcDumpObject("object", refBase, refOff) gcDumpObject("object", refBase, refOff)
......
...@@ -1309,11 +1309,8 @@ func gcDumpObject(label string, obj, off uintptr) { ...@@ -1309,11 +1309,8 @@ func gcDumpObject(label string, obj, off uintptr) {
print(label, "=", hex(obj), " is not in the Go heap\n") print(label, "=", hex(obj), " is not in the Go heap\n")
return return
} }
k := obj >> _PageShift s := spanOf(obj)
x := k print(label, "=", hex(obj))
x -= mheap_.arena_start >> _PageShift
s := mheap_.spans[x]
print(label, "=", hex(obj), " k=", hex(k))
if s == nil { if s == nil {
print(" s=nil\n") print(" s=nil\n")
return return
......
...@@ -390,15 +390,7 @@ func (sc spanClass) noscan() bool { ...@@ -390,15 +390,7 @@ func (sc spanClass) noscan() bool {
//go:nowritebarrier //go:nowritebarrier
//go:nosplit //go:nosplit
func inheap(b uintptr) bool { func inheap(b uintptr) bool {
if b == 0 || b < mheap_.arena_start || b >= mheap_.arena_used { return spanOfHeap(b) != nil
return false
}
// Not a beginning of a block, consult span table to find the block beginning.
s := mheap_.spans[(b-mheap_.arena_start)>>_PageShift]
if s == nil || b < s.base() || b >= s.limit || s.state != mSpanInUse {
return false
}
return true
} }
// inHeapOrStack is a variant of inheap that returns true for pointers // inHeapOrStack is a variant of inheap that returns true for pointers
...@@ -407,11 +399,7 @@ func inheap(b uintptr) bool { ...@@ -407,11 +399,7 @@ func inheap(b uintptr) bool {
//go:nowritebarrier //go:nowritebarrier
//go:nosplit //go:nosplit
func inHeapOrStack(b uintptr) bool { func inHeapOrStack(b uintptr) bool {
if b == 0 || b < mheap_.arena_start || b >= mheap_.arena_used { s := spanOf(b)
return false
}
// Not a beginning of a block, consult span table to find the block beginning.
s := mheap_.spans[(b-mheap_.arena_start)>>_PageShift]
if s == nil || b < s.base() { if s == nil || b < s.base() {
return false return false
} }
...@@ -423,9 +411,6 @@ func inHeapOrStack(b uintptr) bool { ...@@ -423,9 +411,6 @@ func inHeapOrStack(b uintptr) bool {
} }
} }
// TODO: spanOf and spanOfUnchecked are open-coded in a lot of places.
// Use the functions instead.
// spanOf returns the span of p. If p does not point into the heap // spanOf returns the span of p. If p does not point into the heap
// arena or no span has ever contained p, spanOf returns nil. // arena or no span has ever contained p, spanOf returns nil.
// //
...@@ -433,6 +418,10 @@ func inHeapOrStack(b uintptr) bool { ...@@ -433,6 +418,10 @@ func inHeapOrStack(b uintptr) bool {
// span that does *not* contain p. If this is a possibility, the // span that does *not* contain p. If this is a possibility, the
// caller should either call spanOfHeap or check the span bounds // caller should either call spanOfHeap or check the span bounds
// explicitly. // explicitly.
//
// Must be nosplit because it has callers that are nosplit.
//
//go:nosplit
func spanOf(p uintptr) *mspan { func spanOf(p uintptr) *mspan {
if p == 0 || p < mheap_.arena_start || p >= mheap_.arena_used { if p == 0 || p < mheap_.arena_start || p >= mheap_.arena_used {
return nil return nil
...@@ -443,12 +432,20 @@ func spanOf(p uintptr) *mspan { ...@@ -443,12 +432,20 @@ func spanOf(p uintptr) *mspan {
// spanOfUnchecked is equivalent to spanOf, but the caller must ensure // spanOfUnchecked is equivalent to spanOf, but the caller must ensure
// that p points into the heap (that is, mheap_.arena_start <= p < // that p points into the heap (that is, mheap_.arena_start <= p <
// mheap_.arena_used). // mheap_.arena_used).
//
// Must be nosplit because it has callers that are nosplit.
//
//go:nosplit
func spanOfUnchecked(p uintptr) *mspan { func spanOfUnchecked(p uintptr) *mspan {
return mheap_.spans[(p-mheap_.arena_start)>>_PageShift] return mheap_.spans[(p-mheap_.arena_start)>>_PageShift]
} }
// spanOfHeap is like spanOf, but returns nil if p does not point to a // spanOfHeap is like spanOf, but returns nil if p does not point to a
// heap object. // heap object.
//
// Must be nosplit because it has callers that are nosplit.
//
//go:nosplit
func spanOfHeap(p uintptr) *mspan { func spanOfHeap(p uintptr) *mspan {
s := spanOf(p) s := spanOf(p)
// If p is not allocated, it may point to a stale span, so we // If p is not allocated, it may point to a stale span, so we
......
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