Slide 1

Slide 1 text

Go Stack: Should it be Moving Like That? Yarden Laifenfeld

Slide 2

Slide 2 text

2 Who Am I? • Software Engineer at Rookout • Go, Java, Ruby • C#, Python, JavaScript, C++ • Amateur sewist

Slide 3

Slide 3 text

What is Stack? ● Section of memory ○ One stack per thread ● Works like a stack (LIFO) ● Stores function parameters, local variables, return addresses 3

Slide 4

Slide 4 text

What is Stack? 4 … func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... } Stack

Slide 5

Slide 5 text

What is Stack? 5 … 1 a Local variables Stack func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 6

Slide 6 text

What is Stack? 6 … 1 a Local variables Stack 1 b Function parameters 2 c func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 7

Slide 7 text

What is Stack? 7 … 1 a Local variables Stack 1 b Function parameters 2 c 0x12345 Return address func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 8

Slide 8 text

What is Stack? 8 … 1 a Local variables Stack 1 b Function parameters 2 c 0x12345 Return address func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... } 0 d Local variables

Slide 9

Slide 9 text

What is Stack? 9 … 1 a Local variables Stack 1 b Function parameters 2 c 0x12345 Return address 0 d Local variables func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 10

Slide 10 text

What is Stack? 10 … 1 a Local variables Stack 1 b Function parameters 2 c 0x12345 Return address func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 11

Slide 11 text

What is Stack? ● Grows down - last thing we pushed onto the stack will be at the lowest address ● RSP - “variable” that holds the last address of the stack 11

Slide 12

Slide 12 text

What is Stack? 12 … 1 0x1238 Local variables Stack 1 0x1230 Function parameters 2 0x1228 0x12345 func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... } Return address 0x1220

Slide 13

Slide 13 text

What is Stack? 13 … 1 0x1238 Local variables Stack 1 0x1230 Function parameters 2 0x1228 0x12345 func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... } Return address 0x1220 rsp

Slide 14

Slide 14 text

What is Stack? 14 … 1 0x1238 Local variables Stack 1 0x1230 Function parameters 2 0x1228 rsp Bigger rsp → smaller stack

Slide 15

Slide 15 text

What’s So Special About Go? 15 ● Threads ≠ Goroutines ● Threads - 1-10MB ● Goroutines - 4K

Slide 16

Slide 16 text

What If I Need morestack? 16

Slide 17

Slide 17 text

When Is morestack Called? 17 ● The compiler adds a prologue and epilogue to every function ● Prologue checks if more stack is needed ● Epilogue calls `morestack`

Slide 18

Slide 18 text

When is morestack Called? 18

Slide 19

Slide 19 text

needsMorestack() 19 ● Not a real function ● A condition that compares: ○ Available stack ○ Stack in use ● How does that look like?

Slide 20

Slide 20 text

g struct 20 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... rsp: 0x1090

Slide 21

Slide 21 text

g struct 21 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x rsp: 0x1078 g.stack.lo g.stack.hi

Slide 22

Slide 22 text

g struct 22 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1010 x g.stack.lo g.stack.hi

Slide 23

Slide 23 text

g struct 23 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x

Slide 24

Slide 24 text

g struct 24 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x

Slide 25

Slide 25 text

25 `morestack` needs 0x10 stack!

Slide 26

Slide 26 text

`morestack` needs 0x10 stack 26 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 27

Slide 27 text

`morestack` needs 0x10 stack 27 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 28

Slide 28 text

`morestack` needs 0x10 stack 28 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 29

Slide 29 text

`morestack` needs 0x10 stack 29 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 30

Slide 30 text

`morestack` needs 0x10 stack 30 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 31

Slide 31 text

`morestack` needs 0x10 stack 31 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 32

Slide 32 text

`morestack` needs 0x10 stack 32 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 33

Slide 33 text

`morestack` needs 0x10 stack 33 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 34

Slide 34 text

