From 610f088c5466c136a8c1a47c4e5a1a8fbe718f62 Mon Sep 17 00:00:00 2001 From: Paul Cacheux Date: Mon, 20 Jan 2025 10:46:40 +0100 Subject: [PATCH] linker: do not copy instructions when there is no reference When resolving the bpf-to-bpf calls we need to copy the instructions from the program to flatten the references. But when there is no reference there is nothing to do so we can skip the copy operation altogether. Signed-off-by: Paul Cacheux --- linker.go | 10 ++++++++-- linker_test.go | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/linker.go b/linker.go index 6f97af278..024b72bbc 100644 --- a/linker.go +++ b/linker.go @@ -207,13 +207,19 @@ func flattenPrograms(progs map[string]*ProgramSpec, names []string) { // dependencies of each program. func flattenInstructions(name string, progs map[string]*ProgramSpec, refs map[*ProgramSpec][]string) asm.Instructions { prog := progs[name] + progRefs := refs[prog] + + if len(progRefs) == 0 { + // No references, nothing to do. + return prog.Instructions + } insns := make(asm.Instructions, len(prog.Instructions)) copy(insns, prog.Instructions) // Add all direct references of prog to the list of to be linked programs. - pending := make([]string, len(refs[prog])) - copy(pending, refs[prog]) + pending := make([]string, len(progRefs)) + copy(pending, progRefs) // All references for which we've appended instructions. linked := make(map[string]bool) diff --git a/linker_test.go b/linker_test.go index 39b01cf65..cbe31d683 100644 --- a/linker_test.go +++ b/linker_test.go @@ -159,3 +159,24 @@ func TestSplitSymbols(t *testing.T) { qt.Assert(t, qt.HasLen(m["sym3"], 3)) qt.Assert(t, qt.HasLen(m["sym4"], 4)) } + +func TestFlattenInstructionsAllocations(t *testing.T) { + name := "entrypoint" + instructions := asm.Instructions{ + asm.LoadImm(asm.R0, 0, asm.DWord), + asm.Return(), + } + prog := &ProgramSpec{ + Name: name, + Instructions: instructions, + } + progs := map[string]*ProgramSpec{name: prog} + refs := make(map[*ProgramSpec][]string) + + // ensure that flattenInstructions does not allocate memory + // if there is no reference for the given program. + allocs := testing.AllocsPerRun(5, func() { + _ = flattenInstructions(name, progs, refs) + }) + qt.Assert(t, qt.Equals(allocs, float64(0))) +}