Skip to content

Commit 452b22d

Browse files
authored
Unrolled build for #147526
Rollup merge of #147526 - bjorn3:alloc_shim_weak_shape, r=petrochenkov,RalfJung Move computation of allocator shim contents to cg_ssa In the future this should make it easier to use weak symbols for the allocator shim on platforms that properly support weak symbols. And it would allow reusing the allocator shim code for handling default implementations of the upcoming externally implementable items feature on platforms that don't properly support weak symbols. In addition to make this possible, the alloc error handler is now handled in a way such that it is possible to avoid using the allocator shim when liballoc is compiled without `no_global_oom_handling` if you use `#[alloc_error_handler]`. Previously this was only possible if you avoided liballoc entirely or compiled it with `no_global_oom_handling`. You still need to avoid libstd and to define the symbol that indicates that avoiding the allocator shim is unstable.
2 parents 844264a + cf02560 commit 452b22d

File tree

20 files changed

+207
-233
lines changed

20 files changed

+207
-233
lines changed

compiler/rustc_ast/src/expand/allocator.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use rustc_span::{Symbol, sym};
33

44
#[derive(Clone, Debug, Copy, Eq, PartialEq, HashStable_Generic)]
55
pub enum AllocatorKind {
6+
/// Use `#[global_allocator]` as global allocator.
67
Global,
8+
/// Use the default implementation in libstd as global allocator.
79
Default,
810
}
911

@@ -15,23 +17,22 @@ pub fn default_fn_name(base: Symbol) -> String {
1517
format!("__rdl_{base}")
1618
}
1719

18-
pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str {
19-
match alloc_error_handler_kind {
20-
AllocatorKind::Global => "__rg_oom",
21-
AllocatorKind::Default => "__rdl_oom",
22-
}
23-
}
24-
20+
pub const ALLOC_ERROR_HANDLER: Symbol = sym::alloc_error_handler;
2521
pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2";
2622

23+
/// Argument or return type for methods in the allocator shim
24+
#[derive(Copy, Clone)]
2725
pub enum AllocatorTy {
2826
Layout,
27+
Never,
2928
Ptr,
3029
ResultPtr,
3130
Unit,
3231
Usize,
3332
}
3433

