question about shot write barrier instructions

89 views
Skip to first unread message

计算鸡

unread,
May 10, 2021, 8:56:28 AM5/10/21
to golang-nuts

```go 
package main

type T struct {
        a *int
}

func test(t *T, b *int) {
        t.a = b
}
```
compile this code use cmd `go build -gcflags '-l' main.go` 
only disable inline stage .

here is the plan9 assembly of function test 

```assembly
TEXT main.test(SB) src/write-barrier/main.go
  main.go:7   0x45ec60   64488b0c25f8ffffff   MOVQ FS:0xfffffff8, CX
  main.go:7   0x45ec69   483b6110             CMPQ 0x10(CX), SP
  main.go:7   0x45ec6d   7639                 JBE 0x45eca8
  main.go:7   0x45ec6f   4883ec08             SUBQ $0x8, SP
  main.go:7   0x45ec73   48892c24             MOVQ BP, 0(SP)
  main.go:7   0x45ec77   488d2c24             LEAQ 0(SP), BP
  main.go:8   0x45ec7b   488b7c2410           MOVQ 0x10(SP), DI
  main.go:8   0x45ec80   8407                 TESTB AL, 0(DI)
  main.go:8   0x45ec82   833d379c090000       CMPL $0x0, runtime.writeBarrier(SB)
  main.go:8   0x45ec89   7511                 JNE 0x45ec9c
  main.go:8   0x45ec8b   488b442418           MOVQ 0x18(SP), AX
  main.go:8   0x45ec90   488907               MOVQ AX, 0(DI)
  main.go:9   0x45ec93   488b2c24             MOVQ 0(SP), BP
  main.go:9   0x45ec97   4883c408             ADDQ $0x8, SP
  main.go:9   0x45ec9b   c3                   RET
  main.go:8   0x45ec9c   488b442418           MOVQ 0x18(SP), AX
  main.go:8   0x45eca1   e8facaffff           CALL runtime.gcWriteBarrier(SB)
  main.go:8   0x45eca6   ebeb                 JMP 0x45ec93
  main.go:7   0x45eca8   e8b3afffff           CALL runtime.morestack_noctxt(SB)
  main.go:7   0x45ecad   ebb1                 JMP main.test(SB)
```

i was confused with the instruction ` main.go:8   0x45ec80   8407                 TESTB AL, 0(DI)` 
i think it must used for checking nil pointer . but both test and cmp will modify ZF in eflags. ( there is a cmp instruction follow the test )

i think it should insert instruction `JE 0x45ec9c ` between  test and cml instruction . 





Ian Lance Taylor

unread,
May 10, 2021, 9:18:42 AM5/10/21
to 计算鸡, golang-nuts
The "TESTB AL, 0(DI)" instruction will force the processor to attempt
to retrieve the value at address 0(DI). If DI does not hold a valid
address, the processor will fault. The runtime will pick up this
fault and turn it into a run-time panic saying "invalid memory address
or nil pointer dereference".

That is, the instruction is not being executed to set the flags. It
is being executed for its effect of testing whether the memory is
valid.

Ian
Reply all
Reply to author
Forward
0 new messages