Introduction to Go 1.5

The latest Go release, version 1.5, is a significant release, including major architectural changes to the implementation. Despite that, we expect almost all Go programs to continue to compile and run as before, because the release still maintains the Go 1 promise of compatibility.

The biggest developments in the implementation are:

These and a number of other changes to the implementation and tools are discussed below.

The release also contains one small language change involving map literals.

Finally, the timing of the release strays from the usual six-month interval, both to provide more time to prepare this major release and to shift the schedule thereafter to time the release dates more conveniently.

Changes to the language

Map literals

Due to an oversight, the rule that allowed the element type to be elided from slice literals was not applied to map keys. This has been corrected in Go 1.5. An example will make this clear: as of Go 1.5, this map literal,

m := map[Point]string{
    Point{29.935523, 52.891566}:   "Persepolis",
    Point{-25.352594, 131.034361}: "Uluru",
    Point{37.422455, -122.084306}: "Googleplex",
}

may be written as follows, without the Point type listed explicitly:

m := map[Point]string{
    {29.935523, 52.891566}:   "Persepolis",
    {-25.352594, 131.034361}: "Uluru",
    {37.422455, -122.084306}: "Googleplex",
}

The Implementation

No more C

The compiler and runtime are now implemented in Go and assembler, without C. The only C source left in the tree is related to testing or to cgo. There was a C compiler in the tree in 1.4 and earlier. It was used to build the runtime; a custom compiler was necessary in part to guarantee the C code would work with the stack management of goroutines. Since the runtime is in Go now, there is no need for this C compiler and it is gone. Details of the process to eliminate C are discussed elsewhere.

The conversion from C was done with the help of custom tools created for the job. Most important, the compiler was actually moved by automatic translation of the C code into Go. It is in effect the same program in a different language. It is not a new implementation of the compiler so we expect the process will not have introduced new compiler bugs. An overview of this process is available in the slides for this presentation.

Compiler and tools

Independent of but encouraged by the move to Go, the names of the tools have changed. The old names 6g, 8g and so on are gone; instead there is just one binary, accessible as go tool compile, that compiles Go source into binaries suitable for the architecture and operating system specified by $GOARCH and $GOOS. Similarly, there is now one linker (go tool link) and one assembler (go tool asm). The linker was translated automatically from the old C implementation, but the assembler is a new native Go implementation discussed in more detail below.

Similar to the drop of the names 6g, 8g, and so on, the output of the compiler and assembler are now given a plain .o suffix rather than .8, .6, etc.

Garbage collector

TODO

Runtime

In Go 1.5, the order in which goroutines are scheduled has been changed. The properties of the scheduler were never defined by the language, but programs that depended on the scheduling order may be broken by this change. We have seen a few (erroneous) programs affected by this change. If you have programs that implicitly depend on the scheduling order, you will need to update them.

Another potentially breaking change is that the runtime now sets the default number of threads to run simultaneously, defined by GOMAXPROCS, to the number of cores available on the CPU. In prior releases it defaulted to 1. Programs that do not expect to run with multiple cores may break inadvertently. They can be updated by removing the restriction or by setting GOMAXPROCS explicitly.

Build

Now that the Go compiler and runtime are implemented in Go, a Go compiler must be available to compile the distribution from source. Thus, to build the Go core, a working Go distribution must already be in place. (Go programmers who do not work on the core are unaffected by this change.) Any Go 1.4 or later distribution (including gccgo) will serve. For details, see the design document.

Ports

Due mostly to the industry's move away the 32-bit x86 architecture, the set of binary downloads provided is reduced in 1.5. A distribution for the OS X operating system is provided only for the amd64 architecture, not 386. Similarly, the ports for Snow Leopard (Apple OS X 10.6) still work but are no longer released as a download or maintained since Apple no longer maintains that version of the operating system. Also, the dragonfly/386 port is no longer supported at all because DragonflyBSD itself no longer supports the 32-bit 386 architecture.

There are however several new ports available to be built from source. These include darwin/arm and darwin/arm64. The new port linux/arm64 is mostly in place, but cgo is only supported using external linking.

On FreeBSD, Go 1.5 requires FreeBSD 8-STABLE+ because of its new use of the SYSCALL instruction.

On NaCl, Go 1.5 requires SDK version pepper-39 or above because it now uses the get_random_bytes system call.

Tools:

