mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
BPF program builder: Cache map of label sources.
This speeds up BPF program generation by 10x, due to the large amount of time otherwise spent scanning labels linearly. PiperOrigin-RevId: 582759289
This commit is contained in:
committed by
gVisor bot
parent
6262b00330
commit
7bf7830078
+19
-17
@@ -34,6 +34,9 @@ type ProgramBuilder struct {
|
||||
// Maps label names to label objects.
|
||||
labels map[string]*label
|
||||
|
||||
// Maps label sources to the label name it references.
|
||||
jumpSourceToLabel map[source]string
|
||||
|
||||
// unusableLabels are labels that are added before being referenced in a
|
||||
// jump. Any labels added this way cannot be referenced later in order to
|
||||
// avoid backwards references.
|
||||
@@ -46,8 +49,9 @@ type ProgramBuilder struct {
|
||||
// NewProgramBuilder creates a new ProgramBuilder instance.
|
||||
func NewProgramBuilder() *ProgramBuilder {
|
||||
return &ProgramBuilder{
|
||||
labels: map[string]*label{},
|
||||
unusableLabels: map[string]bool{},
|
||||
labels: map[string]*label{},
|
||||
jumpSourceToLabel: map[source]string{},
|
||||
unusableLabels: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,8 +79,7 @@ type source struct {
|
||||
// Program line where the label reference is present.
|
||||
line int
|
||||
|
||||
// True if label reference is in the 'jump if true' part of the jump.
|
||||
// False if label reference is in the 'jump if false' part of the jump.
|
||||
// Which type of jump is referencing this label.
|
||||
jt JumpType
|
||||
}
|
||||
|
||||
@@ -151,7 +154,12 @@ func (b *ProgramBuilder) addLabelSource(labelName string, t JumpType) {
|
||||
l = &label{sources: make([]source, 0), target: -1}
|
||||
b.labels[labelName] = l
|
||||
}
|
||||
l.sources = append(l.sources, source{line: len(b.instructions), jt: t})
|
||||
src := source{line: len(b.instructions), jt: t}
|
||||
l.sources = append(l.sources, src)
|
||||
if existingLabel, found := b.jumpSourceToLabel[src]; found {
|
||||
panic(fmt.Sprintf("label %q already present at source %v; one source may only have one label", existingLabel, src))
|
||||
}
|
||||
b.jumpSourceToLabel[src] = labelName
|
||||
}
|
||||
|
||||
func (b *ProgramBuilder) resolveLabels() error {
|
||||
@@ -342,21 +350,15 @@ func (f ProgramFragment) Outcomes() FragmentOutcomes {
|
||||
}
|
||||
case Jmp:
|
||||
for _, offset := range ins.JumpOffsets() {
|
||||
var foundLabelName string
|
||||
var foundLabel *label
|
||||
for labelName, label := range f.b.labels {
|
||||
for _, s := range label.sources {
|
||||
if s.jt == offset.Type && s.line == pc {
|
||||
foundLabelName = labelName
|
||||
foundLabel = label
|
||||
break
|
||||
}
|
||||
foundLabelName, found := f.b.jumpSourceToLabel[source{line: pc, jt: offset.Type}]
|
||||
if found {
|
||||
foundLabel = f.b.labels[foundLabelName]
|
||||
if foundLabel.target == -1 {
|
||||
outcomes.MayJumpToUnresolvedLabels[foundLabelName] = struct{}{}
|
||||
continue
|
||||
}
|
||||
}
|
||||
if foundLabel != nil && foundLabel.target == -1 {
|
||||
outcomes.MayJumpToUnresolvedLabels[foundLabelName] = struct{}{}
|
||||
continue
|
||||
}
|
||||
var target int
|
||||
if foundLabel != nil {
|
||||
target = foundLabel.target
|
||||
|
||||
Reference in New Issue
Block a user