From f8ddcbf52702ce133ee2d2f4507e1675e169f5de Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 18 Aug 2022 15:10:11 +0300 Subject: [PATCH] Refactor Artifact enum into a struct Closes #3063 Refactor Artifact type from enum to struct #3063 https://github.com/wasmerio/wasmer/issues/3063 --- lib/compiler/src/engine/artifact.rs | 178 +++++++++------------------ lib/types/src/compilation/section.rs | 6 + lib/types/src/serialize.rs | 2 +- 3 files changed, 65 insertions(+), 121 deletions(-) diff --git a/lib/compiler/src/engine/artifact.rs b/lib/compiler/src/engine/artifact.rs index 7358347b851..06abb5d7898 100644 --- a/lib/compiler/src/engine/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -21,9 +21,10 @@ use std::sync::Mutex; #[cfg(feature = "static-artifact-create")] use wasmer_object::{emit_compilation, emit_data, get_object_for_target, Object}; #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] -use wasmer_types::compilation::symbols::{ModuleMetadata, ModuleMetadataSymbolRegistry}; +use wasmer_types::compilation::symbols::ModuleMetadata; use wasmer_types::entity::{BoxedSlice, PrimaryMap}; use wasmer_types::MetadataHeader; +use wasmer_types::SerializableCompilation; use wasmer_types::{ CompileError, CpuFeature, DataInitializer, DeserializeError, FunctionIndex, LocalFunctionIndex, MemoryIndex, ModuleInfo, OwnedDataInitializer, SerializableModule, SerializeError, @@ -35,44 +36,20 @@ use wasmer_vm::{FunctionBodyPtr, MemoryStyle, TableStyle, VMSharedSignatureIndex use wasmer_vm::{InstanceAllocator, InstanceHandle, StoreObjects, TrapHandlerFn, VMExtern}; /// A compiled wasm module, ready to be instantiated. -pub enum Artifact { - /// The default artifact format. - Universal(UniversalArtifact), - /// Stores functions etc as symbols and data meant to be stored in object files and - /// executables. - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Static(StaticArtifact), -} - -/// The default artifact format. -pub struct UniversalArtifact { +pub struct Artifact { artifact: ArtifactBuild, finished_functions: BoxedSlice, finished_function_call_trampolines: BoxedSlice, finished_dynamic_function_trampolines: BoxedSlice, signatures: BoxedSlice, - frame_info_registration: Mutex>, + /// Some(_) only if this is not a deserialized static artifact + frame_info_registration: Option>>, finished_function_lengths: BoxedSlice, } #[cfg(feature = "static-artifact-create")] pub type PrefixerFn = Box String + Send>; -/// Stores functions etc as symbols and data meant to be stored in object files and -/// executables. -#[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] -pub struct StaticArtifact { - metadata: ModuleMetadata, - _module_bytes: Vec, - finished_functions: BoxedSlice, - finished_function_call_trampolines: BoxedSlice, - finished_dynamic_function_trampolines: BoxedSlice, - signatures: BoxedSlice, - // Length of the serialized metadata - _metadata_length: usize, - _symbol_registry: ModuleMetadataSymbolRegistry, -} - #[cfg(feature = "static-artifact-create")] const WASMER_METADATA_SYMBOL: &[u8] = b"WASMER_METADATA"; @@ -220,15 +197,15 @@ impl Artifact { finished_dynamic_function_trampolines.into_boxed_slice(); let signatures = signatures.into_boxed_slice(); - Ok(Self::Universal(UniversalArtifact { + Ok(Artifact { artifact, finished_functions, finished_function_call_trampolines, finished_dynamic_function_trampolines, signatures, - frame_info_registration: Mutex::new(None), + frame_info_registration: Some(Mutex::new(None)), finished_function_lengths, - })) + }) } /// Check if the provided bytes look like a serialized `ArtifactBuild`. @@ -239,59 +216,31 @@ impl Artifact { impl ArtifactCreate for Artifact { fn create_module_info(&self) -> ModuleInfo { - match self { - Self::Universal(UniversalArtifact { artifact, .. }) => artifact.create_module_info(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(StaticArtifact { metadata, .. }) => metadata.compile_info.module.clone(), - } + self.artifact.create_module_info() } fn features(&self) -> &Features { - match self { - Self::Universal(UniversalArtifact { artifact, .. }) => artifact.features(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(StaticArtifact { metadata, .. }) => &metadata.compile_info.features, - } + self.artifact.features() } fn cpu_features(&self) -> EnumSet { - match self { - Self::Universal(_self) => _self.artifact.cpu_features(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => EnumSet::from_u64(_self.metadata.cpu_features), - } + self.artifact.cpu_features() } fn data_initializers(&self) -> &[OwnedDataInitializer] { - match self { - Self::Universal(_self) => _self.artifact.data_initializers(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => &_self.metadata.data_initializers, - } + self.artifact.data_initializers() } fn memory_styles(&self) -> &PrimaryMap { - match self { - Self::Universal(_self) => _self.artifact.memory_styles(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => &_self.metadata.compile_info.memory_styles, - } + self.artifact.memory_styles() } fn table_styles(&self) -> &PrimaryMap { - match self { - Self::Universal(UniversalArtifact { artifact, .. }) => artifact.table_styles(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(StaticArtifact { metadata, .. }) => &metadata.compile_info.table_styles, - } + self.artifact.table_styles() } fn serialize(&self) -> Result, SerializeError> { - match self { - Self::Universal(UniversalArtifact { artifact, .. }) => artifact.serialize(), - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(StaticArtifact { .. }) => todo!(), - } + self.artifact.serialize() } } @@ -300,55 +249,41 @@ impl Artifact { /// /// This is required to ensure that any traps can be properly symbolicated. pub fn register_frame_info(&self) { - match self { - Self::Universal(_self) => { - let mut info = _self.frame_info_registration.lock().unwrap(); + if let Some(frame_info_registration) = self.frame_info_registration.as_ref() { + let mut info = frame_info_registration.lock().unwrap(); - if info.is_some() { - return; - } - - let finished_function_extents = _self - .finished_functions - .values() - .copied() - .zip(_self.finished_function_lengths.values().copied()) - .map(|(ptr, length)| FunctionExtent { ptr, length }) - .collect::>() - .into_boxed_slice(); - - let frame_infos = _self.artifact.get_frame_info_ref(); - *info = register_frame_info( - _self.artifact.create_module_info(), - &finished_function_extents, - frame_infos.clone(), - ); - } - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => { - // Do nothing for static artifact + if info.is_some() { + return; } + + let finished_function_extents = self + .finished_functions + .values() + .copied() + .zip(self.finished_function_lengths.values().copied()) + .map(|(ptr, length)| FunctionExtent { ptr, length }) + .collect::>() + .into_boxed_slice(); + + let frame_infos = self.artifact.get_frame_info_ref(); + *info = register_frame_info( + self.artifact.create_module_info(), + &finished_function_extents, + frame_infos.clone(), + ); } } /// Returns the functions allocated in memory or this `Artifact` /// ready to be run. pub fn finished_functions(&self) -> &BoxedSlice { - match self { - Self::Universal(_self) => &_self.finished_functions, - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => &_self.finished_functions, - } + &self.finished_functions } /// Returns the function call trampolines allocated in memory of this /// `Artifact`, ready to be run. pub fn finished_function_call_trampolines(&self) -> &BoxedSlice { - match self { - Self::Universal(_self) => &_self.finished_function_call_trampolines, - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => &_self.finished_function_call_trampolines, - } + &self.finished_function_call_trampolines } /// Returns the dynamic function trampolines allocated in memory @@ -356,20 +291,12 @@ impl Artifact { pub fn finished_dynamic_function_trampolines( &self, ) -> &BoxedSlice { - match self { - Self::Universal(_self) => &_self.finished_dynamic_function_trampolines, - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => &_self.finished_dynamic_function_trampolines, - } + &self.finished_dynamic_function_trampolines } /// Returns the associated VM signatures for this `Artifact`. pub fn signatures(&self) -> &BoxedSlice { - match self { - Self::Universal(_self) => &_self.signatures, - #[cfg(any(feature = "static-artifact-create", feature = "static-artifact-load"))] - Self::Static(_self) => &_self.signatures, - } + &self.signatures } /// Do preinstantiation logic that is executed before instantiating @@ -657,7 +584,7 @@ impl Artifact { let metadata_len = MetadataHeader::parse(bytes)?; let metadata_slice = &bytes[MetadataHeader::LEN..][..metadata_len]; - let mut metadata: ModuleMetadata = ModuleMetadata::deserialize(metadata_slice)?; + let metadata: ModuleMetadata = ModuleMetadata::deserialize(metadata_slice)?; const WORD_SIZE: usize = mem::size_of::(); let mut byte_buffer = [0u8; WORD_SIZE]; @@ -726,18 +653,29 @@ impl Artifact { finished_dynamic_function_trampolines.push(fp); } - let (_compile_info, _symbol_registry) = metadata.split(); - Ok(Self::Static(StaticArtifact { - metadata, - _module_bytes: bytes.to_vec(), + let artifact = ArtifactBuild::from_serializable(SerializableModule { + compilation: SerializableCompilation::default(), + compile_info: metadata.compile_info, + data_initializers: metadata.data_initializers, + cpu_features: metadata.cpu_features, + }); + + let finished_function_lengths = finished_functions + .values() + .map(|_| 0) + .collect::>() + .into_boxed_slice(); + + Ok(Artifact { + artifact, finished_functions: finished_functions.into_boxed_slice(), finished_function_call_trampolines: finished_function_call_trampolines .into_boxed_slice(), finished_dynamic_function_trampolines: finished_dynamic_function_trampolines .into_boxed_slice(), signatures: signatures.into_boxed_slice(), - _metadata_length: metadata_len, - _symbol_registry, - })) + finished_function_lengths, + frame_info_registration: None, + }) } } diff --git a/lib/types/src/compilation/section.rs b/lib/types/src/compilation/section.rs index ed8e49885b9..1f82ebad488 100644 --- a/lib/types/src/compilation/section.rs +++ b/lib/types/src/compilation/section.rs @@ -32,6 +32,12 @@ pub struct SectionIndex(u32); entity_impl!(SectionIndex); +impl Default for SectionIndex { + fn default() -> Self { + Self(0) + } +} + /// Custom section Protection. /// /// Determines how a custom section may be used. diff --git a/lib/types/src/serialize.rs b/lib/types/src/serialize.rs index abffcfc782e..4bf7bfac000 100644 --- a/lib/types/src/serialize.rs +++ b/lib/types/src/serialize.rs @@ -16,7 +16,7 @@ use std::path::Path; use std::{fs, mem}; /// The compilation related data for a serialized modules -#[derive(Archive, RkyvDeserialize, RkyvSerialize)] +#[derive(Archive, Default, RkyvDeserialize, RkyvSerialize)] #[allow(missing_docs)] pub struct SerializableCompilation { pub function_bodies: PrimaryMap,