2015-02-13 14:40:36 -05:00
|
|
|
// 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: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
"cmd/compile/internal/types"
|
2016-12-07 16:02:42 -08:00
|
|
|
"cmd/internal/src"
|
2018-03-29 11:15:18 -04:00
|
|
|
"cmd/internal/sys"
|
2015-02-13 14:40:36 -05:00
|
|
|
)
|
|
|
|
|
|
2018-06-27 11:40:24 -05:00
|
|
|
// The racewalk pass is currently handled in three parts.
|
2015-10-20 10:00:07 -07:00
|
|
|
//
|
2018-03-27 13:50:08 -07:00
|
|
|
// First, for flag_race, it inserts calls to racefuncenter and
|
|
|
|
|
// racefuncexit at the start and end (respectively) of each
|
|
|
|
|
// function. This is handled below.
|
2015-02-13 14:40:36 -05:00
|
|
|
//
|
2018-03-27 13:50:08 -07:00
|
|
|
// 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.
|
2018-06-27 11:40:24 -05:00
|
|
|
//
|
|
|
|
|
// Third we remove calls to racefuncenter and racefuncexit, for leaf
|
|
|
|
|
// functions without instrumented operations. This is done as part of
|
|
|
|
|
// ssa opt pass via special rule.
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// 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.
|
2018-04-10 22:33:03 +08:00
|
|
|
var omit_pkgs = []string{"runtime/internal/atomic", "runtime/internal/sys", "runtime", "runtime/race", "runtime/msan", "internal/cpu"}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-10-09 16:48:30 -04:00
|
|
|
// Only insert racefuncenterfp/racefuncexit into the following packages.
|
2015-02-13 14:40:36 -05:00
|
|
|
// Memory accesses in the packages are either uninteresting or will cause false positives.
|
2015-10-21 07:04:10 -07:00
|
|
|
var norace_inst_pkgs = []string{"sync", "sync/atomic"}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
func ispkgin(pkgs []string) bool {
|
2015-02-13 14:40:36 -05:00
|
|
|
if myimportpath != "" {
|
2015-09-08 22:22:44 +02:00
|
|
|
for _, p := range pkgs {
|
|
|
|
|
if myimportpath == p {
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-10-20 10:00:07 -07:00
|
|
|
func instrument(fn *Node) {
|
2018-03-27 15:35:51 -07:00
|
|
|
if fn.Func.Pragma&Norace != 0 {
|
2015-02-13 14:40:36 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-13 18:37:18 -07:00
|
|
|
if !flag_race || !ispkgin(norace_inst_pkgs) {
|
2018-03-27 13:50:08 -07:00
|
|
|
fn.Func.SetInstrumentBody(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-13 18:37:18 -07:00
|
|
|
if flag_race {
|
2018-03-27 13:50:08 -07:00
|
|
|
lno := lineno
|
|
|
|
|
lineno = src.NoXPos
|
|
|
|
|
|
2018-03-29 11:15:18 -04:00
|
|
|
if thearch.LinkArch.Arch == sys.ArchPPC64LE {
|
|
|
|
|
fn.Func.Enter.Prepend(mkcall("racefuncenterfp", nil, nil))
|
|
|
|
|
fn.Func.Exit.Append(mkcall("racefuncexit", nil, nil))
|
|
|
|
|
} else {
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2018-03-29 11:15:18 -04:00
|
|
|
// nodpc is the PC of the caller as extracted by
|
|
|
|
|
// getcallerpc. We use -widthptr(FP) for x86.
|
|
|
|
|
// BUG: This only works for amd64. This will not
|
|
|
|
|
// work on arm or others that might support
|
|
|
|
|
// race in the future.
|
|
|
|
|
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))
|
|
|
|
|
}
|
2018-03-27 13:50:08 -07:00
|
|
|
lineno = lno
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|