diff --git a/rust/upb.rs b/rust/upb.rs index 34d57bfd3caa..15196b828aa5 100644 --- a/rust/upb.rs +++ b/rust/upb.rs @@ -19,14 +19,16 @@ use std::cell::UnsafeCell; use std::ffi::c_int; use std::fmt; use std::marker::PhantomData; -use std::mem::{size_of, ManuallyDrop, MaybeUninit}; +use std::mem::{align_of, size_of, ManuallyDrop, MaybeUninit}; use std::ops::Deref; use std::ptr::{self, NonNull}; use std::slice; -use std::sync::{Once, OnceLock}; +use std::sync::OnceLock; /// See `upb/port/def.inc`. const UPB_MALLOC_ALIGN: usize = 8; +const _CHECK_UPB_MALLOC_ALIGN_AT_LEAST_POINTER_ALIGNED: () = + assert!(UPB_MALLOC_ALIGN >= align_of::<*const ()>()); /// A wrapper over a `upb_Arena`. /// @@ -148,37 +150,23 @@ impl Drop for Arena { } } -static mut INTERNAL_PTR: Option = None; -static INIT: Once = Once::new(); - -// The scratch size of 64 KiB matches the maximum supported size that a -// upb_Message can possibly be. -// TODO: Allow dynamic sized ScratchSpace. +/// The scratch size of 64 KiB matches the maximum supported size that a +/// upb_Message can possibly be. const UPB_SCRATCH_SPACE_BYTES: usize = 65_536; -const ALIGN: usize = 32; /// Holds a zero-initialized block of memory for use by upb. +/// /// By default, if a message is not set in cpp, a default message is created. /// upb departs from this and returns a null ptr. However, since contiguous /// chunks of memory filled with zeroes are legit messages from upb's point of /// view, we can allocate a large block and refer to that when dealing /// with readonly access. -pub struct ScratchSpace; +#[repr(C, align(8))] // align to UPB_MALLOC_ALIGN = 8 +pub struct ScratchSpace([u8; UPB_SCRATCH_SPACE_BYTES]); impl ScratchSpace { pub fn zeroed_block(_private: Private) -> RawMessage { - unsafe { - INIT.call_once(|| { - let layout = - std::alloc::Layout::from_size_align(UPB_SCRATCH_SPACE_BYTES, ALIGN).unwrap(); - let Some(ptr) = - crate::__internal::RawMessage::new(std::alloc::alloc_zeroed(layout).cast()) - else { - std::alloc::handle_alloc_error(layout) - }; - INTERNAL_PTR = Some(ptr) - }); - INTERNAL_PTR.unwrap() - } + static ZEROED_BLOCK: ScratchSpace = ScratchSpace([0; UPB_SCRATCH_SPACE_BYTES]); + NonNull::from(&ZEROED_BLOCK).cast() } }