Skip to content

Commit a22bd3d

Browse files
committed
cmd/compile: use getcallerpc for racefuncentry
Currently, when instrumenting for the race detector, the compiler inserts racefuncentry/racefuncentryfp at the entry of instrumented functions. racefuncentry takes the caller's PC. On AMD64, we synthesize a node which points to -8(FP) which is where the return address is stored. Later this node turns to a special Arg in SSA that is not really an argument. This causes problems in the new ABI work so that special node has to be special-cased. This CL changes the special node to a call to getcallerpc, which lowers to an intrinsic in SSA. This also unifies AMD64 code path and LR machine code path, as getcallerpc works on all platforms. Change-Id: I1377e140b91e0473cfcadfda221f26870c1b124d Reviewed-on: https://go-review.googlesource.com/c/go/+/297929 Trust: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
1 parent a829114 commit a22bd3d

File tree

6 files changed

+44
-55
lines changed

6 files changed

+44
-55
lines changed

src/cmd/compile/internal/base/base.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,6 @@ var NoInstrumentPkgs = []string{
7070
"internal/cpu",
7171
}
7272

73-
// Don't insert racefuncenterfp/racefuncexit into the following packages.
73+
// Don't insert racefuncenter/racefuncexit into the following packages.
7474
// Memory accesses in the packages are either uninteresting or will cause false positives.
7575
var NoRacePkgs = []string{"sync", "sync/atomic"}

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,18 +1612,18 @@ func needRaceCleanup(sym *AuxCall, v *Value) bool {
16121612
if !f.Config.Race {
16131613
return false
16141614
}
1615-
if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncenterfp") && !isSameCall(sym, "runtime.racefuncexit") {
1615+
if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncexit") {
16161616
return false
16171617
}
16181618
for _, b := range f.Blocks {
16191619
for _, v := range b.Values {
16201620
switch v.Op {
16211621
case OpStaticCall, OpStaticLECall:
1622-
// Check for racefuncenter/racefuncenterfp will encounter racefuncexit and vice versa.
1622+
// Check for racefuncenter will encounter racefuncexit and vice versa.
16231623
// Allow calls to panic*
16241624
s := v.Aux.(*AuxCall).Fn.String()
16251625
switch s {
1626-
case "runtime.racefuncenter", "runtime.racefuncenterfp", "runtime.racefuncexit",
1626+
case "runtime.racefuncenter", "runtime.racefuncexit",
16271627
"runtime.panicdivide", "runtime.panicwrap",
16281628
"runtime.panicshift":
16291629
continue

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4564,6 +4564,9 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder {
45644564
if sym.Pkg == types.LocalPkg {
45654565
pkg = base.Ctxt.Pkgpath
45664566
}
4567+
if sym.Pkg == ir.Pkgs.Runtime {
4568+
pkg = "runtime"
4569+
}
45674570
if base.Flag.Race && pkg == "sync/atomic" {
45684571
// The race detector needs to be able to intercept these calls.
45694572
// We can't intrinsify them.

src/cmd/compile/internal/typecheck/builtin.go

Lines changed: 29 additions & 28 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/compile/internal/typecheck/builtin/runtime.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
// to update builtin.go. This is not done automatically
77
// to avoid depending on having a working compiler binary.
88

9+
//go:build ignore
910
// +build ignore
1011

1112
package runtime
@@ -224,9 +225,10 @@ func uint32tofloat64(uint32) float64
224225

225226
func complex128div(num complex128, den complex128) (quo complex128)
226227

228+
func getcallerpc() uintptr
229+
227230
// race detection
228231
func racefuncenter(uintptr)
229-
func racefuncenterfp()
230232
func racefuncexit()
231233
func raceread(uintptr)
232234
func racewrite(uintptr)

src/cmd/compile/internal/walk/race.go

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@ package walk
77
import (
88
"cmd/compile/internal/base"
99
"cmd/compile/internal/ir"
10-
"cmd/compile/internal/ssagen"
11-
"cmd/compile/internal/typecheck"
1210
"cmd/compile/internal/types"
1311
"cmd/internal/src"
14-
"cmd/internal/sys"
1512
)
1613

1714
func instrument(fn *ir.Func) {
@@ -26,26 +23,12 @@ func instrument(fn *ir.Func) {
2623
if base.Flag.Race {
2724
lno := base.Pos
2825
base.Pos = src.NoXPos
29-
if ssagen.Arch.LinkArch.Arch.Family != sys.AMD64 {
30-
fn.Enter.Prepend(mkcallstmt("racefuncenterfp"))
31-
fn.Exit.Append(mkcallstmt("racefuncexit"))
32-
} else {
33-
34-
// nodpc is the PC of the caller as extracted by
35-
// getcallerpc. We use -widthptr(FP) for x86.
36-
// This only works for amd64. This will not
37-
// work on arm or others that might support
38-
// race in the future.
39-
40-
nodpc := ir.NewNameAt(src.NoXPos, typecheck.Lookup(".fp"))
41-
nodpc.Class = ir.PPARAM
42-
nodpc.SetUsed(true)
43-
nodpc.SetType(types.Types[types.TUINTPTR])
44-
nodpc.SetFrameOffset(int64(-types.PtrSize))
45-
fn.Dcl = append(fn.Dcl, nodpc)
46-
fn.Enter.Prepend(mkcallstmt("racefuncenter", nodpc))
47-
fn.Exit.Append(mkcallstmt("racefuncexit"))
26+
var init ir.Nodes
27+
fn.Enter.Prepend(mkcallstmt("racefuncenter", mkcall("getcallerpc", types.Types[types.TUINTPTR], &init)))
28+
if len(init) != 0 {
29+
base.Fatalf("race walk: unexpected init for getcallerpc")
4830
}
31+
fn.Exit.Append(mkcallstmt("racefuncexit"))
4932
base.Pos = lno
5033
}
5134
}

0 commit comments

Comments
 (0)