Go 1.21
Inference rewrite plus min/max/clear. Unified IR is the only frontend. abi.Type unification. Unwinder iterator replaces gentraceback. PGO devirtualization, and the compiler itself is built with PGO. PanicNilError. Pinner. wasip1. Tracer groundwork and FP unwinding.
Each area lists the stage every thread reached in this release (with what was left open afterwards), then changes that are not part of a thread. Thread names link to the full thread on its topic page.
Memory management
From Runtime: memory allocator and garbage collector (Go 1.18–1.28)
- GC pacer redesign — Done: cons/mark smoothing became the max over 5 cycles, biased against assists (
b513bd808f, comment fix600b982df9). Left open: after an application becomes less GC-active, the stale cons/mark persists for 5 cycles. The commit accepts this (b513bd808f). - Soft memory limit and GC CPU limiter — Done: user-visible the limit is initialized in
mallocinit, so early allocations do not scavenge needlessly (96e8e62821). Headroom became proportional (3%) to stop GOGC=off programs from scavenging on most allocations (e97bd776f9). Eager-scavenge details were added toscavtrace(a3e90dc377). Thego119MemoryLimitSupportflag was removed (79edd1d19d), a lost idle-time flush was fixed (24617a068c), and a/gc/gomemlimit:bytesmetric was added (2544b1051e). Left open: “This choice is still somewhat arbitrary … perhaps worth revisiting” (e97bd776f9). - Scavenger redesign — Done: idle Ps’ page caches flushed at the end of each GC so the scavenger can see them (
8d68b388d4); index initialization andminHeapIdxrestored (8588a3fa08,15c1276246); eager-scavenge statistics inscavtrace(a3e90dc377); density tracking (huge-page thread). Left open: nothing noted. - Transparent huge page management — Done: explicit policy with 96% density and 1-GC-cycle hysteresis (
8fa9e3beee),sysNoHugePage(84eaceaba7) with a page-alignment check (ada0eec827), and metadata huge pages only for large heaps (1f9d80e331). Left open: “The main risk here is churn” (8fa9e3beee). - Finalizers, runtime.AddCleanup and the cleanup queue — Done: test portability only (
fbf14ae166). Left open: nothing noted. - Object pinning (runtime.Pinner) — Done: user-visible the
PinnerAPI (251daf46fb), gcBits-based state (697644070c), ref preallocation and P cache (4bb38fe458,0adcc5ace8, benchmarks94c75232fb,5d68121628), lock-rank edges (78df00dd6f,807cce479f), and docs (c7b2f6494c). Alongside:heapObjectsCanMove()(always false) forgo4.org/unsafe/assume-no-moving-gc, so that package stops breaking on each release (055c186f53,789701e93a). Left open: nothing noted. - Memory arenas experiment — Done: user-visible
reflect.ArenaNewchanged to takeTand return*T, a breaking change (2b0ff4b629). Left open: nothing noted. - Mark worker scheduling and GC work queues — Done:
work.full/work.emptypadded against false sharing (gRPC +8%, DeathStarBench +9.7%,bdc5533f39); duplicatework.fullcheck removed (9411075748). Left open: nothing noted. - Sweeper termination and pacing — Done: overflow in the sweep-assist delta could pin all allocators in sweeping until termination; fixed (
a7b75972f2). Left open: nothing noted. - Address-space layout, tagged pointers and the mem.go layer — Done:
lfstack→taggedPointer(d959dd97b1); fallback tommapwhenmadviseis compiled out of Linux (5ffdc1f15c). Left open: nothing noted. - Linear-memory heaps (Wasm and sbrk platforms) — Done: Wasm reuses blocks freed via
sysFreeOS, sharing Plan 9’s sbrk strategy (dac514ea37). Left open: nothing noted.
Other changes
- Write-barrier buffer generalized for batching internal — the runtime no longer requires pointers in pairs and checks overflow first (
d3daeb5267); the compiler batches barriered writes intogcWriteBarrier1..8buffer slots (21d82e6ac8, compiler area). user-visibleGODEBUG=cgocheck=2becameGOEXPERIMENT=cgocheck2to enable these barrier optimizations (55044288ad). - reflect typedmemmovepartial removed internal — unused (
df6396fc22). - Tracer state refactors at GC call sites internal —
traceEnabled()and per-P trace state (8992bb19ad,b7e767b022), diag area.
Scheduler and concurrency
From Runtime: scheduler, timers, channels, locks and synchronization (Go 1.18–1.28)
- Scheduler core: spinning Ms, work conservation, stealing, STW interaction — Done: stale
nowused by netpolling Ms fixed (6f13d0bfe4); checkdead double-lock/startm handling (f229787aff,ff059add10); extra-M API cleanup and exclusion fromSetMaxThreads(77b1f23af7,734b26d4b9). Left open: nothing noted. - sync package API evolution — Done: user-visible
OnceFunc,OnceValue,OnceValues(bb44c2b54e); Map memory model docs (f07910bd57). Left open: closure retention. - Runtime lock ranking — Done: raceFiniLock, pinner and mspanSpecial/gcBitsArenas edges (
f00e947cdf,78df00dd6f,807cce479f). Left open: nothing noted. - Netpoller — Done: fd sequence tags (
d5514013b6); wasip1 netpoll throughpoll_oneoff(c5c2184538); windows filter by completion key (7830180dcd). Left open: 32-bit tag. - Goroutine lifecycle and identity — Done: user-visible parent goroutine ID in tracebacks (
51225f6fc6). Left open: nothing noted.
Other changes
- Tracer refactors internal — per-g/m trace state types, trace clock,
tracedSyscallEnter, block reasons (c213c905a2,2f35a655e7,b60db8f7d9,865179164e,7c91e1e568,a2737b1aab,62bf7a4809,c890d40d0d,e3ada56537); regular unwinding for cgo callbacks (3dd221a94d); frame-pointer unwinding off (608f204ac7) then on for amd64/arm64 (2d83b646d6). - Unwinder rewrite internal —
gentracebackdeleted (3790ceca97),inlineUnwinder(166e5ee4f2), top+bottom 50 frames printed for deep stacks (9eba17ff90). - Pinner caching internal — per-P inner pinner (
0adcc5ace8). - Misc internal —
syscallfork avoids serialising on ForkLock (d6473a1263); wasm timeout calls (1cfacfbe8a); loong64 fcc in async preempt (48d61a46e2);extraMInUse(7911f7c21d);raceignorereset on new goroutine (48dbb6227a); linkname signature fix (8fb9565832).
Data structures and type metadata
From Runtime: maps, built-in data structures, hashing, randomness and type metadata (Go 1.18–1.28)
- Compiler-generated equality/hash functions and type descriptor emission (reflectdata) — Done: equal/hash generation moved to walk and factored (
ea3054aecc,864b54e2c3,4636c57fe1,25f5d9d4a2; one revert/reland95be547e0a/eee2697c38),AfterGlobalEscapeAnalysisremoved (8ffcd3da93). Left open: nothing noted. - internal/abi type layout unification and type metadata (rtype → abi.Type) — Done: above;
bdc6ae579a,a2838ec5f2,6cf7602b71,3ee12d5702. Left open: “the new files in internal/abi are copied from the end of the stack; ultimately this will all end up being used” (bdc6ae579a), i.e. the rtype receiver change was reverted (6d2309b576). - reflect implementation: performance, allocation and escape behaviour — Done:
Valuecan be stack-allocated (0ac72f8b96),Typedoes not escape (be4fe08b57),Value.Clear(d42c08a2be),SliceHeader/StringHeaderdeprecated again (33d8cdeedc), unusedtypedmemmovepartialremoved (df6396fc22). Left open: nothing noted. - memmove / memclr / memequal / internal/bytealg assembly optimisation — Done: Power10 memclr/memmove/equal/index/compare (
e6faa375b4,cdf77c7209,8377f2014d,56c4422770,5f1a0320b9,db32aba508), riscv64 compare unaligned 8-byte loads (261fe25c83, -11..17%), a series of riscv64 alignment fixes (a4772a1a59,bfa25c3f6c,9552a1122f,03cd8a7b0e),PCALIGNmodified to ensure alignment (e23322e2cc). Left open: nothing noted. - Slice growth, string building and allocation-free bytes/strings helpers — Done:
MakeNoZero(132fae93b7),unsafe.Sliceusable from nowritebarrierrec (da384766a0). Left open: nothing noted. - Classic map maintenance and maps package helpers (pre-swiss) — Done:
e22bd2348c,231f290e51, maps helpers. Left open: nothing noted.
Diagnostics and knobs
From Runtime: tracing, profiling, metrics and diagnostics (Go 1.18–1.28)
- The new execution tracer (trace v2): generations, per-M buffers, new parser — Done: user-visible STW events emitted for all pauses with kinds, not just GC (
b1aadd034c; bumps trace version to 1.21 and adds test data); trace clock formalized (b60db8f7d9); a long series of preparatory refactors for the redesign: per-M trace state in a type (2f35a655e7),traceEnabled/traceShuttingDownhelpers (3e9876cd3a,62bf7a4809),tracedSyscallEnterreplacing the subtlesysBlockTracedflag (865179164e), non-reentranttrace.lock(94a948d1b1),HeapGoalrecorded at start (192814985d); regular unwinding for cgo callbacks viam.incgocallback(3dd221a94d). Left open: still one global buffer design; redesign proposal in #60773. - Frame-pointer unwinding in tracing and profiling; profile stack depth — Done: new
tracebackPCsAPI built onunwinder(3e360b035f, skip arg later removedc3db9af3a6); FP unwinding for tracing on amd64 (enabled, turned off, then re-enabled by default for amd64 and arm64 in2d83b646d6, after crash fixes and arm64 frame-pointer fixup on stack copy); disabled on plan9 (bce7aec3cd). Left open: cgo-callback threads fall back to slow path. - CPU profiling, goroutine profiling, pprof labels and the protobuf writer — Done: generic instantiated symbol names recorded in CPU profiles so PGO can match them (
10ad6c91de); concurrent goroutine profile flag removed, making it the only path (469afbcc46); lazy regexps ininternal/profilecut init 185µs → 6µs (f53137f95c). Left open: nothing noted. - runtime/metrics and MemStats — Done: user-visible
/gc/heap/live:bytes(ef2bb813c8),/gc/gogc:percent(1eae5c160d),/gc/gomemlimit:bytes(2544b1051e),/gc/scan/{stack,globals,heap,total}:bytes(8b51eb5199,a63afe4720,131267f147,5124371c1c; consistency fix72bf8acee9),/godebug/non-default-behavior/*counters (213495a4a6);/sched/latencies:secondsmarked cumulative (c2c787d73e); doc clarifications of OS stack metrics (b2215e49c7);ReadMemStatsnil check before stack switch (e126572f8a). Left open:/gc/scan/*was always 0 (fixed in 1.22). - Coverage redesign: runtime/coverage, internal/coverage, covdata — Done: user-visible atomic-only counter APIs (
61e5ea4929); count-vs-emit discrepancy fix (39957b5d89);coverage.snapshotfortesting.Coverage()(ef67022471); auxiliary meta-data files for packages without tests (c99d966c17);EmitPercentaggregation (380529d5c3); counter file ordering (0f91f92ee0). Left open: go command wiring for no-test packages (landed in 1.22). - Race detector, ASan, MSan and Valgrind integration — Done: race tracebacks symbolize wrappers last (
cb6b45a993);__tsan_finimarks entering non-Go code (30886390c2); 1-byte load for address checking inracecallatomic(1a7709d6af); ppc64le thunk cleanup (e78871ea07). Left open: nothing noted.
Other changes
- Tracer/coverage/metrics internals internal —
traceClockNownosplit (e6fb1905cb), M passed totraceReleaseBuffer(07a25a9f6e), trace lock/extra-M refactors (a2737b1aab,c890d40d0d,e3ada56537), faketimetrace.Stopdeadlock (942c1c12d8), CPU stats accumulation refactor (3651d8e516), histogram metric doc (14f833f117), moduledata function-name dedup (dcb4c1c1aa), coverage encode/decode seek and func-literal fixes (7b89531860,5322e66a12,620399ef0d,695a53620f),covdata percentformat (5cdc3874b0). - GODEBUG counters user-visible — non-default behaviour counters for settings in cmd/go cache and elsewhere (
14ab998f95,9b41418074,6a063b01b0).
OS layer, stacks and panics
From Runtime: OS and platform layer, stacks, panics and tracebacks (Go 1.18–1.28)
- Defer, panic and recover re-implementation — Done: user-visible
panic(nil)replaced bypanic(new(runtime.PanicNilError))sorecover()can no longer return nil for a panicking goroutine (aa51c40b1c). Left open: nothing noted. - Unwinder: gentraceback →
unwinderiterator, inline unwinder, pcvalue cache — Done: traceback iterator (f758d648b0),waspaniceliminated (5acd2d658e), callee funcInfo resolved after the current frame (6f22d42c74), all callbacks migrated (2d99109cfc), PC back-up simplified (c9b2da3f28),gentracebackdeleted (3790ceca97), inline unwinder API (f52bede354), tests for inlined frames in tracebacks (59d0de16e4), callee tracking fixed in printing (5f62ba621e),Callers/FPCallersbenchmarks (2d93805171,25f9af6661). Left open:Callersgot slower; hot-path inlining ofunwindernot solved. - Symbol tables,
runtime.CallerandCallersFrames— Done: name logic deduped into a moduledata method (dcb4c1c1aa); linker emits full symbol names for generic functions into the runtime table (1a612783c5); ID constants merged intointernal/abi(9754521157,7843ca83e7). Left open: nothing noted. - Frame pointers: explicit NOFRAME, FP maintenance and FP unwinding — Done: explicit NOFRAME on windows/amd64 (
083d94f69c), darwin (d939b3717f, after reverta9780d8dfd), linux (521d2614df), dragonfly, freebsd, netbsd (asm_netbsd_amd64.sdeleted), openbsd, solaris, plan9; heuristic removed (d20e688fcf); unneeded NOFRAME removed (b35ee3b046,43f911b0b6); FP adjusted on stack copy for ARM64 (a41a29ad19); FP unwinding in tracer on amd64 (ba71817390); frame pointer loop fix (b52f6d3721);systemstackFP adjustment fix and test (2380d17aea,6dca1a29ab,47e6fd05f7); tracer avoids FP unwinding incgocallbackg(265d19ed52). Left open: FP unwinding only on amd64 at this point. - Stack growth, stack bounds and the crash stack — Done: sigpanic is not injected when the fault is on a g0 stack (
a0c9d153e0): output becomes a plainSIGSEGV ... signal arrived during cgo executionand C/debugger unwinders aren’t confused. Left open: nothing noted. - C-to-Go callbacks: extra-M reuse, system-stack bounds, init gating — Done: M cached per C thread in a pthread key (
ccad8a9f9c,7b874619be,c426c87012, with revertsbfe3c678ab,94850c6f79,72c33a5ef0);needmbetter g0 stack bound (443eb9757c); extra-M API cleaned (77b1f23af7); tsan sync for cgo traceback function (618fb4ab06,46bc9a6e1e); PPC64 vector registers preserved in crosscall (1e51b1fac3,5c51e9f45b). Left open: stack-bound staleness (fixed in 1.21/1.22 follow-ups below). - Library entry points and runtime initialization — Done: ppc64le/linux library startup cleaned (
12e65dbdb1,ac571a388d), libfuzzer stack alignment (5d76600cc0), loong64 c-shared (80eeec6979). Left open: nothing noted. - Security hardening: AT_SECURE, std fds, AT_RANDOM, gated debug features — Done: user-visible SUID/SGID protections (
2496653d0a);GOTRACEBACK=weron Windows (65ea4c5021); debugger hook for fatal signals (d8c9eece28). Left open: “in the future we may add additional protections”. - Signals and async-preemption machinery — Done: debugger fatal-signal hook (
d8c9eece28),sigreturnsymbol named with “sigaction” for gdb (0ed364a463),EXCEPTION_IN_PAGE_ERROR(e03ee85ef4),sigtrampfixes on ppc64 (ac571a388d), no sigpanic off user G stack (a0c9d153e0). Left open: nothing noted. - Windows runtime port — Done: TEB slots on 386 (
28f8dbd7b9),LoadLibraryEx(a17d959deb),GOTRACEBACK=wer(65ea4c5021), procid (140000dd55), high-res timers on arm/arm64 (b6f29d2365), TEB fallback (715d53c090), windows sigtramp factored (cf9263dee1), NOFRAME cleanup (b35ee3b046). Left open: nothing noted. - New, ported and removed platforms — Done: wasip1 (
8890c3a05f,be50055eef),go:wasmimportlimits (53c0158905), wasm memory reuse (dac514ea37), arm64 non-regabi removed (602e6aa979), loong64 c-shared (80eeec6979). Left open: nothing noted. - CPU feature detection, GOAMD64 checks and cpu GODEBUG options — Done: auxv exposed (
1a9893a969); Neoverse N2/V2 (e4b03f9425); ppc64 default osinit (ada6ffca83). Left open: nothing noted.
Other changes
- loong64 cleanups internal — entry point,
sigtrampcallee-saved registers, RSB removed, hardware NOPs,cputicksfrom stable counter (574c620901,5fa65d8c93,6f2ef5ec98,7789966286,f92a69f907,c8402cd330,b5c8ae9816,93897960cb); PPC64 funcdesc consolidation (6827f0d772,1064335047, landed after reverts of8c2900bb9f),-fstack-protectorlinking (066b780502,48f4728211); write-barrier buffer no longer requires pointer pairs (d3daeb5267,d49719b1f7); gentraceback stack tracking dropped (4f132b7ef8);stackguard1-style cgo fixes (fba8566cdareverted99276aeb5e). - SUID/exec details internal —
syscallrestores NOFILE rlimit in child (f5eef58e43);fcntlconsolidated (547aed18e0,10532fdb14,58315a771a);ossigpiperemoved (719e2b6f09). - Wasm/wasip1 net user-visible —
net.FileListener/FileConnon wasip1 (a17de43ef1),Fcntl(7756f82590). - auxv exposed internal — for x/sys/cpu (
1a9893a969); arm64 SHA512 hwcaps (b90971b292). - Darwin core dumps user-visible — permitted on darwin-amd64 (
d7d235c92f); AIX/Solaris_exit(6bbbc5dc70); Illumospthread_attr_get_np(ad87a124be, reverted0e9b2bc39a).
Compiler frontend · types2
From Compiler frontend: the types2 type checker (Go 1.18–1.28)
- Type sets, union terms, interfaces and constraint satisfaction — Done:
b44f2222b5(methods considered when unifying a type parameter against its constraint) and the missing-method rework (09852e75ac,c10ba768fe,9f2fe2d721,2f9e38a1be,4ad72feb92,c6cdfdabefambiguity message). - Instantiation, Named types, Context deduplication and lazy expansion — Done:
ac9137f8d3(NewCheckerdoes not mutate its arguments);1dd24d8216/2ce84c3a6einterface and missing-method fixes. - Type inference and unification — Done: user-visible the big inference release (proposals #58650, #59338, #60353, #58671).
683b2c4600(infer2),969c3ba839(exclusive use; two unifier tweaks: use underlying type when the other side is a type literal or basic type, and always continue with the core type for unbound type parameters). Reverse inference of generic function arguments in assignments (cc048b32f3, behindConfig.EnableReverseTypeInference; flag removed byfc106b016cwhen proposal #59338 was accepted), corrected to model the assignment as a single function-typed argumentg'(func(t1…))so parameter types must be identical (3367475e83, #60688). Generic functions as arguments (099f5a985fpermits partially instantiated functions,ea9097c9f7reverse inference for function arguments,8337ca094brename generic function arguments,13201d5728). Untyped constants: the minimum default type is inferred (3c3b1d39be, from proposal #58671) and2e4fe8bbf0removes the version check. Interface inference (#60353):c4afec232cand948f11b8a8unify against interfaces by shared methods,527d0e8a91reverted one attempt,6b7aab7750enabled it,1d3daebc5f/d49017a7c3/7183e77cc0fixes,d2db8267f4keeps inferring from constraints for-lang < go1.21. Smaller:a5350558e6exclude untyped nil early,d9dce0cd26check for nil targs,4cba0bd74a. Left open:c4afec232caddedEnableInterfaceInferenceas a config flag, later made internal; in 1.229070f270391.22 disables interface inference for versions before 1.21 after60dd8311031.22 reverted the constant removal. - Per-file language versions and version gating — Done:
804d786a30,4f9a966926(fix version downgrade bug withoutConfig.GoVersion),ade3f3f5ef(check builtins even if there is a version error),b490bdc27drecordConfig.GoVersionforPackage.GoVersion. - Language features as seen by the type checker (by release) — Done: user-visible
8c37d486c8refuses pointer-to-array forclear(theclearbuiltin itself,5c834a2eb01.20, is in the 1.20 bullet);b5515eef56min/max(b3ca8d2b3crecords the final type for arguments;8abc6e25971.22 in 1.22 rejects untyped value arguments); reverse inference (inference thread). - Error reporting: codes, messages, and sub-errors — Done:
ad3ea0134f,1079a5c08abetter inference failure message;dbdb3359b5,c6cdfdabef; test-framework:5cd805c6dfdistinguishes substring vs regexp error patterns,3af3810a3e,d4639ecdfc. - Sharing code between go/types and types2 — Done: first generated files and
util.go.
Other changes
- Assignment/expression refactors internal —
c013ed5b52refactor ofmultiExpr/exprList,70d836debbandc02e1bfbdb/8c5e8a38dfrefactors ofassignVar,assignVars,initVars,91a40f43b6no mismatch errors when others exist,d93f02010conly mark variables used if they are,b1f1fb2950spurious “declared and not used”,969ab34e46no panic on invalid comma-ok assignments,05293d6b49incorrect logic in assignability check. - Cgo type names internal —
40bdc56180resolve cgo base type names. - Concurrent stdlib test internal —
0aedfc196bTestStdlib type-checks concurrently. - Small fixes, unifier/assignment refactors, message and tracing tweaks internal — 55 commits:
cf5dbd4459,97f843b51f,21b4e0146a,6b8b7823c7,bd749504b8,cda461bb79,07dca0fe14,756a8ac91a,d871f63bcf,3313880bdc,331f0c6976,da47cd6192,a4d5fbc3a4,5e6ccd1223,e7201cfa9f,e2f2123e25,ebc2aaae24,c80b9912e6,8e19d2bbaf,acce3abb7e,bd7b19356f,bf9d9b7dba,abf9b112fd,a933d06271,1742691270,f46ea60f2b,9c75c4b6d7,f05c1941dd,35ec948de7,57678d5e03,6a5f35047f,522eace4ca,73a4684caa,fb4a306e3a,c486f74eeb,26899ef3ee,05ca41d3ef,0a9875c5c8,f3247f6110,2532352ffb,f30cd52051,945a2b17f3,803a7dfb80,cecf8b9328,8e3dfe783a,44b8f3907c,72f448cb48,1dad7ef572,a965318ac0,f78483eaac,0cd9064cd7,ea51e92c8a,f35d2dae74,ee361ce66c,d983be9cb5
Compiler frontend · syntax, IR, generics
From Compiler frontend: syntax, IR, unified IR and the generics implementation (Go 1.18–1.28)
- Generics via GC-shape stenciling and runtime dictionaries — Done: user-visible reverse type inference enabled (
1f570787a8,767fbe01aehandlesInfo.Instancesin assignment contexts), more lenient inference of untyped arguments (956d31ecd5,4088e97fc2); instantiated generic methods recompiled in-linksharedmode (bcd82125f8); reproducible builds of aliased generic types (f58c6cccc4). Oldnounifiedfrontend and TTYPEPARAM/TUNION types removed (see unified IR thread). - Unified IR: one serialization for noding, stenciling, inlining and export — Done:
4f467f1082removes the nounified knob,de9bffb5f1turns unreachable code into Fatalf,da9761303cremoves the nounified frontend,a7de684e1b+f5eb0a7a5astop creating/removeTUNION/TTYPEPARAM,13c70b12d7removesMarkdcl/Pushdcl/Popdcl,178080740cunused noding code;7240d7e9e4suppresses a union-type consistency check. - Old typechecker and IR node-model cleanup — Done: constant arithmetic overflow checks removed from typecheck (
fd208c8850),typecheck.EvalConstremoved (25bc96dbd2), division-by-zero no longer reported there (60e6afb689),HasBreakremoved (4c20c0a826),typecheck.Assignopstops callingbase.Errorf(374bd6a3ac),Implementsexported (13e9696437). - Static initialization and package init — Done: hidden-field fix
f773bef9ab; wrap global map init enabled (b46e44a399); inlstaticinit disabled again (b7736cbceb) then re-enabled (20c349e534) with fixes (abd55d8483substituted arguments,89138ce740unhides closure funcs moved to staticinit,3161081c12);5b603f79fbdrops special treatment of cover vars in initorder;3494a72600no DWARF for static vars. - Compile-time performance, concurrency and the self-PGO’d compiler — Done: the compiler is built with PGO (
ad6dcf9da4; reverted298ff30958, reapplied6111ac826e, reverted6ffd135256, reapplied45b74d20a0after x/tools and ppc64 failures): Template -1.4%, Unicode -5.0%, Compiler -5.6%; SCC-reordering for inlining (f5c7416511). - Compiler debugging infrastructure: bisect/hash debugging, flags, dumps — Done: HashDebug moves onto the new
internal/bisectpackage (da5a3146ec),134c9b2b17(drop FS hash form),1099644f52(extra info in bisect output),9dd0c7fc78,ef9c211de8(match exclusion),42866e566a,81a31f5dd5(godebug bisect). user-visible error URLs:7a21f799a5-url,e0db8ab6e0, enabled by defaulte7a9ca0a53and reverted42f387aae1;2cbab4e98cpasses types2 error codes through;626d478d82generates Markdown docs for each error code. - Frontend support for new language features and spec changes — Done: user-visible
clear(b89a840d65),min/max(b0f15b4ac0),//go:wasmimport(02411bcd7c,aff2f4a724), reverse type inference (1f570787a8), lenient untyped-arg inference (956d31ecd5), experimental loop-variable semanticsGOEXPERIMENT=loopvar+-d=loopvar(c20d959163,5a7793b7b8flag on FOR/RANGE that preserves loop semantics across inlining), wasip1 (7f5af094f8). - The syntax package (parser, scanner, tree) — Done:
Crawlremoved (3c357409d1), better=vs==message (db3f952b1f).
Other changes
- Runtime hash for known types internal —
memhashand runtime hash functions (b1fd277318,fcff7226f3). - Type eq/hash non-inlineable internal —
7fb075ddc0, laterf123f5c7681.22 (1.22//go:noinlineon generated eq/hash). - Inlined-location preservation internal — full inlined position for locals (
6dd20f4f12);ffc4cc05f5outer-to-inner position lists. - PGO call devirtualization user-visible —
8c445b7c9f(opt area). - Race internal — no inlining from norace packages in race mode (
87e69c1812). - Unified IR: noder/writer/reader refinements and pkgbits (1.21) internal — RType/implicit-conversion wiring,
*Athelpers, optional expression handling, UIR documentation and grammar,pkgbits.Index/SectionKindrenames, synthetic closure positions, unsafe.Sizeof handling and related reader/writer fixes (fa9efd9171) - Old typechecker and IR node-model cleanup (1.21) internal — removal of unused typecheck/ir/types code (Ntype, CurFunc uses, vargen, Resolve dependencies), more typed IR node construction, simplified DeclFunc/NewMethodExpr and constant handling (
6d4101ea68,532e34dd38,f0b1563535,b94dc384ca,617cf132ae,171850f169,89567a35c1,47e2d7495f,9fab498ab1) - Syntax package: error messages and parser tolerance (1.21) internal — better syntax and go/parser error messages, accepted type-parameter lists, parser simplifications (
afbcf2138c,63f5596788) - Housekeeping (1.21) internal — dead-code removal, ioutil/seek/slices/atomic-type replacements, README edits, debug-flag removal, assorted small bug fixes and doc comments (
8ffcd3da93,37a2004b43,231806c83d,fc99c4b3f3,ed9744dff5,e539461e34,1e5955aabd,4bd77619b7,9a0c506a4e,70451004bd,750e91152b,761e813829,6b2ad9ef50,7c2cd0bbe2)
Middle end and SSA optimizer
From Compiler: middle end and SSA optimization (Go 1.18–1.28)
- Profile-guided optimization (PGO): hot-call inlining, devirtualization, profile preprocessing — Done: user-visible
8c445b7c9fadds PGO devirtualization of interface calls, based on Uber’s CL 484838. Follow-ups:3637132233handles methods from other packages when the current package references the concrete type.fd03e6ebc9checks the method name.38e2376f35adjusts the diagnostics.
- Hot calls are no longer inlined into “big” functions. The PGO budget had bypassed the callee cap of 20 that applies to big functions (
c1ac63e973). - Symbol matching escapes package paths (
0fd6ae548f), and profile open and parse errors are reported (afbcf2138c). - Graph fixes:
7180a09745,5e4e2acc8e,a4b66b14e2. - The pprof graph moved to
pgo/internal/graphand dead code was deleted (d740b365b7,7484dd30fd). Node weights leftIRNode(4b6a542048), the post-inlining graph dump was removed (cce67690b8), and the “WORK IN PROGRESS” label was dropped (446ad131f6). -d=pgoinlinebecame-d=pgodebug(7c2cd0bbe2).- The compiler itself is now built with PGO (
45b74d20a0). - Functions from norace packages are not inlined in race mode, an issue PGO exposed (
87e69c1812).
8c445b7c9fmessage lists its limitations: only interface calls, only the single hottest callee, and no lookup of callees missing from export data. - Inliner: budget, closures, and the interleaved inline/devirtualize driver — Done:
-m=2flags “large” functions (733ba92187), andisBigFuncrecognizes unified IR codegen (6f6276ce36).- Operations inside SCCs are reordered so callees are analyzed before callers: +47 inlinable functions in the runtime (
f5c7416511, followed by6b2ad9ef50and63edd418b6). - user-visible Functions that construct closures became inlinable, +57/−10 inlinable functions in std (
445e520d49). This landed after several revert rounds caused by closure-name and position issues. - Hidden closures that become unreferenced after inlining are dead-coded (
f1caf1aa1c, reworked inea69de9b92).
- Escape analysis: call modelling, closures, func-variable callees, and solver speed — Done: fixed memory corruption from escape analysis of
unsafe.SliceData/StringData(198074abd7) and genericgo/defercalls (93f10b8829).-m=2output was fixed for recursive functions with closures (1e12c63aac). Left open: nothing noted. - Allocation avoidance: stack-allocated slice backing stores and allocation-free literals — Done: an empty
makesliceis rewritten to azerobasepointer (fc814056aa,0d8d181bd5). Left open: nothing noted. - Prove pass and bounds-check elimination: from poset relations to a dense limit table, topo-sorted walk, and division-aware proofs — Done:
- More bounds information from logic operators (
9be533a8ee). - loopbce handles 8-, 16- and 32-bit induction variables (
bb5ff5342d). - Unsigned division, modulus and right shift (
35755d772f).ORrelanded (63a08e61bd). - Slice-to-array-pointer casts are known non-nil (
0d9eb8bea2), while a slice’s pointer is not assumed non-nil (61bc17f04e).
- More bounds information from logic operators (
- Memory-op optimization: memcombine, dead stores, store-to-load forwarding, alias analysis, mem2reg — Done: the separate memcombine pass (
cedf5008a8). It was made robust to reassociated expressions (6042a062dc). Left open: nothing noted. - Lowering of builtins to memory ops: memmove/memclr/memequal inlining and generated equality — Done:
- Type equality functions are generated during walk (
864b54e2c3). The unusedeqForwas removed (89c3f7c119). - Known-size
memclrNoHeapPointersbecomesOpZero(1fc585dc2f), with PPC64 support (ebe49f98c8). Negative-size memclr is not inlined (07559ceb72). clearon slices with zero-size elements was fixed (0b65b02ba5).memequalwas removed from more string compares (6b165577fe).
- Type equality functions are generated during walk (
- Switch lowering: jump tables, type-switch caches, and switch lookup tables — Done: the
go119UseJumpTablesflag was removed (4e3abee245). Better code for switches folded to a constant early (74b52d9519). Left open: nothing noted. - Loop variable per-iteration semantics (loopvar) — Done: [user-visible, experiment]
GOEXPERIMENT=loopvar,-d=loopvarand-d=loopvarhashwere added (c20d959163).- A flag on FOR/RANGE preserves the semantics across inlining (
5a7793b7b8). - The return-in-loop optimization was restored correctly (
23e8f43cb1). - “loop-transformed” logopt (
dace96b9a1), logging tweaks (59d19ba797,1524bd1c78), and bisect report improvements (b3d1cce3eb,48f8c5c037).
5a7793b7b8says the change would later be “triggered … by the specified version for compilation”. - Sparse conditional constant propagation (sccp) — Done: first landing of the pass (
fa50248ce6, Yi Yang, #59399). Left open: it was withdrawn and had to be resubmitted. - Constant-folding loads from type metadata and dictionaries — Done: fold loads from constant dictionaries and types (
635839a17a,bd3f44e4ff, #59591);ir.Funcexposed to SSA (598cf5e6ac).
Other changes
- Misc internal — 386 ReverseBytes (
d7ac5d1480), phiElimValue from removePhiArg (d29dd2ecf7), wasmimport type restrictions (53c0158905), PGO sample position fix (cdc65b83fe), callsite line for arg marshaling (c643b29381). - min/max builtins user-visible — codegen, order-of-evaluation and mayCall fixes (
a031f4ef83,4ad4128d3c,79d4defa75,8b5fe5980c,96d16803c2). - Inliner: more inlining of functions that construct closures internal — three-part series (
2ff684a541,39986d28e4,f8162a0e72), closure naming incorporates inlined names (7f1467ff4d), hidden-closure dead marking reworked (d240226fe5); “Inliner” thread extension. - Write barrier internal — reorganized and completion detected differently (
6b5b7b3240,44d22e75dd). - Compiler allocations shared by shape internal — one allocator for similar-shape slices (
0e42632301). - Misc rules internal — De Morgan rewrite (
95c4f320d5), arithmetic rules (da4687923b), zero-constant comparisons (85d54a7667),len(string([]byte))without conversion (35a71dc56d), first instruction not inlined for FuncForPC (103f37497f,cbb9cd03f8), huge-function -N tightening (40a6e2dae5).
Backends and assemblers · architectures, ABI
From Compiler backend: architectures, register allocation, ABI and assemblers (Go 1.18–1.28)
- Register allocator, scheduler and block-level backend passes — Done: scheduling pass improved (forward scheduling)
12befc3ce3; register args scheduled before stack argsb08d5ee5e9; values with no in-block uses scheduled later6224db9b4d; SP scheduled early40ed359182, InitMem after Args518889b35c;tightenpass enhanced for memory valuesea8f037996(revertedaa6e168480, relandede0ceba8139); heuristics for resultInArg0 overwrite decisions3c7884a21b(reverted2bf0f54bbd); “avoid registers” priority lowered4237dea5e3; drop overwritten block input requirements2c6aaaea64; anchored SP (SPanchored) so LEAQ of a variable schedules after its VARDEFf959fb3872; explicit boolean for “clobbers flags” mov marker8354f6b5bb. - amd64 code generation and GOAMD64 microarchitecture levels — Done: X15 + XORL for
zerorangein ggen326df693d7; shorter movzx forLoweredHASCPUFeature1ddab59229; simplified signed division2a41dbf13c,ee522e2cda; broken LEA “optimization” removed6a97a60b4b; RDPID in the assembler05cd6cbb98; frame pointer:obj/x86uses PUSH/POP to save/restore BP (Windows toolchain −0.7%)f66581ead6, then MOV instead of LEA for FP setupadc1db23ee, with the implicit NOFRAME heuristic for frameless nosplit functions removed after every amd64 OS marked asm explicitly (d939b3717f…ea75b9458f,d20e688fcf). - arm64 code generation and assembler — Done: redundant sign/zero extension omitted
4d180f71dc; address folding for globals on ARM64 except -dynlinkb675a75c3d; CMP→CMN under<,>=42f99b203d; assembler code cleanup series (8aa0175368…e7c7f33263). - riscv64 compiler and assembler (RVA profiles, vector, compressed) — Done: loading large immediates with trailing zeros
481a6beba5; invalid shift amount check5454834f01; FMA negation commutativity fix3fce111535; regenerate encoding table8e8303e1d0. - loong64 backend and assembler — Done: c-shared
1f908bd060; save LR after SP decrement, remove branch delay slots (3ed8a1e629,b561ebab46); all unconditional jumps realized with B/BL (inheritedBEQ ZERO,ZEROfrom MIPS dropped)09f1ddb158; BEQ/BNE with 0 → beqz/bnez22f9317f20; auto-align loop heads to 16 bytes via syntheticPCALIGN $16(≤3 NOOPs)f736a9ad01, PCALIGN directive47b22b6548; MUL/DIV rewrites14015be5bb,96428e160d; PCALAU12Ib4ac4b4b42. - PPC64 / Power10 backend (GOPPC64, prefixed instructions, PC-relative code) — Done: prefixed MOV*/ADD for power10
72301a9863; SETBC/SETBCR rules (2.5% on ISEL-heavy loops, fewer registers)a432d89137; byte-reverse intrinsics for power10cd1fc87156; NOTOC29d5272da8; PCrel in linkerccb8db88c5; unbounded-shift reworkf98dd29910; SETB99f811ecca; xxspltidp (1.23)ebf7747dbe1.23. - Late-lower pass, memory-op combining and arch-independent rule migration — Done: memcombine pass
cedf5008a8; generic rules cleanup: store rules use store type60140a86b3. - Prologue, frame pointer, stack split and function alignment (cmd/internal/obj) — Done: amd64 BP save via PUSH/POP
f66581ead6, explicit NOFRAME on every OS + removal of heuristic (d939b3717f…d20e688fcf). - Atomics and memory-ordering code generation — Done: MIPS64x And/Or
75add1ce0e. - s390x, MIPS, 386 and 32-bit ARM backends — Done: 386 TrailingZeros intrinsics
cedfcba3e8; s390x breakpoint fix3e77efc720; Windows 386 TEB TLS slots28f8dbd7b9; arm HAUTO addpoolfdb3dc471d.
Other changes
- Write-barrier batching internal — barrier call returns a buffer pointer into which generated code records pointers (42 files)
21d82e6ac8; detection of write-barrier completion changed44d22e75dd; uninterruptible range simplified (1.22)c94f39a80e1.22,bf2a6d19571.22,727ebce6ce1.22. - SEH aux symbols for windows/amd64
76ac54b50e; flag init functions in object file55bd193575. - internal/abi consts merge
2668a190ba(reverted pieces466e6dae95). - ssa go:generate
47a0d46716;GetCallerSPmemory arg45dc81d856. - reproducible aix/ppc64 builds
ccf75b36ff. - 1 small mips/s390x/arm/wasm commits internal — e.g. cc: support -buildmode=c-shared on linux/mips64{,le}. (
d5fea5078b) - 6 small obj/loong64 and loong64 asm commits internal — e.g. cmd/asm: add RDTIME{L,H}.W, RDTIME.D support for loong64; obj: remove redundant cnames on loong64; cc: improve logical shift with MASKEQZ on loong64. (
bf8d142b4e,e29dd78ffe,83907206de,7789966286,2ef70d9d0f,c054f223e7) - 17 small ssa/regalloc/liveness/obj generic commits internal — e.g. cc,cmd/link: set DW_AT_decl_line for function declarations; obj: drop Filesym from DwarfAbstractFunc; cc: improve register overwrite decision for resultInArg0 ops. (
9e45b1d53e,a34cec8e41,4a0e84a1be,d29dd2ecf7,21f434058c,a42bb79dd4,40a6e2dae5,3360be4a11,4481042c43,d8d22664c6,b3bc8620f8,a3f3868c7a,9a0c506a4e,f5f7755da8,03ad1f1a34,4e8c6af239,10141676d1) - 9 small obj/x86 and amd64/386 rules commits internal — e.g. runtime: use explicit NOFRAME on darwin/amd64; runtime: use explicit NOFRAME on linux/amd64; runtime: use explicit NOFRAME on dragonfly/amd64. (
cea70301e2,521d2614df,516753278d,ddb423a7da,f76fc28c6b,0b41b678c2,1a5cf03b1b,b958d4a597,f9cf2c4d04) - 14 small obj/arm64 and arm64 rules commits internal — e.g. obj/arm64: use obj.REG_NONE where appropriate; obj/arm64: invert SP check; obj/arm64: remove spurious assignments with OR. (
8f3a13de9a,ecff9c9335,71c02bed67,f07fafacef,8b67cf0bc6,d389f779d4,0a092d7f80,d15fcbc79f,91a2e921dd,e81cc9119f,e7af0e0cac,d75cc4b9c6,6ed8474317,9fc84363d1) - 5 small cmd/asm commits internal — e.g. cmd/asm: remove the incorrect check of LDADDx-like instructi; cmd/asm: reject avx512 .Z instructions without a mask regist; cmd/asm: preserve 3rd arg when GOT-rewriting assembly instru. (
41e8679611,ee5ce77c62,1e0c32cccb,455168d113,cf624a6127) - 3 small obj/ppc64 and PPC64 rules commits internal — e.g. obj/ppc64: add VC[LT]ZLSBB instructions; obj/ppc64: fix incorrect base reg causing segv; cc: on PPC64, fix sign/zero extension when masking. (
7f4a54c0df,2716dfd995,5e4000ad7f)
Linker and object files
From Linker, object files and debug info (Go 1.18–1.28)
- DWARF quality for debuggers (types, variables, trampolines) — Done:
DW_AT_decl_linefor functions9e45b1d53e; inlinedDW_AT_call_linehonours//linef60a2a9c94; DWARF section sizes checked separatelyc2becd70c5. Left open: nothing noted. - Nosplit stack checking and stack constants — Done: StackLimit/StackGuard rationalized into
abi.StackNosplitBase(landed, revertedd11ff3f081, relanded)921699fe5f,0f099a4bc5; stack check forced to 1 in distb12366bbb51.20 (1.20). Left open: nothing noted. - Dead code elimination and reflection-aware pruning — Done: user-visible linker side of dead-map removal
e2ca417ee7; ReflectMethod flag in-dumpdep0bbb54a02d. Left open: nothing noted. - Linker performance and memory — Done: symbol index
Symbecomes uint32 (−17.7% peak memory linking cmd/compile externally)d33a5136e1; outer-symbol slice and special/generator bitmaps (Symtab 12.9 to 6.4 ms)21c2fdd91c; data symbols sorted by index not name (Dodata −4.7%)ddd822e5ca; type name decode without allocation630ef2edc2; per-binary slice cleanup8e8f4be3f4Left open: nothing noted. - Reproducible build IDs, buildinfo and symbol tables — Done: go.buildinfo kept with
--gc-sections54bdb8ee70; plugin build id6c8ea391cf; reproducible toolchain build8a27154bcd. Left open: nothing noted. - ELF/relro/hardening and external-link policy — Done: only needed symbols exported in ELF external links
1f29f39795; external linking default for cgo std packages06b67591e7reverted20da76da91, replaced bypreferlinkexttoken for odd cgo flags035db07d7c; c-archive consolidation43115ff094. Left open: nothing noted. - Per-platform object formats and internal linking (Mach-O, PE, XCOFF, wasm, ppc64, riscv64, loong64) — Done: PE
.xdata39ca989b88and.pdata14cf82aa37(start of SEH unwinding) with SEH aux symbols76ac54b50e; power10 PCrel and NOTOCccb8db88c5,29d5272da8; loong64 psABI v2a3dd959229; wasip199de78e175; ARM trampoline fixes0b5affb193,f26bf203ac; macho label symbols for duff7dbd6de7d4; c-shared on loong641f908bd060. Left open: nothing noted.
Other changes
- Internal-linking additions internal — mips64 SDYNIMPORT (
4a1829b65a), PPC64 PCrel trampolines and power10 relocs (a3df6c0e81,de788efeac,27500d88f0,e946f0e1ff,4cf79e479b,f742ddc349,3c46d8f511), Windows ADDR32NB and DOS header (f57f02fcd5,e587a7691b), COFF complex types (d9c29ec6a5,b37c0602cd,6e57ecdb03), loong64 padding/alignment (71f82df19a,0d3c23fe87), etext padding (a6c382eaa8), ELFArch refactor (2ab0e04681), PAX_FLAGS dropped (ffb07d0c66),-fstack-protectorlibs (066b780502,c3d3be1066), dsymutil temp file workaround (a9a01ea280), builtin list update (be91040ea7). - Package init order in linker user-visible — dependable ordering computed by the linker, then reverted (
ce2a609909,642542cb3c). - Zero-sized data at runtime.zerobase internal (
19fd96512c).