Skip to content

Commit 8d5c499

Browse files
committed
Avoid unnecessary heap allocation in ConcreteBlock's descriptor
1 parent 101b175 commit 8d5c499

File tree

1 file changed

+10
-16
lines changed

1 file changed

+10
-16
lines changed

objc2_block/src/lib.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ extern crate std;
5555
#[cfg(test)]
5656
mod test_utils;
5757

58-
use alloc::boxed::Box;
5958
use core::ffi::c_void;
6059
use core::marker::PhantomData;
6160
use core::mem;
@@ -349,7 +348,7 @@ concrete_block_impl!(
349348
#[repr(C)]
350349
pub struct ConcreteBlock<A, R, F> {
351350
base: BlockBase<A, R>,
352-
descriptor: Box<BlockDescriptor<ConcreteBlock<A, R, F>>>,
351+
descriptor: *const BlockDescriptor<ConcreteBlock<A, R, F>>,
353352
closure: F,
354353
}
355354

@@ -374,19 +373,25 @@ where
374373
}
375374

376375
impl<A, R, F> ConcreteBlock<A, R, F> {
376+
const DESCRIPTOR: BlockDescriptor<Self> = BlockDescriptor {
377+
_reserved: 0,
378+
block_size: mem::size_of::<Self>() as c_ulong,
379+
copy_helper: block_context_copy::<Self>,
380+
dispose_helper: block_context_dispose::<Self>,
381+
};
382+
377383
/// Constructs a `ConcreteBlock` with the given invoke function and closure.
378384
/// Unsafe because the caller must ensure the invoke function takes the
379385
/// correct arguments.
380386
unsafe fn with_invoke(invoke: unsafe extern "C" fn(*mut Self, ...) -> R, closure: F) -> Self {
381387
ConcreteBlock {
382388
base: BlockBase {
383389
isa: &ffi::_NSConcreteStackBlock,
384-
// 1 << 25 = BLOCK_HAS_COPY_DISPOSE
385-
flags: 1 << 25,
390+
flags: ffi::BLOCK_HAS_COPY_DISPOSE,
386391
_reserved: 0,
387392
invoke: mem::transmute(invoke),
388393
},
389-
descriptor: Box::new(BlockDescriptor::new()),
394+
descriptor: &Self::DESCRIPTOR,
390395
closure,
391396
}
392397
}
@@ -452,17 +457,6 @@ struct BlockDescriptor<B> {
452457
dispose_helper: unsafe extern "C" fn(&mut B),
453458
}
454459

455-
impl<B> BlockDescriptor<B> {
456-
fn new() -> BlockDescriptor<B> {
457-
BlockDescriptor {
458-
_reserved: 0,
459-
block_size: mem::size_of::<B>() as c_ulong,
460-
copy_helper: block_context_copy::<B>,
461-
dispose_helper: block_context_dispose::<B>,
462-
}
463-
}
464-
}
465-
466460
#[cfg(test)]
467461
mod tests {
468462
use super::{ConcreteBlock, RcBlock};

0 commit comments

Comments
 (0)