about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/allocator.rs
diff options
context:
space:
mode:
authorbjorn3 <bjorn3@users.noreply.github.com>2021-07-03 16:46:41 +0200
committerbjorn3 <17426603+bjorn3@users.noreply.github.com>2023-05-11 14:23:31 +0000
commit4ce20663f767c7d1610411b21ed31db3e9af21f4 (patch)
treeb47cbfe93da3d7ffb5eeae7a49e0ac8d764a45e8 /compiler/rustc_codegen_llvm/src/allocator.rs
parent79fa6ce7a140efb47c67567f80e59a4f19b452a6 (diff)
downloadrust-4ce20663f767c7d1610411b21ed31db3e9af21f4.tar.gz
rust-4ce20663f767c7d1610411b21ed31db3e9af21f4.zip
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.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/allocator.rs')
-rw-r--r--compiler/rustc_codegen_llvm/src/allocator.rs136
1 files changed, 70 insertions, 66 deletions
diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs
index 668d9292705..acf44f3276d 100644
--- a/compiler/rustc_codegen_llvm/src/allocator.rs
+++ b/compiler/rustc_codegen_llvm/src/allocator.rs
@@ -1,10 +1,11 @@
 use crate::attributes;
 use libc::c_uint;
-use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS};
+use rustc_ast::expand::allocator::{
+    alloc_error_handler_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS,
+};
 use rustc_middle::bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{DebugInfo, OomStrategy};
-use rustc_span::symbol::sym;
 
 use crate::debuginfo;
 use crate::llvm::{self, False, True};
@@ -29,75 +30,78 @@ pub(crate) unsafe fn codegen(
     let i8p = llvm::LLVMPointerType(i8, 0);
     let void = llvm::LLVMVoidTypeInContext(llcx);
 
-    for method in ALLOCATOR_METHODS {
-        let mut args = Vec::with_capacity(method.inputs.len());
-        for ty in method.inputs.iter() {
-            match *ty {
-                AllocatorTy::Layout => {
-                    args.push(usize); // size
-                    args.push(usize); // align
+    if kind == AllocatorKind::Default {
+        for method in ALLOCATOR_METHODS {
+            let mut args = Vec::with_capacity(method.inputs.len());
+            for ty in method.inputs.iter() {
+                match *ty {
+                    AllocatorTy::Layout => {
+                        args.push(usize); // size
+                        args.push(usize); // align
+                    }
+                    AllocatorTy::Ptr => args.push(i8p),
+                    AllocatorTy::Usize => args.push(usize),
+
+                    AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
                 }
-                AllocatorTy::Ptr => args.push(i8p),
-                AllocatorTy::Usize => args.push(usize),
-
-                AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"),
             }
-        }
-        let output = match method.output {
-            AllocatorTy::ResultPtr => Some(i8p),
-            AllocatorTy::Unit => None,
+            let output = match method.output {
+                AllocatorTy::ResultPtr => Some(i8p),
+                AllocatorTy::Unit => None,
 
-            AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
-                panic!("invalid allocator output")
+                AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => {
+                    panic!("invalid allocator output")
+                }
+            };
+            let ty = llvm::LLVMFunctionType(
+                output.unwrap_or(void),
+                args.as_ptr(),
+                args.len() as c_uint,
+                False,
+            );
+            let name = format!("__rust_{}", method.name);
+            let llfn =
+                llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
+
+            if tcx.sess.target.default_hidden_visibility {
+                llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
+            }
+            if tcx.sess.must_emit_unwind_tables() {
+                let uwtable = attributes::uwtable_attr(llcx);
+                attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
             }
-        };
-        let ty = llvm::LLVMFunctionType(
-            output.unwrap_or(void),
-            args.as_ptr(),
-            args.len() as c_uint,
-            False,
-        );
-        let name = format!("__rust_{}", method.name);
-        let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty);
-
-        if tcx.sess.target.default_hidden_visibility {
-            llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-        }
-        if tcx.sess.must_emit_unwind_tables() {
-            let uwtable = attributes::uwtable_attr(llcx);
-            attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
-        }
 
-        let callee = kind.fn_name(method.name);
-        let callee =
-            llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
-        llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
-
-        let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
-
-        let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
-        llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
-        let args = args
-            .iter()
-            .enumerate()
-            .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
-            .collect::<Vec<_>>();
-        let ret = llvm::LLVMRustBuildCall(
-            llbuilder,
-            ty,
-            callee,
-            args.as_ptr(),
-            args.len() as c_uint,
-            [].as_ptr(),
-            0 as c_uint,
-        );
-        llvm::LLVMSetTailCall(ret, True);
-        if output.is_some() {
-            llvm::LLVMBuildRet(llbuilder, ret);
-        } else {
-            llvm::LLVMBuildRetVoid(llbuilder);
+            let callee = AllocatorKind::Default.fn_name(method.name);
+            let callee =
+                llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
+            llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden);
+
+            let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast());
+
+            let llbuilder = llvm::LLVMCreateBuilderInContext(llcx);
+            llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb);
+            let args = args
+                .iter()
+                .enumerate()
+                .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint))
+                .collect::<Vec<_>>();
+            let ret = llvm::LLVMRustBuildCall(
+                llbuilder,
+                ty,
+                callee,
+                args.as_ptr(),
+                args.len() as c_uint,
+                [].as_ptr(),
+                0 as c_uint,
+            );
+            llvm::LLVMSetTailCall(ret, True);
+            if output.is_some() {
+                llvm::LLVMBuildRet(llbuilder, ret);
+            } else {
+                llvm::LLVMBuildRetVoid(llbuilder);
+            }
+            llvm::LLVMDisposeBuilder(llbuilder);
         }
-        llvm::LLVMDisposeBuilder(llbuilder);
     }
 
     // rust alloc error handler
@@ -118,7 +122,7 @@ pub(crate) unsafe fn codegen(
         attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]);
     }
 
-    let callee = alloc_error_handler_kind.fn_name(sym::oom);
+    let callee = alloc_error_handler_name(alloc_error_handler_kind);
     let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty);
     // -> ! DIFlagNoReturn
     attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]);