mirror of
https://github.com/golang/go
synced 2024-11-05 17:46:16 -07:00
runtime: Pin silently allow pinning of non-Go pointers
People may don't know the detail of a pointer, this make the runtime.Pinner.Pin API easier to use. Fixes #62356
This commit is contained in:
parent
ee788dbae0
commit
418b1ad7f2
@ -59,8 +59,9 @@ func (p *Pinner) Pin(pointer any) {
|
||||
}
|
||||
}
|
||||
ptr := pinnerGetPtr(&pointer)
|
||||
setPinned(ptr, true)
|
||||
p.refs = append(p.refs, ptr)
|
||||
if setPinned(ptr, true) {
|
||||
p.refs = append(p.refs, ptr)
|
||||
}
|
||||
}
|
||||
|
||||
// Unpin unpins all pinned objects of the Pinner.
|
||||
@ -144,14 +145,15 @@ func isPinned(ptr unsafe.Pointer) bool {
|
||||
}
|
||||
|
||||
// setPinned marks or unmarks a Go pointer as pinned.
|
||||
func setPinned(ptr unsafe.Pointer, pin bool) {
|
||||
func setPinned(ptr unsafe.Pointer, pin bool) bool {
|
||||
span := spanOfHeap(uintptr(ptr))
|
||||
if span == nil {
|
||||
if isGoPointerWithoutSpan(ptr) {
|
||||
// this is a linker-allocated or zero size object, nothing to do.
|
||||
return
|
||||
if !pin {
|
||||
panic(errorString("runtime.Pinner.Unpin: unexpected non Go pointer"))
|
||||
}
|
||||
panic(errorString("runtime.Pinner.Pin: argument is not a Go pointer"))
|
||||
// this is a linker-allocated, zero size object or other object,
|
||||
// nothing to do, silently ignore it.
|
||||
return false
|
||||
}
|
||||
|
||||
// ensure that the span is swept, b/c sweeping accesses the specials list
|
||||
@ -209,7 +211,7 @@ func setPinned(ptr unsafe.Pointer, pin bool) {
|
||||
}
|
||||
unlock(&span.speciallock)
|
||||
releasem(mp)
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
type pinState struct {
|
||||
|
@ -522,3 +522,19 @@ func BenchmarkPinnerIsPinnedOnUnpinnedParallel(b *testing.B) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// const string data is not in span.
|
||||
func TestPinnerConstStringData(t *testing.T) {
|
||||
var pinner runtime.Pinner
|
||||
str := "test-const-string"
|
||||
p := unsafe.StringData(str)
|
||||
addr := unsafe.Pointer(p)
|
||||
if !runtime.IsPinned(addr) {
|
||||
t.Fatal("not marked as pinned")
|
||||
}
|
||||
pinner.Pin(p)
|
||||
pinner.Unpin()
|
||||
if !runtime.IsPinned(addr) {
|
||||
t.Fatal("not marked as pinned")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user