Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: do more static initialization at compile time rather than runtime #7599

Open
josharian opened this issue Mar 20, 2014 · 4 comments
Milestone

Comments

@josharian
Copy link
Contributor

Staticly initialized global variables are given bss symbols that are populated using
autogenerated init code. However, in most cases (maps are the only exception I can think
of), these variables could be given pre-populated symbols instead, using linker-resolved
data.

This would save space -- populated data symbols are smaller than the code generated to
populate them. This would also save run time -- no need to populate the bss symbols on
each program startup.

At the least, there should be a few special cases added for common, simple cases like
creating a slice.

Example using tip:


$ cat sinit.go

package main

var (
    a = [...]uint16{0, 1, 2, 3}
    s = a[:]
)

func main() {
    _ = s
}


$ go tool 6g -S sinit.go

"".main t=1 size=16 value=0 args=0 locals=0
    000000 00000 (i.go:8)   TEXT    "".main+0(SB),4,$0-0
    000000 00000 (i.go:8)   NOP ,
    000000 00000 (i.go:8)   NOP ,
    000000 00000 (i.go:8)   FUNCDATA    $2,"".gcargs·0+0(SB)
    000000 00000 (i.go:8)   FUNCDATA    $3,"".gclocals·1+0(SB)
    000000 00000 (i.go:10)  RET ,
    000000 c3                                               .
"".init t=1 size=144 value=0 args=0 locals=0x10
    000000 00000 (i.go:10)  TEXT    "".init+0(SB),$16-0
    000000 00000 (i.go:10)  MOVQ    2208(GS),CX
    0x0009 00009 (i.go:10)  CMPQ    SP,(CX)
    0x000c 00012 (i.go:10)  JHI ,21
    0x000e 00014 (i.go:10)  CALL    ,runtime.morestack00_noctxt(SB)
    0x0013 00019 (i.go:10)  JMP ,0
    0x0015 00021 (i.go:10)  SUBQ    $16,SP
    0x0019 00025 (i.go:10)  MOVQ    $0,8(SP)
    0x0022 00034 (i.go:10)  MOVBQZX "".initdone·+0(SB),AX
    0x002b 00043 (i.go:10)  FUNCDATA    $2,"".gcargs·2+0(SB)
    0x002b 00043 (i.go:10)  FUNCDATA    $3,"".gclocals·3+0(SB)
    0x002b 00043 (i.go:10)  CMPB    AL,$0
    0x002d 00045 (i.go:10)  JEQ ,63
    0x002f 00047 (i.go:10)  CMPB    AL,$2
    0x0031 00049 (i.go:10)  JNE ,56
    0x0033 00051 (i.go:10)  ADDQ    $16,SP
    0x0037 00055 (i.go:10)  RET ,
    0x0038 00056 (i.go:10)  PCDATA  $0,$0
    0x0038 00056 (i.go:10)  PCDATA  $1,$1
    0x0038 00056 (i.go:10)  CALL    ,runtime.throwinit(SB)
    0x003d 00061 (i.go:10)  UNDEF   ,
    0x003f 00063 (i.go:10)  MOVB    $1,"".initdone·+0(SB)
    0x0047 00071 (i.go:5)   LEAQ    "".a+0(SB),BX
    0x004f 00079 (i.go:5)   MOVQ    BX,"".autotmp_0000+8(SP)
    0x0054 00084 (i.go:5)   MOVQ    "".autotmp_0000+8(SP),BX
    0x0059 00089 (i.go:5)   CMPQ    BX,$0
    0x005d 00093 (i.go:5)   JEQ $1,140
    0x005f 00095 (i.go:5)   MOVQ    BX,"".s+0(SB)
    0x0067 00103 (i.go:5)   MOVQ    $4,"".s+8(SB)
    0x0073 00115 (i.go:5)   MOVQ    $4,"".s+16(SB)
    0x007f 00127 (i.go:10)  MOVB    $2,"".initdone·+0(SB)
    0x0087 00135 (i.go:10)  ADDQ    $16,SP
    0x008b 00139 (i.go:10)  RET ,
    0x008c 00140 (i.go:5)   MOVL    AX,(BX)
    0x008e 00142 (i.go:5)   JMP ,95
    000000 65 48 8b 0c 25 a0 08 00 00 48 3b 21 77 07 e8 00  eH..%....H;!w...
    0x0010 00 00 00 eb eb 48 83 ec 10 48 c7 44 24 08 00 00  .....H...H.D$...
    0x0020 00 00 48 0f b6 04 25 00 00 00 00 3c 00 74 10 3c  ..H...%....<.t.<
    0x0030 02 75 05 48 83 c4 10 c3 e8 00 00 00 00 0f 0b c6  .u.H............
    0x0040 04 25 00 00 00 00 01 48 8d 1c 25 00 00 00 00 48  .%.....H..%....H
    0x0050 89 5c 24 08 48 8b 5c 24 08 48 83 fb 00 74 2d 48  .\$.H.\$.H...t-H
    0x0060 89 1c 25 00 00 00 00 48 c7 04 25 00 00 00 00 04  ..%....H..%.....
    0x0070 00 00 00 48 c7 04 25 00 00 00 00 04 00 00 00 c6  ...H..%.........
    0x0080 04 25 00 00 00 00 02 48 83 c4 10 c3 89 03 eb cf  .%.....H........
    rel 15+4 t=247 runtime.morestack00_noctxt+0
    rel 39+4 t=120 "".initdone·+0
    rel 57+4 t=247 runtime.throwinit+0
    rel 66+4 t=120 "".initdone·+0
    rel 75+4 t=120 "".a+0
    rel 99+4 t=120 "".s+0
    rel 107+4 t=120 "".s+8
    rel 119+4 t=120 "".s+16
    rel 130+4 t=120 "".initdone·+0
