diff options
author | Cherry Zhang <cherryyz@google.com> | 2019-10-20 17:23:02 -0400 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2019-11-02 22:02:43 +0000 |
commit | 3873e5497d21979910a1ec7cf90a34577fa1f6ae (patch) | |
tree | 169399bd2e8b383891c55a3c99f9d7b7eb055c18 /src/runtime/preempt.go | |
parent | 7955ecebfc85851d43913f9358fa5f6a7bbb7c59 (diff) | |
download | go-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.go | 10 |
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 |