// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package gc import ( "cmd/compile/internal/types" "cmd/internal/src" ) // The racewalk pass is currently handled in two parts. // // First, for flag_race, it inserts calls to racefuncenter and // racefuncexit at the start and end (respectively) of each // function. This is handled below. // // Second, during buildssa, it inserts appropriate instrumentation // calls immediately before each memory load or store. This is handled // by the (*state).instrument method in ssa.go, so here we just set // the Func.InstrumentBody flag as needed. For background on why this // is done during SSA construction rather than a separate SSA pass, // see issue #19054. // TODO(dvyukov): do not instrument initialization as writes: // a := make([]int, 10) // Do not instrument the following packages at all, // at best instrumentation would cause infinite recursion. var omit_pkgs = []string{"runtime/internal/atomic", "runtime/internal/sys", "runtime", "runtime/race", "runtime/msan"} // Only insert racefuncenterfp/racefuncexit into the following packages. // Memory accesses in the packages are either uninteresting or will cause false positives. var norace_inst_pkgs = []string{"sync", "sync/atomic"} func ispkgin(pkgs []string) bool { if myimportpath != "" { for _, p := range pkgs { if myimportpath == p { return true } } } return false } func instrument(fn *Node) { if fn.Func.Pragma&Norace != 0 { return } if !flag_race || !ispkgin(norace_inst_pkgs) { fn.Func.SetInstrumentBody(true) } if flag_race { lno := lineno lineno = src.NoXPos // nodpc is the PC of the caller as extracted by // getcallerpc. We use -widthptr(FP) for x86. // BUG: this will not work on arm. nodpc := nodfp.copy() nodpc.Type = types.Types[TUINTPTR] nodpc.Xoffset = int64(-Widthptr) fn.Func.Dcl = append(fn.Func.Dcl, nodpc) fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc)) fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil)) lineno = lno } }