Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Array Internals and the Call Stack in Go

Array Internals and the Call Stack in Go

Georgi Knox

January 22, 2015
Tweet

More Decks by Georgi Knox

Other Decks in Technology

Transcript

  1. func main() { a := [4]int{1, 2, 3, 4} println("a

    addr:", &a) for i := range a { print("Value: ", a[i]) println(" Address:", &a[i]) } }
  2. on 64bit architecture, each int = 8 bytes func main()

    { a := [4]int{1, 2, 3, 4} println("a addr:", &a) for i := range a { print("Value: ", a[i]) println(" Address:", &a[i]) } } a addr: 0x220822bf20 Value: 1 IndexAddr: 0x220822bf20 Value: 2 IndexAddr: 0x220822bf28 Value: 3 IndexAddr: 0x220822bf30 Value: 4 IndexAddr: 0x220822bf38
  3. In Go, everything is pass by value. When we pass

    an array as an argument, we pass a copy of the array not a reference to the array. package main func main() { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(names) println(names[0]) } func f1(a [4]string) { a[0] = "marie" }
  4. 1. A copy of names is made when f1 is

    called 1 package main func main() { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(names) println(names[0]) } func f1(a [4]string) { a[0] = "marie" }
  5. 2. The copy of names is assigned to local var

    a 1 package main func main() { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(names) println(names[0]) } func f1(a [4]string) { a[0] = "marie" } 2
  6. 3. We make a change to the copy 3 2

    1 package main func main() { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(names) println(names[0]) } func f1(a [4]string) { a[0] = "marie" }
  7. 3 2 1 package main func main() { names :=

    [4]string {"ada", "lovelace", "tom", "jerry"} f1(names) println(names[0]) } func f1(a [4]string) { a[0] = "marie" } // ada
  8. If we want to share names with f1 so f1

    can modify it, then we pass the address of names to f1. package main func main() { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(&names) println(names[0]) } func f1(a *[4]string) { a[0] = "marie" }
  9. 1. Pass the address of names package main func main()

    { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(&names) println(names[0]) } func f1(a *[4]string) { a[0] = "marie" } 1
  10. 2. f1 accepts a pointer variable package main func main()

    { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(&names) println(names[0]) } func f1(a *[4]string) { a[0] = "marie" } 2 1
  11. 3. Changes to a update the array that a points

    to, names. package main func main() { names := [4]string {"ada", "lovelace", "tom", "jerry"} f1(&names) println(names[0]) } func f1(a *[4]string) { a[0] = "marie" } 3 2 1
  12. package main func main() { names := [4]string {"ada", "lovelace",

    "tom", "jerry"} f1(&names) println(names[0]) } func f1(a *[4]string) { a[0] = "marie" } 3 2 1 // marie
  13. func main() { a := [4]int{1, 2, 3, 4} println("a

    addr:", &a) for i := range a { print("Value: ", a[i]) println(" Address:", &a[i]) } } print
  14. func main() { a := [4]int{1, 2, 3, 4} println("a

    addr:", &a) for i := range a { print("Value: ", a[i]) println(" Address:", &a[i]) } } print func main() { a := [4]int{1, 2, 3, 4} println("a addr:", &a) for i := range a { print("Value: ", a[i]) println(" Address:", &a[i]) } } import "fmt" func main() { a := [4]int{1, 2, 3, 4} fmt.Printf("a addr: %p \n", &a) for i := range a { fmt.Printf("V: %v A: %p \n", a[i], &a[i]) } } import "fmt" func main() { a := [4]int{1, 2, 3, 4} fmt.Printf("a addr: %p \n", &a) for i := range a { fmt.Printf("V: %v A: %p \n", a[i], &a[i]) } } fmt.Print
  15. 1. escape analysis go build -gcflags=-m main.go:6: moved to heap:

    a main.go:8: &a escapes to heap main.go:11: &a[i] escapes to heap main.go:8: main ... argument does not escape main.go:11: main ... argument does not escape with ft.Printf
  16. 1. inlining func main() { names := [2]string{"ada", "lovelace"} f1(names)

    println(names[0]) } func f1(a [2]string) { a[0] = "marie" }
  17. inlining func main() { names := [2]string{"ada", "lovelace"} f1(names) println(names[0])

    } func f1(a [2]string) { a[0] = "marie" // Do this to prevent inlining. var x int fmt.Sprintf("Prevent Inlining: %d", x) }