$ the-wire · showcase
crypto/tls frees pinned buffers, compiler tail call DCE fix lands
By RepoJournal · Filed · About Go
TLS connections no longer pin record-sized buffers during blocked reads, and a compiler fix prevents linker drops that caused unreachable method panics.
crypto/tls no longer pins record-sized buffers while a connection is blocked in Read [1]. A Conn's rawInput buffer, a bytes.Buffer, grew to the maximum record size (~17 kB) and never shrank, so long-polling or idle connections stranded that heap memory for minutes or hours. Servers with millions of open TLS connections lost gigabytes to buffers holding no data. The hand buffer similarly retained memory after use.
The compiler now marks interface calls as used when generating tail call wrappers [2]. The linker previously dropped callees via DCE, causing an unreachable method runtime panic; this marks the calls as used and fixes that panic.
encoding/json restores historical behavior for named string map keys [3]: MarshalText is no longer called on them, matching pre-1.26 behavior. unicode/utf16.Encode avoids overallocating for invalid runes above U+10FFFF [4], and math.Log2's accuracy near 1 improves dramatically, with worst error dropping from 9.6e14 to 1.31 ulp over 13442 arguments on darwin/arm64 [5].
gcexportdata deprecates NewReader as the project decouples the compiler's "u" format from the "i" format used by x/tools [6]. gopls now handles new(expr) completions for Go 1.26 and later [7], and the modernize analyzer elides redundant clones in appendclipped [8]. gopls protocol tracing fixes an error-handling bug found by telemetry and a memory leak [9]. The website sorts prerelease versions numerically, so rc10 now sorts ahead of rc9 [10], and the minimum macOS version for Go 1.27 updates per go.dev/doc/go1.27#darwin [11].
Action items
- → Upgrade to a Go toolchain containing these fixes to avoid the unreachable method panic and the TLS memory retention. golang/go [plan]
- → If you rely on encoding/json MarshalText for named string map keys, verify your behavior against pre-1.26. golang/go [monitor]
- → Update gopls to get new(expr) completion support and the protocol trace fix. golang/tools [monitor]
References
- [1] crypto/tls: don't pin record-sized buffers while blocked in Read ↗ golang/go
- [2] cmd/compile: correctly mark interface calls as used for tail call wrappers ↗ golang/go
- [3] encoding/json: avoid calling MarshalText on named string map keys ↗ golang/go
- [4] unicode/utf16: avoid overallocating in Encode ↗ golang/go
- [5] math: improve Log2 accuracy near 1 ↗ golang/go
- [6] go/gcexportdata: update package docs + minor tweaks ↗ golang/tools
- [7] gopls/internal/golang/completion: handle new(expr) ↗ golang/tools
- [8] go/analysis/passes/modernize: elide redundant clone in appendclipped ↗ golang/tools
- [9] gopls/internal/protocol: trace error messages ↗ golang/tools
- [10] internal/dl: sort multi-digit prerelease versions numerically ↗ golang/website
- [11] internal/dl: update minimum macOS version for Go 1.27 ↗ golang/website