Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

avoid clones when making an Artifact from a Compilation #140

Merged
merged 2 commits into from
Sep 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions lib/compiler-singlepass/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,14 @@ impl Compiler for SinglepassCompiler {
.collect::<PrimaryMap<FunctionIndex, FunctionBody>>()
});

Ok(Compilation::new(
Ok(Compilation {
functions,
import_trampolines,
custom_sections: import_trampolines,
function_call_trampolines,
dynamic_function_trampolines,
None,
None,
))
debug: None,
trampolines: None,
})
}
}

Expand Down
136 changes: 6 additions & 130 deletions lib/compiler/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ impl TrampolinesSection {
#[derive(Debug, PartialEq, Eq)]
pub struct Compilation {
/// Compiled code for the function bodies.
functions: Functions,
pub functions: Functions,

/// Custom sections for the module.
/// It will hold the data, for example, for constants used in a
/// function, global variables, rodata_64, hot/cold function partitioning, ...
custom_sections: CustomSections,
pub custom_sections: CustomSections,

/// Trampolines to call a function defined locally in the wasm via a
/// provided `Vec` of values.
Expand All @@ -157,7 +157,7 @@ pub struct Compilation {
/// let func = instance.exports.get_function("my_func");
/// func.call(&[Value::I32(1)]);
/// ```
function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,
pub function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,

/// Trampolines to call a dynamic function defined in
/// a host, from a Wasm module.
Expand All @@ -178,135 +178,11 @@ pub struct Compilation {
/// ```
///
/// Note: Dynamic function trampolines are only compiled for imported function types.
dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,
pub dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,

/// Section ids corresponding to the Dwarf debug info
debug: Option<Dwarf>,
pub debug: Option<Dwarf>,

/// Trampolines for the arch that needs it
trampolines: Option<TrampolinesSection>,
}

impl Compilation {
/// Creates a compilation artifact from a contiguous function buffer and a set of ranges
pub fn new(
functions: Functions,
custom_sections: CustomSections,
function_call_trampolines: PrimaryMap<SignatureIndex, FunctionBody>,
dynamic_function_trampolines: PrimaryMap<FunctionIndex, FunctionBody>,
debug: Option<Dwarf>,
trampolines: Option<TrampolinesSection>,
) -> Self {
Self {
functions,
custom_sections,
function_call_trampolines,
dynamic_function_trampolines,
debug,
trampolines,
}
}

/// Gets the bytes of a single function
pub fn get(&self, func: LocalFunctionIndex) -> &CompiledFunction {
&self.functions[func]
}

/// Gets the number of functions defined.
pub fn len(&self) -> usize {
self.functions.len()
}

/// Returns whether there are no functions defined.
pub fn is_empty(&self) -> bool {
self.functions.is_empty()
}

/// Gets functions relocations.
pub fn get_relocations(&self) -> PrimaryMap<LocalFunctionIndex, Vec<Relocation>> {
self.functions
.iter()
.map(|(_, func)| func.relocations.clone())
.collect::<PrimaryMap<LocalFunctionIndex, _>>()
}

/// Gets functions bodies.
pub fn get_function_bodies(&self) -> PrimaryMap<LocalFunctionIndex, FunctionBody> {
self.functions
.iter()
.map(|(_, func)| func.body.clone())
.collect::<PrimaryMap<LocalFunctionIndex, _>>()
}

/// Gets functions jump table offsets.
pub fn get_jt_offsets(&self) -> PrimaryMap<LocalFunctionIndex, JumpTableOffsets> {
self.functions
.iter()
.map(|(_, func)| func.jt_offsets.clone())
.collect::<PrimaryMap<LocalFunctionIndex, _>>()
}

/// Gets functions frame info.
pub fn get_frame_info(&self) -> PrimaryMap<LocalFunctionIndex, CompiledFunctionFrameInfo> {
self.functions
.iter()
.map(|(_, func)| func.frame_info.clone())
.collect::<PrimaryMap<LocalFunctionIndex, _>>()
}

/// Gets function call trampolines.
pub fn get_function_call_trampolines(&self) -> PrimaryMap<SignatureIndex, FunctionBody> {
self.function_call_trampolines.clone()
}

/// Gets function call trampolines.
pub fn get_dynamic_function_trampolines(&self) -> PrimaryMap<FunctionIndex, FunctionBody> {
self.dynamic_function_trampolines.clone()
}

/// Gets custom section data.
pub fn get_custom_sections(&self) -> PrimaryMap<SectionIndex, CustomSection> {
self.custom_sections.clone()
}

/// Gets relocations that apply to custom sections.
pub fn get_custom_section_relocations(&self) -> PrimaryMap<SectionIndex, Vec<Relocation>> {
self.custom_sections
.iter()
.map(|(_, section)| section.relocations.clone())
.collect::<PrimaryMap<SectionIndex, _>>()
}

/// Returns the Dwarf info.
pub fn get_debug(&self) -> Option<Dwarf> {
self.debug.clone()
}

/// Returns the Trampolines info.
pub fn get_trampolines(&self) -> Option<TrampolinesSection> {
self.trampolines.clone()
}
}

impl<'a> IntoIterator for &'a Compilation {
type IntoIter = Iter<'a>;
type Item = <Self::IntoIter as Iterator>::Item;

fn into_iter(self) -> Self::IntoIter {
Iter {
iterator: self.functions.iter(),
}
}
}

pub struct Iter<'a> {
iterator: <&'a Functions as IntoIterator>::IntoIter,
}

impl<'a> Iterator for Iter<'a> {
type Item = &'a CompiledFunction;

fn next(&mut self) -> Option<Self::Item> {
self.iterator.next().map(|(_, b)| b)
}
pub trampolines: Option<TrampolinesSection>,
}
43 changes: 30 additions & 13 deletions lib/engine-universal/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,14 @@ impl UniversalEngine {
memory_styles,
table_styles,
};
let compilation = compiler.compile_module(
let wasmer_compiler::Compilation {
functions,
custom_sections,
function_call_trampolines,
dynamic_function_trampolines,
debug,
trampolines,
} = compiler.compile_module(
&self.target(),
&compile_info,
// SAFETY: Calling `unwrap` is correct since
Expand All @@ -130,26 +137,36 @@ impl UniversalEngine {
translation.module_translation_state.as_ref().unwrap(),
translation.function_body_inputs,
)?;
let function_call_trampolines = compilation.get_function_call_trampolines();
let dynamic_function_trampolines = compilation.get_dynamic_function_trampolines();
let data_initializers = translation
.data_initializers
.iter()
.map(wasmer_types::OwnedDataInitializer::new)
.collect();

let frame_infos = compilation.get_frame_info();
let mut function_frame_info = PrimaryMap::with_capacity(functions.len());
let mut function_bodies = PrimaryMap::with_capacity(functions.len());
let mut function_relocations = PrimaryMap::with_capacity(functions.len());
let mut function_jt_offsets = PrimaryMap::with_capacity(functions.len());
for (_, func) in functions.into_iter() {
function_bodies.push(func.body);
function_relocations.push(func.relocations);
function_jt_offsets.push(func.jt_offsets);
function_frame_info.push(func.frame_info);
}
let custom_section_relocations = custom_sections
.iter()
.map(|(_, section)| section.relocations.clone())
.collect::<PrimaryMap<SectionIndex, _>>();
Ok(crate::UniversalExecutable {
function_bodies: compilation.get_function_bodies(),
function_relocations: compilation.get_relocations(),
function_jt_offsets: compilation.get_jt_offsets(),
function_frame_info: frame_infos,
function_bodies,
function_relocations,
function_jt_offsets,
function_frame_info,
function_call_trampolines,
dynamic_function_trampolines,
custom_sections: compilation.get_custom_sections(),
custom_section_relocations: compilation.get_custom_section_relocations(),
debug: compilation.get_debug(),
trampolines: compilation.get_trampolines(),
custom_sections,
custom_section_relocations,
debug,
trampolines,
compile_info,
data_initializers,
cpu_features: self.target().cpu_features().as_u64(),
Expand Down