Skip to content

Commit d3bb097

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 2295a4b commit d3bb097

File tree

15 files changed

+109
-249
lines changed

15 files changed

+109
-249
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 const ALLOC_ERROR_HANDLER: &str = "__rust_alloc_error_handler";
1915
pub const ALLOC_ERROR_HANDLER_DEFAULT: &str = "__rdl_oom";
2016
pub const NO_ALLOC_SHIM_IS_UNSTABLE: &str = "__rust_no_alloc_shim_is_unstable_v2";

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 13 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,37 @@
33

44
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
55
use rustc_ast::expand::allocator::{
6-
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind,
7-
AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
6+
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE,
87
};
9-
use rustc_codegen_ssa::base::allocator_kind_for_codegen;
8+
use rustc_codegen_ssa::base::needs_allocator_shim;
109
use rustc_session::config::OomStrategy;
1110
use rustc_symbol_mangling::mangle_internal_symbol;
1211

1312
use crate::prelude::*;
1413

1514
/// Returns whether an allocator shim was created
1615
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
17-
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-
);
25-
true
16+
if needs_allocator_shim(tcx) {
17+
codegen_inner(
18+
tcx,
19+
module,
20+
tcx.alloc_error_handler_kind(()).unwrap(),
21+
tcx.sess.opts.unstable_opts.oom,
22+
);
23+
true
24+
} else {
25+
false
26+
}
2627
}
2728

2829
fn codegen_inner(
2930
tcx: TyCtxt<'_>,
3031
module: &mut dyn Module,
31-
kind: AllocatorKind,
3232
alloc_error_handler_kind: AllocatorKind,
3333
oom_strategy: OomStrategy,
3434
) {
3535
let usize_ty = module.target_config().pointer_type();
3636

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"),
50-
}
51-
}
52-
let output = match method.output {
53-
AllocatorTy::ResultPtr => Some(usize_ty),
54-
AllocatorTy::Unit => None,
55-
56-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
57-
panic!("invalid allocator output")
58-
}
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-
);
72-
}
73-
}
74-
7537
if alloc_error_handler_kind == AllocatorKind::Default {
7638
let sig = Signature {
7739
call_conv: module.target_config().default_call_conv,

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 @@ use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type};
22
#[cfg(feature = "master")]
33
use gccjit::{FnAttribute, VarAttribute};
44
use rustc_ast::expand::allocator::{
5-
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind,
6-
AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
5+
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE,
76
};
87
use rustc_middle::bug;
98
use rustc_middle::ty::TyCtxt;
@@ -18,7 +17,6 @@ pub(crate) unsafe fn codegen(
1817
tcx: TyCtxt<'_>,
1918
mods: &mut GccContext,
2019
_module_name: &str,
21-
kind: AllocatorKind,
2220
alloc_error_handler_kind: AllocatorKind,
2321
) {
2422
let context = &mods.context;
@@ -29,37 +27,6 @@ pub(crate) unsafe fn codegen(
2927
tws => bug!("Unsupported target word size for int: {}", tws),
3028
};
3129
let i8 = context.new_type::<i8>();
32-
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"),
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-
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);
61-
}
62-
}
6330

6431
if alloc_error_handler_kind == AllocatorKind::Default {
6532
// FIXME(bjorn3): Add noreturn attribute

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ impl ExtraBackendMethods for GccCodegenBackend {
281281
&self,
282282
tcx: TyCtxt<'_>,
283283
module_name: &str,
284-
kind: AllocatorKind,
285284
alloc_error_handler_kind: AllocatorKind,
286285
) -> Self::Module {
287286
let mut mods = GccContext {
@@ -292,7 +291,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
292291
};
293292

294293
unsafe {
295-
allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind);
294+
allocator::codegen(tcx, &mut mods, module_name, alloc_error_handler_kind);
296295
}
297296
mods
298297
}

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-
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, ALLOCATOR_METHODS, AllocatorKind,
4-
AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, default_fn_name, global_fn_name,
3+
ALLOC_ERROR_HANDLER, ALLOC_ERROR_HANDLER_DEFAULT, AllocatorKind, NO_ALLOC_SHIM_IS_UNSTABLE,
54
};
65
use rustc_codegen_ssa::traits::BaseTypeCodegenMethods as _;
76
use rustc_middle::bug;
@@ -18,7 +17,6 @@ pub(crate) unsafe fn codegen(
1817
tcx: TyCtxt<'_>,
1918
cx: SimpleCx<'_>,
2019
module_name: &str,
21-
kind: AllocatorKind,
2220
alloc_error_handler_kind: AllocatorKind,
2321
) {
2422
let usize = match tcx.sess.target.pointer_width {
@@ -28,38 +26,6 @@ pub(crate) unsafe fn codegen(
2826
tws => bug!("Unsupported target word size for int: {}", tws),
2927
};
3028
let i8 = cx.type_i8();
31-
let i8p = cx.type_ptr();
32-
33-
if kind == AllocatorKind::Default {
34-
for method in ALLOCATOR_METHODS {
35-
let mut args = Vec::with_capacity(method.inputs.len());
36-
for input in method.inputs.iter() {
37-
match input.ty {
38-
AllocatorTy::Layout => {
39-
args.push(usize); // size
40-
args.push(usize); // align
41-
}
42-
AllocatorTy::Ptr => args.push(i8p),
43-
AllocatorTy::Usize => args.push(usize),
44-
45-
AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
46-
}
47-
}
48-
let output = match method.output {
49-
AllocatorTy::ResultPtr => Some(i8p),
50-
AllocatorTy::Unit => None,
51-
52-
AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
53-
panic!("invalid allocator output")
54-
}
55-
};
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, &cx, &from_name, Some(&to_name), &args, output, false);
61-
}
62-
}
6329

