1
1
use crate :: attributes;
2
2
use libc:: c_uint;
3
- use rustc_ast:: expand:: allocator:: { AllocatorKind , AllocatorTy , ALLOCATOR_METHODS } ;
3
+ use rustc_ast:: expand:: allocator:: {
4
+ alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind , AllocatorTy ,
5
+ ALLOCATOR_METHODS , NO_ALLOC_SHIM_IS_UNSTABLE ,
6
+ } ;
4
7
use rustc_middle:: bug;
5
8
use rustc_middle:: ty:: TyCtxt ;
6
9
use rustc_session:: config:: { DebugInfo , OomStrategy } ;
7
- use rustc_span:: symbol:: sym;
8
10
9
11
use crate :: debuginfo;
10
12
use crate :: llvm:: { self , False , True } ;
@@ -29,75 +31,78 @@ pub(crate) unsafe fn codegen(
29
31
let i8p = llvm:: LLVMPointerType ( i8, 0 ) ;
30
32
let void = llvm:: LLVMVoidTypeInContext ( llcx) ;
31
33
32
- for method in ALLOCATOR_METHODS {
33
- let mut args = Vec :: with_capacity ( method. inputs . len ( ) ) ;
34
- for ty in method. inputs . iter ( ) {
35
- match * ty {
36
- AllocatorTy :: Layout => {
37
- args. push ( usize) ; // size
38
- args. push ( usize) ; // align
34
+ if kind == AllocatorKind :: Default {
35
+ for method in ALLOCATOR_METHODS {
36
+ let mut args = Vec :: with_capacity ( method. inputs . len ( ) ) ;
37
+ for ty in method. inputs . iter ( ) {
38
+ match * 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" ) ,
39
47
}
40
- AllocatorTy :: Ptr => args. push ( i8p) ,
41
- AllocatorTy :: Usize => args. push ( usize) ,
42
-
43
- AllocatorTy :: ResultPtr | AllocatorTy :: Unit => panic ! ( "invalid allocator arg" ) ,
44
48
}
45
- }
46
- let output = match method. output {
47
- AllocatorTy :: ResultPtr => Some ( i8p) ,
48
- AllocatorTy :: Unit => None ,
49
+ let output = match method. output {
50
+ AllocatorTy :: ResultPtr => Some ( i8p) ,
51
+ AllocatorTy :: Unit => None ,
49
52
50
- AllocatorTy :: Layout | AllocatorTy :: Usize | AllocatorTy :: Ptr => {
51
- panic ! ( "invalid allocator output" )
53
+ AllocatorTy :: Layout | AllocatorTy :: Usize | AllocatorTy :: Ptr => {
54
+ panic ! ( "invalid allocator output" )
55
+ }
56
+ } ;
57
+ let ty = llvm:: LLVMFunctionType (
58
+ output. unwrap_or ( void) ,
59
+ args. as_ptr ( ) ,
60
+ args. len ( ) as c_uint ,
61
+ False ,
62
+ ) ;
63
+ let name = global_fn_name ( method. name ) ;
64
+ let llfn =
65
+ llvm:: LLVMRustGetOrInsertFunction ( llmod, name. as_ptr ( ) . cast ( ) , name. len ( ) , ty) ;
66
+
67
+ if tcx. sess . target . default_hidden_visibility {
68
+ llvm:: LLVMRustSetVisibility ( llfn, llvm:: Visibility :: Hidden ) ;
69
+ }
70
+ if tcx. sess . must_emit_unwind_tables ( ) {
71
+ let uwtable = attributes:: uwtable_attr ( llcx) ;
72
+ attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Function , & [ uwtable] ) ;
52
73
}
53
- } ;
54
- let ty = llvm:: LLVMFunctionType (
55
- output. unwrap_or ( void) ,
56
- args. as_ptr ( ) ,
57
- args. len ( ) as c_uint ,
58
- False ,
59
- ) ;
60
- let name = format ! ( "__rust_{}" , method. name) ;
61
- let llfn = llvm:: LLVMRustGetOrInsertFunction ( llmod, name. as_ptr ( ) . cast ( ) , name. len ( ) , ty) ;
62
-
63
- if tcx. sess . target . default_hidden_visibility {
64
- llvm:: LLVMRustSetVisibility ( llfn, llvm:: Visibility :: Hidden ) ;
65
- }
66
- if tcx. sess . must_emit_unwind_tables ( ) {
67
- let uwtable = attributes:: uwtable_attr ( llcx) ;
68
- attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Function , & [ uwtable] ) ;
69
- }
70
74
71
- let callee = kind. fn_name ( method. name ) ;
72
- let callee =
73
- llvm:: LLVMRustGetOrInsertFunction ( llmod, callee. as_ptr ( ) . cast ( ) , callee. len ( ) , ty) ;
74
- llvm:: LLVMRustSetVisibility ( callee, llvm:: Visibility :: Hidden ) ;
75
-
76
- let llbb = llvm:: LLVMAppendBasicBlockInContext ( llcx, llfn, "entry\0 " . as_ptr ( ) . cast ( ) ) ;
77
-
78
- let llbuilder = llvm:: LLVMCreateBuilderInContext ( llcx) ;
79
- llvm:: LLVMPositionBuilderAtEnd ( llbuilder, llbb) ;
80
- let args = args
81
- . iter ( )
82
- . enumerate ( )
83
- . map ( |( i, _) | llvm:: LLVMGetParam ( llfn, i as c_uint ) )
84
- . collect :: < Vec < _ > > ( ) ;
85
- let ret = llvm:: LLVMRustBuildCall (
86
- llbuilder,
87
- ty,
88
- callee,
89
- args. as_ptr ( ) ,
90
- args. len ( ) as c_uint ,
91
- [ ] . as_ptr ( ) ,
92
- 0 as c_uint ,
93
- ) ;
94
- llvm:: LLVMSetTailCall ( ret, True ) ;
95
- if output. is_some ( ) {
96
- llvm:: LLVMBuildRet ( llbuilder, ret) ;
97
- } else {
98
- llvm:: LLVMBuildRetVoid ( llbuilder) ;
75
+ let callee = default_fn_name ( method. name ) ;
76
+ let callee =
77
+ llvm:: LLVMRustGetOrInsertFunction ( llmod, callee. as_ptr ( ) . cast ( ) , callee. len ( ) , ty) ;
78
+ llvm:: LLVMRustSetVisibility ( callee, llvm:: Visibility :: Hidden ) ;
79
+
80
+ let llbb = llvm:: LLVMAppendBasicBlockInContext ( llcx, llfn, "entry\0 " . as_ptr ( ) . cast ( ) ) ;
81
+
82
+ let llbuilder = llvm:: LLVMCreateBuilderInContext ( llcx) ;
83
+ llvm:: LLVMPositionBuilderAtEnd ( llbuilder, llbb) ;
84
+ let args = args
85
+ . iter ( )
86
+ . enumerate ( )
87
+ . map ( |( i, _) | llvm:: LLVMGetParam ( llfn, i as c_uint ) )
88
+ . collect :: < Vec < _ > > ( ) ;
89
+ let ret = llvm:: LLVMRustBuildCall (
90
+ llbuilder,
91
+ ty,
92
+ callee,
93
+ args. as_ptr ( ) ,
94
+ args. len ( ) as c_uint ,
95
+ [ ] . as_ptr ( ) ,
96
+ 0 as c_uint ,
97
+ ) ;
98
+ llvm:: LLVMSetTailCall ( ret, True ) ;
99
+ if output. is_some ( ) {
100
+ llvm:: LLVMBuildRet ( llbuilder, ret) ;
101
+ } else {
102
+ llvm:: LLVMBuildRetVoid ( llbuilder) ;
103
+ }
104
+ llvm:: LLVMDisposeBuilder ( llbuilder) ;
99
105
}
100
- llvm:: LLVMDisposeBuilder ( llbuilder) ;
101
106
}
102
107
103
108
// rust alloc error handler
@@ -118,7 +123,7 @@ pub(crate) unsafe fn codegen(
118
123
attributes:: apply_to_llfn ( llfn, llvm:: AttributePlace :: Function , & [ uwtable] ) ;
119
124
}
120
125
121
- let callee = alloc_error_handler_kind . fn_name ( sym :: oom ) ;
126
+ let callee = alloc_error_handler_name ( alloc_error_handler_kind ) ;
122
127
let callee = llvm:: LLVMRustGetOrInsertFunction ( llmod, callee. as_ptr ( ) . cast ( ) , callee. len ( ) , ty) ;
123
128
// -> ! DIFlagNoReturn
124
129
attributes:: apply_to_llfn ( callee, llvm:: AttributePlace :: Function , & [ no_return] ) ;
@@ -156,6 +161,14 @@ pub(crate) unsafe fn codegen(
156
161
let llval = llvm:: LLVMConstInt ( i8, val as u64 , False ) ;
157
162
llvm:: LLVMSetInitializer ( ll_g, llval) ;
158
163
164
+ let name = NO_ALLOC_SHIM_IS_UNSTABLE ;
165
+ let ll_g = llvm:: LLVMRustGetOrInsertGlobal ( llmod, name. as_ptr ( ) . cast ( ) , name. len ( ) , i8) ;
166
+ if tcx. sess . target . default_hidden_visibility {
167
+ llvm:: LLVMRustSetVisibility ( ll_g, llvm:: Visibility :: Hidden ) ;
168
+ }
169
+ let llval = llvm:: LLVMConstInt ( i8, 0 , False ) ;
170
+ llvm:: LLVMSetInitializer ( ll_g, llval) ;
171
+
159
172
if tcx. sess . opts . debuginfo != DebugInfo :: None {
160
173
let dbg_cx = debuginfo:: CodegenUnitDebugContext :: new ( llmod) ;
161
174
debuginfo:: metadata:: build_compile_unit_di_node ( tcx, module_name, & dbg_cx) ;
0 commit comments