From 2a054d76ae167e7c2a6b4bfb1cf51770f93d394a Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 7 Aug 2023 10:57:02 -0400 Subject: [PATCH 1/2] btf: avoid multiple vector allocations Rather than creating an empty vector and iteratively appending - which might induce intermediate allocations - create an ExactSizeIterator and collect it into a vector, which should produce exactly one allocation. --- aya-obj/src/btf/types.rs | 286 ++++++++++++++++++++++++++++----------- 1 file changed, 204 insertions(+), 82 deletions(-) diff --git a/aya-obj/src/btf/types.rs b/aya-obj/src/btf/types.rs index 84497ec8..37f547ca 100644 --- a/aya-obj/src/btf/types.rs +++ b/aya-obj/src/btf/types.rs @@ -342,12 +342,19 @@ pub struct Int { impl Int { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.size)); - buf.extend(bytes_of::(&self.data)); - buf + let Self { + name_offset, + info, + size, + data, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(size), + bytes_of::(data), + ] + .concat() } pub(crate) fn kind(&self) -> BtfKind { @@ -404,15 +411,24 @@ pub struct Enum { impl Enum { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.size)); - for v in &self.variants { - buf.extend(bytes_of::(&v.name_offset)); - buf.extend(bytes_of::(&v.value)); - } - buf + let Self { + name_offset, + info, + size, + variants, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(size), + ] + .into_iter() + .chain(variants.iter().flat_map(|BtfEnum { name_offset, value }| { + [bytes_of::(name_offset), bytes_of::(value)] + })) + .flatten() + .copied() + .collect() } pub(crate) fn kind(&self) -> BtfKind { @@ -458,16 +474,34 @@ pub struct Enum64 { impl Enum64 { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.size)); - for v in &self.variants { - buf.extend(bytes_of::(&v.name_offset)); - buf.extend(bytes_of::(&v.value_high)); - buf.extend(bytes_of::(&v.value_low)); - } - buf + let Self { + name_offset, + info, + size, + variants, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(size), + ] + .into_iter() + .chain(variants.iter().flat_map( + |BtfEnum64 { + name_offset, + value_low, + value_high, + }| { + [ + bytes_of::(name_offset), + bytes_of::(value_low), + bytes_of::(value_high), + ] + }, + )) + .flatten() + .copied() + .collect() } pub(crate) fn kind(&self) -> BtfKind { @@ -502,16 +536,34 @@ pub struct Struct { impl Struct { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.size)); - for v in &self.members { - buf.extend(bytes_of::(&v.name_offset)); - buf.extend(bytes_of::(&v.btf_type)); - buf.extend(bytes_of::(&v.offset)); - } - buf + let Self { + name_offset, + info, + size, + members, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(size), + ] + .into_iter() + .chain(members.iter().flat_map( + |BtfMember { + name_offset, + btf_type, + offset, + }| { + [ + bytes_of::(name_offset), + bytes_of::(btf_type), + bytes_of::(offset), + ] + }, + )) + .flatten() + .copied() + .collect() } pub(crate) fn kind(&self) -> BtfKind { @@ -563,16 +615,34 @@ pub struct Union { impl Union { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.size)); - for v in &self.members { - buf.extend(bytes_of::(&v.name_offset)); - buf.extend(bytes_of::(&v.btf_type)); - buf.extend(bytes_of::(&v.offset)); - } - buf + let Self { + name_offset, + info, + size, + members, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(size), + ] + .into_iter() + .chain(members.iter().flat_map( + |BtfMember { + name_offset, + btf_type, + offset, + }| { + [ + bytes_of::(name_offset), + bytes_of::(btf_type), + bytes_of::(offset), + ] + }, + )) + .flatten() + .copied() + .collect() } pub(crate) fn kind(&self) -> BtfKind { @@ -609,6 +679,7 @@ pub(crate) struct BtfArray { pub(crate) index_type: u32, pub(crate) len: u32, } + #[repr(C)] #[derive(Clone, Debug)] pub struct Array { @@ -620,12 +691,19 @@ pub struct Array { impl Array { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self._unused)); - buf.extend(bytes_of::(&self.array)); - buf + let Self { + name_offset, + info, + _unused, + array, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(_unused), + bytes_of::(array), + ] + .concat() } pub(crate) fn kind(&self) -> BtfKind { @@ -670,15 +748,27 @@ pub struct FuncProto { impl FuncProto { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.return_type)); - for p in &self.params { - buf.extend(bytes_of::(&p.name_offset)); - buf.extend(bytes_of::(&p.btf_type)); - } - buf + let Self { + name_offset, + info, + return_type, + params, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(return_type), + ] + .into_iter() + .chain(params.iter().flat_map( + |BtfParam { + name_offset, + btf_type, + }| { [bytes_of::(name_offset), bytes_of::(btf_type)] }, + )) + .flatten() + .copied() + .collect() } pub(crate) fn kind(&self) -> BtfKind { @@ -732,12 +822,19 @@ pub struct Var { impl Var { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.btf_type)); - buf.extend(bytes_of::(&self.linkage)); - buf + let Self { + name_offset, + info, + btf_type, + linkage, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(btf_type), + bytes_of::(linkage), + ] + .concat() } pub(crate) fn kind(&self) -> BtfKind { @@ -778,16 +875,34 @@ pub struct DataSec { impl DataSec { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.size)); - for e in &self.entries { - buf.extend(bytes_of::(&e.btf_type)); - buf.extend(bytes_of::(&e.offset)); - buf.extend(bytes_of::(&e.size)); - } - buf + let Self { + name_offset, + info, + size, + entries, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(size), + ] + .into_iter() + .chain(entries.iter().flat_map( + |DataSecEntry { + btf_type, + offset, + size, + }| { + [ + bytes_of::(btf_type), + bytes_of::(offset), + bytes_of::(size), + ] + }, + )) + .flatten() + .copied() + .collect() } pub(crate) fn kind(&self) -> BtfKind { @@ -821,12 +936,19 @@ pub struct DeclTag { impl DeclTag { pub(crate) fn to_bytes(&self) -> Vec { - let mut buf = vec![]; - buf.extend(bytes_of::(&self.name_offset)); - buf.extend(bytes_of::(&self.info)); - buf.extend(bytes_of::(&self.btf_type)); - buf.extend(bytes_of::(&self.component_index)); - buf + let Self { + name_offset, + info, + btf_type, + component_index, + } = self; + [ + bytes_of::(name_offset), + bytes_of::(info), + bytes_of::(btf_type), + bytes_of::(component_index), + ] + .concat() } pub(crate) fn kind(&self) -> BtfKind { From 826e0e5050e9bf9e0cdff6d2a20c1169820d0e57 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Mon, 7 Aug 2023 10:59:44 -0400 Subject: [PATCH 2/2] btf: use Self instead of restating the type --- aya-obj/src/btf/types.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/aya-obj/src/btf/types.rs b/aya-obj/src/btf/types.rs index 37f547ca..a910b126 100644 --- a/aya-obj/src/btf/types.rs +++ b/aya-obj/src/btf/types.rs @@ -76,7 +76,7 @@ impl Const { pub(crate) fn new(btf_type: u32) -> Self { let info = (BtfKind::Const as u32) << 24; - Const { + Self { name_offset: 0, info, btf_type, @@ -150,7 +150,7 @@ impl Ptr { pub fn new(name_offset: u32, btf_type: u32) -> Self { let info = (BtfKind::Ptr as u32) << 24; - Ptr { + Self { name_offset, info, btf_type, @@ -181,7 +181,7 @@ impl Typedef { pub(crate) fn new(name_offset: u32, btf_type: u32) -> Self { let info = (BtfKind::Typedef as u32) << 24; - Typedef { + Self { name_offset, info, btf_type, @@ -211,7 +211,7 @@ impl Float { pub fn new(name_offset: u32, size: u32) -> Self { let info = (BtfKind::Float as u32) << 24; - Float { + Self { name_offset, info, size, @@ -262,7 +262,7 @@ impl Func { pub fn new(name_offset: u32, proto: u32, linkage: FuncLinkage) -> Self { let mut info = (BtfKind::Func as u32) << 24; info |= (linkage as u32) & 0xFFFF; - Func { + Self { name_offset, info, btf_type: proto, @@ -301,7 +301,7 @@ impl TypeTag { pub fn new(name_offset: u32, btf_type: u32) -> Self { let info = (BtfKind::TypeTag as u32) << 24; - TypeTag { + Self { name_offset, info, btf_type, @@ -370,7 +370,7 @@ impl Int { data |= (encoding as u32 & 0x0f) << 24; data |= (offset & 0xff) << 16; data |= (size * 8) & 0xff; - Int { + Self { name_offset, info, size, @@ -442,7 +442,7 @@ impl Enum { pub fn new(name_offset: u32, variants: Vec) -> Self { let mut info = (BtfKind::Enum as u32) << 24; info |= (variants.len() as u32) & 0xFFFF; - Enum { + Self { name_offset, info, size: 4, @@ -577,7 +577,7 @@ impl Struct { pub(crate) fn new(name_offset: u32, members: Vec, size: u32) -> Self { let mut info = (BtfKind::Struct as u32) << 24; info |= (members.len() as u32) & 0xFFFF; - Struct { + Self { name_offset, info, size, @@ -717,7 +717,7 @@ impl Array { #[cfg(test)] pub(crate) fn new(name_offset: u32, element_type: u32, index_type: u32, len: u32) -> Self { let info = (BtfKind::Array as u32) << 24; - Array { + Self { name_offset, info, _unused: 0, @@ -782,7 +782,7 @@ impl FuncProto { pub fn new(params: Vec, return_type: u32) -> Self { let mut info = (BtfKind::FuncProto as u32) << 24; info |= (params.len() as u32) & 0xFFFF; - FuncProto { + Self { name_offset: 0, info, return_type, @@ -847,7 +847,7 @@ impl Var { pub fn new(name_offset: u32, btf_type: u32, linkage: VarLinkage) -> Self { let info = (BtfKind::Var as u32) << 24; - Var { + Self { name_offset, info, btf_type, @@ -916,7 +916,7 @@ impl DataSec { pub fn new(name_offset: u32, entries: Vec, size: u32) -> Self { let mut info = (BtfKind::DataSec as u32) << 24; info |= (entries.len() as u32) & 0xFFFF; - DataSec { + Self { name_offset, info, size, @@ -961,7 +961,7 @@ impl DeclTag { pub fn new(name_offset: u32, btf_type: u32, component_index: i32) -> Self { let info = (BtfKind::DeclTag as u32) << 24; - DeclTag { + Self { name_offset, info, btf_type,