build: external linking support for windows (https://golang.org/cl/7163, 7282, 7283, 7284, 7534, 7535)
cmd/cover: tool now lives in the standard repository (https://golang.org/cl/9560)
cmd/gc: constant arithmetic is based on math/big (https://golang.org/cl/7830, 7851, 7857, 8426, 7858, 7912, 8171)
cmd/go, go/build: add ${SRCDIR} variable expansion to cgo lines (https://golang.org/cl/1756)
cmd/go: add $DOLLAR to generate's variables (https://golang.org/cl/8091)
cmd/go: std wildcard now excludes commands in main repo (https://golang.org/cl/5550)
cmd/go: .swig/.swigcxx files now require SWIG 3.0.6 or later
cmd/go: add -run flag to go generate (https://golang.org/cl/9005)
cmd/go: add $GOLINE to generate's variables (https://golang.org/cl/9007)
cmd/go: add go doc (https://golang.org/cl/9227)
cmd/go: internal enforced even outside standard library (golang.org/s/go14internal; https://golang.org/cl/9156)
cmd/go, testing: add go test -count (https://golang.org/cl/10669)
cmd/go: add preliminary support for vendor directories (https://golang.org/cl/10923)
cmd/vet: better validation of struct tags (https://golang.org/cl/2685)
cmd/ld: no longer record build timestamp in Windows PE file header (https://golang.org/cl/3740)
cmd/go: add -toolexec build option
cmd/go: drop -ccflags build option
cmd/go: add -asmflags build option
cmd/go: add -buildmode build option
cmd/gc: add -dynlink option (for amd64 only)
cmd/ld: add -buildmode option
cmd/trace: new command to view traces (https://golang.org/cl/3601)

Performance:

cmd/gc: evaluate concrete == interface without allocating (https://golang.org/cl/2096)
cmd/gc: optimize memclr of slices and arrays (https://golang.org/cl/2520)
cmd/gc: transform closure calls to function calls (https://golang.org/cl/4050)
cmd/gc: transitive inlining (https://golang.org/cl/5952)
cmd/gc, runtime: speed up some cases of _, ok := i.(T) (https://golang.org/cl/7697)
cmd/gc: speed up large string switches (https://golang.org/cl/7698)
cmd/gc: inline x := y.(*T) and x, ok := y.(*T) (https://golang.org/cl/7862)
cmd/gc: allocate backing storage for non-escaping interfaces on stack (https://golang.org/cl/8201)
encoding/xml: avoid an allocation for tags without attributes (https://golang.org/cl/4160)
image: many optimizations
runtime: add ARM runtime.cmpstring and bytes.Compare (https://golang.org/cl/8010)
runtime: do not scan maps when k/v do not contain pointers (https://golang.org/cl/3288)
runtime: reduce thrashing of gs between ps (https://golang.org/cl/9872)
sort: number of Sort performance optimizations (https://golang.org/cl/2100, https://golang.org/cl/2614, ...)
strconv: optimize decimal to string conversion (https://golang.org/cl/2105)
strconv: optimize float to string conversion (https://golang.org/cl/5600)
sync: add active spinning to Mutex (https://golang.org/cl/5430)
math/big: faster assembly kernels for amd64 and 386 (https://golang.org/cl/2503, https://golang.org/cl/2560)
math/big: faster "pure Go" kernels for platforms w/o assembly kernels (https://golang.org/cl/2480)
regexp: port RE2's bitstate backtracker to the regexp package (https://golang.org/cl/2153)

Assembler:

New cmd/asm tool (now use go tool asm, not go tool 6a)

Assembler now supports -dynlink option.

ARM assembly syntax has had some features removed.

	- mentioning SP or PC as a hardware register
		These are always pseudo-registers except that in some contexts
		they're not, and it's confusing because the context should not affect
		which register you mean. Change the references to the hardware
		registers to be explicit: R13 for SP, R15 for PC.
	- constant creation using assignment
		The files say a=b when they could instead say #define a b.
		There is no reason to have both mechanisms.
	- R(0) to refer to R0.
		Some macros use this to a great extent. Again, it's easy just to
		use a #define to rename a register.

Also expression evaluation now uses uint64s instead of signed integers and the
precedence of operators is now Go-like rather than C-like.

Core library

Flag

The flag package's PrintDefaults function, and method on FlagSet, have been modified to create nicer usage messages. The format has been changed to be more human-friendly and in the usage messages a word quoted with `backquotes` is taken to be the name of the flag's operand to display in the usage message. For instance, a flag created with the invocation,

cpuFlag = flag.Int("cpu", 1, "run `N` processes in parallel")

will show the help message,

-cpu N
    	run N processes in parallel (default 1)

Also, the default is now listed only when it is not the zero value for the type.

Floats in math/big

The math/big package has a new, fundamental data type, Float, which implements arbitrary-precision floating-point numbers. A Float value is represented by a boolean sign, a variable-length mantissa, and a 32-bit fixed-size signed exponent. The precision of a Float (the mantissa size in bits) can be specified explicitly or is otherwise determined by the first operation that creates the value. Once created, the size of a Float's mantissa may be modified with the SetPrec method. Floats support the concept of infinities, such as are created by overflow, but values that would lead to the equivalent of IEEE 754 NaNs trigger a panic. Float operations support all IEEE-754 rounding modes. When the precision is set to 24 (53) bits, operations that stay within the range of normalized float32 (float64) values produce the same results as the corresponding IEEE-754 arithmetic on those values.

Reflect

The reflect package has two new functions: ArrayOf and FuncOf. These functions, analogous to the extant SliceOffunction, create new types at runtime to describe arrays and functions.

Hardening

Several dozen bugs were found in the standard library through randomized testing with the go-fuzz tool. Bugs were fixed in the archive/tar, archive/zip, compress/flate, encoding/gob, fmt, html/template, image/gif, image/jpeg, image/png, and text/template, packages. The fixes harden the implementation against incorrect and malicious inputs.

Minor changes to the library