Skip to content

Commit 4ce2066

Browse files
committed
Don't use an allocator shim for #[global_allocator]
This makes it possible to use liballoc/libstd in combination with `--emit obj` if you use `#[global_allocator]`. Making it work for the default libstd allocator would require weak functions, which are not well supported on all systems.
1 parent 79fa6ce commit 4ce2066

File tree

4 files changed

+177
-160
lines changed

4 files changed

+177
-160
lines changed

compiler/rustc_ast/src/expand/allocator.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_span::symbol::{sym, Symbol};
22

3-
#[derive(Clone, Debug, Copy, HashStable_Generic)]
3+
#[derive(Clone, Debug, Copy, Eq, PartialEq, HashStable_Generic)]
44
pub enum AllocatorKind {
55
Global,
66
Default,
@@ -9,12 +9,19 @@ pub enum AllocatorKind {
99
impl AllocatorKind {
1010
pub fn fn_name(&self, base: Symbol) -> String {
1111
match *self {
12-
AllocatorKind::Global => format!("__rg_{base}"),
12+
AllocatorKind::Global => format!("__rust_{base}"),
1313
AllocatorKind::Default => format!("__rdl_{base}"),
1414
}
1515
}
1616
}
1717

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+
1825
pub enum AllocatorTy {
1926
Layout,
2027
Ptr,

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
use crate::prelude::*;
55

6-
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
6+
use rustc_ast::expand::allocator::{
7+
alloc_error_handler_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS,
8+
};
79
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
810
use rustc_session::config::OomStrategy;
9-
use rustc_span::symbol::sym;
1011

1112
/// Returns whether an allocator shim was created
1213
pub(crate) fn codegen(
@@ -34,41 +35,43 @@ fn codegen_inner(
3435
) {
3536
let usize_ty = module.target_config().pointer_type();
3637

37-
for method in ALLOCATOR_METHODS {
38-
let mut arg_tys = Vec::with_capacity(method.inputs.len());
39-
for ty in method.inputs.iter() {
40-
match *ty {
41-
AllocatorTy::Layout => {
42-
arg_tys.push(usize_ty); // size
43-
arg_tys.push(usize_ty); // align
44-
}
45-
AllocatorTy::Ptr => arg_tys.push(usize_ty),
46-
AllocatorTy::Usize => arg_tys.push(usize_ty),
38+
if kind == AllocatorKind::Default {
39+
for method in ALLOCATOR_METHODS {
40+
let mut arg_tys = Vec::with_capacity(method.inputs.len());
41+
for ty in method.inputs.iter() {
42+
match *ty {
43+
AllocatorTy::Layout => {
44+
arg_tys.push(usize_ty); // size
45+
arg_tys.push(usize_ty); // align
46+
}
47+
AllocatorTy::Ptr => arg_tys.push(usize_ty),
48+
AllocatorTy::Usize => arg_tys.push(usize_ty),
4749

48-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
50+
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
51+
}
4952
}
50-
}
51-
let output = match method.output {
52-
AllocatorTy::ResultPtr => Some(usize_ty),
53-
AllocatorTy::Unit => None,
53+
let output = match method.output {
54+
AllocatorTy::ResultPtr => Some(usize_ty),
55+
AllocatorTy::Unit => None,
5456

55-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
56-
panic!("invalid allocator output")
57-
}
58-
};
57+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
58+
panic!("invalid allocator output")
59+
}
60+
};
5961

60-
let sig = Signature {
61-
call_conv: module.target_config().default_call_conv,
62-
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
63-
returns: output.into_iter().map(AbiParam::new).collect(),
64-
};
65-
crate::common::create_wrapper_function(
66-
module,
67-
unwind_context,
68-
sig,
69-
&format!("__rust_{}", method.name),
70-
&kind.fn_name(method.name),
71-
);
62+
let sig = Signature {
63+
call_conv: module.target_config().default_call_conv,
64+
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
65+
returns: output.into_iter().map(AbiParam::new).collect(),
66+
};
67+
crate::common::create_wrapper_function(
68+
module,
69+
unwind_context,
70+
sig,
71+
&format!("__rust_{}", method.name),
72+
&AllocatorKind::Default.fn_name(method.name),
73+
);
74+
}
7275
}
7376

7477
let sig = Signature {
@@ -81,7 +84,7 @@ fn codegen_inner(
8184
unwind_context,
8285
sig,
8386
"__rust_alloc_error_handler",
84-
&alloc_error_handler_kind.fn_name(sym::oom),
87+
&alloc_error_handler_name(alloc_error_handler_kind),
8588
);
8689

8790
let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap();

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 61 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#[cfg(feature="master")]
22
use gccjit::FnAttribute;
33
use gccjit::{FunctionType, GlobalKind, ToRValue};
4-
use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
4+
use rustc_ast::expand::allocator::{
5+
alloc_error_handler_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS,
6+
};
57
use rustc_middle::bug;
68
use rustc_middle::ty::TyCtxt;
79
use rustc_session::config::OomStrategy;
8-
use rustc_span::symbol::sym;
910

1011
use crate::GccContext;
1112

@@ -22,69 +23,71 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
2223
let i8p = i8.make_pointer();
2324
let void = context.new_type::<()>();
2425

25-
for method in ALLOCATOR_METHODS {
26-
let mut types = Vec::with_capacity(method.inputs.len());
27-
for ty in method.inputs.iter() {
28-
match *ty {
29-
AllocatorTy::Layout => {
30-
types.push(usize);
31-
types.push(usize);
26+
if kind == AllocatorKind::Default {
27+
for method in ALLOCATOR_METHODS {
28+
let mut types = Vec::with_capacity(method.inputs.len());
29+
for ty in method.inputs.iter() {
30+
match *ty {
31+
AllocatorTy::Layout => {
32+
types.push(usize);
33+
types.push(usize);
34+
}
35+
AllocatorTy::Ptr => types.push(i8p),
36+
AllocatorTy::Usize => types.push(usize),
37+
38+
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
3239
}
33-
AllocatorTy::Ptr => types.push(i8p),
34-
AllocatorTy::Usize => types.push(usize),
35-
36-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
3740
}
38-
}
39-
let output = match method.output {
40-
AllocatorTy::ResultPtr => Some(i8p),
41-
AllocatorTy::Unit => None,
41+
let output = match method.output {
42+
AllocatorTy::ResultPtr => Some(i8p),
43+
AllocatorTy::Unit => None,
4244

43-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
44-
panic!("invalid allocator output")
45-
}
46-
};
47-
let name = format!("__rust_{}", method.name);
45+
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
46+
panic!("invalid allocator output")
47+
}
48+
};
49+
let name = format!("__rust_{}", method.name);
50+
51+
let args: Vec<_> = types.iter().enumerate()
52+
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
53+
.collect();
54+
let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, name, false);
4855

49-
let args: Vec<_> = types.iter().enumerate()
50-
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
51-
.collect();
52-
let func = context.new_function(None, FunctionType::Exported, output.unwrap_or(void), &args, name, false);
56+
if tcx.sess.target.options.default_hidden_visibility {
57+
#[cfg(feature="master")]
58+
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
59+
}
60+
if tcx.sess.must_emit_unwind_tables() {
61+
// TODO(antoyo): emit unwind tables.
62+
}
5363

54-
if tcx.sess.target.options.default_hidden_visibility {
64+
let callee = AllocatorKind::Default.fn_name(method.name);
65+
let args: Vec<_> = types.iter().enumerate()
66+
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
67+
.collect();
68+
let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, callee, false);
5569
#[cfg(feature="master")]
56-
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
57-
}
58-
if tcx.sess.must_emit_unwind_tables() {
59-
// TODO(antoyo): emit unwind tables.
60-
}
70+
callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
71+
72+
let block = func.new_block("entry");
73+
74+
let args = args
75+
.iter()
76+
.enumerate()
77+
.map(|(i, _)| func.get_param(i as i32).to_rvalue())
78+
.collect::<Vec<_>>();
79+
let ret = context.new_call(None, callee, &args);
80+
//llvm::LLVMSetTailCall(ret, True);
81+
if output.is_some() {
82+
block.end_with_return(None, ret);
83+
}
84+
else {
85+
block.end_with_void_return(None);
86+
}
6187

62-
let callee = kind.fn_name(method.name);
63-
let args: Vec<_> = types.iter().enumerate()
64-
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
65-
.collect();
66-
let callee = context.new_function(None, FunctionType::Extern, output.unwrap_or(void), &args, callee, false);
67-
#[cfg(feature="master")]
68-
callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
69-
70-
let block = func.new_block("entry");
71-
72-
let args = args
73-
.iter()
74-
.enumerate()
75-
.map(|(i, _)| func.get_param(i as i32).to_rvalue())
76-
.collect::<Vec<_>>();
77-
let ret = context.new_call(None, callee, &args);
78-
//llvm::LLVMSetTailCall(ret, True);
79-
if output.is_some() {
80-
block.end_with_return(None, ret);
81-
}
82-
else {
83-
block.end_with_void_return(None);
88+
// TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances
89+
// as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643
8490
}
85-
86-
// TODO(@Commeownist): Check if we need to emit some extra debugging info in certain circumstances
87-
// as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643
8891
}
8992

9093
let types = [usize, usize];
@@ -99,7 +102,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
99102
func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden));
100103
}
101104

102-
let callee = alloc_error_handler_kind.fn_name(sym::oom);
105+
let callee = alloc_error_handler_name(alloc_error_handler_kind);
103106
let args: Vec<_> = types.iter().enumerate()
104107
.map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index)))
105108
.collect();

0 commit comments

Comments
 (0)