zoukankan      html  css  js  c++  java
  • [go]slice源码

    slice源码探究

    slice源码

    参考

    append: 当cap不够时, 会调用growslice扩容

    // go 1.9.5 src/runtime/slice.go:82
    func growslice(et *_type, old slice, cap int) slice {
        // ……
        newcap := old.cap
        doublecap := newcap + newcap
        if cap > doublecap {
            newcap = cap
        } else {
            if old.len < 1024 {
                newcap = doublecap
            } else {
                for newcap < cap {
                    newcap += newcap / 4
                }
            }
        }
        // ……
    
        capmem = roundupsize(uintptr(newcap) * ptrSize)
        newcap = int(capmem / ptrSize)
    }
    

    查看汇编

    //main.go
    
    package main
    
    import "fmt"
    
    func main() {
    	arr := make([]int, 0)
    	arr = append(arr, 1)
    	fmt.Println(arr)
    }
    
    
    $ go tool compile -S main.go
    os.(*File).close STEXT dupok nosplit size=26 args=0x18 locals=0x0
    	0x0000 00000 (<autogenerated>:1)	TEXT	os.(*File).close(SB), DUPOK|NOSPLIT|ABIInternal, $0-24
    	0x0000 00000 (<autogenerated>:1)	FUNCDATA	$0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
    	0x0000 00000 (<autogenerated>:1)	FUNCDATA	$1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
    	0x0000 00000 (<autogenerated>:1)	FUNCDATA	$2, gclocals·9fb7f0986f647f17cb53dda1484e0f7a(SB)
    	0x0000 00000 (<autogenerated>:1)	PCDATA	$0, $1
    	0x0000 00000 (<autogenerated>:1)	PCDATA	$1, $1
    	0x0000 00000 (<autogenerated>:1)	MOVQ	""..this+8(SP), AX
    	0x0005 00005 (<autogenerated>:1)	MOVQ	(AX), AX
    	0x0008 00008 (<autogenerated>:1)	PCDATA	$0, $0
    	0x0008 00008 (<autogenerated>:1)	PCDATA	$1, $0
    	0x0008 00008 (<autogenerated>:1)	MOVQ	AX, ""..this+8(SP)
    	0x000d 00013 (<autogenerated>:1)	XORPS	X0, X0
    	0x0010 00016 (<autogenerated>:1)	MOVUPS	X0, "".~r0+16(SP)
    	0x0015 00021 (<autogenerated>:1)	JMP	os.(*file).close(SB)
    	0x0000 48 8b 44 24 08 48 8b 00 48 89 44 24 08 0f 57 c0  H.D$.H..H.D$..W.
    	0x0010 0f 11 44 24 10 e9 00 00 00 00                    ..D$......
    	rel 22+4 t=8 os.(*file).close+0
    "".main STEXT size=251 args=0x0 locals=0x58
    	0x0000 00000 (main.go:5)	TEXT	"".main(SB), ABIInternal, $88-0
    	0x0000 00000 (main.go:5)	MOVQ	(TLS), CX
    	0x0009 00009 (main.go:5)	CMPQ	SP, 16(CX)
    	0x000d 00013 (main.go:5)	JLS	241
    	0x0013 00019 (main.go:5)	SUBQ	$88, SP
    	0x0017 00023 (main.go:5)	MOVQ	BP, 80(SP)
    	0x001c 00028 (main.go:5)	LEAQ	80(SP), BP
    	0x0021 00033 (main.go:5)	FUNCDATA	$0, gclocals·69c1753bd5f81501d95132d08af04464(SB)
    	0x0021 00033 (main.go:5)	FUNCDATA	$1, gclocals·568470801006e5c0dc3947ea998fe279(SB)
    	0x0021 00033 (main.go:5)	FUNCDATA	$2, gclocals·bfec7e55b3f043d1941c093912808913(SB)
    	0x0021 00033 (main.go:5)	FUNCDATA	$3, "".main.stkobj(SB)
    	0x0021 00033 (main.go:6)	PCDATA	$0, $1
    	0x0021 00033 (main.go:6)	PCDATA	$1, $0
    	0x0021 00033 (main.go:6)	LEAQ	type.int(SB), AX
    	0x0028 00040 (main.go:6)	PCDATA	$0, $0
    	0x0028 00040 (main.go:6)	MOVQ	AX, (SP)
    	0x002c 00044 (main.go:6)	XORPS	X0, X0
    	0x002f 00047 (main.go:6)	MOVUPS	X0, 8(SP)
    	0x0034 00052 (main.go:6)	CALL	runtime.makeslice(SB)
    	0x0039 00057 (main.go:6)	PCDATA	$0, $1
    	0x0039 00057 (main.go:6)	MOVQ	24(SP), AX
    	0x003e 00062 (main.go:7)	PCDATA	$0, $2
    	0x003e 00062 (main.go:7)	LEAQ	type.int(SB), CX
    	0x0045 00069 (main.go:7)	PCDATA	$0, $1
    	0x0045 00069 (main.go:7)	MOVQ	CX, (SP)
    	0x0049 00073 (main.go:7)	PCDATA	$0, $0
    	0x0049 00073 (main.go:7)	MOVQ	AX, 8(SP)
    	0x004e 00078 (main.go:7)	XORPS	X0, X0
    	0x0051 00081 (main.go:7)	MOVUPS	X0, 16(SP)
    	0x0056 00086 (main.go:7)	MOVQ	$1, 32(SP)
    	0x005f 00095 (main.go:7)	CALL	runtime.growslice(SB)
    	0x0064 00100 (main.go:7)	PCDATA	$0, $1
    	0x0064 00100 (main.go:7)	MOVQ	40(SP), AX
    	0x0069 00105 (main.go:7)	MOVQ	48(SP), CX
    	0x006e 00110 (main.go:7)	MOVQ	56(SP), DX
    	0x0073 00115 (main.go:7)	MOVQ	$1, (AX)
    	0x007a 00122 (main.go:8)	PCDATA	$0, $0
    	0x007a 00122 (main.go:8)	MOVQ	AX, (SP)
    	0x007e 00126 (main.go:7)	LEAQ	1(CX), AX
    	0x0082 00130 (main.go:8)	MOVQ	AX, 8(SP)
    	0x0087 00135 (main.go:8)	MOVQ	DX, 16(SP)
    	0x008c 00140 (main.go:8)	CALL	runtime.convTslice(SB)
    	0x0091 00145 (main.go:8)	PCDATA	$0, $1
    	0x0091 00145 (main.go:8)	MOVQ	24(SP), AX
    	0x0096 00150 (main.go:8)	PCDATA	$1, $1
    	0x0096 00150 (main.go:8)	XORPS	X0, X0
    	0x0099 00153 (main.go:8)	MOVUPS	X0, ""..autotmp_13+64(SP)
    	0x009e 00158 (main.go:8)	PCDATA	$0, $2
    	0x009e 00158 (main.go:8)	LEAQ	type.[]int(SB), CX
    	0x00a5 00165 (main.go:8)	PCDATA	$0, $1
    	0x00a5 00165 (main.go:8)	MOVQ	CX, ""..autotmp_13+64(SP)
    	0x00aa 00170 (main.go:8)	PCDATA	$0, $0
    	0x00aa 00170 (main.go:8)	MOVQ	AX, ""..autotmp_13+72(SP)
    	0x00af 00175 (<unknown line number>)	NOP
    	0x00af 00175 ($GOROOT/src/fmt/print.go:274)	PCDATA	$0, $1
    	0x00af 00175 ($GOROOT/src/fmt/print.go:274)	MOVQ	os.Stdout(SB), AX
    	0x00b6 00182 ($GOROOT/src/fmt/print.go:274)	PCDATA	$0, $2
    	0x00b6 00182 ($GOROOT/src/fmt/print.go:274)	LEAQ	go.itab.*os.File,io.Writer(SB), CX
    	0x00bd 00189 ($GOROOT/src/fmt/print.go:274)	PCDATA	$0, $1
    	0x00bd 00189 ($GOROOT/src/fmt/print.go:274)	MOVQ	CX, (SP)
    	0x00c1 00193 ($GOROOT/src/fmt/print.go:274)	PCDATA	$0, $0
    	0x00c1 00193 ($GOROOT/src/fmt/print.go:274)	MOVQ	AX, 8(SP)
    	0x00c6 00198 ($GOROOT/src/fmt/print.go:274)	PCDATA	$0, $1
    	0x00c6 00198 ($GOROOT/src/fmt/print.go:274)	PCDATA	$1, $0
    	0x00c6 00198 ($GOROOT/src/fmt/print.go:274)	LEAQ	""..autotmp_13+64(SP), AX
    	0x00cb 00203 ($GOROOT/src/fmt/print.go:274)	PCDATA	$0, $0
    	0x00cb 00203 ($GOROOT/src/fmt/print.go:274)	MOVQ	AX, 16(SP)
    	0x00d0 00208 ($GOROOT/src/fmt/print.go:274)	MOVQ	$1, 24(SP)
    	0x00d9 00217 ($GOROOT/src/fmt/print.go:274)	MOVQ	$1, 32(SP)
    	0x00e2 00226 ($GOROOT/src/fmt/print.go:274)	CALL	fmt.Fprintln(SB)
    	0x00e7 00231 (<unknown line number>)	MOVQ	80(SP), BP
    	0x00ec 00236 (<unknown line number>)	ADDQ	$88, SP
    	0x00f0 00240 (<unknown line number>)	RET
    	0x00f1 00241 (<unknown line number>)	NOP
    	0x00f1 00241 (main.go:5)	PCDATA	$1, $-1
    	0x00f1 00241 (main.go:5)	PCDATA	$0, $-1
    	0x00f1 00241 (main.go:5)	CALL	runtime.morestack_noctxt(SB)
    	0x00f6 00246 (main.go:5)	JMP	0
    	0x0000 64 48 8b 0c 25 00 00 00 00 48 3b 61 10 0f 86 de  dH..%....H;a....
    	0x0010 00 00 00 48 83 ec 58 48 89 6c 24 50 48 8d 6c 24  ...H..XH.l$PH.l$
    	0x0020 50 48 8d 05 00 00 00 00 48 89 04 24 0f 57 c0 0f  PH......H..$.W..
    	0x0030 11 44 24 08 e8 00 00 00 00 48 8b 44 24 18 48 8d  .D$......H.D$.H.
    	0x0040 0d 00 00 00 00 48 89 0c 24 48 89 44 24 08 0f 57  .....H..$H.D$..W
    	0x0050 c0 0f 11 44 24 10 48 c7 44 24 20 01 00 00 00 e8  ...D$.H.D$ .....
    	0x0060 00 00 00 00 48 8b 44 24 28 48 8b 4c 24 30 48 8b  ....H.D$(H.L$0H.
    	0x0070 54 24 38 48 c7 00 01 00 00 00 48 89 04 24 48 8d  T$8H......H..$H.
    	0x0080 41 01 48 89 44 24 08 48 89 54 24 10 e8 00 00 00  A.H.D$.H.T$.....
    	0x0090 00 48 8b 44 24 18 0f 57 c0 0f 11 44 24 40 48 8d  .H.D$..W...D$@H.
    	0x00a0 0d 00 00 00 00 48 89 4c 24 40 48 89 44 24 48 48  .....H.L$@H.D$HH
    	0x00b0 8b 05 00 00 00 00 48 8d 0d 00 00 00 00 48 89 0c  ......H......H..
    	0x00c0 24 48 89 44 24 08 48 8d 44 24 40 48 89 44 24 10  $H.D$.H.D$@H.D$.
    	0x00d0 48 c7 44 24 18 01 00 00 00 48 c7 44 24 20 01 00  H.D$.....H.D$ ..
    	0x00e0 00 00 e8 00 00 00 00 48 8b 6c 24 50 48 83 c4 58  .......H.l$PH..X
    	0x00f0 c3 e8 00 00 00 00 e9 05 ff ff ff                 ...........
    	rel 5+4 t=16 TLS+0
    	rel 36+4 t=15 type.int+0
    	rel 53+4 t=8 runtime.makeslice+0
    	rel 65+4 t=15 type.int+0
    	rel 96+4 t=8 runtime.growslice+0
    	rel 141+4 t=8 runtime.convTslice+0
    	rel 161+4 t=15 type.[]int+0
    	rel 178+4 t=15 os.Stdout+0
    	rel 185+4 t=15 go.itab.*os.File,io.Writer+0
    	rel 227+4 t=8 fmt.Fprintln+0
    	rel 242+4 t=8 runtime.morestack_noctxt+0
    go.cuinfo.packagename. SDWARFINFO dupok size=0
    	0x0000 6d 61 69 6e                                      main
    go.info.fmt.Println$abstract SDWARFINFO dupok size=42
    	0x0000 04 66 6d 74 2e 50 72 69 6e 74 6c 6e 00 01 01 11  .fmt.Println....
    	0x0010 61 00 00 00 00 00 00 11 6e 00 01 00 00 00 00 11  a.......n.......
    	0x0020 65 72 72 00 01 00 00 00 00 00                    err.......
    	rel 19+4 t=28 go.info.[]interface {}+0
    	rel 27+4 t=28 go.info.int+0
    	rel 37+4 t=28 go.info.error+0
    go.loc.os.(*File).close SDWARFLOC dupok size=0
    go.info.os.(*File).close SDWARFINFO dupok size=55
    	0x0000 03 6f 73 2e 28 2a 46 69 6c 65 29 2e 63 6c 6f 73  .os.(*File).clos
    	0x0010 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  e...............
    	0x0020 00 00 01 9c 00 00 00 00 01 0f 7e 72 30 00 01 ec  ..........~r0...
    	0x0030 01 00 00 00 00 00 00                             .......
    	rel 18+8 t=1 os.(*File).close+0
    	rel 26+8 t=1 os.(*File).close+26
    	rel 36+4 t=29 gofile..<autogenerated>+0
    	rel 49+4 t=28 go.info.error+0
    go.range.os.(*File).close SDWARFRANGE dupok size=0
    go.isstmt.os.(*File).close SDWARFMISC dupok size=0
    	0x0000 04 05 01 10 02 05 00                             .......
    go.loc."".main SDWARFLOC size=134
    	0x0000 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00  ................
    	0x0010 3e 00 00 00 00 00 00 00 64 00 00 00 00 00 00 00  >.......d.......
    	0x0020 07 00 50 93 08 93 08 93 08 69 00 00 00 00 00 00  ..P......i......
    	0x0030 00 73 00 00 00 00 00 00 00 07 00 50 93 08 93 08  .s.........P....
    	0x0040 93 08 73 00 00 00 00 00 00 00 82 00 00 00 00 00  ..s.............
    	0x0050 00 00 08 00 50 93 08 93 08 51 93 08 82 00 00 00  ....P....Q......
    	0x0060 00 00 00 00 91 00 00 00 00 00 00 00 08 00 93 08  ................
    	0x0070 50 93 08 51 93 08 00 00 00 00 00 00 00 00 00 00  P..Q............
    	0x0080 00 00 00 00 00 00                                ......
    	rel 8+8 t=1 "".main+0
    go.info."".main SDWARFINFO size=74
    	0x0000 03 22 22 2e 6d 61 69 6e 00 00 00 00 00 00 00 00  ."".main........
    	0x0010 00 00 00 00 00 00 00 00 00 01 9c 00 00 00 00 01  ................
    	0x0020 0b 61 72 72 00 06 00 00 00 00 00 00 00 00 06 00  .arr............
    	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 08 00 00                    ..........
    	rel 9+8 t=1 "".main+0
    	rel 17+8 t=1 "".main+251
    	rel 27+4 t=29 gofile../root/code/main.go+0
    	rel 38+4 t=28 go.info.[]int+0
    	rel 42+4 t=28 go.loc."".main+0
    	rel 47+4 t=28 go.info.fmt.Println$abstract+0
    	rel 51+8 t=1 "".main+175
    	rel 59+8 t=1 "".main+231
    	rel 67+4 t=29 gofile../root/code/main.go+0
    go.range."".main SDWARFRANGE size=0
    go.isstmt."".main SDWARFMISC size=0
    	0x0000 04 13 04 0e 03 07 01 0c 02 05 01 05 02 07 01 1a  ................
    	0x0010 02 05 01 16 02 04 01 04 02 05 01 05 02 05 01 1e  ................
    	0x0020 02 07 01 2c 02 05 01 0a 02 0a 00                 ...,.......
    runtime.gcbits.01 SRODATA dupok size=1
    	0x0000 01                                               .
    type..namedata.*interface {}- SRODATA dupok size=16
    	0x0000 00 00 0d 2a 69 6e 74 65 72 66 61 63 65 20 7b 7d  ...*interface {}
    type.*interface {} SRODATA dupok size=56
    	0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    	0x0010 4f 0f 96 9d 00 08 08 36 00 00 00 00 00 00 00 00  O......6........
    	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                          ........
    	rel 24+8 t=1 runtime.algarray+80
    	rel 32+8 t=1 runtime.gcbits.01+0
    	rel 40+4 t=5 type..namedata.*interface {}-+0
    	rel 48+8 t=1 type.interface {}+0
    runtime.gcbits.02 SRODATA dupok size=1
    	0x0000 02                                               .
    type.interface {} SRODATA dupok size=80
    	0x0000 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00  ................
    	0x0010 e7 57 a0 18 02 08 08 14 00 00 00 00 00 00 00 00  .W..............
    	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  ................
    	rel 24+8 t=1 runtime.algarray+144
    	rel 32+8 t=1 runtime.gcbits.02+0
    	rel 40+4 t=5 type..namedata.*interface {}-+0
    	rel 44+4 t=6 type.*interface {}+0
    	rel 56+8 t=1 type.interface {}+80
    type..namedata.*[]interface {}- SRODATA dupok size=18
    	0x0000 00 00 0f 2a 5b 5d 69 6e 74 65 72 66 61 63 65 20  ...*[]interface 
    	0x0010 7b 7d                                            {}
    type.*[]interface {} SRODATA dupok size=56
    	0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    	0x0010 f3 04 9a e7 00 08 08 36 00 00 00 00 00 00 00 00  .......6........
    	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                          ........
    	rel 24+8 t=1 runtime.algarray+80
    	rel 32+8 t=1 runtime.gcbits.01+0
    	rel 40+4 t=5 type..namedata.*[]interface {}-+0
    	rel 48+8 t=1 type.[]interface {}+0
    type.[]interface {} SRODATA dupok size=56
    	0x0000 18 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    	0x0010 70 93 ea 2f 02 08 08 17 00 00 00 00 00 00 00 00  p../............
    	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                          ........
    	rel 24+8 t=1 runtime.algarray+0
    	rel 32+8 t=1 runtime.gcbits.01+0
    	rel 40+4 t=5 type..namedata.*[]interface {}-+0
    	rel 44+4 t=6 type.*[]interface {}+0
    	rel 48+8 t=1 type.interface {}+0
    type..namedata.*[1]interface {}- SRODATA dupok size=19
    	0x0000 00 00 10 2a 5b 31 5d 69 6e 74 65 72 66 61 63 65  ...*[1]interface
    	0x0010 20 7b 7d                                          {}
    type.*[1]interface {} SRODATA dupok size=56
    	0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    	0x0010 bf 03 a8 35 00 08 08 36 00 00 00 00 00 00 00 00  ...5...6........
    	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                          ........
    	rel 24+8 t=1 runtime.algarray+80
    	rel 32+8 t=1 runtime.gcbits.01+0
    	rel 40+4 t=5 type..namedata.*[1]interface {}-+0
    	rel 48+8 t=1 type.[1]interface {}+0
    type.[1]interface {} SRODATA dupok size=72
    	0x0000 10 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00  ................
    	0x0010 50 91 5b fa 02 08 08 11 00 00 00 00 00 00 00 00  P.[.............
    	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 01 00 00 00 00 00 00 00                          ........
    	rel 24+8 t=1 runtime.algarray+144
    	rel 32+8 t=1 runtime.gcbits.02+0
    	rel 40+4 t=5 type..namedata.*[1]interface {}-+0
    	rel 44+4 t=6 type.*[1]interface {}+0
    	rel 48+8 t=1 type.interface {}+0
    	rel 56+8 t=1 type.[]interface {}+0
    ""..inittask SNOPTRDATA size=32
    	0x0000 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................
    	0x0010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    	rel 24+8 t=1 fmt..inittask+0
    type..namedata.*[]int- SRODATA dupok size=9
    	0x0000 00 00 06 2a 5b 5d 69 6e 74                       ...*[]int
    type.*[]int SRODATA dupok size=56
    	0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    	0x0010 1b 31 52 88 00 08 08 36 00 00 00 00 00 00 00 00  .1R....6........
    	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                          ........
    	rel 24+8 t=1 runtime.algarray+80
    	rel 32+8 t=1 runtime.gcbits.01+0
    	rel 40+4 t=5 type..namedata.*[]int-+0
    	rel 48+8 t=1 type.[]int+0
    type.[]int SRODATA dupok size=56
    	0x0000 18 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
    	0x0010 8e 66 f9 1b 02 08 08 17 00 00 00 00 00 00 00 00  .f..............
    	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                          ........
    	rel 24+8 t=1 runtime.algarray+0
    	rel 32+8 t=1 runtime.gcbits.01+0
    	rel 40+4 t=5 type..namedata.*[]int-+0
    	rel 44+4 t=6 type.*[]int+0
    	rel 48+8 t=1 type.int+0
    go.itab.*os.File,io.Writer SRODATA dupok size=32
    	0x0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
    	0x0010 44 b5 f3 33 00 00 00 00 00 00 00 00 00 00 00 00  D..3............
    	rel 0+8 t=1 type.io.Writer+0
    	rel 8+8 t=1 type.*os.File+0
    	rel 24+8 t=1 os.(*File).Write+0
    go.itablink.*os.File,io.Writer SRODATA dupok size=8
    	0x0000 00 00 00 00 00 00 00 00                          ........
    	rel 0+8 t=1 go.itab.*os.File,io.Writer+0
    type..importpath.fmt. SRODATA dupok size=6
    	0x0000 00 00 03 66 6d 74                                ...fmt
    gclocals·e6397a44f8e1b6e77d0f200b4fba5269 SRODATA dupok size=10
    	0x0000 02 00 00 00 03 00 00 00 01 00                    ..........
    gclocals·69c1753bd5f81501d95132d08af04464 SRODATA dupok size=8
    	0x0000 02 00 00 00 00 00 00 00                          ........
    gclocals·9fb7f0986f647f17cb53dda1484e0f7a SRODATA dupok size=10
    	0x0000 02 00 00 00 01 00 00 00 00 01                    ..........
    gclocals·568470801006e5c0dc3947ea998fe279 SRODATA dupok size=10
    	0x0000 02 00 00 00 02 00 00 00 00 02                    ..........
    gclocals·bfec7e55b3f043d1941c093912808913 SRODATA dupok size=11
    	0x0000 03 00 00 00 02 00 00 00 00 01 03                 ...........
    "".main.stkobj SRODATA dupok size=24
    	0x0000 01 00 00 00 00 00 00 00 f0 ff ff ff ff ff ff ff  ................
    	0x0010 00 00 00 00 00 00 00 00                          ........
    	rel 16+8 t=1 type.[1]interface {}+0
    
    

    Go 语言汇编 FUNCDATA 和 PCDATA 是编译器产生的,用于保存一些和垃圾收集相关的信息,我们先不用 care。

    // 只关心下call, 看下go代码调用了runtime哪些函数
    
    [root@VM_115_23_centos ~/code]# go tool compile -S main.go|grep -i call
    	0x0034 00052 (main.go:6)	CALL	runtime.makeslice(SB)           //创建slice
    	0x005f 00095 (main.go:7)	CALL	runtime.growslice(SB)           //扩容slice
    	0x008c 00140 (main.go:8)	CALL	runtime.convTslice(SB)          //类型转换
    	0x00e2 00226 ($GOROOT/src/fmt/print.go:274)	CALL	fmt.Fprintln(SB)//打印函数
    	0x00f1 00241 (main.go:5)	CALL	runtime.morestack_noctxt(SB)    //栈内存扩容
    

    // 小结:
    
    arr := make([]int, 0)  //调用runtime.makeslice(SB)
    arr = append(arr, 1)   //调用runtime.growslice(SB)
    

    arr := make([]int, 0)调用runtime.makeslice

    //功能: 计算当前切片占用的内存空间
    //      并在堆上申请一片连续的内存
    //内存空间 = 切片中元素大小 x 切片容量
    
    func makeslice(et *_type, len, cap int) unsafe.Pointer { // 返回指向底层数组的指针
    	mem, overflow := math.MulUintptr(et.size, uintptr(cap))
    	if overflow || mem > maxAlloc || len < 0 || len > cap {
    		mem, overflow := math.MulUintptr(et.size, uintptr(len))
    		if overflow || mem > maxAlloc || len < 0 {
    			panicmakeslicelen()
    		}
    		panicmakeslicecap()
    	}
    
    	return mallocgc(mem, et, true) //用于申请内存的函数
    }
    

    arr = append(arr,1)

    // src/runtime/slice.go:82
    func growslice(et *_type, old slice, cap int) slice {
        // ……
        newcap := old.cap
        doublecap := newcap + newcap
        if cap > doublecap {
            newcap = cap
        } else {
            if old.len < 1024 {
                newcap = doublecap
            } else {
                for newcap < cap {
                    newcap += newcap / 4
                }
            }
        }
        // ……
        
        capmem = roundupsize(uintptr(newcap) * ptrSize)
        newcap = int(capmem / ptrSize)
    }
    
    

    栈底指针/栈顶指针

    BP 与 SP 是寄存器,它保存的是栈上的地址,所以执行中可以对 SP 做运算找到下一个指令的位置;

    BP(base pointer):  栈底指针, 表示函数栈开始的地方。
    SP(stack pointer): 栈顶指针, 表示函数栈空间分配结束的地方
                       执行中可以对 SP 做运算找到下一个指令的位置.
    

    栈被回收,只是改变了 SP 指向的位置,内存中的数据并不会清空,只有下次被分配使用的时候才会清空;

    看下 main 函数栈帧的开始和收尾部分。

    0x0013 00019 (main.go:5)SUBQ    $96, SP
    0x0017 00023 (main.go:5)MOVQ    BP, 88(SP)
    0x001c 00028 (main.go:5)LEAQ    88(SP), BP
    …………………………
    0x00d3 00211 (main.go:9)MOVQ    88(SP), BP
    0x00d8 00216 (main.go:9)ADDQ    $96, SP
    RET
    
    • 栈针移动规律
  • 相关阅读:
    Asp Net Core Fro MongoDB Part1
    Word 离线发布bolg测试
    Word 2016问题导致无法创建其他博客账号
    字符集工具
    人工智能笔摘
    js数组去重
    ##react-native学习笔记(windows android)##第4天,分析下目录结构
    ##react-native学习笔记(windows android)##第3天,解决白屏闪退问题
    ##react-native学习笔记(windows android)##第2天, Hello world !
    ##react-native学习笔记(windows android)##第1天,搭建开发环境
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/12258598.html
Copyright © 2011-2022 走看看