Skip to content

Commit c2a135b

Browse files
committed
Handle oom strategy in a weak symbol like manner
1 parent a71ba55 commit c2a135b

File tree

12 files changed

+131
-122
lines changed

12 files changed

+131
-122
lines changed

compiler/rustc_builtin_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ mod trace_macros;
5656
pub mod asm;
5757
pub mod cmdline_attrs;
5858
pub mod contracts;
59+
pub mod oom_strategy;
5960
pub mod proc_macro_harness;
6061
pub mod standard_library_imports;
6162
pub mod test_harness;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use rustc_ast::expand::allocator::global_fn_name;
2+
use rustc_ast::{ast, token};
3+
use rustc_expand::base::{ExtCtxt, ResolverExpand};
4+
use rustc_expand::expand::{AstFragment, ExpansionConfig};
5+
use rustc_feature::Features;
6+
use rustc_session::Session;
7+
use rustc_session::config::OomStrategy;
8+
use rustc_span::hygiene::AstPass;
9+
use rustc_span::{DUMMY_SP, Ident, Symbol, kw, sym};
10+
use smallvec::smallvec;
11+
use thin_vec::thin_vec;
12+
13+
pub fn inject(
14+
krate: &mut ast::Crate,
15+
sess: &Session,
16+
features: &Features,
17+
resolver: &mut dyn ResolverExpand,
18+
) {
19+
if sess.opts.unstable_opts.oom == OomStrategy::Abort {
20+
// Handled in the allocator shim
21+
return;
22+
}
23+
24+
let econfig = ExpansionConfig::default(sym::alloc_error_handler, features);
25+
let mut ecx = ExtCtxt::new(sess, econfig, resolver, None);
26+
27+
let expn_id = ecx.resolver.expansion_for_ast_pass(
28+
DUMMY_SP,
29+
AstPass::OomStrategy,
30+
&[sym::rustc_attrs],
31+
None,
32+
);
33+
let sp = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
34+
35+
let decl = ecx.fn_decl(
36+
thin_vec![],
37+
ast::FnRetTy::Ty(
38+
ecx.ty(sp, ast::TyKind::Path(None, ecx.path_ident(sp, Ident::new(sym::u8, sp)))),
39+
),
40+
);
41+
let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp };
42+
let oom_strategy_fn = Box::new(ast::Fn {
43+
defaultness: ast::Defaultness::Final,
44+
ident: Ident::new(Symbol::intern(&global_fn_name(OomStrategy::SYMBOL)), sp),
45+
generics: ast::Generics::default(),
46+
sig,
47+
contract: None,
48+
define_opaque: None,
49+
body: Some(ecx.block_expr({
50+
let suffix = Some(ast::UintTy::U8.name());
51+
let lit = token::Lit::new(token::Integer, sym::integer(1), suffix);
52+
ecx.expr(sp, ast::ExprKind::Lit(lit))
53+
})),
54+
});
55+
56+
let oom_strategy_item = ecx.item(
57+
sp,
58+
thin_vec![ecx.attr_word(sym::rustc_std_internal_symbol, sp)],
59+
ast::ItemKind::Fn(oom_strategy_fn),
60+
);
61+
62+
let items = AstFragment::Items(smallvec![ecx.item_const(
63+
sp,
64+
Ident::new(kw::Underscore, sp),
65+
ecx.ty(sp, ast::TyKind::Tup(thin_vec![])),
66+
ecx.expr_block(ecx.block(sp, thin_vec![ecx.stmt_item(sp, oom_strategy_item)])),
67+
)]);
68+
krate
69+
.items
70+
.push(ecx.monotonic_expander().fully_expand_fragment(items).make_items().pop().unwrap());
71+
}

compiler/rustc_codegen_cranelift/src/allocator.rs

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,7 @@ use crate::prelude::*;
1515
/// Returns whether an allocator shim was created
1616
pub(crate) fn codegen(tcx: TyCtxt<'_>, module: &mut dyn Module) -> bool {
1717
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-
);
18+
codegen_inner(tcx, module, kind, tcx.alloc_error_handler_kind(()).unwrap());
2519
true
2620
}
2721

@@ -30,7 +24,6 @@ fn codegen_inner(
3024
module: &mut dyn Module,
3125
kind: AllocatorKind,
3226
alloc_error_handler_kind: AllocatorKind,
33-
oom_strategy: OomStrategy,
3427
) {
3528
let usize_ty = module.target_config().pointer_type();
3629

@@ -86,33 +79,18 @@ fn codegen_inner(
8679
);
8780
}
8881

