Go 1.20
Unified IR becomes the default frontend with real dictionaries. PGO preview (hot-call inlining). Coverage redesign. Arenas experiment. 1-bit heap bitmap. Pacer smoothing via moving average. clear is type-checked here but gated to go1.21.
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: the PI controller was replaced with a 2-cycle moving average using the actual trigger; the PI controller moved to
mgcscavenge.go, its only remaining user (41795528b0). gctrace printslastStackScaninstead of the max (56bdf7f7d9). Pacer fields were converted to atomic types (see Other, Go 1.20). Left open: right after a phase change the average lags, which can cause a transient rise in assists (tile38 WithinCircle,41795528b0). - Heap bitmap rewrite and allocation headers — Done: 1-bit bitmap rewrite (
b589208c8c). It was reverted for wasm/386 failures (ad0287f496) and relanded unchanged (6a9c674a09) after making the GC never scan noscan objects (cb13022a24) and initializing pointer bits for noscan spans for cgo/heapdump callers (a6e6b11e3a). Word-at-a-time bitmap processing (“~30% faster in heapBitsSetType”) landed, was reverted and relanded the same way (c3833a5543,e1a8e0e05d,e49e876455). Left open: “we should make the gcdata bitmap an array of uintptr … Similarly for the processing of gc programs” (6a9c674a09). - Scavenger redesign — Done:
searchIdxused inscavengeOneto avoid N² behavior within a chunk (2caaad942e), and padding removed (f324355d1f). Left open: nothing noted. - Finalizers, runtime.AddCleanup and the cleanup queue — Done: user-visible documentation that finalizers on tiny (<16 B) objects may never run (
80d487111b); atomicfingStatus(−5% Finalizer benchmark,bd5595d7fa); test cleanup (eaf0e3d465). Left open: nothing noted. - Memory arenas experiment — Done: user-visible runtime arenas (
7866538d25) and thearenapackage withreflect.ArenaNewbehind a GOEXPERIMENT (e0d01b8467); refactors (69fc74f3ee,987f94fa03,4c383951b9); a test skip (e72da1c15d). Left open: “A later CL can potentially export it” (7866538d25); it stayed experimental. - Allocation publication, zeroing and preemptibility — Done: the scanner reads
freeIndexForScan(febe7b8e2a); an accidental submit of the alternative design was reverted (bed2b7cf41,2b59307ac2); Malloc benchmarks fixed (7717ac151a). Left open: nothing noted. - Sweeper termination and pacing — Done: bgsweep heuristic (
8451529e9a, “may be worth considering pushing this number higher”); unused sweepdata field removed (2df6c1abce). Left open: nothing noted. - Address-space layout, tagged pointers and the mem.go layer — Done:
arenaIdxaccessors made nosplit (506e690a26). Left open: nothing noted.
Other changes
- GC controller and heap fields to typed atomics internal — about 20 conversions:
heapLive,heapScan, stack/globals scan,bgScanCredit, mark times, dedicated workers,mSpanStateBox,mcache.flushGen,work.cycles,mspanset,pagesInUse(e76155614a,3a9281ff61,6e9925c4f7,e1b0da6144,02fb9b8ca9,b8f4847d6f,ba89d59a3a,9463638ca8,fe406c8b11,dcd10375bc,014f0e8205,a25a34abe9,28e388589b,d61ffe8b6c,5a37965495,f1b7b2fc52). Manual alignment padding was removed as a result (a52f4952cb,e28cc362a8,1c59199c91), and the cache-line padding formula fixed (f15761b50b). - runtime/internal/sys.NotInHeap internal — replaces the
//go:notinheappragma with an embedded marker type (a719a78c1b). - Write-barrier-enabled pointer atomics internal —
UnsafePointer.Store/CompareAndSwapandPointer[T]with barriers (9fedc481ea). - GC bookkeeping fixes internal —
userForcedset undergcsema(6f7c9ea855);traceGCSTWDoneonly when tracing (8befe0e408); unusedgcmarknewobjectparameter removed (51c34e2f0b);_g_→gprenames (5e8d261918,222799fde6);getStackMapas anstkframemethod (b91e373729).
Scheduler and concurrency
From Runtime: scheduler, timers, channels, locks and synchronization (Go 1.18–1.28)
- Timer rewrite: per-P timer heap, timer.lock, and GC-able synchronous timer channels — Done: timer fields converted to atomic types:
p.timer0When,p.timerModifiedEarliest,p.numTimers,p.deletedTimers,timer.status(e1fd51e076,bb5d656a3a,c82bbc0e8e,6e74c4116a,f78efc0178);schedt.pollUntillikewise (0fc774a68f). Left open: the timer state machine itself is still CAS-based. - Contended runtime-lock profiling (mutex profile for runtime-internal locks) — Done: user-visible
/sync/mutex/wait/total:secondsruntime metric (63ceff95fa); wait reason for goroutine blocked on a mutex made specific (a2c396ce00,686b38b5b2); mprof locks split (1.19,89c0dd829f1.19). Left open: runtime-internal locks invisible in the profile. - Scheduler core: spinning Ms, work conservation, stealing, STW interaction — Done:
sched.needspinning: if work submission (wakep,injectglist) finds no idle P it sets the flag, and a non-spinning M about to drop its P rechecks it and becomes spinning instead; fixes a worst-case deadlock wheninjectglistfinds nothing as all Ps go idle (8cb350d69a). A long list ofschedtfields converted to atomic types (see sync/atomic thread).goschedIfBusyyields ifgp.preempt(50664c236f). bgsweep “low-priority” heuristic: don’t yield if idle Ps exist, sweep >=10 spans between yields, cutting trace events by 90% (8451529e9a). Left open: nothing noted. - sync package API evolution — Done: user-visible
Map.Swap,CompareAndSwap,CompareAndDelete(395323c4d0);Mapandentryuseatomic.Pointer(b0144b3843,7366b199c5); WaitGroup stateatomic.Uint64(ee833ed72e); RWMutex counters atomic (e509452727);Once.doneatomic conversion reverted (b53471a655). Left open: nothing noted. - sync/atomic and runtime atomics — Done: the runtime-wide conversion (
b464708b46,dd8cb66d0b,5d7d50111f,58a1dabfd1,1eeef5d5b4,88ef50e662,3fbcf05d40,951d2c657d,fa0e3bffb4,3f65ddbfd3,301ca7513f…); a revert forncgocall(ef8414101f); user-facing hints toward typed API (0bd4710ca6). Left open: nothing noted. - Runtime lock ranking — Done: DAG generation, unused ranks deleted, trace locks moved to the leaf (
2b8a9a484f,ddfd639408,f42dc0de74,cc8bac8835,44ff9bff0c,c5be4ed7df). Left open: names of ranks lost. - Netpoller — Done:
netpollWaiters,netpollWakeSig,netpollInitedatomic (aab8d2b448,901b9233e6…). Left open: nothing noted. - Goroutine lifecycle and identity — Done:
goiduint64 (dd8cb66d0b). Left open: nothing noted. - Fast random numbers for the scheduler — Done: loong64 wyrand (
3a41094107). Left open: nothing noted.
Other changes
- math/rand auto-seed user-visible —
90a67d052e;math/rand/v2skeleton later (59f0ab40361.22, 1.22). - Exit hooks internal —
addExitHookfor coverage (07bdf1dc54). - godebug settings API internal —
ea4631cc0c. _g_removal and atomics sweep internal —e9d7f54a1a,4358a53a97,4509e951ec; further atomic conversions in the long tail (40fa2dabe0,7666ec1c99,449691b3ef,09cc9bac72,b04e4637db,3121c2bf64,5b0ce94c07,b11b4b4de3,ce7aae5095,ec8ed5bd02,9b988c9094,04d8c2327d,dea67a9b34,7e7ecf5cbb,bc805795bd,f6efcf1fbb,2883af63c2,e0ec1d6770,5634629f0b,7a1ae605eb,1110222bee(reverted),5a6db7c48f).- Lock rank annotations internal —
d29a0282e9,502b6057d2,9923162f1c. - Trace extra-M events internal — added, reverted, re-added (
ea9c3fd42d,fb6c210dc3); schedtrace nil IDs (98e1648823). - atomic pointer inlining internal —
ef69718dd7,b14cf3d93a; misc cleanups (cc9584b54b,f00fa0b98d,0063b9b036,556c978400,ffe5f085cd,e406112011,4fe4601d37,f63b268b9a,185e1a7b27,8232a09e3e).
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: Unified IR starts setting
RTypefields so reflectdata no longer re-derives runtime types from IR (7368647ac6,f70775ff22,2cf632cd57), fewer basic types emitted in every compilation (cb5534c1c6), no content-addressable symbol for generic iface method names (8dc7710fae). Left open: “subsequent CLs will handle the remaining more complex cases” (7368647ac6). - reflect implementation: performance, allocation and escape behaviour — Done: user-visible
Value.Grow(61f0409c31),SetZero(bc1d0d8eb1),Comparable/Equal(acabf87127;Equalrewritten to avoid allocationa343f4017b, panics on two non-comparable values7ffc1e47b4), slice→array conversion (805f174e5c),FuncOfsupports >50 args (d7a3fa120d) by building func types throughStructOf(63668a5155),rtype.MethodByNameby binary search (0053ec452d),IsZerousesrtype.equal(1ab6b790be),unsafe.Stringfor names/tags (26b2c9a620),SliceHeader/StringHeaderdeprecation added (d734203e39) then notices removed because no proposal discussion (9f2951b5d1). Race onfuncTypesfixed (6d8ec89303). Left open: deprecation postponed to 1.22 per wiki rule. - Register ABI completion for reflect, memmove/memclr and bytealg across architectures — Done: riscv64 always on and fallback deleted (
7e72d384d6,5d59fa143a). Left open: nothing noted. - memmove / memclr / memequal / internal/bytealg assembly optimisation — Done: riscv64 memclr/memmove (
44ad662a49,e18d07ddc5), alignment-check correctness (fd82718e06), ppc64xPCALIGN(92c7df116e). Left open: nothing noted. - Slice growth, string building and allocation-free bytes/strings helpers — Done: panic when
unsafe.Sliceparam is nil and length >0 (52d0667e6b). Left open: nothing noted.
Other changes
- Pointer bitmap one-word-at-a-time reverted internal —
c3833a5543,e49e876455reverted bye1a8e0e05d. - Method wrappers only inlined without closures internal —
f21514c7f8.
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: v1 trace lock hygiene as preparation for scalability:
trace.lockonly on the system stack (6c2e327e35,42794f3871), reader parking no longer undertrace.lock(9923162f1c), stack table dumped directly into the trace buffer (d4a3466519,0293a1f308,b648591b70);tracing.enabledmade atomic (5e20f2e4df); extra-M (cgo callback) goroutines get syntheticGoCreate/GoInSyscallevents atStartTraceso the parser stops reporting “no consistent ordering” (fb6c210dc3, after a revert8adc63b3eb). Left open: “No consistent ordering” and the global lock remain structural problems of v1. - Mutex and block profiles, including runtime-internal lock contention — Done: user-visible mutex profile samples scaled at record time, so changing the sample rate (even to 0) does not corrupt old samples, matching block profile (
30b1af00ff);/sync/mutex/wait/total:secondsmetric piggybacking on G runnable tracking and wait reasons (63ceff95fa). Left open: runtime-internal locks not in the profile. - CPU profiling, goroutine profiling, pprof labels and the protobuf writer — Done: user-visible 4-column memprofile text form forced so
pprofdoesn’t collapse alloc==inuse into 2 columns (c2ede92a0d); Windows memory mappings (28afa5b176);Function.start_line(a401468b00); Windows MaxRSS (2cc6983a21);prof.hz,profbuffields to atomic types (54cf1b107d,c3c10f5d67etc.);MemProfileRateno longer set in init (f63b268b9a); empty-stack docs (0bbd67e52f). Left open: nothing noted. - runtime/metrics and MemStats — Done: user-visible estimated CPU time breakdown metrics (
/cpu/classes/...) with total CPU (b7c28f484d);/sync/mutex/wait/total:seconds(63ceff95fa); timeHistogram atomics and size cut (b04e4637db,87eda2a782). Left open: CPU numbers are estimates, not on-CPU counters. - Coverage redesign: runtime/coverage, internal/coverage, covdata — Done: user-visible full pipeline above: encoder/decoder (
f951f697c4,84f95aa811), exit hook (07bdf1dc54), runtime emit (87db4ffada), covdata tool (7a74829858), counter I/O (efa3f1749f), user APIs (ecd112c0d1), package registration hook (cf83a490e4); experimentGOEXPERIMENT=coverageredesignadded (a3434b71a3) and enabled by default (9910f8a403, 2022-09-29); atomic counter reads (cddf792428);-coverprofilelocal-package path capture restored (2730170f63);package mainhandling fix (7973b0e508). Left open: covdata mode clash policy (relaxed in 1.21a371fa5e701.21). - Race detector, ASan, MSan and Valgrind integration — Done: ASan on ppc64le (
9e810997c0); race syso subarch versioning and GOAMD64=v3 image (e665de2861,c75b10be0b,18baca6765); no cgo needed for race on macOS (5bf9aeba1c). Left open: nothing noted. - Crash output, runtime/debug, BuildInfo and debuglog — Done: docs and debuglog
unsafe.Sliceavoided (dadd80ae20,c45ebef05e). Left open: nothing noted.
Other changes
- Cleanups in profiling/coverage/trace code internal —
_g_removal in trace.go (74cee276fe,4400238ec8),unsafe.String/Sliceadoption (4fe4601d37,7ffbcd1987,be3184c405), atomic types for profbuf (04d3d6bf48,5b1658d691), Getrusage error check (2e06019dcd), coverage function renames (47a538842b), pprof mapping/label cleanups (aa4299735b,0857633f8b). - riscv64 SV57 internal (
1e3c19f3fe); atomic-type conversions of profiler/trace fields (3121c2bf64,2af9ee0727,52d9e7f543,bcd1ac7120). - lfstack vs checkptr internal (
d6171c9be2).
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:
panicking,runningPanicDefersconverted to atomic types (bd302502d3,7666ec1c99),canpanicanddopanic_mcleaned (7e952962df,0ad2ec6596). Left open: nothing noted. - Unwinder: gentraceback →
unwinderiterator, inline unwinder, pcvalue cache — Done: switch gp when jumping stacks during traceback (511cd9b8af), only if M doesn’t change (60ef4b2c1e), not at entry ofsystemstack(500bc6b805);stkframeconsolidation and function-context removal (8be94b82ab,35026f3732);morestack_noctxtmarked SPWRITE on LR arches (e4be2ac79f). Left open: the monolithic function and callbacks remain. - Symbol tables,
runtime.CallerandCallersFrames— Done: name/entry offset renames (196003f9fd,7ebaa6587b). Left open: nothing noted. - Stack growth, stack bounds and the crash stack — Done:
-racestack guard increased (893964b972); cmd/dist guard multiplier fixed (b12366bbb5);_Stack*constants tidied (ef8e3b7fa41.21 then partly reverteddf777cfa151.21); 104-byte guard removed (57236fe9f71.21, listed in Go 1.20 by the key file; log places it in 1.20 cycle). Left open: nothing noted. - C-to-Go callbacks: extra-M reuse, system-stack bounds, init gating — Done:
runtime/cgo.Incompletereplaces//go:notinheapin cgo (846c378b8c);-fno-stack-protector(365ca69472); darwin pthread stack size follows rlimit (7d3a5a501c);extram/extraMWaitersatomic (5634629f0b). Left open: nothing noted. - Security hardening: AT_SECURE, std fds, AT_RANDOM, gated debug features — Done: page tracer behind GOEXPERIMENT (
e4435cb844);-fno-stack-protectorfor cgo (365ca69472). Left open: nothing noted. - vDSO,
vgetrandomand fast clocks — Done: fast FreeBSDclock_gettime(e51b3ae0ee,535fe2b226), freebsd/riscv64 vDSO (0e56c31b85), ARM VDSO call helper (876d477b0e). Left open: nothing noted. - Signals and async-preemption machinery — Done:
SI_TKILLlikeSI_USER(d11c58eedb, after revert),sig.stateatomic (d01200e772),TestCgoSigfwdon all Unix (03272d14ed). Left open: nothing noted. - Syscall layer:
AllThreadsSyscall,internal/runtime/syscall, libc and WindowsSyscallN— Done: epoll syscalls moved then reverted/relanded (c7cc2b94c6,4a49af5755), OpenBSD libc (0d6a7f9d2e), MADV_DONTNEED on BSDs and Solaris (19a4804854), FreeBSD non-COMPAT kevent (e0e1ce9888), mipsr2zero (2c7c98c3ad). Left open: openbsd/mips64 stays on syscall(2). - Windows runtime port — Done: TEB TLS slots (
da564d0006), CFG (5c0d314adc), ignore exceptions from non-Go threads on windows arm/arm64 (6fe3ccd74c). Left open: nothing noted. - New, ported and removed platforms — Done: freebsd/riscv64 (
9aa7107cb5,d268504fd9,0e56c31b85). Left open: nothing noted. - CPU feature detection, GOAMD64 checks and cpu GODEBUG options — Done: SHA-NI, arm64 SHA512, openbsd/arm64 detection, M1 cache line (
f1b1557cf3,228f891c90,cd54ef1f61,95a5e20d8f,59865f1420,1163acf3ea). Left open: nothing noted.
Other changes
- FreeBSD/OpenBSD/ppc64 odds internal — msan on freebsd/amd64 (
5fde02e312), symbolic FreeBSD syscall constants (848febdcec,c04977fa76),SI_TKILLhandling (7c87012f04), ppc64 start-up on newer kernels (7d1cab12c7), usleep fix (65f863529c),tforkchange for openbsd/mips64 (e84ce0802d), consolidated low-level error reporting (79d9b395ad), atomic conversions of runtime fields (40fa2dabe0,bc805795bd,e1114fdf88,d3b35a4242,296c40dbbe). _g_cleanup internal —getg()locals replaced across os/signal/traceback/GC files (8666d89ca8,4240ff764b,54a0ab3f7b,b486518964,5999a28de8,c647264619,29b9a328d2,0e18cf6d09,399f50c9d7).- Apple libc atfork hangs internal —
osinit_hackcallsnotify_is_valid_token(0)andxpc_atfork_child()so fork/exec doesn’t deadlock (1f4394a0c9, retried76d39ae349, revert6c9b661867). - Thread creation retry on EAGAIN internal — (
14018c8bec). - darwin DNS via libc user-visible — net uses libc not cgo (
a3559f3301). - internal/godebug internal — lightweight setting API:
godebug.New→*Setting.Get(two atomic loads when unchanged) (ea4631cc0c,8dc08394f0). - Keep mp alive until mexit done internal — (
e252dcf9d3).
Compiler frontend · types2
From Compiler frontend: the types2 type checker (Go 1.18–1.28)
- Type sets, union terms, interfaces and constraint satisfaction — Done: user-visible new
comparablesemantics.5a3900b23cadded an alternative semantics underConfig.AltComparableSemantics(experiment, off by default).15e705ea96made it the default,2ca32a5b99reverted it, and8fd2875c3ereland it, with the flag renamedOldComparableSemanticsand inverted. The commit also adds the exported predicateSatisfies; the compiler flag-oldcomparablewas announced as temporary (“will be removed for Go 1.21”).642fd5f7ceuses strict comparability for type-set intersection. Other:f60c77026b(empty type sets in operand descriptions),0789ca4951(signature instantiation when all type arguments are given). Left open: the flag removal was announced in the message; no removal commit appears in this bucket. - Instantiation, Named types, Context deduplication and lazy expansion — Done: user-visible
ddd8bc1b07makes the instance lookup inLookupFieldOrMethoduse a small inline array before a map: −60% time and −99% allocated bytes on the microbenchmark, ~5% faster type checking of std packages with ~10% fewer allocations.0789ca4951instantiates signatures if all type arguments were provided.70f585f018marks invalid generic types invalid. - Type inference and unification — Done: user-visible
0b323a3c16clearer CTI failure message;e738a2f19balways rename type parameters. - Language features as seen by the type checker (by release) — Done: user-visible
ba5deb408funsafe.String/StringData/SliceData(+ tests8c8429fe41);cd8aa40149slice-to-array conversions;5c834a2eb0clearbuiltin;f80b12667cinteger constant literal overflow check;5a3900b23c→8fd2875c3ecomparable. - Error reporting: codes, messages, and sub-errors — Done: user-visible unification of messages with go/types (above),
b52783c1e9,4a954fafa3,79d0d330a9(field with the name of a missing method),4b993bffb8,de0f4d190f(no unneeded error strings inimplements). - Sharing code between go/types and types2 — Done: test-data consolidation (above) and
157aae6eedfor checker-specific local tests. - Checker performance, memory and API ergonomics — Done:
ddd8bc1b07: LookupFieldOrMethod −60% time, −98.8% bytes on a microbenchmark;c641d48afd1.21 (1.21 by log). - Robustness: invariants, incomplete types and importers — Done:
398d46d538removes package height.
Other changes
- Range/shift/const fixes internal —
51af904456constant shift value,7ec0ec3645skip comparison for invalid operands,245e95dfabno field/method lookup when expecting a type,5ba98b9756report type mismatch when conversion impossible. - Test helpers internal —
bfcc3a755cremoves globalgoVersionflag,27f094b17c,8190876240(mustTypecheck),54ad7f33e4. - Small fixes, unifier/assignment refactors, message and tracing tweaks internal — 18 commits:
cb357835d9,5befb24bb5,0fda8b1932,2392b7061c,c7a0b15659,dad2966a83,0a1118b8a1,4c5a6f9555,17f83e3473,4360fd8d6f,b16501c08b,b2137e7dad,e22af33b48,97d38f3002,665992b515,19095e109d,a8f9d3f0af,dfd13ce59d
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: Unified IR switches to real dictionaries:
c9f2150cfbgeneratesF[T]-dictglobals, aF[T]-shapedfunction with.dict *[N]uintptr, andF[T]as wrapper;38edd9bd8dis the shape-based stenciling commit (initially shape = underlying type, one dictionary per type, shared by all methods, deliberately so that a future “itab in closure register” scheme could find the dictionary; noted drawback: dictionary entries for pruned methods stay alive, possible fix by linkerR_DICTTYPE/R_DICTUSErelocations). Pointer shapingb23d469e85,6985ab27df,07cf24bdfe, itab-section pruning9fc09d2ffb,OCONVNOPfor identical iface conversions34f0029a85, shape rtypes avoided in ssagen (5e0258c700).ca634fa2c5rejects notinheap type arguments. Left open:5e0258c700says shape rtypes are still used forruntime.newobjectof heap-escaping variables and “longer term I would like to get rid of shape rtypes altogether”; no pruning of dictionary entries for dead methods. - Unified IR: one serialization for noding, stenciling, inlining and export — Done: package height dropped from the importer and symbol ordering (
3a1f1e1575,4b78ece3d7,df7cb59de4); dictionary logic pruned (29b07037b1);0a6e1fa986/ddc93a536f/aa6a7fa775fixes for shapifying recursive instantiations and reflect naming of local generic types; default-on via833367e98a(author date 2022-08-09,internal/buildcfg: enable unified IR by default, GOEXPERIMENT=nounified becomes the escape hatch); runtime dictionaries and shapes (see generics thread); pkgbitsEnableSyncbecomes a dynamic header flag (9371a65584, bumping the version; “drchase’s benchmarks show it isn’t as expensive as feared”); body pruning heuristicf995946094(include all inline bodies for… with a simple heuristic rather than crawler-based pruning);e8afb29111“temporary” readers to reuse storage;caa8e1f977type-specializedReadUvarint;6b80b62fd1rawReloc perf.8ef8b60e18stops handling type expressions as expressions. Left open:f995946094is explicitly a short-term heuristic vs. the oldcrawler.go. - Old typechecker and IR node-model cleanup — Done:
OFORUNTILremoved (a5370d038e),OVARKILL/OVARDEF/OVARLIVEremoved from the frontend (e21c1f7896,a726c9f662),typecheckresults stored in the syntax tree rather than a map (59bc93535b, ~3% compile time: SSA -4.0%, Unicode -9.0%),types.Rnd->RoundUp,eagerly create LSym for closures(33738ddd0a),typecheck.EvalConstremoval prepared. - RType/ITab fields and implicit conversions in IR (RTTI plumbing) — Done: RType/ITab fields added (
5960f4ec10),reflectdata.{TypePtr,ITabAddr}refactored to prefer them (f70775ff22), ssagen avoidsreflectType(5e0258c700), set for OMAPLIT (3d432b6c4b), switch/case clauses (61ae2b734c), range assignments (d667be8831), selects (878439cfe5), writer-side implicit conversions for sends, index expr, complits, call args, assignments, returns, binary exprs and multi-valued expressions spilled to temps (5f5422a2dd,a3e474f867,711dacd8cf,a3fea7796a,421e9e9db2,c846fd8e13,3635b07d16), RTTI written to export data (9b70178d58,92798176e7,e376746e54), obsolete wiring removed (f48fa643f1), explicit nil / type-switch handling (318027044a,a4c5198a3c), function instantiations / selectors / receivers handled explicitly (2e6ffd6c5d,88635b3862,de95dca32f),f2851c67fdallows inlining to fail gracefully. Left open:f773bef9ab1.21 (1.21) notes the RType fields aremknode:"-"hidden fields “to avoid throwing off inlining cost heuristics”; “longer term we should unhide them”. - Static initialization and package init — Done: inlined-call static init (
b1678e508b,bed970b3ff,249e51e5d9,c85848a4a6), initially unstable:152119990fadds-d=inlstaticinitand temporarily disables it (“Google-internal testing is hitting additional failure cases”),f89b39c0afre-enables; coverage vars special-cased in init order (4fb35d6cee); Left open: fixes for hidden RType fields (f773bef9ab1.21) still pending. - Compile-time performance, concurrency and the self-PGO’d compiler — Done: one manager goroutine hands out work to at most nWorkers (
2ff5fbfbd4) instead of hundreds of blocked goroutines; default concurrency =GOMAXPROCS, compiler downgrades silently if debug flags are incompatible (b725622ceb,f3d656be50, tagged flags viac81c027982“concurrentOk”); ifGOGCis unset, boost the GC to get rapid starting heap growth: ~14-17% less user build time and 3.5-7.8% wall (44cabb802a);typecheckresults kept in the syntax tree (59bc93535b, ~3%); eagerLSymcreation for closures. - Compiler debugging infrastructure: bisect/hash debugging, flags, dumps — Done: GOSSAHASH refactored to be usable outside ssa (
522f0fc425,03f6d81fc7), separator;->/(1bcfdc777a), file:line hashing incl. inlining (d33043d37d),concurrentOkflag property (c81c027982), coverage fixup mode (e6d9057e2f). - Frontend support for new language features and spec changes — Done: user-visible
unsafe.String/StringData/SliceData(c708532936), slice-to-array conversions (ceffdc8545), alternativecomparablesemantics (b95ea201d5; old removed in 1.21354c8fb4361.21),go:notinheaprestricted (ec2ea40b31) and removed in favour ofruntime/internal/sys.NotInHeap(0ee0bb1003,8bbb362f4c), reject not-in-heap type arguments (ca634fa2c5), updated error messages (“satisfies”, “missing method m”, …) andinternal/types/errorspackage (b440c15db7,49372957ab). - The syntax package (parser, scanner, tree) — Done: tolerant
go/deferparse (BadExprinstead of a fake callc801e4b10f, no spurious “not used” errors489f508ccf), missing-index handling (9485d4c1bd), stricter type instances (1be8fcdcdc),ErrorMap->CommentMap(1.211e005165831.21), import decl tolerance (a330ca5c54). - Method wrappers and promoted-method sharing — Done:
a8780f94c3missing method-value wrapper;1519729c6aetc.
Other changes
- Error messages and error codes user-visible — messages rephrased to match the old compiler (“missing method m”
336ce966e4, “method T.m already declared”7398c3c0c6, “init… cycle”c58bfeeb04, “cannot use … value in …”7997e5f254, “satisfies”46e3d9d12a,6ad27161f8); sharedinternal/types/errorspackage with exported codes (b440c15db7,49372957ab,470d146276,578523e4a0) used by go/types and types2; structs package-annotated when ambiguous (ea2c27fe82). - Std modernisation internal — mechanical
ioutil->os/io,strings.Builderin syntax/ir/pkginit (86f8b8d3f2,1429a97520,431446d0a0),SEEK_*constants,unsafeheader.Slice/String(41089704dd), mmap on solaris/aix (7c3284401f,349d398ea3). - Struct-compare inline heuristic internal — cost-based rather than field count (
6605686e3b); non-CALL comparisons first in array-of-struct equality (c5ba9d22321.21, 1.21). - PGO user-visible — profile-guided inlining first enabled (
99862cd57d, CDF-based thresholdb07e845e76, parameters1b03568ae1; opt area). - Ineffectual linkname user-visible — allowed again in
-lang<=go1.17(aa6240a445). - Reproducible toolchain internal —
cmd/distbuilds cmd withCGO_ENABLED=0(8a27154bcd1.21, 1.21 log). - Unified IR: noder/writer/reader refinements and pkgbits (1.20) 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 (55fc07e164,b39ac80871,46ddf0873e,9e5c968021,e7ef58542c,d6df08693c,c50c6bbc03,7368647ac6,c70e93ff3d,9cb784ac69,46b01ec667,76a82f09d6,64cd6faa13,131f981df0,831fdf1dff,ac0844ec27,2699065483,7d70779db5,9f8685f49e,db84f5315f,2f103873c5,e4b624eae5,dfdf55158d,5d213a3dc7,157e018fc3) - Generics: dictionary/shape fixes in the stenciler (1.20) internal — fixes in dictionary passes for type assertions, comparisons, switches, nested instantiation packages, and recursive generic interface instantiation (
62654dfd4f,9944ba757b) - Old typechecker and IR node-model cleanup (1.20) 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 (
13bd6ddbe7,b911771f12,bd901af30b,68fa3696b6,271f139f17) - Syntax package: error messages and parser tolerance (1.20) internal — better syntax and go/parser error messages, accepted type-parameter lists, parser simplifications (
aa5ff29dab,1280ae7856,8c29881dd1,c591d82ea9) - Housekeeping (1.20) internal — dead-code removal, ioutil/seek/slices/atomic-type replacements, README edits, debug-flag removal, assorted small bug fixes and doc comments (
fb1bfd4d37,0c4db1e347,3ea3d0e8a7,2493072db6,0a86cd6857,e99f285d52,1e7f535475,274528eca1,00bee6d9a4,f8c659b62f,fac5338a6c,ae3abf16e4,8bd803fd4e,4bcf94b023,da6042e82e,7ea0520234,4725c71b73,b726b0cadb,d3726f3469,96711e4d8b,6a70292d1c)
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 Raj Barik’s initial implementation:
pgo/graph.goandirgraph.gobuild the profile graph, and the inliner uses it (99862cd57d, #55022). Within the same cycle the heuristics were reworked:- Inlinability is decided by edge weight rather than node weight (
fb4f7fdb26). - The hot threshold is a CDF over edge weights, not a fixed percentage (
b07e845e76). - Calls are matched by line offset from
start_line(bdd1e283a9, with a fix in0409314db3). - Only the last two frames form an edge (
6e0e492e12). - Defaults became 99% CDF and a 2000 budget, and the debug flags were renamed
pgo*(1b03568ae1). - Supporting work: global state, label handling and per-location maps were removed for speed (
ec0b540293,204be97d24,d73885588a,1a4cc091a9,a72e133422,7e88b866f9,f187c6b08e,d9cc39b25c,3f1bcc58b3); cross-package inlining was fixed (ada9385a5f); empty profiles are accepted (efe541d4e5); debug output and the missing-start_linehint were improved (e5d2814576,64519baf38).
- Inlinability is decided by edge weight rather than node weight (
- Inliner: budget, closures, and the interleaved inline/devirtualize driver — Done:
- With unified IR on, inlining fails gracefully (
f2851c67fd) and more inlining is allowed, lifting the shape restrictions (52016be3f4). - Transitive inlining is deferred until the AST is edited (
f983a9340d). - Cost discounts for
encoding/binaryappends and zero-offset field addresses (629c0b3a6e,638c9aad5f). - A latent
CalleeEffectsissue was fixed (25d74f324d). - Coverage-counter updates do not count against the budget (
4a459cbbad,317f2a7df6).
- With unified IR on, inlining fails gracefully (
- Escape analysis: call modelling, closures, func-variable callees, and solver speed — Done:
OITABandOCHECKNILare supported (0c2f87f23d). 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:
- The relation between
x+deltaandx(d2e0587f77), with 8/16-bit deltas (2addbf3f2a). - Bounds for strided-loop induction variables were tightened (
af7f067e0d). - Signed relations for constant integer phis: −1.4% total size (
d96eb826cb). - Bitwise
OR(3680b5e9c4), reverted for compile time (a6ddb15f8f1.21) and relanded in 1.21. - An index out-of-bounds check in
walkIndexwas removed (98f5152368).
ORsupport was pending a compile-time fix. - The relation between
- Memory-op optimization: memcombine, dead stores, store-to-load forwarding, alias analysis, mem2reg — Done: more constant stores combined on amd64 (
09932f95f5), plus store combining of values (e7307034cc). These were per-arch rules, the predecessor of the memcombine pass. Left open: each architecture needed its own rules, which the 1.21 pass replaced. - Lowering of builtins to memory ops: memmove/memclr/memequal inlining and generated equality — Done: the
memmoveoptimization no longer trusts the destination pointer’s base type (e283473ebb). Struct-compare inlining uses a cost heuristic (6605686e3b). Left open: nothing noted. - Switch lowering: jump tables, type-switch caches, and switch lookup tables — Done: a better split for string binary search (
69aed4712d). Jump tables are off when spectre retpolines are on (1eb0465fa5). Left open: nothing noted. - Static devirtualization and shape-aware type-assertion pruning — Done: fixed a unified IR devirtualization bug (
d6294e00f0).defer/gocalls are not devirtualized (c82304b712).OCALLMETHis desugared toOCALLFUNCwithin devirtualization (4f8bc6224b). Left open: nothing noted. - Range-loop and range-over-func lowering in walk — Done:
OFORUNTILis no longer used (661146bc0b).- Range desugaring was refactored for unified IR, with RType fields for range assignments (
0a503cf43a,d667be8831). - Careful pointer incrementing (
8477562ce5).
- Branch-free lowering: CondSelect-into-math and ARM64 CCMP — Done: CMOV disallowed when an argument is pointer arithmetic, which could be unsafe to speculate (
c8057d8569).
Other changes
- Fixes and small rules (~55 commits) internal — booleans registerizable (
de561dc766), arm64 RotateLeft8/16 and MulUintptr intrinsic (121344ac33,d654117075), loong64 rotate intrinsics (e8f0340fa4), combine rotates (33a7e5a4b4), stack offset alignment beyond PtrSize (1211a62bdc), static-init slice walk/typecheck fixes (fce449680a,03a1810473), libfuzzer instrumentation tuning (6b113c0fec), sparsemaps with position separated (7ddc45263c). - VarKill removal internal — with stack objects, VARKILL is unnecessary; usage stopped, SSA op, frontend OVARKILL, OVARDEF and OVARLIVE ripped out, VarDef only for pointer-ful types (
908499adec,6dc7b060cd,e21c1f7896,a726c9f662,a74e5f584e). - Growslice calling convention redone internal —
growslice(oldPtr, newLen, oldCap, inc, typ)so old length is dead across the call and registers align better (dd323fe205); append-with-constant-length recognition and post-decomposed growslice rule (0156b797e6,9ce27feaeb);unsafe.Slicecodegen (c2a9c55823, nil-with-length panic52d0667e6b). - Late lower pass internal — extra pass so last rules run (
ddc7d2a80c); arch-independent rotate detection (60ad3c48f5);>>c<<cto mask (5b1fbfba1c); Floor/Ceil/Trunc/RoundToEven constant folding (ab8a2c5e44); sqrt assembly removed in favor of intrinsics (c8000a18d6). - Compiler memory reuse internal — cache of sizeable objects via sync.Pool of power-of-two slices (
68bd383368); fuse largest runs of plain blocks (9e0149da3c); quadraticIsNewObjectfix (0202ad0b3a); Not-in-Phi block control elision (fd59c6cf8c, fixed8893da7c72); overlap handling for assignments (332a5981d0,6485e8f503). - riscv64 optimization series (~15 commits) internal — redundant SEQZ/SNEZ, extension avoidance, immediate combining (
9085ff5859,77da976419,7234c90352,5760fde4df); riscv64 Add64/Sub64 intrinsics (969f48a3a2,a6219737e3); arm64 TST/shift/Muluhilo changes (efe5929dbd,54c7bc9cff,8bf9e01473). - dev.unified rtype plumbing internal — extract rtype code from walk, avoid reflectType in ssagen (
93833cd5d8,5e0258c700,3d432b6c4b).
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: temporary registers: ops can declare a temp so regalloc reserves one instead of a fixed register; amd64 converted
5f7abeca5a, with a fix when mask is empty9088c691da;issueSpillremovede81263c791; fix score forSelect{0,1}of flags897ad2fe90; sparsemaps separated7ddc45263c; carry chain scheduling priority readjustedd031e9e07a;OpVarKilldropped from the backend6dc7b060cd. - amd64 code generation and GOAMD64 microarchitecture levels — Done: combine more constant stores
09932f95f5; 3-operand LEA split in the new late-lower pass1c783f7c68,{SHL,SHR,SAR}Xrules moved to late lower44563340cc; Windows TEB TLS slots on amd64/386 (da564d0006). - arm64 code generation and assembler — Done: late-lower pass makes constants materialize once (movz+movk) instead of repeatedly folded into adds
ddc7d2a80c; TST optimizations in-blockefe5929dbd; shift byv&63uses hardware masking54c7bc9cff; CMP↔︎CMN rulescf53990b18; LDP/STP memory moving0a52d80666; carry-chain scheduling enabled on arm64 (reverted oncefec83c8a7d, relanded)4c414c7673,669ec549b5; Duff’s device on darwin/arm644bcc138bc6; Muluhilo split8bf9e01473. - riscv64 compiler and assembler (RVA profiles, vector, compressed) — Done: a run of ~12 constant/extension peepholes: SLTI/SLTIU known outcomes
a7bcc94719, SLT constants→immediateba8c94b5f2, remove redundant SEQZ/SNEZ77da976419, combining ops with immediates7234c90352, mask+zero-ext0ca355318f, avoid extension after word arithmetic5760fde4df, FP compare239115c3ef,646c3eee06, negation folding4274ffd4b8, sub const3e11e61f3c, Slicemaskc011270fa5, bounded shiftda6556968f; CAS32 arg sign-extension fix (LL/SC loads sign-extend; shared with loong64/mips64)0b2ad1d815. - loong64 backend and assembler — Done: brachelim enabled
268f4629df; tail-call flag8a9e2d9d49; MASKEQZ/MASKNEZ1dcef7b3bd; ROTR + intrinsics7d574466a9,e8f0340fa4; Add64/Sub64 intrinsics97760ed651,90a3527427; resultInArg0 register checks removedc1c6b0ca79. - PPC64 / Power10 backend (GOPPC64, prefixed instructions, PC-relative code) — Done: ISA 3.1 and MMA registers
3a067b288e,85c0d26c6a,e6eaf39cfa; atomicCas without branch62125c9b79; condition-code ops (…CC) reuse to drop comparesd0b0b10b5c;lateLowerenabledf841722853with ISEL mergedc6b7c86df; Mul64uhilo rules871a3a409a; big uint32 constants in registers4e6f90fecd. - Duff’s device replaced by generated loops; Zero/Move lowering — Done: Duff’s device enabled on darwin/arm64
4bcc138bc6; fine-tuned memory moving on arm640a52d80666. - Late-lower pass, memory-op combining and arch-independent rule migration — Done: late lower on arm64
ddc7d2a80c, PPC64f841722853,bd6cd7db07, amd641c783f7c68,44563340cc; riscv64 late lower type fix2952fe4f16. - Multi-word arithmetic, intrinsics and carry-chain support — Done: arm64 carry scheduling
669ec549b5; Add64/Sub64 on loong6497760ed651,90a3527427; Muluhilo split on ARM648bf9e01473; 386 TrailingZeros (1.21)cedfcba3e81.21. - WebAssembly backend — Done: bulk memory ops
50557edf10; docs on Go→wasm mapping660d4815ea.
Other changes
- Start line numbers in func metadata user-visible —
runtime._funcandinlinedCallrecord thefunc/TEXT line so pprof can use relative lines; +0.83% binary size vs master, −0.31% vs 1.19f2656f20ea. - debug-hash for FMA internal —
-d=fmahashbisects FMA-sensitive floating-point bugs667c53e159; hash-debug on file:line, including inliningd33043d37d. - cmd/go support for long assembler/cgo commands
5bc8fa74f5; ssa_gen/_builtinrenamed164406ad93. - ssa Config cache of sizeable objects internal
68bd383368. - 10 small obj/arm64 and arm64 rules commits internal — e.g. obj/arm64: remove the transition from $0 to ZR; cmd/asm: add VTBX instruction on arm64; cc: Add shiftIsBounded check for logic shifts of arm64. (
9f0f87c806,9e8020b2d4,454a058ffc,205f636e0a,0613418c98,eeb1ba7a89,ebc75ac1c6,a813be86df,9f78c3cb04,612bb34af5) - 10 small obj/ppc64 and PPC64 rules commits internal — e.g. cmd/asm: add new classification for index memory operands on; obj/ppc64: eliminate dead code from asm9.go; cc: fix confusion with ANDCCconst in PPC64 rules. (
67d85ad00f,f67c766069,c1bfefe9d1,403f91c244,59b15726d1,a50c434308,4350c4a131,6e1b769377,1985507257,888047c310) - 11 small ssa/regalloc/liveness/obj generic commits internal — e.g. obj: remove redundant code in genFuncInfoSyms; abt: use strings.Builder; all: remove unnecessary allocations from w.WriteString(fmt.S. (
f7e6986d6b,0cf996a9c1,4baa486983,00bee6d9a4,1a6af5f7a0,2b1c414fa8,b314eea4cd,85196fc982,e09bbaec69,5497300d9c,e8f78cb60c) - 6 small obj/riscv and riscv64 rules commits internal — e.g. cc: deadcode for LoweredMuluhilo on riscv64; cc: avoid extending when already sufficiently masked on risc; cc: remove NEG when used with SEQZ/SNEZ on riscv64. (
b60432df14,9085ff5859,971373f56a,b6a6847b2f,83d94daec2,af668c689c) - 6 small cmd/asm commits internal — e.g. cmd/asm: use strings.Builder; cmd/asm: use opd.String() instead of fmt.Sprintf; cmd/asm: optimize if statement to return directly. (
cf4edac16e,c4a3fae27e,58093e8e2b,09daf313b2,0b7aa9fa5b,9dde2de454) - 1 small obj/x86 and amd64/386 rules commits internal — e.g. obj/x86: return comparison directly. (
574b5decf2) - 1 small obj/loong64 and loong64 asm commits internal — e.g. cc: remove output registers limit for MUL/DIV on loong64. (
ffc4496306)
Linker and object files
From Linker, object files and debug info (Go 1.18–1.28)
- Relocation-free pclntab and funcdata (offsets instead of relocations) — Done: unused fields removed from
inlinedCallc83e1b6d5b; linker_funcnames aligned with runtime3e75859390; panic if an inlined function lacks FuncInfo8a0cf719a6. Left open: nothing noted. - DWARF quality for debuggers (types, variables, trampolines) — Done: DIEs for zero-sized variables
e59d873ff9; trampolines no longer break line info2340d37179. Left open: nothing noted. - Linker performance and memory — Done: fewer allocations in object writing (−3–6% compiler allocs)
5497300d9c. Left open: nothing noted. - ELF/relro/hardening and external-link policy — Done: glibc vs musl ldso detection
3315066f46;":"used for compiler symbols0f8dffd0aa; coverage counter hooks072c7d4969. Left open: nothing noted. - Per-platform object formats and internal linking (Mach-O, PE, XCOFF, wasm, ppc64, riscv64, loong64) — Done: PPC64 power10 prefixed relocs
69abfab979,-fno-pltsupport7fda98a8d9; freebsd/riscv649faf6b7929. Left open: nothing noted.
Other changes
- Platform work internal — PPC64 inline PLT and ldso paths (
c318f191e4,15d395a196), musl interpreter (0aad4d3257), riscv64 loadelf relocs (bc73996fac), darwin libc msync and no pagezero (d36466fe2a,5231ba2f05,706d84fca2), Windows no timestamp (fe67a21625), PE DLL import symbols (cf93b25366), arm64 ADRP+ADD+LD/ST fusion with -1.06% text on HelloSize (537c4354cb), entry symbol/runtime.a missing errors (77420fa119,fffda6b3ad), libfuzzer counters section (1ba7341cb2), AIX coverage (bf5805eae4), basic types not emitted from every compilation (cb5534c1c6). - Object header records GOARCH setting internal (
819e3394c9). - Drop Go 1.12 darwin compat internal (
8df21a7802). -capturehostobjsdebugging flag internal (bda0235466).