"".gclocals·1 t=7 size=8 value=0
    000000 01 00 00 00 00 00 00 00                          ........
"".gcargs·0 t=7 size=8 value=0
    000000 01 00 00 00 00 00 00 00                          ........
"".gclocals·3 t=7 size=20 value=0
    000000 02 00 00 00 02 00 00 00 00 00 00 00 02 00 00 00  ................
    0x0010 00 00 00 00                                      ....
"".gcargs·2 t=7 size=12 value=0
    000000 02 00 00 00 00 00 00 00 00 00 00 00              ............
"".a t=22 size=8 value=0
    000000 00 00 01 00 02 00 03 00                          ........
"".s t=21 size=24 value=0
"".initdone· t=22 size=1 value=0
"".main·f t=7 dupok size=8 value=0
    000000 00 00 00 00 00 00 00 00                          ........
    rel 0+8 t=120 "".main+0
"".init·f t=7 dupok size=8 value=0
    000000 00 00 00 00 00 00 00 00                          ........
    rel 0+8 t=120 "".init+0
runtime.throwinit·f t=7 dupok size=8 value=0
    000000 00 00 00 00 00 00 00 00                          ........
    rel 0+8 t=120 runtime.throwinit+0
type..gc.uint16 t=7 dupok size=16 value=0
    000000 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
type..gc.[]uint16 t=7 dupok size=40 value=0
    000000 18 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00  ................
    0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0020 00 00 00 00 00 00 00 00                          ........
    rel 24+8 t=120 type..gc.uint16+0
go.string."[]uint16" t=7 dupok size=32 value=0
    000000 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    0x0010 5b 5d 75 69 6e 74 31 36 00                       []uint16.
    rel 0+8 t=120 go.string."[]uint16"+16
type.[]uint16 t=7 dupok size=72 value=0
    000000 18 00 00 00 00 00 00 00 e7 8e e3 20 00 08 08 17  ........... ....
    0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0040 00 00 00 00 00 00 00 00                          ........
    rel 16+8 t=120 runtime.algarray+544
    rel 24+8 t=120 type..gc.[]uint16+0
    rel 32+8 t=120 go.string."[]uint16"+0
    rel 48+8 t=120 go.weak.type.*[]uint16+0
    rel 56+8 t=120 runtime.zerovalue+0
    rel 64+8 t=120 type.uint16+0
go.typelink.[]uint16/[]uint16 t=7 dupok size=8 value=0
    000000 00 00 00 00 00 00 00 00                          ........
    rel 0+8 t=120 type.[]uint16+0
type..gc.[4]uint16 t=7 dupok size=16 value=0
    000000 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