34+
/// A method that will be codegened in the allocator shim.
35+
#[derive(Copy, Clone)]
3536
pub struct AllocatorMethod {
3637
pub name: Symbol,
3738
pub inputs: &'static [AllocatorMethodInput],

compiler/rustc_builtin_macros/src/alloc_error_handler.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_ast::expand::allocator::{ALLOC_ERROR_HANDLER, global_fn_name};
12
use rustc_ast::{
23
self as ast, Fn, FnHeader, FnSig, Generics, ItemKind, Safety, Stmt, StmtKind, TyKind,
34
};
@@ -55,7 +56,7 @@ pub(crate) fn expand(
5556
}
5657

5758
// #[rustc_std_internal_symbol]
58-
// unsafe fn __rg_oom(size: usize, align: usize) -> ! {
59+
// unsafe fn __rust_alloc_error_handler(size: usize, align: usize) -> ! {
5960
// handler(core::alloc::Layout::from_size_align_unchecked(size, align))
6061
// }
6162
fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt {
@@ -84,7 +85,7 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span
8485
let kind = ItemKind::Fn(Box::new(Fn {
8586
defaultness: ast::Defaultness::Final,
8687
sig,
87-
ident: Ident::from_str_and_span("__rg_oom", span),
88+
ident: Ident::from_str_and_span(&global_fn_name(ALLOC_ERROR_HANDLER), span),
8889
generics: Generics::default(),
8990
contract: None,
9091
body,

compiler/rustc_builtin_macros/src/global_allocator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl AllocFnFactory<'_, '_> {
151151
self.cx.expr_ident(self.span, ident)
152152
}
153153

154-
AllocatorTy::ResultPtr | AllocatorTy::Unit => {
154+
AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => {
155155
panic!("can't convert AllocatorTy to an argument")
156156
}
157157
}
@@ -163,7 +163,7 @@ impl AllocFnFactory<'_, '_> {
163163

164164
AllocatorTy::Unit => self.cx.ty(self.span, TyKind::Tup(ThinVec::new())),
165165

166-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
166+
AllocatorTy::Layout | AllocatorTy::Never | AllocatorTy::Usize | AllocatorTy::Ptr => {
167167
panic!("can't convert `AllocatorTy` to an output")
168168
}
169169
}

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 36 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33

44
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
55
use rustc_ast::expand::allocator::{
6-
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
7-
alloc_error_handler_name, default_fn_name, global_fn_name,
6+
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
87
};
9-
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
8+
use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents};
109
use rustc_session::config::OomStrategy;
1110
use rustc_symbol_mangling::mangle_internal_symbol;
1211

@@ -15,75 +14,57 @@ use crate::prelude::*;
1514
/// Returns whether an allocator shim was created
1615
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
1716
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
18-
codegen_inner(
19-
tcx,
20-
module,
21-
kind,
22-
tcx.alloc_error_handler_kind(()).unwrap(),
23-
tcx.sess.opts.unstable_opts.oom,
24-
);
17+
let methods = allocator_shim_contents(tcx, kind);
18+
codegen_inner(tcx, module, &methods, tcx.sess.opts.unstable_opts.oom);
2519
true
2620
}
2721

2822
fn codegen_inner(
2923
tcx: TyCtxt<'_>,
3024
module: &mut dyn Module,
31-
kind: AllocatorKind,
32-
alloc_error_handler_kind: AllocatorKind,
25+
methods: &[AllocatorMethod],
3326
oom_strategy: OomStrategy,
3427
) {
3528
let usize_ty = module.target_config().pointer_type();
3629

37-
if kind == AllocatorKind::Default {
38-
for method in ALLOCATOR_METHODS {
39-
let mut arg_tys = Vec::with_capacity(method.inputs.len());
40-
for input in method.inputs.iter() {
41-
match input.ty {
42-
AllocatorTy::Layout => {
43-
arg_tys.push(usize_ty); // size
44-
arg_tys.push(usize_ty); // align
45-
}
46-
AllocatorTy::Ptr => arg_tys.push(usize_ty),
47-
AllocatorTy::Usize => arg_tys.push(usize_ty),
30+
for method in methods {
31+
let mut arg_tys = Vec::with_capacity(method.inputs.len());
32+
for input in method.inputs.iter() {
33+
match input.ty {
34+
AllocatorTy::Layout => {
35+
arg_tys.push(usize_ty); // size
36+
arg_tys.push(usize_ty); // align
37+
}
38+
AllocatorTy::Ptr => arg_tys.push(usize_ty),
39+
AllocatorTy::Usize => arg_tys.push(usize_ty),
4840

49-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
41+
AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => {
42+
panic!("invalid allocator arg")
5043
}
5144
}
52-
let output = match method.output {
53-
AllocatorTy::ResultPtr => Some(usize_ty),
54-
AllocatorTy::Unit => None,
45+
}
46+
let output = match method.output {
47+
AllocatorTy::ResultPtr => Some(usize_ty),
48+
AllocatorTy::Never | AllocatorTy::Unit => None,
5549

56-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
57-
panic!("invalid allocator output")
58-
}
59-
};
50+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
51+
panic!("invalid allocator output")
52+
}
53+
};
6054

61-
let sig = Signature {
62-
call_conv: module.target_config().default_call_conv,
63-
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
64-
returns: output.into_iter().map(AbiParam::new).collect(),
65-
};
66-
crate::common::create_wrapper_function(
67-
module,
68-
sig,
69-
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
70-
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
71-
);
72-
}
55+
let sig = Signature {
56+
call_conv: module.target_config().default_call_conv,
57+
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
58+
returns: output.into_iter().map(AbiParam::new).collect(),
59+
};
60+
crate::common::create_wrapper_function(
61+
module,
62+
sig,
63+
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
64+
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
65+
);
7366
}
7467

75-
let sig = Signature {
76-
call_conv: module.target_config().default_call_conv,
77-
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
78-
returns: vec![],
79-
};
80-
crate::common::create_wrapper_function(
81-
module,
82-
sig,
83-
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
84-
&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)),
85-
);
86-
8768
{
8869
let sig = Signature {
8970
call_conv: module.target_config().default_call_conv,

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 26 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
use gccjit::FnAttribute;
33
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
44
use rustc_ast::expand::allocator::{
5-
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
6-
alloc_error_handler_name, default_fn_name, global_fn_name,
5+
AllocatorMethod, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
76
};
87
use rustc_middle::bug;
98
use rustc_middle::ty::TyCtxt;
@@ -18,8 +17,7 @@ pub(crate) unsafe fn codegen(
1817
tcx: TyCtxt<'_>,
1918
mods: &mut GccContext,
2019
_module_name: &str,
21-
kind: AllocatorKind,
22-
alloc_error_handler_kind: AllocatorKind,
20+
methods: &[AllocatorMethod],
2321
) {
2422
let context = &mods.context;
2523
let usize = match tcx.sess.target.pointer_width {
@@ -31,45 +29,35 @@ pub(crate) unsafe fn codegen(
3129
let i8 = context.new_type::<i8>();
3230
let i8p = i8.make_pointer();
3331

34-
if kind == AllocatorKind::Default {
35-
for method in ALLOCATOR_METHODS {
36-
let mut types = Vec::with_capacity(method.inputs.len());
37-
for input in method.inputs.iter() {
38-
match input.ty {
39-
AllocatorTy::Layout => {
40-
types.push(usize);
41-
types.push(usize);
42-
}
43-
AllocatorTy::Ptr => types.push(i8p),
44-
AllocatorTy::Usize => types.push(usize),
45-
46-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
32+
for method in methods {
33+
let mut types = Vec::with_capacity(method.inputs.len());
34+
for input in method.inputs.iter() {
35+
match input.ty {
36+
AllocatorTy::Layout => {
37+
types.push(usize);
38+
types.push(usize);
4739
}
48-
}
49-
let output = match method.output {
50-
AllocatorTy::ResultPtr => Some(i8p),
51-
AllocatorTy::Unit => None,
40+
AllocatorTy::Ptr => types.push(i8p),
41+
AllocatorTy::Usize => types.push(usize),
5242

53-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
54-
panic!("invalid allocator output")
43+
AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => {
44+
panic!("invalid allocator arg")
5545
}
56-
};
57-
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
58-
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
59-
60-
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
46+
}
6147
}
62-
}
48+
let output = match method.output {
49+
AllocatorTy::ResultPtr => Some(i8p),
50+
AllocatorTy::Never | AllocatorTy::Unit => None,
6351

64-
// FIXME(bjorn3): Add noreturn attribute
65-
create_wrapper_function(
66-
tcx,
67-
context,
68-
&mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
69-
Some(&mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind))),
70-
&[usize, usize],
71-
None,
72-
);
52+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
53+
panic!("invalid allocator output")
54+
}
55+
};
56+
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
57+
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
58+
59+
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
60+
}
7361

7462
create_const_value_function(
7563
tcx,

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ use back::lto::{ThinBuffer, ThinData};
9292
use gccjit::{CType, Context, OptimizationLevel};
9393
#[cfg(feature = "master")]
9494
use gccjit::{TargetInfo, Version};
95-
use rustc_ast::expand::allocator::AllocatorKind;
95+
use rustc_ast::expand::allocator::AllocatorMethod;
9696
use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule};
9797
use rustc_codegen_ssa::back::write::{
9898
CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn,
@@ -284,8 +284,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
284284
&self,
285285
tcx: TyCtxt<'_>,
286286
module_name: &str,
287-
kind: AllocatorKind,
288-
alloc_error_handler_kind: AllocatorKind,
287+
methods: &[AllocatorMethod],
289288
) -> Self::Module {
290289
let mut mods = GccContext {
291290
context: Arc::new(SyncContext::new(new_context(tcx))),
@@ -295,7 +294,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
295294
};
296295

297296
unsafe {
298-
allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind);
297+
allocator::codegen(tcx, &mut mods, module_name, methods);
299298
}
300299
mods
301300
}

0 commit comments

Comments
 (0)