`morestack` needs 0x10 stack 34 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 35

Slide 35 text

`morestack` needs 0x10 stack 35 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 36

Slide 36 text

`morestack` needs 0x10 stack 36 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0x1000 x g.stack.lo g.stack.hi x x 0xff8 0xff0

Slide 37

Slide 37 text

`morestack` needs 0x10 stack 37 Stack 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... x x x x x x x x x x x x x x x rsp: 0xff0 x g.stack.lo g.stack.hi x x x x 0xff8 0xff0

Slide 38

Slide 38 text

`morestack` needs 0x10 stack 38 38 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1090 0x1088 0x1080 0x1010 ... rsp: 0x1090 g.stack.lo+0x10

Slide 39

Slide 39 text

`morestack` needs 0x10 stack 39 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1010 x x x x x x x x x x x x x x x x g.stack.lo+0x10

Slide 40

Slide 40 text

`morestack` needs 0x10 stack 40 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1010 x x x x x x x x x x x x x x x x g.stack.lo+0x10

Slide 41

Slide 41 text

`morestack` needs 0x10 stack 41 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1010 x x x x x x x x x x x x x x x x g.stack.lo+0x10

Slide 42

Slide 42 text

`morestack` needs 0x10 stack 42 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1000 x x x x x x x x x x x x x x x x g.stack.lo+0x10 x x

Slide 43

Slide 43 text

43 g.stackguard0 = g.stack.lo + 0x10

Slide 44

Slide 44 text

Stackguard 44 ● Used to check if we have enough stack ● Always between stack.lo and stack.hi ● Will leave enough memory for calls to functions like `morestack`

Slide 45

Slide 45 text

45

Slide 46

Slide 46 text

Stack Usage 46

Slide 47

Slide 47 text

Stack Usage 47

Slide 48

Slide 48 text

Stack Usage 48 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1020 x x x x x x x x x x x x x x g.stackguard0

Slide 49

Slide 49 text

Stack Usage 49 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1020 x x x x x x x x x x x x x x g.stackguard0

Slide 50

Slide 50 text

Stack Usage 50 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1020 x x x x x x x x x x x x x x g.stackguard0

Slide 51

Slide 51 text

Stack Usage 51 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0xf20 x x x x x x x x x x x x x x g.stackguard0 x x x x x x x x x x x x x x x x

Slide 52

Slide 52 text

What is Stack? 52 … func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... } Stack

Slide 53

Slide 53 text

What is Stack? 53 … 1 a Local variables Stack func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 54

Slide 54 text

What is Stack? 54 … 1 a Local variables Stack 1 b Function parameters 2 c func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 55

Slide 55 text

What is Stack? 55 … 1 a Local variables Stack 1 b Function parameters 2 c func runFirst() { a := 1 runSecond(a, 2) return } func runSecond(b, c int) { var d int ... }

Slide 56

Slide 56 text

What is Stack? 56 … 1 a Local variables Stack 1 b Function parameters 2 c func runFirst() { a := 1 if shouldRunSecond { runSecond(a, 2) } return }

Slide 57

Slide 57 text

Stack Usage 57 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1020 x x x x x x x x x x x x x x g.stackguard0

Slide 58

Slide 58 text

Stack Usage 58 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1020 x x x x x x x x x x x x x x g.stackguard0

Slide 59

Slide 59 text

Stack Usage 59 Stack g.stack.lo g.stack.hi 0x1000 0x1008 0x1088 0x1080 0x1010 ... rsp: 0x1020 x x x x x x x x x x x x x x g.stackguard0

Slide 60

Slide 60 text

Stack Usage 60

Slide 61

Slide 61 text

61 What Goes Up Must Come Back Down

Slide 62

Slide 62 text

Stack Shrink ● `shrinkstack` ● Called by GC ● Shrink stack if less than a quarter is being used 62

Slide 63

Slide 63 text

Thank You! @yardenlaif 63