Skip to content

Conversation

lmb
Copy link
Collaborator

@lmb lmb commented Mar 20, 2024

coreAreTypesCompatible currently uses two manually maintained stacks to traverse two types to compare. The original idea was that using stacks would somehow be more efficient or it'd be easier to understand than the recursive approach. Time has shown that this was probably not true. Using the stacks is both harder to understand and probably less performant than using recursion. This is because the runtime maintains a stack for us, which can be reused across many invocations. Allocating on the (goroutine) stack is also incredibly cheap.

Rewrite coreAreTypesCompatible to use recursion to traverse the two types. Instead of using walkType we simply open code the switch cases for Pointer, Array and FuncProto. This isn't much code and gets rid of a bunch of complexity and allocations, especially for FuncParam.

The depth check is removed completely. It's a hold over from libbpf, which probably uses it to avoid stack overflow. This isn't necessary in Go, since overflowing the stack is guaranteed to panic. Instead, we deal with cyclical types by maintaining a visited map.

coreAreTypesCompatible currently uses two manually maintained
stacks to traverse two types to compare. The original idea was
that using stacks would somehow be more efficient or it'd be
easier to understand than the recursive approach. Time has shown
that this was probably not true. Using the stacks is both harder
to understand and probably less performant than using recursion.
This is because the runtime maintains a stack for us, which can
be reused across many invocations. Allocating on the (goroutine)
stack is also incredibly cheap.

Rewrite coreAreTypesCompatible to use recursion to traverse the
two types. Instead of using walkType we simply open code the
switch cases for Pointer, Array and FuncProto. This isn't much
code and gets rid of a bunch of complexity and allocations,
especially for FuncParam.

The depth check is removed completely. It's a hold over from
libbpf, which probably uses it to avoid stack overflow. This
isn't necessary in Go, since overflowing the stack is guaranteed
to panic. Instead, we deal with cyclical types by maintaining
a visited map.

Signed-off-by: Lorenz Bauer <[email protected]>
Copy link
Member

@dylandreimerink dylandreimerink left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@lmb lmb merged commit ebf148f into cilium:main Mar 22, 2024
@lmb lmb deleted the btf-core-compatible branch March 22, 2024 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants