mirror of
https://github.com/golang/go
synced 2024-11-17 18:44:44 -07:00
runtime: don't async preempt NO_LOCAL_POINTERS assembly functions
We don't async preempt assembly functions. We do that by checking whether the function has a local pointer map, and assume it is an assembly (or, non-Go) function if there isn't one. However, assembly functions marked with NO_LOCAL_POINTERS still have local pointer maps, and we wouldn't identify them. For them, check for the special pointer map runtime.no_pointers_stackmap as well, and treat them as not async preemptible. Change-Id: I1301e3b4d35893c31c4c5a5147a0d775987bd6f4 Reviewed-on: https://go-review.googlesource.com/c/go/+/202337 Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
7955ecebfc
commit
3873e5497d
@ -55,6 +55,7 @@ package runtime
|
||||
import (
|
||||
"runtime/internal/atomic"
|
||||
"runtime/internal/sys"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type suspendGState struct {
|
||||
@ -369,9 +370,12 @@ func isAsyncSafePoint(gp *g, pc, sp uintptr) bool {
|
||||
// functions (except at calls).
|
||||
return false
|
||||
}
|
||||
if funcdata(f, _FUNCDATA_LocalsPointerMaps) == nil {
|
||||
if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || fd == unsafe.Pointer(&no_pointers_stackmap) {
|
||||
// This is assembly code. Don't assume it's
|
||||
// well-formed.
|
||||
// well-formed. We identify assembly code by
|
||||
// checking that it has either no stack map, or
|
||||
// no_pointers_stackmap, which is the stack map
|
||||
// for ones marked as NO_LOCAL_POINTERS.
|
||||
//
|
||||
// TODO: Are there cases that are safe but don't have a
|
||||
// locals pointer map, like empty frame functions?
|
||||
@ -395,3 +399,5 @@ func isAsyncSafePoint(gp *g, pc, sp uintptr) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var no_pointers_stackmap uint64 // defined in assembly, for NO_LOCAL_POINTERS macro
|
||||
|
Loading…
Reference in New Issue
Block a user