go.string."[4]uint16" t=7 dupok size=32 value=0
    000000 00 00 00 00 00 00 00 00 09 00 00 00 00 00 00 00  ................
    0x0010 5b 34 5d 75 69 6e 74 31 36 00                    [4]uint16.
    rel 0+8 t=120 go.string."[4]uint16"+16
type.[4]uint16 t=7 dupok size=88 value=0
    000000 08 00 00 00 00 00 00 00 3f 77 35 8e 00 02 02 91  ........?w5.....
    0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0050 04 00 00 00 00 00 00 00                          ........
    rel 16+8 t=120 runtime.algarray+160
    rel 24+8 t=120 type..gc.[4]uint16+0
    rel 32+8 t=120 go.string."[4]uint16"+0
    rel 48+8 t=120 go.weak.type.*[4]uint16+0
    rel 56+8 t=120 runtime.zerovalue+0
    rel 64+8 t=120 type.uint16+0
    rel 72+8 t=120 type.[]uint16+0
go.typelink.[4]uint16/[4]uint16 t=7 dupok size=8 value=0
    000000 00 00 00 00 00 00 00 00                          ........
    rel 0+8 t=120 type.[4]uint16+0
type..gc.*[4]uint16 t=7 dupok size=32 value=0
    000000 08 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00  ................
    0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
go.string."*[4]uint16" t=7 dupok size=32 value=0
    000000 00 00 00 00 00 00 00 00 0a 00 00 00 00 00 00 00  ................
    0x0010 2a 5b 34 5d 75 69 6e 74 31 36 00                 *[4]uint16.
    rel 0+8 t=120 go.string."*[4]uint16"+16
type.*[4]uint16 t=7 dupok size=72 value=0
    000000 08 00 00 00 00 00 00 00 42 a7 e4 3c 00 08 08 16  ........B..<....
    0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    0x0040 00 00 00 00 00 00 00 00                          ........
    rel 16+8 t=120 runtime.algarray+160
    rel 24+8 t=120 type..gc.*[4]uint16+0
    rel 32+8 t=120 go.string."*[4]uint16"+0
    rel 48+8 t=120 go.weak.type.**[4]uint16+0
    rel 56+8 t=120 runtime.zerovalue+0
    rel 64+8 t=120 type.[4]uint16+0
go.string."runtime" t=7 dupok size=24 value=0
    000000 00 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00  ................
    0x0010 72 75 6e 74 69 6d 65 00                          runtime.
    rel 0+8 t=120 go.string."runtime"+16
go.importpath.runtime. t=7 dupok size=16 value=0
    000000 00 00 00 00 00 00 00 00 07 00 00 00 00 00 00 00  ................
    rel 0+8 t=120 go.string."runtime"+16
runtime.zerovalue t=7 dupok size=0 value=0


In this case, the 144 byte "".init is used to populate the 24 byte s to read
<&a, 4, 4>.
@ianlancetaylor
Copy link
Contributor

Comment 1:

Labels changed: added repo-main, release-go1.4.

@josharian
Copy link
Contributor Author

Comment 3:

Labels changed: added release-go1.5, removed release-go1.4.

@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014
@mdempsky
Copy link
Member

mdempsky commented Mar 5, 2015

Commit 632217a fixed the specific case of statically initializing function values, at least when referring to global functions (which turns out to be fairly common). It should be possible to also statically initialize function literals like in:

package foo
var f = func() {}

but as of tip this still uses dynamic initialization.

@rsc rsc removed the repo-main label Apr 14, 2015
@josharian
Copy link
Contributor Author

I started on this but given the extent of the changes, I'd prefer to rewrite sinit.go to be idiomatic first, to make it easier to work with. That puts this out of scope for 1.5. Moving to 1.6; holler if you disagree.

@josharian josharian modified the milestones: Go1.6, Go1.5 May 21, 2015
@rsc rsc changed the title cmd/gc: do more static initialization at compile time rather than runtime cmd/compile: do more static initialization at compile time rather than runtime Jun 8, 2015
@josharian josharian modified the milestones: Go1.6, Go1.6Early Jun 29, 2015
@rsc rsc modified the milestones: Unplanned, Go1.6Early Nov 4, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants