Skip to content

Commit 7e467cd

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 116f4ae commit 7e467cd

File tree

9 files changed

+139
-168
lines changed

9 files changed

+139
-168
lines changed

compiler/rustc_ast/src/expand/allocator.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ 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,
2527
Unit,
2628
Usize,
2729
}
2830

31+
#[derive(Copy, Clone)]
2932
pub struct AllocatorMethod {
3033
pub name: Symbol,
3134
pub inputs: &'static [AllocatorMethodInput],

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: 29 additions & 50 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-
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;
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,74 +14,54 @@ 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),
48-
49-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
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
5037
}
51-
}
52-
let output = match method.output {
53-
AllocatorTy::ResultPtr => Some(usize_ty),
54-
AllocatorTy::Unit => None,
38+
AllocatorTy::Ptr => arg_tys.push(usize_ty),
39+
AllocatorTy::Usize => arg_tys.push(usize_ty),
5540

56-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
57-
panic!("invalid allocator output")
41+
AllocatorTy::Never | AllocatorTy::ResultPtr | AllocatorTy::Unit => {
42+
panic!("invalid allocator arg")
5843
}
59-
};
60-
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-
);
44+
}
7245
}
73-
}
46+
let output = match method.output {
47+
AllocatorTy::ResultPtr => Some(usize_ty),
48+
AllocatorTy::Never | AllocatorTy::Unit => None,
49+
50+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
51+
panic!("invalid allocator output")
52+
}
53+
};
7454

75-
if alloc_error_handler_kind == AllocatorKind::Default {
7655
let sig = Signature {
7756
call_conv: module.target_config().default_call_conv,
78-
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
79-
returns: vec![],
57+
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
58+
returns: output.into_iter().map(AbiParam::new).collect(),
8059
};
8160
crate::common::create_wrapper_function(
8261
module,
8362
sig,
84-
&mangle_internal_symbol(tcx, &global_fn_name(ALLOC_ERROR_HANDLER)),
85-
&mangle_internal_symbol(tcx, &default_fn_name(ALLOC_ERROR_HANDLER)),
63+
&mangle_internal_symbol(tcx, &global_fn_name(method.name)),
64+
&mangle_internal_symbol(tcx, &default_fn_name(method.name)),
8665
);
8766
}
8867

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 25 additions & 39 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-
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;
@@ -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,46 +29,34 @@ 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-
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-
);
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);
7460
}
7561

7662
create_const_value_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)