Skip to content

Commit 98c96d6

Browse files
committed
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.
1 parent c2a135b commit 98c96d6

File tree

9 files changed

+166
-208
lines changed

9 files changed

+166
-208
lines changed

compiler/rustc_ast/src/expand/allocator.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,18 @@ pub fn default_fn_name(base: Symbol) -> String {
1818
pub const ALLOC_ERROR_HANDLER: Symbol = sym::alloc_error_handler;
1919
pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2";
2020

21+
#[derive(Copy, Clone)]
2122
pub enum AllocatorTy {
2223
Layout,
24+
Never,
2325
Ptr,
2426
ResultPtr,
27+
U8,
2528
Unit,
2629
Usize,
2730
}
2831

32+
#[derive(Copy, Clone)]
2933
pub struct AllocatorMethod {
3034
pub name: Symbol,
3135
pub inputs: &'static [AllocatorMethodInput],

compiler/rustc_builtin_macros/src/global_allocator.rs

Lines changed: 6 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::ResultPtr | AllocatorTy::U8 | AllocatorTy::Unit | AllocatorTy::Never => {
155155
panic!("can't convert AllocatorTy to an argument")
156156
}
157157
}
@@ -163,7 +163,11 @@ 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
167+
| AllocatorTy::Never
168+
| AllocatorTy::U8
169+
| AllocatorTy::Usize
170+
| AllocatorTy::Ptr => {
167171
panic!("can't convert `AllocatorTy` to an output")
168172
}
169173
}

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 32 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -3,93 +3,64 @@
33

44
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
55
use rustc_ast::expand::allocator::{
6-
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
7-
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;
10-
use rustc_session::config::OomStrategy;
8+
use rustc_codegen_ssa::base::{allocator_kind_for_codegen, allocator_shim_contents};
119
use rustc_symbol_mangling::mangle_internal_symbol;
1210

1311
use crate::prelude::*;
1412

1513
/// Returns whether an allocator shim was created
1614
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
1715
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
18-
codegen_inner(tcx, module, kind, tcx.alloc_error_handler_kind(()).unwrap());
16+
let methods = allocator_shim_contents(tcx, kind);
17+
codegen_inner(tcx, module, &methods);
1918
true
2019
}
2120

