Skip to content

Commit 1a51663

Browse files
committed
[WIP] Use weak linkage instead of compiler generated shims
This is still keeping the allocator shim for the oom handler and the __rust_no_alloc_shim_is_unstable symbol for now. TODO: Update comments everywhere and test on macOS and Windows
1 parent 3bf62cc commit 1a51663

File tree

15 files changed

+107
-245
lines changed

15 files changed

+107
-245
lines changed

compiler/rustc_ast/src/expand/allocator.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@ pub fn global_fn_name(base: Symbol) -> String {
1111
format!("__rust_{base}")
1212
}
1313

14-
pub fn default_fn_name(base: Symbol) -> String {
15-
format!("__rdl_{base}")
16-
}
17-
1814
pub fn alloc_error_handler_name(alloc_error_handler_kind: AllocatorKind) -> &'static str {
1915
match alloc_error_handler_kind {
2016
AllocatorKind::Global => "__rg_oom",

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,34 @@
22
// Adapted from rustc
33

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+
AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name,
76
};
8-
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
7+
use rustc_codegen_ssa::base::needs_allocator_shim;
98
use rustc_session::config::OomStrategy;
109

1110
use crate::prelude::*;
1211

1312
/// Returns whether an allocator shim was created
1413
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
15-
let Some(kind) = allocator_kind_for_codegen(tcx) else { return false };
16-
codegen_inner(
17-
module,
18-
kind,
19-
tcx.alloc_error_handler_kind(()).unwrap(),
20-
tcx.sess.opts.unstable_opts.oom,
21-
);
22-
true
14+
if needs_allocator_shim(tcx) {
15+
codegen_inner(
16+
module,
17+
tcx.alloc_error_handler_kind(()).unwrap(),
18+
tcx.sess.opts.unstable_opts.oom,
19+
);
20+
true
21+
} else {
22+
false
23+
}
2324
}
2425

2526
fn codegen_inner(
2627
module: &mut dyn Module,
27-
kind: AllocatorKind,
2828
alloc_error_handler_kind: AllocatorKind,
2929
oom_strategy: OomStrategy,
3030
) {
3131
let usize_ty = module.target_config().pointer_type();
3232

33-
if kind == AllocatorKind::Default {
34-
for method in ALLOCATOR_METHODS {
35-
let mut arg_tys = Vec::with_capacity(method.inputs.len());
36-
for input in method.inputs.iter() {
37-
match input.ty {
38-
AllocatorTy::Layout => {
39-
arg_tys.push(usize_ty); // size
40-
arg_tys.push(usize_ty); // align
41-
}
42-
AllocatorTy::Ptr => arg_tys.push(usize_ty),
43-
AllocatorTy::Usize => arg_tys.push(usize_ty),
44-
45-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
46-
}
47-
}
48-
let output = match method.output {
49-
AllocatorTy::ResultPtr => Some(usize_ty),
50-
AllocatorTy::Unit => None,
51-
52-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
53-
panic!("invalid allocator output")
54-
}
55-
};
56-
57-
let sig = Signature {
58-
call_conv: module.target_config().default_call_conv,
59-
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
60-
returns: output.into_iter().map(AbiParam::new).collect(),
61-
};
62-
crate::common::create_wrapper_function(
63-
module,
64-
sig,
65-
&global_fn_name(method.name),
66-
&default_fn_name(method.name),
67-
);
68-
}
69-
}
70-
7133
let sig = Signature {
7234
call_conv: module.target_config().default_call_conv,
7335
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
use gccjit::FnAttribute;
33
use gccjit::{Context, FunctionType, GlobalKind, 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+
AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name,
76
};
87
use rustc_middle::bug;
98
use rustc_middle::ty::TyCtxt;
@@ -15,7 +14,6 @@ pub(crate) unsafe fn codegen(
1514
tcx: TyCtxt<'_>,
1615
mods: &mut GccContext,
1716
_module_name: &str,
18-
kind: AllocatorKind,
1917
alloc_error_handler_kind: AllocatorKind,
2018
) {
2119
let context = &mods.context;
@@ -26,37 +24,6 @@ pub(crate) unsafe fn codegen(
2624
tws => bug!("Unsupported target word size for int: {}", tws),
2725
};
2826
let i8 = context.new_type::<i8>();
29-
let i8p = i8.make_pointer();
30-
31-
if kind == AllocatorKind::Default {
32-
for method in ALLOCATOR_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);
39-
}
40-
AllocatorTy::Ptr => types.push(i8p),
41-
AllocatorTy::Usize => types.push(usize),
42-
43-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
44-
}
45-
}
46-
let output = match method.output {
47-
AllocatorTy::ResultPtr => Some(i8p),
48-
AllocatorTy::Unit => None,
49-
50-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
51-
panic!("invalid allocator output")
52-
}
53-
};
54-
let from_name = global_fn_name(method.name);
55-
let to_name = default_fn_name(method.name);
56-
57-
create_wrapper_function(tcx, context, &from_name, &to_name, &types, output);
58-
}
59-
}
6027

6128
// FIXME(bjorn3): Add noreturn attribute
6229
create_wrapper_function(

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,6 @@ impl ExtraBackendMethods for GccCodegenBackend {
291291
&self,
292292
tcx: TyCtxt<'_>,
293293
module_name: &str,
294-
kind: AllocatorKind,
295294
alloc_error_handler_kind: AllocatorKind,
296295
) -> Self::Module {
297296
let mut mods = GccContext {
@@ -301,7 +300,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
301300
};
302301

303302
unsafe {
304-
allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind);
303+
allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind);
305304
}
306305
mods
307306
}

