go 1.20 upgrading note

February 13, 2023
go golang compiler

Prologue

go 1.20 was released on Feb, 2, 2023, which includes some language changes, improvements to tooling and the library, and better overall performance.

However, there’s a thing to notice once you start upgrading you projects to go1.20 toolchain.

The problem

Starting in go1.20, global error created by calling errors.New will be laid out in static data:

$ cat p.go
package p

import "errors"

var FooErr = errors.New("foo")

$ go1.19.5 build -gcflags=-S p.go 2>&1 | grep -q stmp && echo laid out in static data
$ go1.20 build -gcflags=-S p.go 2>&1 | grep -q stmp && echo laid out in static data
laid out in static data

This will reduce the init time, have no link-time overhead, and open room for the linker to perform deadcode elimination.

However, after the release, there’re some regressions reported:

All of them releated to how the compiler handle the inline call at init time.

Though there’re some attempts to fix, and backported to 1.20.1 minor release, there’s still edge case discovered while working on fixing the code.

The conclusion is disabling the optimization for backporting to 1.20 release, then re-enable again during 1.21 development cycle, so we have more time to re-implement or fixing the code properly.

Solution

If you’re going to upgrade your go toolchain to 1.20, remember to add -gcflags=all=-d=inlstaticinit=0 to your CI process.

For 1.20.1 release, just upgrading as usual.

Epilogue

Admittedly, this issue is a bit embarrassing, it will be fixed in go1.20.1, and can be workaround without requiring user to make changes in the code. Please patient while the reported regressions are addressed.

And thank you all for reading so far!

Till next time!


GopherCon 2023

October 2, 2023
gophercon community go golang

Improving parallel calls from C to Go performance

June 29, 2023
go golang cgo runtime

A practical optimization for Go compiler

May 25, 2023
go golang compiler