Skip to content

cmd/compile: PGO devirtualization of partial interface implementations #64673

@prattmic

Description

@prattmic

Callees that only partially implement an interface (they are embedded in another type that completes the interface) cannot be devirtualized.

e.g., consider:

func foo(r io.ReadCloser) {
  b := make([]byte, 64)
  r.Read(b)
}

func main() {
  b := make([]byte, 64)
  r := bytes.NewReader(b)
  rc := io.NopCloser(r)
  foo(rc)
}

io.nopCloser embeds Reader, so the PGO profile will report a call from foo -> bytes.Reader.Read. Devirtualization will consider this candidate, determine that bytes.Reader does not implement io.ReadCloser and decide that it must not be valid, but it is valid because of the wrapper type not visible from the profile.

Devirtualization could be more lenient and only type-check the single method that is called rather than the entire interface, though this risks more false positives in ambiguous situations.

cc @cherrymui @aclements

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    Status

    Todo

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions