-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Open
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
Given:
type X int
func (*X) m() {}
type A struct { X }
type B struct { b int32; X }
type C struct { c uint32; X }
the compiler currently synthesizes method wrappers for the promoted methods:
func (a *A) m() { a.X.m() }
func (b *B) m() { b.X.m() }
func (c *C) m() { c.X.m() }
But we only really need 1 wrapper:
Acan just useX's method directly, because theXfield is at offset 0 anyway.BandCcould use a single shared wrapper, because they need the same pointer adjustment before tail calling to(*X).m.
This would save some executable size, but I also think it could help slightly with CPU I-cache and branch predictions. For example, within the compiler itself, ir.Node's Op and Pos methods are always actually implemented by ir.miniNode (which we always embed at offset 0). But we create a wrapper method for each ir.Node implementation, which means (caveat: hypothesizing) a bunch of identical methods all end up taking up I-cache space and the branch predictor has to guess which one is going to be called.
Metadata
Metadata
Assignees
Labels
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Type
Projects
Status
Todo