Skip to content

Commit 8c1349b

Browse files
thanmgopherbot
authored andcommitted
cmd/compile: use hashed symbol name for go.shape types if too long
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 <[email protected]> Auto-Submit: Than McIntosh <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 1d45a7e commit 8c1349b

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

src/cmd/compile/internal/base/debug.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ type DebugFlags struct {
4040
LoopVar int `help:"shared (0, default), 1 (private loop variables), 2, private + log"`
4141
LoopVarHash string `help:"for debugging changes in loop behavior. Overrides experiment and loopvar flag."`
4242
LocationLists int `help:"print information about DWARF location list creation"`
43+
MaxShapeLen int `help:"hash shape names longer than this threshold (default 500)" concurrent:"ok"`
4344
Nil int `help:"print information about nil checks"`
4445
NoOpenDefer int `help:"disable open-coded defers" concurrent:"ok"`
4546
NoRefName int `help:"do not include referenced symbol names in object file" concurrent:"ok"`

src/cmd/compile/internal/base/flag.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ func ParseFlags() {
176176
Flag.WB = true
177177

178178
Debug.ConcurrentOk = true
179+
Debug.MaxShapeLen = 500
179180
Debug.InlFuncsWithClosures = 1
180181
Debug.InlStaticInit = 1
181182
Debug.PGOInline = 1

src/cmd/compile/internal/noder/reader.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package noder
66

77
import (
8+
"encoding/hex"
89
"fmt"
910
"go/constant"
1011
"internal/buildcfg"
@@ -22,6 +23,7 @@ import (
2223
"cmd/compile/internal/staticinit"
2324
"cmd/compile/internal/typecheck"
2425
"cmd/compile/internal/types"
26+
"cmd/internal/notsha256"
2527
"cmd/internal/obj"
2628
"cmd/internal/objabi"
2729
"cmd/internal/src"
@@ -883,7 +885,16 @@ func shapify(targ *types.Type, basic bool) *types.Type {
883885
under = types.NewPtr(types.Types[types.TUINT8])
884886
}
885887

886-
sym := types.ShapePkg.Lookup(under.LinkString())
888+
// Hash long type names to bound symbol name length seen by users,
889+
// particularly for large protobuf structs (#65030).
890+
uls := under.LinkString()
891+
if base.Debug.MaxShapeLen != 0 &&
892+
len(uls) > base.Debug.MaxShapeLen {
893+
h := notsha256.Sum256([]byte(uls))
894+
uls = hex.EncodeToString(h[:])
895+
}
896+
897+
sym := types.ShapePkg.Lookup(uls)
887898
if sym.Def == nil {
888899
name := ir.NewDeclNameAt(under.Pos(), ir.OTYPE, sym)
889900
typ := types.NewNamed(name)

0 commit comments

Comments
 (0)