1
1
//! The interface to a collector
2
2
3
- use std:: ptr:: NonNull ;
4
- use std:: sync:: Arc ;
5
3
use std:: fmt:: { self , Debug , Formatter } ;
4
+ #[ cfg( feature = "multiple-collectors" ) ]
5
+ use std:: sync:: Arc ;
6
+ #[ cfg( feature = "multiple-collectors" ) ]
7
+ use std:: ptr:: NonNull ;
6
8
7
9
use slog:: { Logger , o} ;
8
10
9
11
use zerogc:: { Gc , GcSafe , GcSystem , Trace , GcSimpleAlloc } ;
10
12
11
13
use crate :: { CollectorContext , CollectionManager } ;
14
+ #[ cfg( not( feature = "multiple-collectors" ) ) ]
15
+ use std:: marker:: PhantomData ;
12
16
13
17
/// A specific implementation of a collector
14
18
pub unsafe trait RawCollectorImpl : ' static + Sized {
@@ -21,19 +25,27 @@ pub unsafe trait RawCollectorImpl: 'static + Sized {
21
25
/// Convert the specified value into a dyn pointer
22
26
unsafe fn create_dyn_pointer < T : Trace > ( t : * mut T ) -> Self :: GcDynPointer ;
23
27
28
+ /// Id of global collector, for when we aren't configured
29
+ /// to allow multiple collectors.
24
30
#[ cfg( not( feature = "multiple-collectors" ) ) ]
31
+ const GLOBAL_ID : & ' static CollectorId < Self > = & CollectorId { _marker : PhantomData } ;
32
+
25
33
/// When the collector is a singleton,
26
34
/// return the global implementation
35
+ #[ cfg( not( feature = "multiple-collectors" ) ) ]
27
36
fn global_ptr ( ) -> * const Self ;
37
+
28
38
#[ cfg( not( feature = "multiple-collectors" ) ) ]
29
39
fn init_global ( logger : Logger ) ;
40
+
30
41
#[ cfg( feature = "multiple-collectors" ) ]
31
42
fn init ( logger : Logger ) -> NonNull < Self > ;
43
+
32
44
/// The id of this collector
33
45
#[ inline]
34
46
fn id ( & self ) -> CollectorId < Self > {
35
47
#[ cfg( not( feature = "multiple-collectors" ) ) ] {
36
- CollectorId { }
48
+ CollectorId { _marker : PhantomData }
37
49
}
38
50
#[ cfg( feature = "multiple-collectors" ) ] {
39
51
CollectorId { rc : NonNull :: from ( self ) }
@@ -63,6 +75,7 @@ impl<C: RawCollectorImpl> PartialEq for CollectorId<C> {
63
75
self . rc . as_ptr ( ) == other. rc . as_ptr ( )
64
76
}
65
77
#[ cfg( not( feature = "multiple-collectors" ) ) ] {
78
+ let CollectorId { _marker : PhantomData } = * other;
66
79
true // Singleton
67
80
}
68
81
}
@@ -103,6 +116,11 @@ pub struct CollectorId<C: RawCollectorImpl> {
103
116
///
104
117
/// We don't know whether the underlying memory will be valid.
105
118
rc : NonNull < C > ,
119
+ /// Phantom reference to `&'static C`
120
+ ///
121
+ /// This represents the fact we (statically) refer to the global instance
122
+ #[ cfg( not( feature = "multiple-collectors" ) ) ]
123
+ _marker : PhantomData < & ' static C >
106
124
}
107
125
impl < C : RawCollectorImpl > CollectorId < C > {
108
126
#[ cfg( feature = "multiple-collectors" ) ]
@@ -118,7 +136,7 @@ impl<C: RawCollectorImpl> CollectorId<C> {
118
136
#[ cfg( not( feature = "multiple-collectors" ) ) ]
119
137
#[ inline]
120
138
pub unsafe fn as_ref ( & self ) -> & C {
121
- & * GLOBAL_COLLECTOR . load ( Ordering :: Acquire )
139
+ & * C :: global_ptr ( )
122
140
}
123
141
#[ cfg( feature = "multiple-collectors" ) ]
124
142
pub unsafe fn weak_ref ( & self ) -> WeakCollectorRef < C > {
@@ -129,7 +147,7 @@ impl<C: RawCollectorImpl> CollectorId<C> {
129
147
}
130
148
#[ cfg( not( feature = "multiple-collectors" ) ) ]
131
149
pub unsafe fn weak_ref ( & self ) -> WeakCollectorRef < C > {
132
- WeakCollectorRef { }
150
+ WeakCollectorRef { _marker : PhantomData }
133
151
}
134
152
}
135
153
unsafe impl < C : RawCollectorImpl > :: zerogc:: CollectorId for CollectorId < C > {
@@ -155,16 +173,16 @@ unsafe impl<C: RawCollectorImpl> ::zerogc::CollectorId for CollectorId<C> {
155
173
& * ( self as * const CollectorId < C > as * const CollectorRef < C > )
156
174
}
157
175
#[ cfg( not( feature = "multiple-collectors" ) ) ] {
158
- // NOTE: We live forever
159
- const COLLECTOR : CollectorRef = CollectorRef { } ;
160
- & COLLECTOR
176
+ & * ( C :: GLOBAL_ID as * const CollectorId < C > as * const CollectorRef < C > )
161
177
}
162
178
}
163
179
}
164
180
165
181
pub struct WeakCollectorRef < C : RawCollectorImpl > {
166
182
#[ cfg( feature = "multiple-collectors" ) ]
167
183
weak : std:: sync:: Weak < C > ,
184
+ #[ cfg( not( feature = "multiple-collectors" ) ) ]
185
+ _marker : PhantomData < & ' static C >
168
186
}
169
187
impl < C : RawCollectorImpl > WeakCollectorRef < C > {
170
188
#[ cfg( feature = "multiple-collectors" ) ]
@@ -179,7 +197,7 @@ impl<C: RawCollectorImpl> WeakCollectorRef<C> {
179
197
}
180
198
#[ cfg( not( feature = "multiple-collectors" ) ) ]
181
199
pub unsafe fn assume_valid ( & self ) -> CollectorId < C > {
182
- CollectorId { }
200
+ CollectorId { _marker : PhantomData }
183
201
}
184
202
pub fn ensure_valid < R > ( & self , func : impl FnOnce ( CollectorId < C > ) -> R ) -> R {
185
203
self . try_ensure_valid ( |id| match id{
@@ -200,7 +218,7 @@ impl<C: RawCollectorImpl> WeakCollectorRef<C> {
200
218
#[ cfg( not( feature = "multiple-collectors" ) ) ]
201
219
pub fn try_ensure_valid < R > ( & self , func : impl FnOnce ( Option < CollectorId < C > > ) -> R ) -> R {
202
220
// global collector is always valid
203
- func ( Some ( CollectorId { } ) )
221
+ func ( Some ( CollectorId { _marker : PhantomData } ) )
204
222
}
205
223
}
206
224
@@ -224,7 +242,10 @@ pub struct CollectorRef<C: RawCollectorImpl> {
224
242
///
225
243
/// It is implemented as a raw pointer around [Arc::into_raw]
226
244
#[ cfg( feature = "multiple-collectors" ) ]
227
- rc : NonNull < C >
245
+ rc : NonNull < C > ,
246
+ /// Phantom reference to the global collector instance
247
+ #[ cfg( not( feature = "multiple-collectors" ) ) ]
248
+ _marker : PhantomData < & ' static C >
228
249
}
229
250
/// We actually are thread safe ;)
230
251
#[ cfg( feature = "sync" ) ]
@@ -241,9 +262,9 @@ impl<C: RawCollectorImpl> CollectorRef<C> {
241
262
}
242
263
#[ cfg( not( feature = "multiple-collectors" ) ) ]
243
264
pub fn with_logger ( logger : Logger ) -> Self {
244
- unsafe { C :: init_global ( logger) }
265
+ C :: init_global ( logger) ; // TODO: Is this safe?
245
266
// NOTE: The raw pointer is implicit (now that we're leaked)
246
- CollectorRef { }
267
+ CollectorRef { _marker : PhantomData }
247
268
}
248
269
249
270
#[ cfg( feature = "multiple-collectors" ) ]
@@ -262,7 +283,7 @@ impl<C: RawCollectorImpl> CollectorRef<C> {
262
283
}
263
284
#[ cfg( not( feature = "multiple-collectors" ) ) ]
264
285
pub ( crate ) fn clone_internal ( & self ) -> CollectorRef < C > {
265
- CollectorRef { }
286
+ CollectorRef { _marker : PhantomData }
266
287
}
267
288
#[ cfg( feature = "multiple-collectors" ) ]
268
289
#[ inline]
@@ -272,7 +293,7 @@ impl<C: RawCollectorImpl> CollectorRef<C> {
272
293
#[ cfg( not( feature = "multiple-collectors" ) ) ]
273
294
#[ inline]
274
295
pub fn as_raw ( & self ) -> & C {
275
- let ptr = GLOBAL_COLLECTOR . load ( Ordering :: Acquire ) ;
296
+ let ptr = C :: global_ptr ( ) ;
276
297
assert ! ( !ptr. is_null( ) ) ;
277
298
unsafe { & * ptr }
278
299
}
0 commit comments