Skip to content

cmd/gc: make interface updates atomic wrt garbage collector #8405

Description

@rsc
Today garbage collection treats interfaces as multiword objects: the type word tells
whether the data word is a pointer.

When we move to a concurrent garbage collector that effectively races with the other
goroutines, interface updates made by an ordinary goroutine must be seen atomically by
the concurrent collector. It must not be possible for the collector to observe a
half-updated interface value.

(The same general problem applies to slices and strings, but the solution will be
different, so they are a separate issue, issue #8404.)

There are at least three possibilities:

(1) Use double-word atomic operations to read and write any interface value stored in
the heap. Interface values on the stack can still be modified using non-atomic
operations, because stack scans happen only at safe points.

(2) Change interface representations so that the data word is always a pointer. The
garbage collector would ignore type and always scan data sa a pointer, reducing the read
to a single word, making it atomic.

(3) Change interface representations to be three words: type, ptr-data, non-ptr data.
The garbage collector would ignore type and always scan ptr-data as a pointer, reducing
the read to a single word, making it atomic.

The benefit of (1) is no representation changes. The drawback is that the atomic
operation may be too expensive and may not even be available on all systems (64-bit
Intel Atom chips?). We don't actually know how many interface updates occur on the stack
vs the heap. My guess is that probably more than half are on the stack, so maybe making
heap updates more expensive is not terrible.

The benefit of (2) is no atomics and no interface value size change. It also brings the
gc and gccgo implementations in line (gccgo already does this). The drawback is the
allocations when converting from integer/bool/tiny struct to interface.

The benefit of (3) is no allocations. The drawback is the larger interface value size. I
expect that there are many places in the code that assume two-word interfaces and that
changing this will require tracking down these many latent assumptions.

I don't think we know which of these is the right solution. We need more data about (1)
how many interface read/writes are from the heap as opposed to the stack, and how
expensive/available the atomic operations are, (2) how many interface values would now
allocate in a typical program, and (3) how much extra space is taken up by the larger
interface values and how invasive the change in size is to other code.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions