Skip to content

Commit 1ce2d3c

Browse files
bjorn3afonso360
authored andcommitted
Allow serializing all cranelift-module data structures (bytecodealliance#6172)
* Remove ModuleCompiledFunction The same information can be retrieved using ctx.compiled_code().unwrap().code_info().total_size In addition for Module implementations that don't immediately compile the given function there is no correct value that can be returned. * Don't give anonymous functions and data objects an internal name This internal name can conflict if a module is serialized and then deserialized into another module. It also wasn't used by any of the Module implementations anyway. * Allow serializing all cranelift-module data structures This allows a Module implementation to serialize it's internal state and deserialize it in another compilation session. For example to implement LTO or to load the module into cranelift-interpreter. * Use expect
1 parent c8fcf23 commit 1ce2d3c

File tree

8 files changed

+359
-100
lines changed

8 files changed

+359
-100
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cranelift/codegen/src/ir/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use super::{RelSourceLoc, SourceLoc, UserExternalName};
3131

3232
/// A version marker used to ensure that serialized clif ir is never deserialized with a
3333
/// different version of Cranelift.
34-
#[derive(Copy, Clone, Debug, PartialEq, Hash)]
34+
#[derive(Default, Copy, Clone, Debug, PartialEq, Hash)]
3535
pub struct VersionMarker;
3636

3737
#[cfg(feature = "enable-serde")]

cranelift/jit/src/backend.rs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
//! Defines `JITModule`.
22
33
use crate::{compiled_blob::CompiledBlob, memory::BranchProtection, memory::Memory};
4+
use cranelift_codegen::binemit::Reloc;
45
use cranelift_codegen::isa::{OwnedTargetIsa, TargetIsa};
56
use cranelift_codegen::settings::Configurable;
67
use cranelift_codegen::{self, ir, settings, MachReloc};
7-
use cranelift_codegen::{binemit::Reloc, CodegenError};
88
use cranelift_control::ControlPlane;
99
use cranelift_entity::SecondaryMap;
1010
use cranelift_module::{
11-
DataDescription, DataId, FuncId, Init, Linkage, Module, ModuleCompiledFunction,
12-
ModuleDeclarations, ModuleError, ModuleExtName, ModuleReloc, ModuleResult,
11+
DataDescription, DataId, FuncId, Init, Linkage, Module, ModuleDeclarations, ModuleError,
12+
ModuleExtName, ModuleReloc, ModuleResult,
1313
};
1414
use log::info;
1515
use std::cell::RefCell;
@@ -272,7 +272,10 @@ impl JITModule {
272272
self.record_function_for_perf(
273273
plt_entry.as_ptr().cast(),
274274
std::mem::size_of::<[u8; 16]>(),
275-
&format!("{}@plt", self.declarations.get_function_decl(id).name),
275+
&format!(
276+
"{}@plt",
277+
self.declarations.get_function_decl(id).linkage_name(id)
278+
),
276279
);
277280
self.function_plt_entries[id] = Some(plt_entry);
278281
}
@@ -323,6 +326,9 @@ impl JITModule {
323326
}
324327
}
325328
};
329+
let name = name
330+
.as_ref()
331+
.expect("anonymous symbol must be defined locally");
326332
if let Some(ptr) = self.lookup_symbol(name) {
327333
ptr
328334
} else if linkage == Linkage::Preemptible {
@@ -554,13 +560,15 @@ impl JITModule {
554560
assert!(self.hotswap_enabled, "Hotswap support is not enabled");
555561
let decl = self.declarations.get_function_decl(func_id);
556562
if !decl.linkage.is_definable() {
557-
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
563+
return Err(ModuleError::InvalidImportDefinition(
564+
decl.linkage_name(func_id).into_owned(),
565+
));
558566
}
559567

560568
if self.compiled_functions[func_id].is_none() {
561569
return Err(ModuleError::Backend(anyhow::anyhow!(
562570
"Tried to redefine not yet defined function {}",
563-
decl.name
571+
decl.linkage_name(func_id),
564572
)));
565573
}
566574

@@ -647,15 +655,19 @@ impl Module for JITModule {
647655
id: FuncId,
648656
ctx: &mut cranelift_codegen::Context,
649657
ctrl_plane: &mut ControlPlane,
650-
) -> ModuleResult<ModuleCompiledFunction> {
658+
) -> ModuleResult<()> {
651659
info!("defining function {}: {}", id, ctx.func.display());
652660
let decl = self.declarations.get_function_decl(id);
653661
if !decl.linkage.is_definable() {
654-
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
662+
return Err(ModuleError::InvalidImportDefinition(
663+
decl.linkage_name(id).into_owned(),
664+
));
655665
}
656666

657667
if !self.compiled_functions[id].is_none() {
658-
return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
668+
return Err(ModuleError::DuplicateDefinition(
669+
decl.linkage_name(id).into_owned(),
670+
));
659671
}
660672

661673
if self.hotswap_enabled {
@@ -678,9 +690,7 @@ impl Module for JITModule {
678690
let alignment = res.alignment as u64;
679691
let compiled_code = ctx.compiled_code().unwrap();
680692

681-
let code_size = compiled_code.code_info().total_size;
682-
683-
let size = code_size as usize;
693+
let size = compiled_code.code_info().total_size as usize;
684694
let align = alignment
685695
.max(self.isa.function_alignment() as u64)
686696
.max(self.isa.symbol_alignment());
@@ -705,7 +715,7 @@ impl Module for JITModule {
705715
.map(|reloc| ModuleReloc::from_mach_reloc(reloc, &ctx.func))
706716
.collect();
707717

708-
self.record_function_for_perf(ptr, size, &decl.name);
718+
self.record_function_for_perf(ptr, size, &decl.linkage_name(id));
709719
self.compiled_functions[id] = Some(CompiledBlob { ptr, size, relocs });
710720

711721
if self.isa.flags().is_pic() {
@@ -739,7 +749,7 @@ impl Module for JITModule {
739749
self.functions_to_finalize.push(id);
740750
}
741751

742-
Ok(ModuleCompiledFunction { size: code_size })
752+
Ok(())
743753
}
744754

745755
fn define_function_bytes(
@@ -749,20 +759,19 @@ impl Module for JITModule {
749759
alignment: u64,
750760
bytes: &[u8],
751761
relocs: &[MachReloc],
752-
) -> ModuleResult<ModuleCompiledFunction> {
762+
) -> ModuleResult<()> {
753763
info!("defining function {} with bytes", id);
754-
let total_size: u32 = match bytes.len().try_into() {
755-
Ok(total_size) => total_size,
756-
_ => Err(CodegenError::CodeTooLarge)?,
757-
};
758-
759764
let decl = self.declarations.get_function_decl(id);
760765
if !decl.linkage.is_definable() {
761-
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
766+
return Err(ModuleError::InvalidImportDefinition(
767+
decl.linkage_name(id).into_owned(),
768+
));
762769
}
763770

764771
if !self.compiled_functions[id].is_none() {
765-
return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
772+
return Err(ModuleError::DuplicateDefinition(
773+
decl.linkage_name(id).into_owned(),
774+
));
766775
}
767776

768777
let size = bytes.len();
@@ -782,7 +791,7 @@ impl Module for JITModule {
782791
ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, size);
783792
}
784793

785-
self.record_function_for_perf(ptr, size, &decl.name);
794+
self.record_function_for_perf(ptr, size, &decl.linkage_name(id));
786795
self.compiled_functions[id] = Some(CompiledBlob {
787796
ptr,
788797
size,
@@ -812,17 +821,21 @@ impl Module for JITModule {
812821
self.functions_to_finalize.push(id);
813822
}
814823

815-
Ok(ModuleCompiledFunction { size: total_size })
824+
Ok(())
816825
}
817826

818827
fn define_data(&mut self, id: DataId, data: &DataDescription) -> ModuleResult<()> {
819828
let decl = self.declarations.get_data_decl(id);
820829
if !decl.linkage.is_definable() {
821-
return Err(ModuleError::InvalidImportDefinition(decl.name.clone()));
830+
return Err(ModuleError::InvalidImportDefinition(
831+
decl.linkage_name(id).into_owned(),
832+
));
822833
}
823834

824835
if !self.compiled_data_objects[id].is_none() {
825-
return Err(ModuleError::DuplicateDefinition(decl.name.to_owned()));
836+
return Err(ModuleError::DuplicateDefinition(
837+
decl.linkage_name(id).into_owned(),
838+
));
826839
}
827840

828841
assert!(!decl.tls, "JIT doesn't yet support TLS");

cranelift/module/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ cranelift-codegen = { workspace = true }
1515
cranelift-control = { workspace = true }
1616
hashbrown = { workspace = true, optional = true }
1717
anyhow = { workspace = true }
18+
serde = { version = "1.0.94", features = ["derive"], optional = true }
1819

1920
[features]
2021
default = ["std"]
2122
std = ["cranelift-codegen/std"]
2223
core = ["hashbrown", "cranelift-codegen/core"]
2324

25+
# For dependent crates that want to serialize some parts of cranelift
26+
enable-serde = ["serde", "cranelift-codegen/enable-serde"]
27+
2428
[badges]
2529
maintenance = { status = "experimental" }

cranelift/module/src/data_context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::ModuleExtName;
1313

1414
/// This specifies how data is to be initialized.
1515
#[derive(Clone, PartialEq, Eq, Debug)]
16+
#[cfg_attr(feature = "enable-serde", derive(serde::Serialize, serde::Deserialize))]
1617
pub enum Init {
1718
/// This indicates that no initialization has been specified yet.
1819
Uninitialized,
@@ -41,6 +42,7 @@ impl Init {
4142

4243
/// A description of a data object.
4344
#[derive(Clone, Debug)]
45+
#[cfg_attr(feature = "enable-serde", derive(serde::Serialize, serde::Deserialize))]
4446
pub struct DataDescription {
4547
/// How the data should be initialized.
4648
pub init: Init,

cranelift/module/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ mod traps;
4343
pub use crate::data_context::{DataDescription, Init};
4444
pub use crate::module::{
4545
DataDeclaration, DataId, FuncId, FuncOrDataId, FunctionDeclaration, Linkage, Module,
46-
ModuleCompiledFunction, ModuleDeclarations, ModuleError, ModuleExtName, ModuleReloc,
47-
ModuleResult,
46+
ModuleDeclarations, ModuleError, ModuleExtName, ModuleReloc, ModuleResult,
4847
};
4948
pub use crate::traps::TrapSite;
5049

0 commit comments

Comments
 (0)