From cbfced7415f6b0ac0be0182cb929e336d5d33ea3 Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Wed, 17 Jun 2020 11:42:47 -0400 Subject: [PATCH] [dev.link] cmd/internal: convert basic types to builtin symbols The Go compiler includes special treatment for a small set of very commonly used type symbols (26 to be exact); for these types it doesn't bother to emit type descriptors for "normal" compilations, and instead only generates them for the runtime package, so as to reduce object file bloat. This patch moves the set of type symbols in question from the PkgIdxNone index space (in the object file) to the PkgIdxBuiltin space, which saves some work in the compiler and loader (reduces each package's index space slightly). Change-Id: I039c805e05c1aef26f035e52760fd0a0af40f7a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/239658 Run-TryBot: Than McIntosh TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang Reviewed-by: Jeremy Faller --- src/cmd/internal/goobj2/builtinlist.go | 38 ++++++++++++++++++++++++++ src/cmd/internal/goobj2/mkbuiltin.go | 36 +++++++++++++++++++++--- src/cmd/link/internal/loader/loader.go | 4 ++- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/cmd/internal/goobj2/builtinlist.go b/src/cmd/internal/goobj2/builtinlist.go index 8fbbe45261..171f57f15f 100644 --- a/src/cmd/internal/goobj2/builtinlist.go +++ b/src/cmd/internal/goobj2/builtinlist.go @@ -7,6 +7,7 @@ var builtins = [...]struct { abi int }{ {"runtime.newobject", 1}, + {"runtime.mallocgc", 1}, {"runtime.panicdivide", 1}, {"runtime.panicshift", 1}, {"runtime.panicmakeslicelen", 1}, @@ -127,6 +128,7 @@ var builtins = [...]struct { {"runtime.block", 1}, {"runtime.makeslice", 1}, {"runtime.makeslice64", 1}, + {"runtime.makeslicecopy", 1}, {"runtime.growslice", 1}, {"runtime.memmove", 1}, {"runtime.memclrNoHeapPointers", 1}, @@ -204,4 +206,40 @@ var builtins = [...]struct { {"runtime.morestack", 0}, {"runtime.morestackc", 0}, {"runtime.morestack_noctxt", 0}, + {"type.int8", 0}, + {"type.*int8", 0}, + {"type.uint8", 0}, + {"type.*uint8", 0}, + {"type.int16", 0}, + {"type.*int16", 0}, + {"type.uint16", 0}, + {"type.*uint16", 0}, + {"type.int32", 0}, + {"type.*int32", 0}, + {"type.uint32", 0}, + {"type.*uint32", 0}, + {"type.int64", 0}, + {"type.*int64", 0}, + {"type.uint64", 0}, + {"type.*uint64", 0}, + {"type.float32", 0}, + {"type.*float32", 0}, + {"type.float64", 0}, + {"type.*float64", 0}, + {"type.complex64", 0}, + {"type.*complex64", 0}, + {"type.complex128", 0}, + {"type.*complex128", 0}, + {"type.unsafe.Pointer", 0}, + {"type.*unsafe.Pointer", 0}, + {"type.uintptr", 0}, + {"type.*uintptr", 0}, + {"type.bool", 0}, + {"type.*bool", 0}, + {"type.string", 0}, + {"type.*string", 0}, + {"type.error", 0}, + {"type.*error", 0}, + {"type.func(error) string", 0}, + {"type.*func(error) string", 0}, } diff --git a/src/cmd/internal/goobj2/mkbuiltin.go b/src/cmd/internal/goobj2/mkbuiltin.go index d773e53e59..4838fa2a67 100644 --- a/src/cmd/internal/goobj2/mkbuiltin.go +++ b/src/cmd/internal/goobj2/mkbuiltin.go @@ -21,6 +21,7 @@ import ( "log" "os" "path/filepath" + "strings" ) var stdout = flag.Bool("stdout", false, "write to stdout instead of builtinlist.go") @@ -98,9 +99,15 @@ func mkbuiltin(w io.Writer) { // The list above only contains ones that are used by the frontend. // The backend may create more references of builtin functions. + // We also want to include predefined types. // Add them. - for _, b := range extra { - name := pkg + "." + b.name + extras := append(fextras[:], enumerateBasicTypes()...) + for _, b := range extras { + prefix := "" + if !strings.HasPrefix(b.name, "type.") { + prefix = pkg + "." + } + name := prefix + b.name if decls[name] { log.Fatalf("%q already added -- mkbuiltin.go out of sync?", name) } @@ -109,10 +116,31 @@ func mkbuiltin(w io.Writer) { fmt.Fprintln(w, "}") } -var extra = [...]struct { +// addBasicTypes returns the symbol names for basic types that are +// defined in the runtime and referenced in other packages. +// Needs to be kept in sync with reflect.go:dumpbasictypes() and +// reflect.go:dtypesym() in the compiler. +func enumerateBasicTypes() []extra { + names := [...]string{ + "int8", "uint8", "int16", "uint16", + "int32", "uint32", "int64", "uint64", + "float32", "float64", "complex64", "complex128", + "unsafe.Pointer", "uintptr", "bool", "string", "error", + "func(error) string"} + result := []extra{} + for _, n := range names { + result = append(result, extra{"type." + n, 0}) + result = append(result, extra{"type.*" + n, 0}) + } + return result +} + +type extra struct { name string abi int -}{ +} + +var fextras = [...]extra{ // compiler frontend inserted calls (sysfunc) {"deferproc", 1}, {"deferprocStack", 1}, diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go index 7cebe23065..8bc5fe21e4 100644 --- a/src/cmd/link/internal/loader/loader.go +++ b/src/cmd/link/internal/loader/loader.go @@ -1980,6 +1980,7 @@ func (l *Loader) preloadSyms(r *oReader, kind int) { } l.growAttrBitmaps(len(l.objSyms) + int(end-start)) needNameExpansion := r.NeedNameExpansion() + loadingRuntimePkg := r.unit.Lib.Pkg == "runtime" for i := start; i < end; i++ { osym := r.Sym(i) name := osym.Name(r.Reader) @@ -2005,7 +2006,8 @@ func (l *Loader) preloadSyms(r *oReader, kind int) { if strings.HasPrefix(name, "go.itablink.") { l.itablink[gi] = struct{}{} } - if strings.HasPrefix(name, "runtime.") { + if strings.HasPrefix(name, "runtime.") || + (loadingRuntimePkg && strings.HasPrefix(name, "type.")) { if bi := goobj2.BuiltinIdx(name, v); bi != -1 { // This is a definition of a builtin symbol. Record where it is. l.builtinSyms[bi] = gi -- 2.48.1