22-
fn codegen_inner(
23-
tcx: TyCtxt<'_>,
24-
module: &mut dyn Module,
25-
kind: AllocatorKind,
26-
alloc_error_handler_kind: AllocatorKind,
27-
) {
21+
fn codegen_inner(tcx: TyCtxt<'_>, module: &mut dyn Module, methods: &[AllocatorMethod]) {
2822
let usize_ty = module.target_config().pointer_type();
2923

30-
if kind == AllocatorKind::Default {
31-
for method in ALLOCATOR_METHODS {
32-
let mut arg_tys = Vec::with_capacity(method.inputs.len());
33-
for input in method.inputs.iter() {
34-
match input.ty {
35-
AllocatorTy::Layout => {
36-
arg_tys.push(usize_ty); // size
37-
arg_tys.push(usize_ty); // align
38-
}
39-
AllocatorTy::Ptr => arg_tys.push(usize_ty),
40-
AllocatorTy::Usize => arg_tys.push(usize_ty),
41-
42-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
24+
for method in methods {
25+
let mut arg_tys = Vec::with_capacity(method.inputs.len());
26+
for input in method.inputs.iter() {
27+
match input.ty {
28+
AllocatorTy::Layout => {
29+
arg_tys.push(usize_ty); // size
30+
arg_tys.push(usize_ty); // align
4331
}
44-
}
45-
let output = match method.output {
46-
AllocatorTy::ResultPtr => Some(usize_ty),
47-
AllocatorTy::Unit => None,
32+
AllocatorTy::Ptr => arg_tys.push(usize_ty),
33+
AllocatorTy::Usize => arg_tys.push(usize_ty),
4834

49-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
50-
panic!("invalid allocator output")
35+
AllocatorTy::Never
36+
| AllocatorTy::ResultPtr
37+
| AllocatorTy::U8
38+
| AllocatorTy::Unit => {
39+
panic!("invalid allocator arg")
5140
}
52-
};
53-
54-
let sig = Signature {
55-
call_conv: module.target_config().default_call_conv,
56-
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
57-
returns: output.into_iter().map(AbiParam::new).collect(),
58-
};
59-
crate::common::create_wrapper_function(
60-
module,
61-
sig,
62-
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
63-
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
64-
);
41+
}
6542
}
66-
}
43+
let output = match method.output {
44+
AllocatorTy::Never => None,
45+
AllocatorTy::ResultPtr => Some(usize_ty),
46+
AllocatorTy::Unit => None,
47+
AllocatorTy::U8 => Some(types::I8),
6748

68-
if alloc_error_handler_kind == AllocatorKind::Default {
69-
let sig = Signature {
70-
call_conv: module.target_config().default_call_conv,
71-
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
72-
returns: vec![],
49+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
50+
panic!("invalid allocator output")
51+
}
7352
};
74-
crate::common::create_wrapper_function(
75-
module,
76-
sig,
77-
&mangle_internal_symbol(tcx, &global_fn_name(ALLOC_ERROR_HANDLER)),
78-
&mangle_internal_symbol(tcx, &default_fn_name(ALLOC_ERROR_HANDLER)),
79-
);
80-
}
8153

82-
if tcx.sess.opts.unstable_opts.oom == OomStrategy::Abort {
8354
let sig = Signature {
8455
call_conv: module.target_config().default_call_conv,
85-
params: vec![],
86-
returns: vec![AbiParam::new(types::I8)],
56+
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
57+
returns: output.into_iter().map(AbiParam::new).collect(),
8758
};
8859
crate::common::create_wrapper_function(
8960
module,
9061
sig,
91-
&mangle_internal_symbol(tcx, &global_fn_name(OomStrategy::SYMBOL)),
92-
&mangle_internal_symbol(tcx, &default_fn_name(OomStrategy::SYMBOL)),
62+
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
63+
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
9364
);
9465
}
9566

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 31 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
use gccjit::FnAttribute;
33
use gccjit::{Context, FunctionType, ToRValue, Type};
44
use rustc_ast::expand::allocator::{
5-
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
6-
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;
10-
use rustc_session::config::OomStrategy;
119
use rustc_symbol_mangling::mangle_internal_symbol;
1210

1311
use crate::GccContext;
@@ -18,8 +16,7 @@ pub(crate) unsafe fn codegen(
1816
tcx: TyCtxt<'_>,
1917
mods: &mut GccContext,
2018
_module_name: &str,
21-
kind: AllocatorKind,
22-
alloc_error_handler_kind: AllocatorKind,
19+
methods: &[AllocatorMethod],
2320
) {
2421
let context = &mods.context;
2522
let usize = match tcx.sess.target.pointer_width {
@@ -30,58 +27,40 @@ pub(crate) unsafe fn codegen(
3027
};
3128
let i8 = context.new_type::<i8>();
3229
let i8p = i8.make_pointer();
33-
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"),
30+
let u8 = context.new_type::<u8>();
31+
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,
52-
53-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
54-
panic!("invalid allocator output")
40+
AllocatorTy::Ptr => types.push(i8p),
41+
AllocatorTy::Usize => types.push(usize),
42+
43+
AllocatorTy::ResultPtr
44+
| AllocatorTy::U8
45+
| AllocatorTy::Unit
46+
| AllocatorTy::Never => {
47+
panic!("invalid allocator arg")
5548
}
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);
49+
}
6150
}
62-
}
51+
let output = match method.output {
52+
AllocatorTy::ResultPtr => Some(i8p),
53+
AllocatorTy::U8 => Some(u8),
54+
AllocatorTy::Unit | AllocatorTy::Never => None,
6355

64-
if alloc_error_handler_kind == AllocatorKind::Default {
65-
// FIXME(bjorn3): Add noreturn attribute
66-
create_wrapper_function(
67-
tcx,
68-
context,
69-
&mangle_internal_symbol(tcx, &global_fn_name(ALLOC_ERROR_HANDLER)),
70-
Some(&mangle_internal_symbol(tcx, &default_fn_name(ALLOC_ERROR_HANDLER))),
71-
&[usize, usize],
72-
None,
73-
);
74-
}
56+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
57+
panic!("invalid allocator output")
58+
}
59+
};
60+
let from_name = mangle_internal_symbol(tcx, &global_fn_name(method.name));
61+
let to_name = mangle_internal_symbol(tcx, &default_fn_name(method.name));
7562

76-
if tcx.sess.opts.unstable_opts.oom == OomStrategy::Abort {
77-
create_wrapper_function(
78-
tcx,
79-
context,
80-
&mangle_internal_symbol(tcx, &global_fn_name(OomStrategy::SYMBOL)),
81-
Some(&mangle_internal_symbol(tcx, &default_fn_name(OomStrategy::SYMBOL))),
82-
&[],
83-
Some(i8),
84-
);
63+
create_wrapper_function(tcx, context, &from_name, Some(&to_name), &types, output);
8564
}
8665

8766
create_wrapper_function(

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)