compiler/rustc_codegen_llvm/src/allocator.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use libc::c_uint;
22
use rustc_ast::expand::allocator::{
3-
ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
4-
alloc_error_handler_name, default_fn_name, global_fn_name,
3+
AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name,
54
};
65
use rustc_middle::bug;
76
use rustc_middle::ty::TyCtxt;
@@ -15,7 +14,6 @@ pub(crate) unsafe fn codegen(
1514
tcx: TyCtxt<'_>,
1615
module_llvm: &mut ModuleLlvm,
1716
module_name: &str,
18-
kind: AllocatorKind,
1917
alloc_error_handler_kind: AllocatorKind,
2018
) {
2119
let llcx = &*module_llvm.llcx;
@@ -29,38 +27,6 @@ pub(crate) unsafe fn codegen(
2927
}
3028
};
3129
let i8 = unsafe { llvm::LLVMInt8TypeInContext(llcx) };
32-
let i8p = unsafe { llvm::LLVMPointerTypeInContext(llcx, 0) };
33-
34-
if kind == AllocatorKind::Default {
35-
for method in ALLOCATOR_METHODS {
36-
let mut args = Vec::with_capacity(method.inputs.len());
37-
for input in method.inputs.iter() {
38-
match input.ty {
39-
AllocatorTy::Layout => {
40-
args.push(usize); // size
41-
args.push(usize); // align
42-
}
43-
AllocatorTy::Ptr => args.push(i8p),
44-
AllocatorTy::Usize => args.push(usize),
45-
46-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
47-
}
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")
55-
}
56-
};
57-
58-
let from_name = global_fn_name(method.name);
59-
let to_name = default_fn_name(method.name);
60-
61-
create_wrapper_function(tcx, llcx, llmod, &from_name, &to_name, &args, output, false);
62-
}
63-
}
6430

6531
// rust alloc error handler
6632
create_wrapper_function(

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,11 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
114114
&self,
115115
tcx: TyCtxt<'tcx>,
116116
module_name: &str,
117-
kind: AllocatorKind,
118117
alloc_error_handler_kind: AllocatorKind,
119118
) -> ModuleLlvm {
120119
let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
121120
unsafe {
122-
allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind);
121+
allocator::codegen(tcx, &mut module_llvm, module_name, alloc_error_handler_kind);
123122
}
124123
module_llvm
125124
}

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_session::config::{CrateType, OomStrategy};
1616
use rustc_target::spec::{SanitizerSet, TlsModel};
1717
use tracing::debug;
1818

19-
use crate::base::allocator_kind_for_codegen;
19+
use crate::base::needs_allocator_shim;
2020

2121
fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
2222
crates_export_threshold(tcx.crate_types())
@@ -206,7 +206,7 @@ fn exported_symbols_provider_local(
206206
}
207207

208208
// Mark allocator shim symbols as exported only if they were generated.
209-
if allocator_kind_for_codegen(tcx).is_some() {
209+
if needs_allocator_shim(tcx) {
210210
for symbol_name in ALLOCATOR_METHODS
211211
.iter()
212212
.map(|method| format!("__rust_{}", method.name))

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::time::{Duration, Instant};
44

55
use itertools::Itertools;
66
use rustc_abi::FIRST_VARIANT;
7-
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name};
7+
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, global_fn_name};
88
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
99
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
1010
use rustc_data_structures::sync::{Lrc, par_map};
@@ -584,7 +584,7 @@ pub fn collect_debugger_visualizers_transitive(
584584
/// Decide allocator kind to codegen. If `Some(_)` this will be the same as
585585
/// `tcx.allocator_kind`, but it may be `None` in more cases (e.g. if using
586586
/// allocator definitions from a dylib dependency).
587-
pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
587+
pub fn needs_allocator_shim(tcx: TyCtxt<'_>) -> bool {
588588
// If the crate doesn't have an `allocator_kind` set then there's definitely
589589
// no shim to generate. Otherwise we also check our dependency graph for all
590590
// our output crate types. If anything there looks like its a `Dynamic`
@@ -595,7 +595,7 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
595595
use rustc_middle::middle::dependency_format::Linkage;
596596
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
597597
});
598-
if any_dynamic_crate { None } else { tcx.allocator_kind(()) }
598+
if any_dynamic_crate { false } else { tcx.allocator_kind(()).is_some() }
599599
}
600600

601601
pub fn codegen_crate<B: ExtraBackendMethods>(
@@ -664,14 +664,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
664664
start_async_codegen(backend.clone(), tcx, target_cpu, metadata, metadata_module);
665665

666666
// Codegen an allocator shim, if necessary.
667-
if let Some(kind) = allocator_kind_for_codegen(tcx) {
667+
if needs_allocator_shim(tcx) {
668668
let llmod_id =
669669
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
670670
let module_llvm = tcx.sess.time("write_allocator_module", || {
671671
backend.codegen_allocator(
672672
tcx,
673673
&llmod_id,
674-
kind,
675674
// If allocator_kind is Some then alloc_error_handler_kind must
676675
// also be Some.
677676
tcx.alloc_error_handler_kind(()).unwrap(),

compiler/rustc_codegen_ssa/src/traits/backend.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ pub trait ExtraBackendMethods:
104104
&self,
105105
tcx: TyCtxt<'tcx>,
106106
module_name: &str,
107-
kind: AllocatorKind,
108107
alloc_error_handler_kind: AllocatorKind,
109108
) -> Self::Module;
110109

compiler/rustc_metadata/src/creader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,6 +1127,8 @@ fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
11271127
fn visit_item(&mut self, item: &'ast ast::Item) {
11281128
if item.ident.name == self.name
11291129
&& attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
1130+
// Ignore the default allocator in libstd with weak linkage
1131+
&& attr::find_by_name(&item.attrs, sym::linkage).is_none()
11301132
{
11311133
self.spans.push(item.span);
11321134
}

0 commit comments

Comments
 (0)