Golang interface values and memory
This repository explores when storing a value in a Go interface allocates memory on the heap.
- Labs: a step-by-step walkthrough of the topic
- FAQ: answers to frequently asked questions
- Links: links to related reference material
Labs
- Prerequisites: how to get from here to there
- Interface values: whatever you do, do not call it "boxing"
- Escape analysis: to malloc or not to malloc
- Missing mallocs: there's a heap of missing memory
FAQ
- What is the x86 assembly instruction
CALL
actually calling? - Where is the
CALL
instruction in ARM assembly? - What is the
hack
directory and the files inside of it?
CALL
actually calling?
What is the x86 assembly instruction The x86 assembly instruction CALL
is used to call a procedure. For example, consider the following line of assembly from this project:
0x003c 00060 (mem_test.go:312) CALL runtime.convT32(SB)
The CALL
instruction specifies runtime.convT32(SB)
. The (SB)
(static base) suffix lets us know that runtime.convT32
is a global symbol and references the memory address for the procedure to call. In order to examine what that symbol is, we can:
-
Build the test binary for this project:
go test -c ./benchmarks
-
Use
go tool objdump
to search for the symbol:$ go tool objdump -s runtime.convT32 benchmarks.test TEXT runtime.convT32(SB) /Users/akutz/.go/1.18beta2/src/runtime/iface.go iface.go:365 0x100008b20 f9400b90 MOVD 16(R28), R16 ...
Procedures in assembly are easy to spot as they are defined with the
TEXT
directive illustrated up above. -
Or build the
runtime
package without linking it into this project's test binary. This assembly provides even more insight into the translation from Go to machine code:$ go build -gcflags "-S" runtime 2>&1 | grep -FA1 '"".convT32 STEXT' "".convT32 STEXT size=144 args=0x8 locals=0x28 funcid=0x0 align=0x0 0x0000 00000 (/Users/akutz/.go/1.18beta2/src/runtime/iface.go:365) TEXT "".convT32(SB), ABIInternal, $48-8 ...
To learn more about the CALL
instruction and procedures, please refer to:
CALL
instruction in ARM assembly?
Where is the The assembly for x86 and amd64 both define the CALL
instruction. However, ARM assembly does not define a CALL
instruction, despite it appearing in the assembly for Go sources in this project when they are compiled on an M1 Macbook. What gives?
What was likely an attempt to maintain naming convention consistency in Go assembly across different processor architectures, Go renames the ARM assembly instruction BLR
(branch with link to register) to CALL
. Both instructions call a procedure (x86) or subroutine (ARM) at a given address, so for all intents and purposes they have semantically similar.
To learn more about the CALL
instruction and Go on ARM, please refer to:
hack
directory and the files inside of it?
What is the The hack
directory is a convention I picked up from working on Kubernetes and projects related to Kuberentes. The directory contains scripts useful to the project, but not a core piece of the project itself. For example:
hack/
asm2md.py
: parses the output ofgo tool compile -S -wb=false *.go
and produces a markdown tableb2md.py
: parses the output ofgo test -bench BenchmarkMem -run Mem -benchmem -count 1 -benchtime 1000x -v
and produces a markdown tablegen.py
: generatesmem_test.go
,print_test.go
, andtypes_test.go