Auto merge of #86844 - bjorn3:global_alloc_improvements, r=pnkfelix
Support #[global_allocator] without the allocator shim This makes it possible to use liballoc/libstd in combination with `--emit obj` if you use `#[global_allocator]`. This is what rust-for-linux uses right now and systemd may use in the future. Currently they have to depend on the exact implementation of the allocator shim to create one themself as `--emit obj` doesn't create an allocator shim. Note that currently the allocator shim also defines the oom error handler, which is normally required too. Once `#![feature(default_alloc_error_handler)]` becomes the only option, this can be avoided. In addition when using only fallible allocator methods and either `--cfg no_global_oom_handling` for liballoc (like rust-for-linux) or `--gc-sections` no references to the oom error handler will exist. To avoid this feature being insta-stable, you will have to define `__rust_no_alloc_shim_is_unstable` to avoid linker errors. (Labeling this with both T-compiler and T-lang as it originally involved both an implementation detail and had an insta-stable user facing change. As noted above, the `__rust_no_alloc_shim_is_unstable` symbol requirement should prevent unintended dependence on this unstable feature.)
This commit is contained in:
commit
e6d1a0ed95
@ -3,10 +3,12 @@
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
|
||||
use rustc_ast::expand::allocator::{
|
||||
alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy,
|
||||
ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE,
|
||||
};
|
||||
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
|
||||
use rustc_session::config::OomStrategy;
|
||||
use rustc_span::symbol::sym;
|
||||
|
||||
/// Returns whether an allocator shim was created
|
||||
pub(crate) fn codegen(
|
||||
@ -34,41 +36,43 @@ fn codegen_inner(
|
||||
) {
|
||||
let usize_ty = module.target_config().pointer_type();
|
||||
|
||||
for method in ALLOCATOR_METHODS {
|
||||
let mut arg_tys = Vec::with_capacity(method.inputs.len());
|
||||
for ty in method.inputs.iter() {
|
||||
match *ty {
|
||||
AllocatorTy::Layout => {
|
||||
arg_tys.push(usize_ty); // size
|
||||
arg_tys.push(usize_ty); // align
|
||||
if kind == AllocatorKind::Default {
|
||||
for method in ALLOCATOR_METHODS {
|
||||
let mut arg_tys = Vec::with_capacity(method.inputs.len());
|
||||
for ty in method.inputs.iter() {
|
||||
match *ty {
|
||||
AllocatorTy::Layout => {
|
||||
arg_tys.push(usize_ty); // size
|
||||
arg_tys.push(usize_ty); // align
|
||||
}
|
||||
AllocatorTy::Ptr => arg_tys.push(usize_ty),
|
||||
AllocatorTy::Usize => arg_tys.push(usize_ty),
|
||||
|
||||
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
|
||||
}
|
||||
AllocatorTy::Ptr => arg_tys.push(usize_ty),
|
||||
AllocatorTy::Usize => arg_tys.push(usize_ty),
|
||||
|
||||
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
|
||||
}
|
||||
let output = match method.output {
|
||||
AllocatorTy::ResultPtr => Some(usize_ty),
|
||||
AllocatorTy::Unit => None,
|
||||
|
||||
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
|
||||
panic!("invalid allocator output")
|
||||
}
|
||||
};
|
||||
|
||||
let sig = Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
|
||||
returns: output.into_iter().map(AbiParam::new).collect(),
|
||||
};
|
||||
crate::common::create_wrapper_function(
|
||||
module,
|
||||
unwind_context,
|
||||
sig,
|
||||
&global_fn_name(method.name),
|
||||
&default_fn_name(method.name),
|
||||
);
|
||||
}
|
||||
let output = match method.output {
|
||||
AllocatorTy::ResultPtr => Some(usize_ty),
|
||||
AllocatorTy::Unit => None,
|
||||
|
||||
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
|
||||
panic!("invalid allocator output")
|
||||
}
|
||||
};
|
||||
|
||||
let sig = Signature {
|
||||
call_conv: module.target_config().default_call_conv,
|
||||
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
|
||||
returns: output.into_iter().map(AbiParam::new).collect(),
|
||||
};
|
||||
crate::common::create_wrapper_function(
|
||||
module,
|
||||
unwind_context,
|
||||
sig,
|
||||
&format!("__rust_{}", method.name),
|
||||
&kind.fn_name(method.name),
|
||||
);
|
||||
}
|
||||
|
||||
let sig = Signature {
|
||||
@ -81,7 +85,7 @@ fn codegen_inner(
|
||||
unwind_context,
|
||||
sig,
|
||||
"__rust_alloc_error_handler",
|
||||
&alloc_error_handler_kind.fn_name(sym::oom),
|
||||
&alloc_error_handler_name(alloc_error_handler_kind),
|
||||
);
|
||||
|
||||
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();
|
||||
@ -90,4 +94,11 @@ fn codegen_inner(
|
||||
let val = oom_strategy.should_panic();
|
||||
data_ctx.define(Box::new([val]));
|
||||
module.define_data(data_id, &data_ctx).unwrap();
|
||||
|
||||
let data_id =
|
||||
module.declare_data(NO_ALLOC_SHIM_IS_UNSTABLE, Linkage::Export, false, false).unwrap();
|
||||
let mut data_ctx = DataContext::new();
|
||||
data_ctx.set_align(1);
|
||||
data_ctx.define(Box::new([0]));
|
||||
module.define_data(data_id, &data_ctx).unwrap();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user