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.

Reply via email to