You have to take a look at the assembly code that gets generated. When you have the additional
field in the struct, then Go actually treats the struct as a struct and keeps it in memory. When you get rid of the additional
field, then your Integer
struct folds down into a single integer. After the stack size check and FUNCDATA
and PCDATA
directives in the assembly, you see the first “real” instruction is to just move the literal, 2
, into the AX
register (I’m on x86_64): The setInteger
function was inlined.
What’s really interesting to me, and maybe I’m missing something, is that I don’t see setInteger
being called or inlined in the version with the additional
field. Anyone else see it?
"".getNumber STEXT size=116 args=0x20 locals=0x38
0x0000 00000 (main.go:27) TEXT "".getNumber(SB), ABIInternal, $56-32
0x0000 00000 (main.go:27) MOVQ TLS, CX
0x0009 00009 (main.go:27) MOVQ (CX)(TLS*2), CX
0x0010 00016 (main.go:27) CMPQ SP, 16(CX)
0x0014 00020 (main.go:27) JLS 109
0x0016 00022 (main.go:27) SUBQ $56, SP
0x001a 00026 (main.go:27) MOVQ BP, 48(SP)
0x001f 00031 (main.go:27) LEAQ 48(SP), BP
0x0024 00036 (main.go:27) FUNCDATA $0, gclocals┬╖7235335ad9f69aa19497c8c3511e8b84(SB)
0x0024 00036 (main.go:27) FUNCDATA $1, gclocals┬╖7d2d5fca80364273fb07d5820a76fef4(SB)
0x0024 00036 (main.go:27) FUNCDATA $3, gclocals┬╖9fb7f0986f647f17cb53dda1484e0f7a(SB)
0x0024 00036 (main.go:29) PCDATA $2, $0
0x0024 00036 (main.go:29) PCDATA $0, $0
0x0024 00036 (main.go:29) XORPS X0, X0
0x0027 00039 (main.go:29) MOVUPS X0, ""..autotmp_5+32(SP)
0x002c 00044 (main.go:29) XCHGL AX, AX
0x002d 00045 (main.go:29) PCDATA $2, $1
0x002d 00045 (main.go:29) LEAQ go.itab."".Integer,"".Number(SB), AX
0x0034 00052 (main.go:29) PCDATA $2, $0
0x0034 00052 (main.go:29) MOVQ AX, (SP)
0x0038 00056 (main.go:29) PCDATA $2, $1
0x0038 00056 (main.go:29) LEAQ ""..autotmp_5+32(SP), AX
0x003d 00061 (main.go:29) PCDATA $2, $0
0x003d 00061 (main.go:29) MOVQ AX, 8(SP)
0x0042 00066 (main.go:29) CALL runtime.convT2Inoptr(SB)
0x0047 00071 (main.go:29) PCDATA $2, $1
0x0047 00071 (main.go:29) MOVQ 24(SP), AX
0x004c 00076 (main.go:29) MOVQ 16(SP), CX
0x0051 00081 (main.go:29) PCDATA $0, $1
0x0051 00081 (main.go:29) MOVQ CX, "".~r0+64(SP)
0x0056 00086 (main.go:29) PCDATA $2, $0
0x0056 00086 (main.go:29) MOVQ AX, "".~r0+72(SP)
0x005b 00091 (main.go:29) PCDATA $0, $2
0x005b 00091 (main.go:29) XORPS X0, X0
0x005e 00094 (main.go:29) MOVUPS X0, "".~r1+80(SP)
0x0063 00099 (main.go:29) MOVQ 48(SP), BP
0x0068 00104 (main.go:29) ADDQ $56, SP
0x006c 00108 (main.go:29) RET
0x006d 00109 (main.go:29) NOP
0x006d 00109 (main.go:27) PCDATA $0, $-1
0x006d 00109 (main.go:27) PCDATA $2, $-1
0x006d 00109 (main.go:27) CALL runtime.morestack_noctxt(SB)
0x0072 00114 (main.go:27) JMP 0
0x0000 65 48 8b 0c 25 28 00 00 00 48 8b 89 00 00 00 00 eH..%(...H......
0x0010 48 3b 61 10 76 57 48 83 ec 38 48 89 6c 24 30 48 H;a.vWH..8H.l$0H
0x0020 8d 6c 24 30 0f 57 c0 0f 11 44 24 20 90 48 8d 05 .l$0.W...D$ .H..
0x0030 00 00 00 00 48 89 04 24 48 8d 44 24 20 48 89 44 ....H..$H.D$ H.D
0x0040 24 08 e8 00 00 00 00 48 8b 44 24 18 48 8b 4c 24 $......H.D$.H.L$
0x0050 10 48 89 4c 24 40 48 89 44 24 48 0f 57 c0 0f 11 .H.L$@H.D$H.W...
0x0060 44 24 50 48 8b 6c 24 30 48 83 c4 38 c3 e8 00 00 D$PH.l$0H..8....
0x0070 00 00 eb 8c ....
rel 12+4 t=16 TLS+0
rel 48+4 t=15 go.itab."".Integer,"".Number+0
rel 67+4 t=8 runtime.convT2Inoptr+0
rel 110+4 t=8 runtime.morestack_noctxt+0