embano1 / go-interface-values

When storing a value in a Go interface allocates memory on the heap.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

  1. Prerequisites: how to get from here to there
  2. Interface values: whatever you do, do not call it "boxing"
  3. Escape analysis: to malloc or not to malloc
  4. Missing mallocs: there's a heap of missing memory

FAQ

What is the x86 assembly instruction CALL actually calling?

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:

  1. Build the test binary for this project:

    go test -c ./benchmarks
  2. 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.

  3. 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:

Where is the CALL instruction in ARM assembly?

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:

What is the hack directory and the files inside of it?

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:

Links

About

When storing a value in a Go interface allocates memory on the heap.

License:Apache License 2.0


Languages

Language:Go 62.7%Language:Python 30.5%Language:Makefile 5.5%Language:Dockerfile 1.4%