Skip to content

cmd/compile: compiling nested generics consumes a lot of memory and takes a long time #76661

@Daniil159x

Description

@Daniil159x

Go version

go version go1.25.4 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='0'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build447586909=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/app/go.mod'
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.4'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Hi!
I found the module github.com/barweiss/go-tuple and I was trying to create a named tuple (like in python, or a dictionary or something like a struct).
I also tried adding chain methods to create a named tuple, similar to how zerolog creates a log object:

a := ZeroMap0{}.
		Int("a", 11).
		Int("b", 22323343)

The chaining methods return the following generic structure with an additional generic parameter.
Thus, a generic of level N creates a generic of level N+1 - hence the name nested generics.

See the full code: https://go.dev/play/p/uCYMGcXhqrZ

What did you see happen?

The compiling consumed 5.5 GB of RAM (resident aka rss) and lasted for 1.5 minutes.
I've captured the following graphs:
Memory:
Image

Flamegraph (click for original svg file):
Image

When limiting the nesting to 2-3 levels or just removing unused chain methods (.Str and .Any), compilation is completed instantly and does not require much RAM.
Flamegraph of compiling of generics of the first 2 levels only (the full code and original svg file):
Image

If, on the opposite, the nesting level is increased, then either the compilation does not complete, or it is killed by OOM.

The problem seems to be related to the reader.obj() method from src/cmd/compile/internal/noder/reader.go.
It is recursively called for each level and creates many temporary objects (however, this may be a false path, I have not profiled the allocation and don't know how to do this without building the compiler).

What did you expect to see?

Fast compilation without consuming gigabytes of memory.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions