-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Closed
Labels
Description
What version of Go are you using (go version
)?
$ go version go version go1.14 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/tdakkota/.cache/go-build" GOENV="/home/tdakkota/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/tdakkota/go" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/local/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build263265353=/tmp/go-build -gno-record-gcc-switches"
What did you do?
https://play.golang.org/p/kSKRNgYnQCS
package main
import (
"fmt"
)
func allocme(n int) string {
arr := make([]byte, n) // first allocation
for i := 0; i < n; i++ {
arr[i] = byte(i + 97)
}
return string(arr) // second allocation + copy
}
func main() {
fmt.Println(allocme(25))
}
Then run with gc's flag -S
$ go build -gcflags "-S" main.go
Output
"".allocme STEXT size=161 args=0x18 locals=0x38 0x0000 00000 (/home/tdakkota/workspace/expirm/main.go:7) TEXT "".allocme(SB), ABIInternal, $56-24 0x0000 00000 (/home/tdakkota/workspace/expirm/main.go:7) MOVQ (TLS), CX 0x0009 00009 (/home/tdakkota/workspace/expirm/main.go:7) CMPQ SP, 16(CX) 0x000d 00013 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $0, $-2 0x000d 00013 (/home/tdakkota/workspace/expirm/main.go:7) JLS 151 0x0013 00019 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $0, $-1 0x0013 00019 (/home/tdakkota/workspace/expirm/main.go:7) SUBQ $56, SP 0x0017 00023 (/home/tdakkota/workspace/expirm/main.go:7) MOVQ BP, 48(SP) 0x001c 00028 (/home/tdakkota/workspace/expirm/main.go:7) LEAQ 48(SP), BP 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $0, $-2 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $1, $-2 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7) FUNCDATA $0, gclocals·568470801006e5c0dc3947ea998fe279(SB) 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB) 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:7) FUNCDATA $2, gclocals·1cf923758aae2e428391d1783fe59973(SB) 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:8) PCDATA $0, $1 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:8) PCDATA $1, $0 0x0021 00033 (/home/tdakkota/workspace/expirm/main.go:8) LEAQ type.uint8(SB), AX 0x0028 00040 (/home/tdakkota/workspace/expirm/main.go:8) PCDATA $0, $0 0x0028 00040 (/home/tdakkota/workspace/expirm/main.go:8) MOVQ AX, (SP) 0x002c 00044 (/home/tdakkota/workspace/expirm/main.go:8) MOVQ "".n+64(SP), AX 0x0031 00049 (/home/tdakkota/workspace/expirm/main.go:8) MOVQ AX, 8(SP) 0x0036 00054 (/home/tdakkota/workspace/expirm/main.go:8) MOVQ AX, 16(SP) 0x003b 00059 (/home/tdakkota/workspace/expirm/main.go:8) CALL runtime.makeslice(SB) 0x0040 00064 (/home/tdakkota/workspace/expirm/main.go:8) PCDATA $0, $1 0x0040 00064 (/home/tdakkota/workspace/expirm/main.go:8) MOVQ 24(SP), AX 0x0045 00069 (/home/tdakkota/workspace/expirm/main.go:10) MOVQ "".n+64(SP), CX 0x004a 00074 (/home/tdakkota/workspace/expirm/main.go:10) XORL DX, DX 0x004c 00076 (/home/tdakkota/workspace/expirm/main.go:10) JMP 88 0x004e 00078 (/home/tdakkota/workspace/expirm/main.go:11) LEAQ 97(DX), BX 0x0052 00082 (/home/tdakkota/workspace/expirm/main.go:11) MOVB BL, (AX)(DX*1) 0x0055 00085 (/home/tdakkota/workspace/expirm/main.go:10) INCQ DX 0x0058 00088 (/home/tdakkota/workspace/expirm/main.go:10) CMPQ DX, CX 0x005b 00091 (/home/tdakkota/workspace/expirm/main.go:10) JLT 78 0x005d 00093 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ $0, (SP) 0x0065 00101 (/home/tdakkota/workspace/expirm/main.go:14) PCDATA $0, $0 0x0065 00101 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ AX, 8(SP) 0x006a 00106 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ CX, 16(SP) 0x006f 00111 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ CX, 24(SP) 0x0074 00116 (/home/tdakkota/workspace/expirm/main.go:14) CALL runtime.slicebytetostring(SB) 0x0079 00121 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ 40(SP), AX 0x007e 00126 (/home/tdakkota/workspace/expirm/main.go:14) PCDATA $0, $2 0x007e 00126 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ 32(SP), CX 0x0083 00131 (/home/tdakkota/workspace/expirm/main.go:14) PCDATA $0, $0 0x0083 00131 (/home/tdakkota/workspace/expirm/main.go:14) PCDATA $1, $1 0x0083 00131 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ CX, "".~r1+72(SP) 0x0088 00136 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ AX, "".~r1+80(SP) 0x008d 00141 (/home/tdakkota/workspace/expirm/main.go:14) MOVQ 48(SP), BP 0x0092 00146 (/home/tdakkota/workspace/expirm/main.go:14) ADDQ $56, SP 0x0096 00150 (/home/tdakkota/workspace/expirm/main.go:14) RET 0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:14) NOP 0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $1, $-1 0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $0, $-2 0x0097 00151 (/home/tdakkota/workspace/expirm/main.go:7) CALL runtime.morestack_noctxt(SB) 0x009c 00156 (/home/tdakkota/workspace/expirm/main.go:7) PCDATA $0, $-1 0x009c 00156 (/home/tdakkota/workspace/expirm/main.go:7) JMP 0
What did you expect to see?
One allocation at all.
arr
does not escape, so we can use runtime.slicebytetostringtmp
instead of runtime.slicebytetostring
What did you see instead?
Two allocation and copying,