Why does interface type carries pointer to basic types but not values itself?

164 views
Skip to first unread message

Никифор Серяков

unread,
Sep 18, 2020, 1:31:16 PM9/18/20
to golang-nuts
Lets imagine this code.

```go
var i int

func main() {
    i = 3

    F(i)
}

var q interface{}

//go:noinline
func F(a interface{}) {
    q = a
}
```

then run `go tool compile -S ~/a.go`

Skipping all not related, in main function we'll see

```
0x001d 00029 (/home/nik/a.go:6) MOVQ $3, "".i(SB)
0x0028 00040 (/home/nik/a.go:8) MOVQ $3, (SP)
0x0030 00048 (/home/nik/a.go:8) PCDATA $1, $0
0x0030 00048 (/home/nik/a.go:8) CALL runtime.convT64(SB)
0x0035 00053 (/home/nik/a.go:8) LEAQ type.int(SB), AX
0x003c 00060 (/home/nik/a.go:8) MOVQ AX, (SP)
0x0040 00064 (/home/nik/a.go:8) CALL "".F(SB)
```

which allocates (except some small optimization) new `*int` variable instead of just copying value itself.

```go
type eface struct {
_type *_type
data  unsafe.Pointer
}
```

`int` to `interface{}` conversion looks like
```go
v := new(int)
*v = value
return eface{
    _type: &type.int,
    data: unsafe.Pointer(&v),
}
```
instead of
```go
return eface{
    _type: &type.int,
    data: unsafe.Pointer(value),
}
```

I have some guess, that it is connected with garbage collection and requirement to know in advance if some piece of memory is pointer or not. But isn't it worth it to add some `if` in gc and do not make such allocations, reducing gc pressure?

Ian Lance Taylor

unread,
Sep 18, 2020, 1:45:40 PM9/18/20
to Никифор Серяков, golang-nuts
Interface values used to work more or less as you describe. As you
guessed, it was changed to support a more efficient concurent garbage
collector. The garbage collector has to know whether a value is a
pointer or not. With the implementation the gc compiler uses today,
both fields of an interface value are always pointers. If the second
word in an interface is sometimes a pointer and sometimes not, then
the garbage collector has to look at the first word to decide. And
that is a race condition for a concurrent garbage collector. It might
be possible to handle it, but it would significantly complicate the
write barrier.

Ian
Reply all
Reply to author
Forward
0 new messages