github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/compile/internal/gc/racewalk.go (about) 1 // Copyright 2012 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gc 6 7 import ( 8 "github.com/gagliardetto/golang-go/cmd/compile/internal/types" 9 "github.com/gagliardetto/golang-go/cmd/internal/src" 10 "github.com/gagliardetto/golang-go/cmd/internal/sys" 11 ) 12 13 // The racewalk pass is currently handled in three parts. 14 // 15 // First, for flag_race, it inserts calls to racefuncenter and 16 // racefuncexit at the start and end (respectively) of each 17 // function. This is handled below. 18 // 19 // Second, during buildssa, it inserts appropriate instrumentation 20 // calls immediately before each memory load or store. This is handled 21 // by the (*state).instrument method in ssa.go, so here we just set 22 // the Func.InstrumentBody flag as needed. For background on why this 23 // is done during SSA construction rather than a separate SSA pass, 24 // see issue #19054. 25 // 26 // Third we remove calls to racefuncenter and racefuncexit, for leaf 27 // functions without instrumented operations. This is done as part of 28 // ssa opt pass via special rule. 29 30 // TODO(dvyukov): do not instrument initialization as writes: 31 // a := make([]int, 10) 32 33 // Do not instrument the following packages at all, 34 // at best instrumentation would cause infinite recursion. 35 var omit_pkgs = []string{ 36 "runtime/internal/atomic", 37 "runtime/internal/sys", 38 "runtime/internal/math", 39 "runtime", 40 "runtime/race", 41 "runtime/msan", 42 "github.com/gagliardetto/golang-go/not-internal/cpu", 43 } 44 45 // Only insert racefuncenterfp/racefuncexit into the following packages. 46 // Memory accesses in the packages are either uninteresting or will cause false positives. 47 var norace_inst_pkgs = []string{"sync", "sync/atomic"} 48 49 func ispkgin(pkgs []string) bool { 50 if myimportpath != "" { 51 for _, p := range pkgs { 52 if myimportpath == p { 53 return true 54 } 55 } 56 } 57 58 return false 59 } 60 61 func instrument(fn *Node) { 62 if fn.Func.Pragma&Norace != 0 { 63 return 64 } 65 66 if !flag_race || !ispkgin(norace_inst_pkgs) { 67 fn.Func.SetInstrumentBody(true) 68 } 69 70 if flag_race { 71 lno := lineno 72 lineno = src.NoXPos 73 74 if thearch.LinkArch.Arch.Family != sys.AMD64 { 75 fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil)) 76 fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil)) 77 } else { 78 79 // nodpc is the PC of the caller as extracted by 80 // getcallerpc. We use -widthptr(FP) for x86. 81 // This only works for amd64. This will not 82 // work on arm or others that might support 83 // race in the future. 84 nodpc := nodfp.copy() 85 nodpc.Type = types.Types[TUINTPTR] 86 nodpc.Xoffset = int64(-Widthptr) 87 fn.Func.Dcl = append(fn.Func.Dcl, nodpc) 88 fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc)) 89 fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil)) 90 } 91 lineno = lno 92 } 93 }