]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use hashed symbol name for go.shape types if too long
authorThan McIntosh <thanm@google.com>
Tue, 9 Jan 2024 15:06:15 +0000 (15:06 +0000)
committerGopher Robot <gobot@golang.org>
Wed, 10 Jan 2024 15:27:52 +0000 (15:27 +0000)
Shape-based stenciling in the Go compiler's generic instantiation
phase looks up shape types using the underlying type of a given target
type. This has a beneficial effect in most cases (e.g. we can use the
same shape type for two different named types whose underlying type is
"int"), but causes some problems when the underlying type is a very
large structure. The link string for the underlying type of a large
imported struct can be extremely long, since the link string
essentially enumerates the full package path for every field type;
this can produce a "go.shape.struct { ... " symbol name that is
absurdly long.

This patch switches the compiler to use a hash of the underlying type
link string instead of the string itself, which should continue to
provide commoning but keep symbol name lengths reasonable for shape
types based on large imported structs.

Fixes #65030.

Change-Id: I87d602626c43172beb99c186b8ef72327b8227a2
Reviewed-on: https://go-review.googlesource.com/c/go/+/554975
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Than McIntosh <thanm@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/base/debug.go
src/cmd/compile/internal/base/flag.go
src/cmd/compile/internal/noder/reader.go

index aadd950a0a0ad6a1752c635441d7eb2793846779..420ad1305e8c86b8c91498fdc1c90257f0847b2d 100644 (file)
@@ -40,6 +40,7 @@ type DebugFlags struct {
        LoopVar               int    `help:"shared (0, default), 1 (private loop variables), 2, private + log"`
        LoopVarHash           string `help:"for debugging changes in loop behavior. Overrides experiment and loopvar flag."`
        LocationLists         int    `help:"print information about DWARF location list creation"`
+       MaxShapeLen           int    `help:"hash shape names longer than this threshold (default 500)" concurrent:"ok"`
        Nil                   int    `help:"print information about nil checks"`
        NoOpenDefer           int    `help:"disable open-coded defers" concurrent:"ok"`
        NoRefName             int    `help:"do not include referenced symbol names in object file" concurrent:"ok"`
index e2e15c3c9c45d64afb691128a23a529c0c8e4ac4..a3144f8fb4a6c2f4b6b77acb822786c3f8c44c64 100644 (file)
@@ -176,6 +176,7 @@ func ParseFlags() {
        Flag.WB = true
 
        Debug.ConcurrentOk = true
+       Debug.MaxShapeLen = 500
        Debug.InlFuncsWithClosures = 1
        Debug.InlStaticInit = 1
        Debug.PGOInline = 1
index 99e778fd70bd14197f606e5446aec553194b3b3b..f5d1fce50cf039d9e7c7a23076689a6eab871d9e 100644 (file)
@@ -5,6 +5,7 @@
 package noder
 
 import (
+       "encoding/hex"
        "fmt"
        "go/constant"
        "internal/buildcfg"
@@ -22,6 +23,7 @@ import (
        "cmd/compile/internal/staticinit"
        "cmd/compile/internal/typecheck"
        "cmd/compile/internal/types"
+       "cmd/internal/notsha256"
        "cmd/internal/obj"
        "cmd/internal/objabi"
        "cmd/internal/src"
@@ -883,7 +885,16 @@ func shapify(targ *types.Type, basic bool) *types.Type {
                under = types.NewPtr(types.Types[types.TUINT8])
        }
 
-       sym := types.ShapePkg.Lookup(under.LinkString())
+       // Hash long type names to bound symbol name length seen by users,
+       // particularly for large protobuf structs (#65030).
+       uls := under.LinkString()
+       if base.Debug.MaxShapeLen != 0 &&
+               len(uls) > base.Debug.MaxShapeLen {
+               h := notsha256.Sum256([]byte(uls))
+               uls = hex.EncodeToString(h[:])
+       }
+
+       sym := types.ShapePkg.Lookup(uls)
        if sym.Def == nil {
                name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
                typ := types.NewNamed(name)