From dd6e0339d3231a9ef30a10af7b53415d316a9e2a Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Tue, 28 Nov 2023 20:01:10 -0500 Subject: [PATCH] Refactor create_type_object so that most of the code is monomorphic In pyca/cryptography this function is the #1 source of lines of generated LLVM IR, because it is duplicated 42x (and growing!). By rewriting it so most of the logic is monomorphic, we reduce the generated LLVM IR for this function by 4x. --- src/pyclass/create_type_object.rs | 58 +++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/src/pyclass/create_type_object.rs b/src/pyclass/create_type_object.rs index 33bcacf718b..a7196f30288 100644 --- a/src/pyclass/create_type_object.rs +++ b/src/pyclass/create_type_object.rs @@ -33,17 +33,34 @@ pub(crate) fn create_type_object(py: Python<'_>) -> PyResult, + base: *mut ffi::PyTypeObject, + dealloc: unsafe extern "C" fn(*mut ffi::PyObject), + dealloc_with_gc: unsafe extern "C" fn(*mut ffi::PyObject), + is_mapping: bool, + is_sequence: bool, + doc: &'static CStr, + dict_offset: Option, + weaklist_offset: Option, + is_basetype: bool, + items_iter: PyClassItemsIter, + name: &'static str, + module: Option<&'static str>, + size_of: usize, + ) -> PyResult { PyTypeBuilder { slots: Vec::new(), method_defs: Vec::new(), getset_builders: HashMap::new(), cleanup: Vec::new(), - tp_base: T::BaseType::type_object_raw(py), - tp_dealloc: tp_dealloc::, - tp_dealloc_with_gc: tp_dealloc_with_gc::, - is_mapping: T::IS_MAPPING, - is_sequence: T::IS_SEQUENCE, + tp_base: base, + tp_dealloc: dealloc, + tp_dealloc_with_gc: dealloc_with_gc, + is_mapping, + is_sequence, has_new: false, has_dealloc: false, has_getitem: false, @@ -55,11 +72,30 @@ where #[cfg(all(not(Py_3_9), not(Py_LIMITED_API)))] buffer_procs: Default::default(), } - .type_doc(T::doc(py)?) - .offsets(T::dict_offset(), T::weaklist_offset()) - .set_is_basetype(T::IS_BASETYPE) - .class_items(T::items_iter()) - .build(py, T::NAME, T::MODULE, std::mem::size_of::>()) + .type_doc(doc) + .offsets(dict_offset, weaklist_offset) + .set_is_basetype(is_basetype) + .class_items(items_iter) + .build(py, name, module, size_of) + } + + unsafe { + inner( + py, + T::BaseType::type_object_raw(py), + tp_dealloc::, + tp_dealloc_with_gc::, + T::IS_MAPPING, + T::IS_SEQUENCE, + T::doc(py)?, + T::dict_offset(), + T::weaklist_offset(), + T::IS_BASETYPE, + T::items_iter(), + T::NAME, + T::MODULE, + std::mem::size_of::>(), + ) } }