Skip to content

Commit 35836b3

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 59177fc commit 35836b3

File tree

1 file changed

+61
-58
lines changed

1 file changed

+61
-58
lines changed

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)