6430
if alloc_error_handler_kind == AllocatorKind::Default {
6531
// rust alloc error handler

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,13 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
108108
&self,
109109
tcx: TyCtxt<'tcx>,
110110
module_name: &str,
111-
kind: AllocatorKind,
112111
alloc_error_handler_kind: AllocatorKind,
113112
) -> ModuleLlvm {
114113
let module_llvm = ModuleLlvm::new_metadata(tcx, module_name);
115114
let cx =
116115
SimpleCx::new(module_llvm.llmod(), &module_llvm.llcx, tcx.data_layout.pointer_size);
117116
unsafe {
118-
allocator::codegen(tcx, cx, module_name, kind, alloc_error_handler_kind);
117+
allocator::codegen(tcx, cx, module_name, alloc_error_handler_kind);
119118
}
120119
module_llvm
121120
}

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
2020
use rustc_target::spec::{SanitizerSet, TlsModel};
2121
use tracing::debug;
2222

23-
use crate::base::allocator_kind_for_codegen;
23+
use crate::base::needs_allocator_shim;
2424

2525
fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
2626
crates_export_threshold(tcx.crate_types())
@@ -214,7 +214,7 @@ fn exported_symbols_provider_local<'tcx>(
214214
}
215215

216216
// Mark allocator shim symbols as exported only if they were generated.
217-
if allocator_kind_for_codegen(tcx).is_some() {
217+
if needs_allocator_shim(tcx) {
218218
for symbol_name in ALLOCATOR_METHODS
219219
.iter()
220220
.map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))

compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::time::{Duration, Instant};
66
use itertools::Itertools;
77
use rustc_abi::FIRST_VARIANT;
88
use rustc_ast as ast;
9-
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name};
9+
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, global_fn_name};
1010
use rustc_attr_data_structures::OptimizeAttr;
1111
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
1212
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
@@ -648,7 +648,7 @@ pub fn collect_debugger_visualizers_transitive(
648648
/// Decide allocator kind to codegen. If `Some(_)` this will be the same as
649649
/// `tcx.allocator_kind`, but it may be `None` in more cases (e.g. if using
650650
/// allocator definitions from a dylib dependency).
651-
pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
651+
pub fn needs_allocator_shim(tcx: TyCtxt<'_>) -> bool {
652652
// If the crate doesn't have an `allocator_kind` set then there's definitely
653653
// no shim to generate. Otherwise we also check our dependency graph for all
654654
// our output crate types. If anything there looks like its a `Dynamic`
@@ -659,7 +659,7 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
659659
use rustc_middle::middle::dependency_format::Linkage;
660660
list.iter().any(|&linkage| linkage == Linkage::Dynamic)
661661
});
662-
if any_dynamic_crate { None } else { tcx.allocator_kind(()) }
662+
if any_dynamic_crate { false } else { tcx.allocator_kind(()).is_some() }
663663
}
664664

665665
pub fn codegen_crate<B: ExtraBackendMethods>(
@@ -705,14 +705,13 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
705705
let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu);
706706

707707
// Codegen an allocator shim, if necessary.
708-
if let Some(kind) = allocator_kind_for_codegen(tcx) {
708+
if needs_allocator_shim(tcx) {
709709
let llmod_id =
710710
cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
711711
let module_llvm = tcx.sess.time("write_allocator_module", || {
712712
backend.codegen_allocator(
713713
tcx,
714714
&llmod_id,
715-
kind,
716715
// If allocator_kind is Some then alloc_error_handler_kind must
717716
// also be Some.
718717
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
@@ -107,7 +107,6 @@ pub trait ExtraBackendMethods:
107107
&self,
108108
tcx: TyCtxt<'tcx>,
109109
module_name: &str,
110-
kind: AllocatorKind,
111110
alloc_error_handler_kind: AllocatorKind,
112111
) -> Self::Module;
113112

compiler/rustc_metadata/src/creader.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,8 @@ fn fn_spans(krate: &ast::Crate, name: Symbol) -> Vec<Span> {
14061406
if let Some(ident) = item.kind.ident()
14071407
&& ident.name == self.name
14081408
&& attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol)
1409+
// Ignore the default allocator in libstd with weak linkage
1410+
&& attr::find_by_name(&item.attrs, sym::linkage).is_none()
14091411
{
14101412
self.spans.push(item.span);
14111413
}

0 commit comments

Comments
 (0)