On Fri, Sep 18, 2020 at 10:31 AM Никифор Серяков <nikand...@gmail.com> wrote: > > 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) > ``` > > Where `runtime.convT64` is > https://github.com/golang/go/blob/master/src/runtime/iface.go#L364, > which allocates (except some small optimization) new `*int` variable instead > of just copying value itself. > > So for interface declared (here > https://github.com/golang/go/blob/master/src/runtime/runtime2.go#L208) as > ```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?
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 -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAOyqgcWO%2BuzVj9qR0O9%3Drz_VuvymPjw2JD8AJ-45vTQ-4RE%3DqQ%40mail.gmail.com.