89-
{
82+
if tcx.sess.opts.unstable_opts.oom == OomStrategy::Abort {
9083
let sig = Signature {
9184
call_conv: module.target_config().default_call_conv,
9285
params: vec![],
9386
returns: vec![AbiParam::new(types::I8)],
9487
};
95-
let func_id = module
96-
.declare_function(
97-
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
98-
Linkage::Export,
99-
&sig,
100-
)
101-
.unwrap();
102-
let mut ctx = Context::new();
103-
ctx.func.signature = sig;
104-
{
105-
let mut func_ctx = FunctionBuilderContext::new();
106-
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
107-
108-
let block = bcx.create_block();
109-
bcx.switch_to_block(block);
110-
let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64);
111-
bcx.ins().return_(&[value]);
112-
bcx.seal_all_blocks();
113-
bcx.finalize();
114-
}
115-
module.define_function(func_id, &mut ctx).unwrap();
88+
crate::common::create_wrapper_function(
89+
module,
90+
sig,
91+
&mangle_internal_symbol(tcx, &global_fn_name(OomStrategy::SYMBOL)),
92+
&mangle_internal_symbol(tcx, &default_fn_name(OomStrategy::SYMBOL)),
93+
);
11694
}
11795

11896
{

compiler/rustc_codegen_gcc/src/allocator.rs

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#[cfg(feature = "master")]
22
use gccjit::FnAttribute;
3-
use gccjit::{Context, FunctionType, RValue, ToRValue, Type};
3+
use gccjit::{Context, FunctionType, ToRValue, Type};
44
use rustc_ast::expand::allocator::{
55
ALLOC_ERROR_HANDLER, ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE,
66
default_fn_name, global_fn_name,
@@ -73,13 +73,16 @@ pub(crate) unsafe fn codegen(
7373
);
7474
}
7575

76-
create_const_value_function(
77-
tcx,
78-
context,
79-
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
80-
i8,
81-
context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32),
82-
);
76+
if tcx.sess.opts.unstable_opts.oom == OomStrategy::Abort {
77+
create_wrapper_function(
78+
tcx,
79+
context,
80+
&mangle_internal_symbol(tcx, &global_fn_name(OomStrategy::SYMBOL)),
81+
Some(&mangle_internal_symbol(tcx, &default_fn_name(OomStrategy::SYMBOL))),
82+
&[],
83+
Some(i8),
84+
);
85+
}
8386

8487
create_wrapper_function(
8588
tcx,
@@ -91,34 +94,6 @@ pub(crate) unsafe fn codegen(
9194
);
9295
}
9396

94-
fn create_const_value_function(
95-
tcx: TyCtxt<'_>,
96-
context: &Context<'_>,
97-
name: &str,
98-
output: Type<'_>,
99-
value: RValue<'_>,
100-
) {
101-
let func = context.new_function(None, FunctionType::Exported, output, &[], name, false);
102-
103-
#[cfg(feature = "master")]
104-
{
105-
func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc(
106-
tcx.sess.default_visibility(),
107-
)));
108-
109-
// FIXME(antoyo): cg_llvm sets AlwaysInline, but AlwaysInline is different in GCC and using
110-
// it here will causes linking errors when using LTO.
111-
func.add_attribute(FnAttribute::Inline);
112-
}
113-
114-
if tcx.sess.must_emit_unwind_tables() {
115-
// TODO(antoyo): emit unwind tables.
116-
}
117-
118-
let block = func.new_block("entry");
119-
block.end_with_return(None, value);
120-
}
121-
12297
fn create_wrapper_function(
12398
tcx: TyCtxt<'_>,
12499
context: &Context<'_>,

compiler/rustc_codegen_llvm/src/allocator.rs

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
1414
use crate::attributes::llfn_attrs_from_instance;
1515
use crate::builder::SBuilder;
1616
use crate::declare::declare_simple_fn;
17-
use crate::llvm::{self, FALSE, FromGeneric, TRUE, Type, Value};
17+
use crate::llvm::{self, FromGeneric, TRUE, Type};
1818
use crate::{SimpleCx, attributes, debuginfo};
1919

2020
pub(crate) unsafe fn codegen(
@@ -97,16 +97,19 @@ pub(crate) unsafe fn codegen(
9797
);
9898
}
9999

100-
// __rust_alloc_error_handler_should_panic_v2
101-
create_const_value_function(
102-
tcx,
103-
&cx,
104-
&mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
105-
&i8,
106-
unsafe {
107-
llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, FALSE)
108-
},
109-
);
100+
if tcx.sess.opts.unstable_opts.oom == OomStrategy::Abort {
101+
// __rust_alloc_error_handler_should_panic_v2
102+
create_wrapper_function(
103+
tcx,
104+
&cx,
105+
&mangle_internal_symbol(tcx, &global_fn_name(OomStrategy::SYMBOL)),
106+
Some(&mangle_internal_symbol(tcx, &default_fn_name(OomStrategy::SYMBOL))),
107+
&[],
108+
Some(i8),
109+
false,
110+
&CodegenFnAttrs::new(),
111+
);
112+
}
110113

