How are interfaces marked by the GC?

162 views
Skip to first unread message

Kristoffer Semelka

unread,
Jul 13, 2021, 4:29:20 PM7/13/21
to golan...@googlegroups.com
I noticed that word sized datatypes can be stored directly in the data field of an iface/eface, but I'm confused on how marking works with these kinds of inline cases. I checked the mark routines in the runtime/gcmark.go and couldn't find special casing for interfaces. How does the runtime know when not to follow an interface's data pointer? Does it just scan that word conservatively? How does the func's pointer map fit into this?

Kind regards, Kris

Ian Lance Taylor

unread,
Jul 13, 2021, 4:32:06 PM7/13/21
to Kristoffer Semelka, golang-nuts
On Tue, Jul 13, 2021 at 1:29 PM Kristoffer Semelka <ksem...@gmail.com> wrote:
>
> I noticed that word sized datatypes can be stored directly in the data field of an iface/eface, but I'm confused on how marking works with these kinds of inline cases. I checked the mark routines in the runtime/gcmark.go and couldn't find special casing for interfaces. How does the runtime know when not to follow an interface's data pointer? Does it just scan that word conservatively? How does the func's pointer map fit into this?

In the current implementations the data field of an interface value is
always a pointer. It was once true that small scalar values were
stored directly in interface values, but that is no longer true today.

Ian

ben...@gmail.com

unread,
Jul 14, 2021, 5:11:27 PM7/14/21
to golang-nuts
Out of interest, why was that changed? Was the optimization not worth it? Did it just require too much special handling so the code was unclear?

Ian Lance Taylor

unread,
Jul 14, 2021, 8:24:20 PM7/14/21
to ben...@gmail.com, golang-nuts
On Wed, Jul 14, 2021 at 2:11 PM ben...@gmail.com <ben...@gmail.com> wrote:
>
> Out of interest, why was that changed? Was the optimization not worth it? Did it just require too much special handling so the code was unclear?

When we switched to using a concurrent garbage collector, we had to
consider the possibility that the program would change an interface
value from a type that used a pointer to a type that used a scalar
value exactly as the concurrent collector was examining the interface
value. Any simple approach would lead to races where the garbage
collector would misunderstand a scalar value as a pointer or
vice-versa, leading to dangling pointers or incorrectly retained
memory. The simplest way to resolve the issue was to change
interfaces to always use pointers.

Ian


> On Wednesday, July 14, 2021 at 8:32:06 AM UTC+12 Ian Lance Taylor wrote:
>>
>> On Tue, Jul 13, 2021 at 1:29 PM Kristoffer Semelka <ksem...@gmail.com> wrote:
>> >
>> > I noticed that word sized datatypes can be stored directly in the data field of an iface/eface, but I'm confused on how marking works with these kinds of inline cases. I checked the mark routines in the runtime/gcmark.go and couldn't find special casing for interfaces. How does the runtime know when not to follow an interface's data pointer? Does it just scan that word conservatively? How does the func's pointer map fit into this?
>>
>> In the current implementations the data field of an interface value is
>> always a pointer. It was once true that small scalar values were
>> stored directly in interface values, but that is no longer true today.
>>
>> 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...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/0e940dea-7e1a-41a4-ad8f-4784a943be98n%40googlegroups.com.

Ben Hoyt

unread,
Jul 14, 2021, 9:52:19 PM7/14/21
to Ian Lance Taylor, golang-nuts
Interesting, thanks for the explanation!
Reply all
Reply to author
Forward
0 new messages