aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/preempt.go
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2019-10-20 17:23:02 -0400
committerAustin Clements <austin@google.com>2019-11-02 22:02:43 +0000
commit3873e5497d21979910a1ec7cf90a34577fa1f6ae (patch)
tree169399bd2e8b383891c55a3c99f9d7b7eb055c18 /src/runtime/preempt.go
parent7955ecebfc85851d43913f9358fa5f6a7bbb7c59 (diff)
downloadgo-3873e5497d21979910a1ec7cf90a34577fa1f6ae.tar.gz
go-3873e5497d21979910a1ec7cf90a34577fa1f6ae.zip
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>
Diffstat (limited to 'src/runtime/preempt.go')
-rw-r--r--src/runtime/preempt.go10
1 files changed, 8 insertions, 2 deletions
diff --git a/src/runtime/preempt.go b/src/runtime/preempt.go
index 71c3089830..544c251a9f 100644
--- a/src/runtime/preempt.go
+++ b/src/runtime/preempt.go
@@ -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