111114
// __rust_no_alloc_shim_is_unstable_v2
112115
create_wrapper_function(
@@ -127,34 +130,6 @@ pub(crate) unsafe fn codegen(
127130
}
128131
}
129132

130-
fn create_const_value_function(
131-
tcx: TyCtxt<'_>,
132-
cx: &SimpleCx<'_>,
133-
name: &str,
134-
output: &Type,
135-
value: &Value,
136-
) {
137-
let ty = cx.type_func(&[], output);
138-
let llfn = declare_simple_fn(
139-
&cx,
140-
name,
141-
llvm::CallConv::CCallConv,
142-
llvm::UnnamedAddr::Global,
143-
llvm::Visibility::from_generic(tcx.sess.default_visibility()),
144-
ty,
145-
);
146-
147-
attributes::apply_to_llfn(
148-
llfn,
149-
llvm::AttributePlace::Function,
150-
&[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)],
151-
);
152-
153-
let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) };
154-
let mut bx = SBuilder::build(&cx, llbb);
155-
bx.ret(value);
156-
}
157-
158133
fn create_wrapper_function(
159134
tcx: TyCtxt<'_>,
160135
cx: &SimpleCx<'_>,

compiler/rustc_codegen_ssa/src/back/symbol_export.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ pub(crate) fn allocator_shim_symbols(
501501
.map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
502502
.chain([
503503
mangle_internal_symbol(tcx, global_fn_name(ALLOC_ERROR_HANDLER).as_str()),
504-
mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
504+
mangle_internal_symbol(tcx, global_fn_name(OomStrategy::SYMBOL).as_str()),
505505
mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
506506
])
507507
.map(move |symbol_name| {

compiler/rustc_interface/src/passes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ fn configure_and_expand(
255255
rustc_builtin_macros::test_harness::inject(&mut krate, sess, features, resolver)
256256
});
257257

258+
rustc_builtin_macros::oom_strategy::inject(&mut krate, sess, features, resolver);
259+
258260
let has_proc_macro_decls = sess.time("AST_validation", || {
259261
rustc_ast_passes::ast_validation::check_crate(
260262
sess,

compiler/rustc_session/src/config.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3465,14 +3465,7 @@ pub enum OomStrategy {
34653465
}
34663466

34673467
impl OomStrategy {
3468-
pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic_v2";
3469-
3470-
pub fn should_panic(self) -> u8 {
3471-
match self {
3472-
OomStrategy::Panic => 1,
3473-
OomStrategy::Abort => 0,
3474-
}
3475-
}
3468+
pub const SYMBOL: Symbol = sym::alloc_error_handler_should_panic_v2;
34763469
}
34773470

34783471
/// How to run proc-macro code when building this crate

compiler/rustc_span/src/hygiene.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,7 @@ pub enum AstPass {
12041204
StdImports,
12051205
TestHarness,
12061206
ProcMacroHarness,
1207+
OomStrategy,
12071208
}
12081209

12091210
impl AstPass {
@@ -1212,6 +1213,7 @@ impl AstPass {
12121213
AstPass::StdImports => "standard library imports",
12131214
AstPass::TestHarness => "test harness",
12141215
AstPass::ProcMacroHarness => "proc macro harness",
1216+
AstPass::OomStrategy => "oom strategy definition",
12151217
}
12161218
}
12171219
}

compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ symbols! {
437437
all,
438438
alloc,
439439
alloc_error_handler,
440+
alloc_error_handler_should_panic_v2,
440441
alloc_layout,
441442
alloc_zeroed,
442443
allocator,

0 commit comments

Comments
 (0)