mirror of
https://github.com/golang/go
synced 2024-11-15 02:40:32 -07:00
internal/coverage/cfile: remove more //go:linkname usage
Move code so that basic imports work instead of //go:linkname for metadata lists. For #67401. Change-Id: Id02075570befc45a9426559aad2137ab540928b2 Reviewed-on: https://go-review.googlesource.com/c/go/+/585915 Reviewed-by: Than McIntosh <thanm@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
c96159c252
commit
df4e49366c
@ -39,23 +39,34 @@ import (
|
|||||||
var depsRules = `
|
var depsRules = `
|
||||||
# No dependencies allowed for any of these packages.
|
# No dependencies allowed for any of these packages.
|
||||||
NONE
|
NONE
|
||||||
< cmp, container/list, container/ring,
|
< unsafe
|
||||||
internal/cfg, internal/coverage, internal/coverage/rtcov,
|
< cmp,
|
||||||
internal/coverage/uleb128, internal/coverage/calloc,
|
container/list,
|
||||||
internal/goarch, internal/godebugs,
|
container/ring,
|
||||||
internal/goexperiment, internal/goos, internal/byteorder,
|
internal/byteorder,
|
||||||
internal/goversion, internal/nettrace, internal/platform,
|
internal/cfg,
|
||||||
internal/profilerecord, internal/trace/traceviewer/format,
|
internal/coverage,
|
||||||
|
internal/coverage/rtcov,
|
||||||
|
internal/coverage/uleb128,
|
||||||
|
internal/coverage/calloc,
|
||||||
|
internal/cpu,
|
||||||
|
internal/goarch,
|
||||||
|
internal/godebugs,
|
||||||
|
internal/goexperiment,
|
||||||
|
internal/goos,
|
||||||
|
internal/goversion,
|
||||||
|
internal/nettrace,
|
||||||
|
internal/platform,
|
||||||
|
internal/profilerecord,
|
||||||
|
internal/trace/traceviewer/format,
|
||||||
log/internal,
|
log/internal,
|
||||||
unicode/utf8, unicode/utf16, unicode,
|
math/bits,
|
||||||
unsafe;
|
unicode,
|
||||||
|
unicode/utf8,
|
||||||
|
unicode/utf16;
|
||||||
|
|
||||||
# internal/abi depends only on internal/goarch and unsafe.
|
internal/goarch < internal/abi;
|
||||||
internal/goarch, unsafe < internal/abi;
|
internal/byteorder, internal/goarch < internal/chacha8rand;
|
||||||
|
|
||||||
internal/byteorder, internal/goarch, unsafe < internal/chacha8rand;
|
|
||||||
|
|
||||||
unsafe < internal/cpu;
|
|
||||||
|
|
||||||
# RUNTIME is the core runtime group of packages, all of them very light-weight.
|
# RUNTIME is the core runtime group of packages, all of them very light-weight.
|
||||||
internal/abi,
|
internal/abi,
|
||||||
@ -66,7 +77,8 @@ var depsRules = `
|
|||||||
internal/godebugs,
|
internal/godebugs,
|
||||||
internal/goexperiment,
|
internal/goexperiment,
|
||||||
internal/goos,
|
internal/goos,
|
||||||
internal/profilerecord
|
internal/profilerecord,
|
||||||
|
math/bits
|
||||||
< internal/bytealg
|
< internal/bytealg
|
||||||
< internal/stringslite
|
< internal/stringslite
|
||||||
< internal/itoa
|
< internal/itoa
|
||||||
@ -86,22 +98,17 @@ var depsRules = `
|
|||||||
< internal/godebug
|
< internal/godebug
|
||||||
< internal/reflectlite
|
< internal/reflectlite
|
||||||
< errors
|
< errors
|
||||||
< internal/oserror, math/bits
|
< internal/oserror;
|
||||||
|
|
||||||
|
cmp, internal/race, math/bits
|
||||||
< iter
|
< iter
|
||||||
|
< maps, slices;
|
||||||
|
|
||||||
|
internal/oserror, maps, slices
|
||||||
< RUNTIME;
|
< RUNTIME;
|
||||||
|
|
||||||
RUNTIME, unsafe
|
RUNTIME
|
||||||
< maps;
|
< sort
|
||||||
|
|
||||||
# slices depends on unsafe for overlapping check, cmp for comparison
|
|
||||||
# semantics, and math/bits for # calculating bitlength of numbers.
|
|
||||||
RUNTIME, unsafe, cmp, math/bits
|
|
||||||
< slices;
|
|
||||||
|
|
||||||
RUNTIME, slices
|
|
||||||
< sort;
|
|
||||||
|
|
||||||
sort
|
|
||||||
< container/heap;
|
< container/heap;
|
||||||
|
|
||||||
RUNTIME
|
RUNTIME
|
||||||
@ -663,7 +670,7 @@ var depsRules = `
|
|||||||
< internal/trace/traceviewer;
|
< internal/trace/traceviewer;
|
||||||
|
|
||||||
# Coverage.
|
# Coverage.
|
||||||
FMT, crypto/md5, encoding/binary, regexp, sort, text/tabwriter, unsafe,
|
FMT, crypto/md5, encoding/binary, regexp, sort, text/tabwriter,
|
||||||
internal/coverage, internal/coverage/uleb128
|
internal/coverage, internal/coverage/uleb128
|
||||||
< internal/coverage/cmerge,
|
< internal/coverage/cmerge,
|
||||||
internal/coverage/pods,
|
internal/coverage/pods,
|
||||||
|
@ -7,6 +7,7 @@ package cfile
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/coverage"
|
"internal/coverage"
|
||||||
|
"internal/coverage/rtcov"
|
||||||
"io"
|
"io"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -17,7 +18,7 @@ func WriteMetaDir(dir string) error {
|
|||||||
if !finalHashComputed {
|
if !finalHashComputed {
|
||||||
return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
|
return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
|
||||||
}
|
}
|
||||||
return emitMetaDataToDirectory(dir, getCovMetaList())
|
return emitMetaDataToDirectory(dir, rtcov.Meta.List)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteMeta implements [runtime/coverage.WriteMeta].
|
// WriteMeta implements [runtime/coverage.WriteMeta].
|
||||||
@ -28,7 +29,7 @@ func WriteMeta(w io.Writer) error {
|
|||||||
if !finalHashComputed {
|
if !finalHashComputed {
|
||||||
return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
|
return fmt.Errorf("error: no meta-data available (binary not built with -cover?)")
|
||||||
}
|
}
|
||||||
ml := getCovMetaList()
|
ml := rtcov.Meta.List
|
||||||
return writeMetaData(w, ml, cmode, cgran, finalHash)
|
return writeMetaData(w, ml, cmode, cgran, finalHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ func WriteCounters(w io.Writer) error {
|
|||||||
return fmt.Errorf("meta-data not written yet, unable to write counter data")
|
return fmt.Errorf("meta-data not written yet, unable to write counter data")
|
||||||
}
|
}
|
||||||
|
|
||||||
pm := getCovPkgMap()
|
pm := rtcov.Meta.PkgMap
|
||||||
s := &emitState{
|
s := &emitState{
|
||||||
counterlist: cl,
|
counterlist: cl,
|
||||||
pkgmap: pm,
|
pkgmap: pm,
|
||||||
|
@ -29,25 +29,13 @@ import (
|
|||||||
// emitted at the end of code coverage testing runs, from instrumented
|
// emitted at the end of code coverage testing runs, from instrumented
|
||||||
// executables.
|
// executables.
|
||||||
|
|
||||||
// getCovMetaList returns a list of meta-data blobs registered
|
|
||||||
// for the currently executing instrumented program. It is defined in the
|
|
||||||
// runtime.
|
|
||||||
//go:linkname getCovMetaList
|
|
||||||
func getCovMetaList() []rtcov.CovMetaBlob
|
|
||||||
|
|
||||||
// getCovCounterList returns a list of counter-data blobs registered
|
// getCovCounterList returns a list of counter-data blobs registered
|
||||||
// for the currently executing instrumented program. It is defined in the
|
// for the currently executing instrumented program. It is defined in the
|
||||||
// runtime.
|
// runtime.
|
||||||
|
//
|
||||||
//go:linkname getCovCounterList
|
//go:linkname getCovCounterList
|
||||||
func getCovCounterList() []rtcov.CovCounterBlob
|
func getCovCounterList() []rtcov.CovCounterBlob
|
||||||
|
|
||||||
// getCovPkgMap returns a map storing the remapped package IDs for
|
|
||||||
// hard-coded runtime packages (see internal/coverage/pkgid.go for
|
|
||||||
// more on why hard-coded package IDs are needed). This function
|
|
||||||
// is defined in the runtime.
|
|
||||||
//go:linkname getCovPkgMap
|
|
||||||
func getCovPkgMap() map[int]int
|
|
||||||
|
|
||||||
// emitState holds useful state information during the emit process.
|
// emitState holds useful state information during the emit process.
|
||||||
//
|
//
|
||||||
// When an instrumented program finishes execution and starts the
|
// When an instrumented program finishes execution and starts the
|
||||||
@ -180,7 +168,7 @@ func granClash(g coverage.CounterGranularity) bool {
|
|||||||
// all meta-data blobs and capturing os args.
|
// all meta-data blobs and capturing os args.
|
||||||
func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) {
|
func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) {
|
||||||
// Ask the runtime for the list of coverage meta-data symbols.
|
// Ask the runtime for the list of coverage meta-data symbols.
|
||||||
ml := getCovMetaList()
|
ml := rtcov.Meta.List
|
||||||
|
|
||||||
// In the normal case (go build -o prog.exe ... ; ./prog.exe)
|
// In the normal case (go build -o prog.exe ... ; ./prog.exe)
|
||||||
// len(ml) will always be non-zero, but we check here since at
|
// len(ml) will always be non-zero, but we check here since at
|
||||||
@ -210,7 +198,7 @@ func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) {
|
|||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "\n")
|
fmt.Fprintf(os.Stderr, "\n")
|
||||||
}
|
}
|
||||||
pm := getCovPkgMap()
|
pm := rtcov.Meta.PkgMap
|
||||||
fmt.Fprintf(os.Stderr, "=+= remap table:\n")
|
fmt.Fprintf(os.Stderr, "=+= remap table:\n")
|
||||||
for from, to := range pm {
|
for from, to := range pm {
|
||||||
fmt.Fprintf(os.Stderr, "=+= from %d to %d\n",
|
fmt.Fprintf(os.Stderr, "=+= from %d to %d\n",
|
||||||
@ -310,7 +298,7 @@ func emitCounterDataToDirectory(outdir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ask the runtime for the list of coverage counter symbols.
|
// Ask the runtime for the list of coverage counter symbols.
|
||||||
pm := getCovPkgMap()
|
pm := rtcov.Meta.PkgMap
|
||||||
s := &emitState{
|
s := &emitState{
|
||||||
counterlist: cl,
|
counterlist: cl,
|
||||||
pkgmap: pm,
|
pkgmap: pm,
|
||||||
@ -591,8 +579,8 @@ func MarkProfileEmitted(val bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func reportErrorInHardcodedList(slot, pkgID int32, fnID, nCtrs uint32) {
|
func reportErrorInHardcodedList(slot, pkgID int32, fnID, nCtrs uint32) {
|
||||||
metaList := getCovMetaList()
|
metaList := rtcov.Meta.List
|
||||||
pkgMap := getCovPkgMap()
|
pkgMap := rtcov.Meta.PkgMap
|
||||||
|
|
||||||
println("internal error in coverage meta-data tracking:")
|
println("internal error in coverage meta-data tracking:")
|
||||||
println("encountered bad pkgID:", pkgID, " at slot:", slot,
|
println("encountered bad pkgID:", pkgID, " at slot:", slot,
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"internal/coverage/decodecounter"
|
"internal/coverage/decodecounter"
|
||||||
"internal/coverage/decodemeta"
|
"internal/coverage/decodemeta"
|
||||||
"internal/coverage/pods"
|
"internal/coverage/pods"
|
||||||
|
"internal/coverage/rtcov"
|
||||||
"internal/runtime/atomic"
|
"internal/runtime/atomic"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -33,7 +34,7 @@ func ProcessCoverTestDir(dir string, cfile string, cm string, cpkg string, w io.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit meta-data and counter data.
|
// Emit meta-data and counter data.
|
||||||
ml := getCovMetaList()
|
ml := rtcov.Meta.List
|
||||||
if len(ml) == 0 {
|
if len(ml) == 0 {
|
||||||
// This corresponds to the case where we have a package that
|
// This corresponds to the case where we have a package that
|
||||||
// contains test code but no functions (which is fine). In this
|
// contains test code but no functions (which is fine). In this
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
|
|
||||||
package rtcov
|
package rtcov
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
// This package contains types whose structure is shared between
|
// This package contains types whose structure is shared between
|
||||||
// the runtime package and the "runtime/coverage" package.
|
// the runtime package and the "runtime/coverage" implementation.
|
||||||
|
|
||||||
// CovMetaBlob is a container for holding the meta-data symbol (an
|
// CovMetaBlob is a container for holding the meta-data symbol (an
|
||||||
// RODATA variable) for an instrumented Go package. Here "p" points to
|
// RODATA variable) for an instrumented Go package. Here "p" points to
|
||||||
@ -32,3 +34,55 @@ type CovCounterBlob struct {
|
|||||||
Counters *uint32
|
Counters *uint32
|
||||||
Len uint64
|
Len uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Meta is the top-level container for bits of state related to
|
||||||
|
// code coverage meta-data in the runtime.
|
||||||
|
var Meta struct {
|
||||||
|
// List contains the list of currently registered meta-data
|
||||||
|
// blobs for the running program.
|
||||||
|
List []CovMetaBlob
|
||||||
|
|
||||||
|
// PkgMap records mappings from hard-coded package IDs to
|
||||||
|
// slots in the List above.
|
||||||
|
PkgMap map[int]int
|
||||||
|
|
||||||
|
// Set to true if we discover a package mapping glitch.
|
||||||
|
hardCodedListNeedsUpdating bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddMeta is invoked during package "init" functions by the
|
||||||
|
// compiler when compiling for coverage instrumentation; here 'p' is a
|
||||||
|
// meta-data blob of length 'dlen' for the package in question, 'hash'
|
||||||
|
// is a compiler-computed md5.sum for the blob, 'pkpath' is the
|
||||||
|
// package path, 'pkid' is the hard-coded ID that the compiler is
|
||||||
|
// using for the package (or -1 if the compiler doesn't think a
|
||||||
|
// hard-coded ID is needed), and 'cmode'/'cgran' are the coverage
|
||||||
|
// counter mode and granularity requested by the user. Return value is
|
||||||
|
// the ID for the package for use by the package code itself,
|
||||||
|
// or 0 for impossible errors.
|
||||||
|
func AddMeta(p unsafe.Pointer, dlen uint32, hash [16]byte, pkgpath string, pkgid int, cmode uint8, cgran uint8) uint32 {
|
||||||
|
slot := len(Meta.List)
|
||||||
|
Meta.List = append(Meta.List, CovMetaBlob{
|
||||||
|
P: (*byte)(p),
|
||||||
|
Len: dlen,
|
||||||
|
Hash: hash,
|
||||||
|
PkgPath: pkgpath,
|
||||||
|
PkgID: pkgid,
|
||||||
|
CounterMode: cmode,
|
||||||
|
CounterGranularity: cgran,
|
||||||
|
})
|
||||||
|
if pkgid != -1 {
|
||||||
|
if Meta.PkgMap == nil {
|
||||||
|
Meta.PkgMap = make(map[int]int)
|
||||||
|
}
|
||||||
|
if _, ok := Meta.PkgMap[pkgid]; ok {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
// Record the real slot (position on meta-list) for this
|
||||||
|
// package; we'll use the map to fix things up later on.
|
||||||
|
Meta.PkgMap[pkgid] = slot
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID zero is reserved as invalid.
|
||||||
|
return uint32(slot + 1)
|
||||||
|
}
|
||||||
|
@ -9,64 +9,12 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// covMeta is the top-level container for bits of state related to
|
// The compiler emits calls to runtime.addCovMeta
|
||||||
// code coverage meta-data in the runtime.
|
// but this code has moved to rtcov.AddMeta.
|
||||||
var covMeta struct {
|
func addCovMeta(p unsafe.Pointer, dlen uint32, hash [16]byte, pkgpath string, pkgid int, cmode uint8, cgran uint8) uint32 {
|
||||||
// metaList contains the list of currently registered meta-data
|
id := rtcov.AddMeta(p, dlen, hash, pkgpath, pkgid, cmode, cgran)
|
||||||
// blobs for the running program.
|
if id == 0 {
|
||||||
metaList []rtcov.CovMetaBlob
|
throw("runtime.addCovMeta: coverage package map collision")
|
||||||
|
|
||||||
// pkgMap records mappings from hard-coded package IDs to
|
|
||||||
// slots in the covMetaList above.
|
|
||||||
pkgMap map[int]int
|
|
||||||
|
|
||||||
// Set to true if we discover a package mapping glitch.
|
|
||||||
hardCodedListNeedsUpdating bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// addCovMeta is invoked during package "init" functions by the
|
|
||||||
// compiler when compiling for coverage instrumentation; here 'p' is a
|
|
||||||
// meta-data blob of length 'dlen' for the package in question, 'hash'
|
|
||||||
// is a compiler-computed md5.sum for the blob, 'pkpath' is the
|
|
||||||
// package path, 'pkid' is the hard-coded ID that the compiler is
|
|
||||||
// using for the package (or -1 if the compiler doesn't think a
|
|
||||||
// hard-coded ID is needed), and 'cmode'/'cgran' are the coverage
|
|
||||||
// counter mode and granularity requested by the user. Return value is
|
|
||||||
// the ID for the package for use by the package code itself.
|
|
||||||
func addCovMeta(p unsafe.Pointer, dlen uint32, hash [16]byte, pkpath string, pkid int, cmode uint8, cgran uint8) uint32 {
|
|
||||||
slot := len(covMeta.metaList)
|
|
||||||
covMeta.metaList = append(covMeta.metaList,
|
|
||||||
rtcov.CovMetaBlob{
|
|
||||||
P: (*byte)(p),
|
|
||||||
Len: dlen,
|
|
||||||
Hash: hash,
|
|
||||||
PkgPath: pkpath,
|
|
||||||
PkgID: pkid,
|
|
||||||
CounterMode: cmode,
|
|
||||||
CounterGranularity: cgran,
|
|
||||||
})
|
|
||||||
if pkid != -1 {
|
|
||||||
if covMeta.pkgMap == nil {
|
|
||||||
covMeta.pkgMap = make(map[int]int)
|
|
||||||
}
|
|
||||||
if _, ok := covMeta.pkgMap[pkid]; ok {
|
|
||||||
throw("runtime.addCovMeta: coverage package map collision")
|
|
||||||
}
|
|
||||||
// Record the real slot (position on meta-list) for this
|
|
||||||
// package; we'll use the map to fix things up later on.
|
|
||||||
covMeta.pkgMap[pkid] = slot
|
|
||||||
}
|
}
|
||||||
|
return id
|
||||||
// ID zero is reserved as invalid.
|
|
||||||
return uint32(slot + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:linkname coverage_getCovMetaList internal/coverage/cfile.getCovMetaList
|
|
||||||
func coverage_getCovMetaList() []rtcov.CovMetaBlob {
|
|
||||||
return covMeta.metaList
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:linkname coverage_getCovPkgMap internal/coverage/cfile.getCovPkgMap
|
|
||||||
func coverage_getCovPkgMap() map[int]int {
|
|
||||||
return covMeta.pkgMap
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user