]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: find g in Windows profiler using SP
authorRuss Cox <rsc@golang.org>
Wed, 27 Jan 2021 16:06:04 +0000 (11:06 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 19 Feb 2021 00:03:22 +0000 (00:03 +0000)
The architecture-specific interpretation of m->tls[0]
is unnecessary and fragile. Delete it.

This CL is part of a stack adding windows/arm64
support (#36439), intended to land in the Go 1.17 cycle.
This CL is, however, not windows/arm64-specific.
It is cleanup meant to make the port (and future ports) easier.

Change-Id: I927345e52fa2f1741d4914478a29d1fb8acb0dc3
Reviewed-on: https://go-review.googlesource.com/c/go/+/288806
Trust: Russ Cox <rsc@golang.org>
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/runtime/os_windows.go
src/runtime/sys_windows_arm.s

index a2a124cd9d029989013b82731f70934d4b9795dc..a8406460e2391682752b942485d02281036ec29a 100644 (file)
@@ -1132,21 +1132,21 @@ func profilem(mp *m, thread uintptr) {
        c.contextflags = _CONTEXT_CONTROL
        stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
 
-       gp := gFromTLS(mp)
+       gp := gFromSP(mp, c.sp())
 
        sigprof(c.ip(), c.sp(), c.lr(), gp, mp)
 }
 
-func gFromTLS(mp *m) *g {
-       switch GOARCH {
-       case "arm":
-               tls := &mp.tls[0]
-               return **((***g)(unsafe.Pointer(tls)))
-       case "386", "amd64":
-               tls := &mp.tls[0]
-               return *((**g)(unsafe.Pointer(tls)))
+func gFromSP(mp *m, sp uintptr) *g {
+       if gp := mp.g0; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+               return gp
+       }
+       if gp := mp.gsignal; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+               return gp
+       }
+       if gp := mp.curg; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
+               return gp
        }
-       throw("unsupported architecture")
        return nil
 }
 
@@ -1295,7 +1295,7 @@ func preemptM(mp *m) {
        unlock(&suspendLock)
 
        // Does it want a preemption and is it safe to preempt?
-       gp := gFromTLS(mp)
+       gp := gFromSP(mp, c.sp())
        if wantAsyncPreempt(gp) {
                if ok, newpc := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
                        // Inject call to asyncPreempt
index a55f474d39b8550900a0851df1c1be3265745f9c..a30d63513ac7a336e2f1ec2bbfbe20bc5c728264 100644 (file)
@@ -350,9 +350,6 @@ TEXT runtime·tstart_stdcall(SB),NOSPLIT|NOFRAME,$0
        MOVW    R0, g_m(g)
        BL      runtime·save_g(SB)
 
-       // do per-thread TLS initialization
-       BL      init_thread_tls<>(SB)
-
        // Layout new m scheduler stack on os stack.
        MOVW    R13, R0
        MOVW    R0, g_stack+stack_hi(g)
@@ -581,39 +578,8 @@ TEXT runtime·_initcgo(SB),NOSPLIT|NOFRAME,$0
        MOVW    $runtime·tls_g(SB), R1
        MOVW    R0, (R1)
 
-       BL      init_thread_tls<>(SB)
-
        MOVW    R4, R13
        MOVM.IA.W (R13), [R4, R15]      // pop {r4, pc}
 
-// void init_thread_tls()
-//
-// Does per-thread TLS initialization. Saves a pointer to the TLS slot
-// holding G, in the current m.
-//
-//     g->m->tls[0] = &_TEB->TlsSlots[tls_g]
-//
-// The purpose of this is to enable the profiling handler to get the
-// current g associated with the thread. We cannot use m->curg because curg
-// only holds the current user g. If the thread is executing system code or
-// external code, m->curg will be NULL. The thread's TLS slot always holds
-// the current g, so save a reference to this location so the profiling
-// handler can get the real g from the thread's m.
-//
-// Clobbers R0-R3
-TEXT init_thread_tls<>(SB),NOSPLIT|NOFRAME,$0
-       // compute &_TEB->TlsSlots[tls_g]
-       MRC     15, 0, R0, C13, C0, 2
-       ADD     $0xe10, R0
-       MOVW    $runtime·tls_g(SB), R1
-       MOVW    (R1), R1
-       MOVW    R1<<2, R1
-       ADD     R1, R0
-
-       // save in g->m->tls[0]
-       MOVW    g_m(g), R1
-       MOVW    R0, m_tls(R1)
-       RET
-
 // Holds the TLS Slot, which was allocated by TlsAlloc()
 GLOBL runtime·tls_g+0(SB), NOPTR, $4