Skip to content

Commit 44a8479

Browse files
TethysSvenssoncalebzulawski
authored andcommitted
Emit smaller dispatcher code
1 parent 6eb6177 commit 44a8479

2 files changed

Lines changed: 18 additions & 51 deletions

File tree

src/dispatcher.rs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub(crate) struct Dispatcher {
1111

1212
impl ToTokens for Dispatcher {
1313
fn to_tokens(&self, tokens: &mut TokenStream) {
14-
let function_arguments = &self.signature.inputs.iter();
14+
let function_arguments = self.signature.inputs.iter();
1515
let argument_names = &self
1616
.signature
1717
.inputs
@@ -48,50 +48,41 @@ impl ToTokens for Dispatcher {
4848
let return_if_detected = self.functions.iter().map(|(target, function)| {
4949
let target_arch = target.target_arch();
5050
let features_detected = target.features_detected();
51-
let function_arguments = function_arguments.clone();
52-
let argument_names = argument_names.clone();
5351
quote! {
5452
#target_arch
5553
{
56-
// wrap the function in an unsafe function with the same signature
57-
unsafe fn unsafe_wrapper(#(#function_arguments),*) #returns {
58-
#function(#(#argument_names),*)
59-
}
6054
if #features_detected {
61-
return unsafe_wrapper
55+
return #function
6256
}
6357
}
6458
}
6559
});
6660
let default = &self.default;
67-
let function_arguments = function_arguments.clone();
68-
let argument_names = argument_names.clone();
6961
quote! {
7062
#(#return_if_detected)*
7163
#[cfg(not(any(#(target_arch = #defaulted_arches),*)))]
7264
{
73-
unsafe fn unsafe_wrapper(#(#function_arguments),*) #returns {
74-
#default(#(#argument_names),*)
75-
}
76-
return unsafe_wrapper
65+
return #default
7766
}
7867
}
7968
};
8069
tokens.extend(quote! {
81-
use std::sync::atomic::{AtomicUsize, Ordering};
70+
use std::sync::atomic::{AtomicPtr, Ordering};
8271
type __fn_ty = unsafe fn (#(#argument_ty),*) #returns;
8372
#[cold]
8473
fn __get_fn() -> __fn_ty {
8574
#feature_detection
8675
}
87-
static __DISPATCHED_FN: AtomicUsize = AtomicUsize::new(0usize);
88-
let mut __current_ptr = __DISPATCHED_FN.load(Ordering::SeqCst);
89-
if __current_ptr == 0 {
90-
__current_ptr = unsafe { std::mem::transmute(__get_fn()) };
91-
__DISPATCHED_FN.store(__current_ptr, Ordering::SeqCst);
76+
#[cold]
77+
unsafe fn __resolver_fn (#(#function_arguments),*) #returns {
78+
let __current_fn = __get_fn();
79+
__DISPATCHED_FN.store(__current_fn as *mut (), Ordering::SeqCst);
80+
__current_fn(#(#argument_names),*)
9281
}
82+
static __DISPATCHED_FN: AtomicPtr<()> = AtomicPtr::new(__resolver_fn as *mut ());
83+
let __current_ptr = __DISPATCHED_FN.load(Ordering::SeqCst);
9384
unsafe {
94-
let __current_fn = std::mem::transmute::<usize, __fn_ty>(__current_ptr);
85+
let __current_fn = std::mem::transmute::<*mut (), __fn_ty>(__current_ptr);
9586
__current_fn(#(#argument_names),*)
9687
}
9788
});

src/target_clones.rs

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use proc_macro2::{Span, TokenStream};
66
use quote::{quote, ToTokens};
77
use syn::parse::{Parse, ParseStream, Result};
88
use syn::punctuated::Punctuated;
9-
use syn::{token, Attribute, Block, FnArg, Ident, ItemFn, LitStr, Signature, Token, Visibility};
9+
use syn::{token, Attribute, Block, Ident, ItemFn, LitStr, Signature, Token, Visibility};
1010

1111
pub(crate) struct Config {
1212
targets: Vec<Target>,
@@ -39,36 +39,12 @@ impl ToTokens for FunctionClone<'_> {
3939
.as_ref()
4040
.map_or(TokenStream::new(), |x| x.target_features());
4141
let signature = &self.signature;
42-
let body = &self.body;
43-
tokens.extend(if signature.unsafety.is_some() || self.target.is_none() {
44-
quote! { #target_arch #target_features #signature #body }
45-
} else {
46-
let mut unsafe_signature = signature.clone();
47-
unsafe_signature.unsafety = Some(token::Unsafe {
48-
span: Span::call_site(),
49-
});
50-
unsafe_signature.ident = Ident::new("__unsafe_fn", Span::call_site());
51-
let argument_names = &signature
52-
.inputs
53-
.iter()
54-
.map(|x| {
55-
if let FnArg::Typed(p) = x {
56-
p.pat.as_ref()
57-
} else {
58-
unimplemented!("member fn not supported")
59-
}
60-
})
61-
.collect::<Vec<_>>();
62-
quote! {
63-
#target_arch
64-
#signature {
65-
#target_features #unsafe_signature #body
66-
unsafe {
67-
__unsafe_fn(#(#argument_names),*)
68-
}
69-
}
70-
}
42+
let mut unsafe_signature = signature.clone();
43+
unsafe_signature.unsafety = Some(token::Unsafe {
44+
span: Span::call_site(),
7145
});
46+
let body = &self.body;
47+
tokens.extend(quote! { #target_arch #target_features #unsafe_signature #body });
7248
}
7349
}
7450

0 commit comments

Comments
 (0)