aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/base/debug.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2020-11-19 20:49:23 -0500
committerRuss Cox <rsc@golang.org>2020-11-25 16:39:54 +0000
commit26b66fd60b258d323d7b8df2c489d5bd292c0809 (patch)
tree8f1e79b17c947b69aa41283abad13f02f8da1230 /src/cmd/compile/internal/base/debug.go
parenteb3086e5a8958723ae696ea48d4cc7981c6779fa (diff)
downloadgo-26b66fd60b258d323d7b8df2c489d5bd292c0809.tar.xz
[dev.regabi] cmd/compile: introduce cmd/compile/internal/base [generated]
Move Flag, Debug, Ctxt, Exit, and error messages to new package cmd/compile/internal/base. These are the core functionality that everything in gc uses and which otherwise prevent splitting any other code out of gc into different packages. A minor milestone: the compiler source code no longer contains the string "yy". [git-generate] cd src/cmd/compile/internal/gc rf ' mv atExit AtExit mv Ctxt atExitFuncs AtExit Exit base.go mv lineno Pos mv linestr FmtPos mv flusherrors FlushErrors mv yyerror Errorf mv yyerrorl ErrorfAt mv yyerrorv ErrorfVers mv noder.yyerrorpos noder.errorAt mv Warnl WarnfAt mv errorexit ErrorExit mv base.go debug.go flag.go print.go cmd/compile/internal/base ' : # update comments sed -i '' 's/yyerrorl/ErrorfAt/g; s/yyerror/Errorf/g' *.go : # bootstrap.go is not built by default so invisible to rf sed -i '' 's/Fatalf/base.Fatalf/' bootstrap.go goimports -w bootstrap.go : # update cmd/dist to add internal/base cd ../../../dist sed -i '' '/internal.amd64/a\ "cmd/compile/internal/base", ' buildtool.go gofmt -w buildtool.go Change-Id: I59903c7084222d6eaee38823fd222159ba24a31a Reviewed-on: https://go-review.googlesource.com/c/go/+/272250 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/base/debug.go')
-rw-r--r--src/cmd/compile/internal/base/debug.go194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/base/debug.go b/src/cmd/compile/internal/base/debug.go
new file mode 100644
index 0000000000..45a552a4d9
--- /dev/null
+++ b/src/cmd/compile/internal/base/debug.go
@@ -0,0 +1,194 @@
+// Copyright 2009 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.
+
+// Debug arguments, set by -d flag.
+
+package base
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "reflect"
+ "strconv"
+ "strings"
+
+ "cmd/internal/objabi"
+)
+
+// Debug holds the parsed debugging configuration values.
+var Debug = DebugFlags{
+ Fieldtrack: &objabi.Fieldtrack_enabled,
+}
+
+// DebugFlags defines the debugging configuration values (see var Debug).
+// Each struct field is a different value, named for the lower-case of the field name.
+// Each field must be an int or string and must have a `help` struct tag.
+//
+// The -d option takes a comma-separated list of settings.
+// Each setting is name=value; for ints, name is short for name=1.
+type DebugFlags struct {
+ Append int `help:"print information about append compilation"`
+ Checkptr int `help:"instrument unsafe pointer conversions"`
+ Closure int `help:"print information about closure compilation"`
+ CompileLater int `help:"compile functions as late as possible"`
+ DclStack int `help:"run internal dclstack check"`
+ Defer int `help:"print information about defer compilation"`
+ DisableNil int `help:"disable nil checks"`
+ DumpPtrs int `help:"show Node pointers values in dump output"`
+ DwarfInl int `help:"print information about DWARF inlined function creation"`
+ Export int `help:"print export data"`
+ Fieldtrack *int `help:"enable field tracking"`
+ GCProg int `help:"print dump of GC programs"`
+ Libfuzzer int `help:"enable coverage instrumentation for libfuzzer"`
+ LocationLists int `help:"print information about DWARF location list creation"`
+ Nil int `help:"print information about nil checks"`
+ PCTab string `help:"print named pc-value table"`
+ Panic int `help:"show all compiler panics"`
+ Slice int `help:"print information about slice compilation"`
+ SoftFloat int `help:"force compiler to emit soft-float code"`
+ TypeAssert int `help:"print information about type assertion inlining"`
+ TypecheckInl int `help:"eager typechecking of inline function bodies"`
+ WB int `help:"print information about write barriers"`
+
+ any bool // set when any of the values have been set
+}
+
+// Any reports whether any of the debug flags have been set.
+func (d *DebugFlags) Any() bool { return d.any }
+
+type debugField struct {
+ name string
+ help string
+ val interface{} // *int or *string
+}
+
+var debugTab []debugField
+
+func init() {
+ v := reflect.ValueOf(&Debug).Elem()
+ t := v.Type()
+ for i := 0; i < t.NumField(); i++ {
+ f := t.Field(i)
+ if f.Name == "any" {
+ continue
+ }
+ name := strings.ToLower(f.Name)
+ help := f.Tag.Get("help")
+ if help == "" {
+ panic(fmt.Sprintf("base.Debug.%s is missing help text", f.Name))
+ }
+ ptr := v.Field(i).Addr().Interface()
+ switch ptr.(type) {
+ default:
+ panic(fmt.Sprintf("base.Debug.%s has invalid type %v (must be int or string)", f.Name, f.Type))
+ case *int, *string:
+ // ok
+ case **int:
+ ptr = *ptr.(**int) // record the *int itself
+ }
+ debugTab = append(debugTab, debugField{name, help, ptr})
+ }
+}
+
+// DebugSSA is called to set a -d ssa/... option.
+// If nil, those options are reported as invalid options.
+// If DebugSSA returns a non-empty string, that text is reported as a compiler error.
+var DebugSSA func(phase, flag string, val int, valString string) string
+
+// parseDebug parses the -d debug string argument.
+func parseDebug(debugstr string) {
+ // parse -d argument
+ if debugstr == "" {
+ return
+ }
+ Debug.any = true
+Split:
+ for _, name := range strings.Split(debugstr, ",") {
+ if name == "" {
+ continue
+ }
+ // display help about the -d option itself and quit
+ if name == "help" {
+ fmt.Print(debugHelpHeader)
+ maxLen := len("ssa/help")
+ for _, t := range debugTab {
+ if len(t.name) > maxLen {
+ maxLen = len(t.name)
+ }
+ }
+ for _, t := range debugTab {
+ fmt.Printf("\t%-*s\t%s\n", maxLen, t.name, t.help)
+ }
+ // ssa options have their own help
+ fmt.Printf("\t%-*s\t%s\n", maxLen, "ssa/help", "print help about SSA debugging")
+ fmt.Print(debugHelpFooter)
+ os.Exit(0)
+ }
+ val, valstring, haveInt := 1, "", true
+ if i := strings.IndexAny(name, "=:"); i >= 0 {
+ var err error
+ name, valstring = name[:i], name[i+1:]
+ val, err = strconv.Atoi(valstring)
+ if err != nil {
+ val, haveInt = 1, false
+ }
+ }
+ for _, t := range debugTab {
+ if t.name != name {
+ continue
+ }
+ switch vp := t.val.(type) {
+ case nil:
+ // Ignore
+ case *string:
+ *vp = valstring
+ case *int:
+ if !haveInt {
+ log.Fatalf("invalid debug value %v", name)
+ }
+ *vp = val
+ default:
+ panic("bad debugtab type")
+ }
+ continue Split
+ }
+ // special case for ssa for now
+ if DebugSSA != nil && strings.HasPrefix(name, "ssa/") {
+ // expect form ssa/phase/flag
+ // e.g. -d=ssa/generic_cse/time
+ // _ in phase name also matches space
+ phase := name[4:]
+ flag := "debug" // default flag is debug
+ if i := strings.Index(phase, "/"); i >= 0 {
+ flag = phase[i+1:]
+ phase = phase[:i]
+ }
+ err := DebugSSA(phase, flag, val, valstring)
+ if err != "" {
+ log.Fatalf(err)
+ }
+ continue Split
+ }
+ log.Fatalf("unknown debug key -d %s\n", name)
+ }
+}
+
+const debugHelpHeader = `usage: -d arg[,arg]* and arg is <key>[=<value>]
+
+<key> is one of:
+
+`
+
+const debugHelpFooter = `
+<value> is key-specific.
+
+Key "checkptr" supports values:
+ "0": instrumentation disabled
+ "1": conversions involving unsafe.Pointer are instrumented
+ "2": conversions to unsafe.Pointer force heap allocation
+
+Key "pctab" supports values:
+ "pctospadj", "pctofile", "pctoline", "pctoinline", "pctopcdata"
+`