]> Cypherpunks repositories - gostls13.git/commitdiff
cmd, runtime: eliminate runtime.no_pointers_stackmap
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 1 Oct 2021 23:25:32 +0000 (16:25 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 4 Oct 2021 22:45:17 +0000 (22:45 +0000)
runtime.no_pointers_stackmap is an odd beast.
It is defined in a Go file, populated by assembly,
used by the GC, and its address is magic used
by async pre-emption to ascertain whether a
routine was implemented in assembly.

A subsequent change will force all GC data into the go.func.* linker symbol.
runtime.no_pointers_stackmap is GC data, so it must go there.
Yet it also needs to go into rodata, for the runtime address trick.

This change eliminates it entirely.

Replace the runtime address check with the newly introduced asm funcflag.

Handle the assembly macro as magic, similarly to our handling of go_args_stackmap.
This allows the no_pointers_stackmap to be identical in all ways
to other gclocals stackmaps, including content-addressability.

Change-Id: Id2f20a262cfab0719beb88e6342984ec4b196268
Reviewed-on: https://go-review.googlesource.com/c/go/+/353672
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/internal/obj/plist.go
src/runtime/asm.s
src/runtime/funcdata.h
src/runtime/preempt.go

index 348a16356ebc7f1cd22c71151a10ff27725df5bd..e5bbdd51a7548de50edb7553b79d8686e5e5574e 100644 (file)
@@ -54,11 +54,28 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string
                        if curtext == nil { // func _() {}
                                continue
                        }
-                       if p.To.Sym.Name == "go_args_stackmap" {
+                       switch p.To.Sym.Name {
+                       case "go_args_stackmap":
                                if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_ArgsPointerMaps {
                                        ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
                                }
                                p.To.Sym = ctxt.LookupDerived(curtext, curtext.Name+".args_stackmap")
+                       case "no_pointers_stackmap":
+                               if p.From.Type != TYPE_CONST || p.From.Offset != objabi.FUNCDATA_LocalsPointerMaps {
+                                       ctxt.Diag("FUNCDATA use of no_pointers_stackmap(SB) without FUNCDATA_LocalsPointerMaps")
+                               }
+                               // funcdata for functions with no local variables in frame.
+                               // Define two zero-length bitmaps, because the same index is used
+                               // for the local variables as for the argument frame, and assembly
+                               // frames have two argument bitmaps, one without results and one with results.
+                               // Write []uint32{2, 0}.
+                               b := make([]byte, 8)
+                               ctxt.Arch.ByteOrder.PutUint32(b, 2)
+                               s := ctxt.GCLocalsSym(b)
+                               if !s.OnList() {
+                                       ctxt.Globl(s, int64(len(s.P)), int(RODATA|DUPOK))
+                               }
+                               p.To.Sym = s
                        }
 
                }
index 0e14fcd3e6a3569f17357b31e3cefa4a142c0ae8..84d56de7dd85168084987b2ef7f47b48eaca6e36 100644 (file)
@@ -4,14 +4,6 @@
 
 #include "textflag.h"
 
-// funcdata for functions with no local variables in frame.
-// Define two zero-length bitmaps, because the same index is used
-// for the local variables as for the argument frame, and assembly
-// frames have two argument bitmaps, one without results and one with results.
-DATA runtime·no_pointers_stackmap+0x00(SB)/4, $2
-DATA runtime·no_pointers_stackmap+0x04(SB)/4, $0
-GLOBL runtime·no_pointers_stackmap(SB),RODATA, $8
-
 #ifndef GOARCH_amd64
 TEXT ·sigpanic0(SB),NOSPLIT,$0-0
        JMP     ·sigpanic<ABIInternal>(SB)
index 1002b181e4cf62c39f6962affa41bdf9ac53f53a..15f1b5c9a1ffc13a0f7645f64b0792c80db6c7a0 100644 (file)
@@ -44,7 +44,7 @@
 
 // NO_LOCAL_POINTERS indicates that the assembly function stores
 // no pointers to heap objects in its local stack variables.
-#define NO_LOCAL_POINTERS      FUNCDATA $FUNCDATA_LocalsPointerMaps, runtime·no_pointers_stackmap(SB)
+#define NO_LOCAL_POINTERS      FUNCDATA $FUNCDATA_LocalsPointerMaps, no_pointers_stackmap(SB)
 
 // ArgsSizeUnknown is set in Func.argsize to mark all functions
 // whose argument size is unknown (C vararg functions, and
index 18566a745987251ce3aae3b4262d825cef856c3c..da24f5042c0707eb9e7611196904843e0c8177e7 100644 (file)
@@ -56,7 +56,6 @@ import (
        "internal/abi"
        "internal/goarch"
        "runtime/internal/atomic"
-       "unsafe"
 )
 
 type suspendGState struct {
@@ -405,12 +404,9 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
                // functions (except at calls).
                return false, 0
        }
-       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. 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.
+       if fd := funcdata(f, _FUNCDATA_LocalsPointerMaps); fd == nil || f.flag&funcFlag_ASM != 0 {
+               // This is assembly code. Don't assume it's well-formed.
+               // TODO: Empirically we still need the fd == nil check. Why?
                //
                // TODO: Are there cases that are safe but don't have a
                // locals pointer map, like empty frame functions?
@@ -455,5 +451,3 @@ func isAsyncSafePoint(gp *g, pc, sp, lr uintptr) (bool, uintptr) {
        }
        return true, pc
 }
-
-var no_pointers_stackmap uint64 // defined in assembly, for NO_LOCAL_POINTERS macro