Skip to content

Commit 08cb933

Browse files
committed
Attempt Significant API redesign
However, first I need to cleanup this 'CollectorId' mess. Transmutes and double-indirections everywhere....
1 parent 358774e commit 08cb933

File tree

13 files changed

+647
-779
lines changed

13 files changed

+647
-779
lines changed

libs/context/src/collector.rs

Lines changed: 259 additions & 116 deletions
Large diffs are not rendered by default.

libs/context/src/handle.rs

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use core::sync::atomic::{self, AtomicPtr, AtomicUsize, Ordering};
88
use alloc::boxed::Box;
99
use alloc::vec::Vec;
1010

11-
use zerogc::{Trace, GcSafe, GcErase, GcRebrand, GcVisitor, NullTrace, TraceImmutable, GcHandleSystem, GcBindHandle};
12-
use crate::{GcRef, WeakCollectorRef, CollectorId, CollectorContext, CollectorRef, CollectionManager};
13-
use crate::collector::RawCollectorImpl;
11+
use zerogc::{Trace, GcSafe, GcErase, GcRebrand, GcVisitor, NullTrace, TraceImmutable, GcHandleSystem, GcBindHandle, Gc};
12+
use crate::{WeakCollectorRef, CollectorId, CollectorContext, GarbageCollector, CollectionManager};
13+
use crate::collector::{RawCollectorImpl, CollectorPtr};
1414

1515
const INITIAL_HANDLE_CAPACITY: usize = 64;
1616

@@ -23,13 +23,6 @@ pub unsafe trait RawHandleImpl: RawCollectorImpl {
2323

2424
fn handle_list(&self) -> &GcHandleList<Self>;
2525
}
26-
/// A type hack on [RawHandleImpl] to get the associated type
27-
/// of [::zerogc::GcRef]
28-
///
29-
/// This is needed because we don't have generic associated types (yet)
30-
pub trait RawHandleImplHack<'gc, T: GcSafe + 'gc>: RawHandleImpl {
31-
type Gc: GcRef<'gc, T, Id=CollectorId<Self>>;
32-
}
3326

3427
/// Concurrent list of [GcHandle]s
3528
///
@@ -421,7 +414,7 @@ impl<T: GcSafe, C: RawHandleImpl> GcHandle<T, C> {
421414
}
422415
}
423416
unsafe impl<T: GcSafe, C: RawHandleImpl> ::zerogc::GcHandle<T> for GcHandle<T, C> {
424-
type System = CollectorRef<C>;
417+
type System = GarbageCollector<C>;
425418
type Id = CollectorId<C>;
426419

427420
fn use_critical<R>(&self, func: impl FnOnce(&T) -> R) -> R {
@@ -435,7 +428,7 @@ unsafe impl<T: GcSafe, C: RawHandleImpl> ::zerogc::GcHandle<T> for GcHandle<T, C
435428
* This is preferable to using `recursive_read`,
436429
* since that could starve writers (collectors).
437430
*/
438-
C::Manager::prevent_collection(collector.as_ref(), || {
431+
C::Manager::prevent_collection(&*collector.as_ptr(), || {
439432
let value = self.inner.as_ref().value
440433
.load(Ordering::Acquire) as *mut T;
441434
func(&*value)
@@ -444,11 +437,10 @@ unsafe impl<T: GcSafe, C: RawHandleImpl> ::zerogc::GcHandle<T> for GcHandle<T, C
444437
}
445438
}
446439
unsafe impl<'new_gc, T, C> GcBindHandle<'new_gc, T> for GcHandle<T, C>
447-
where T: GcSafe, T: GcRebrand<'new_gc, CollectorId<C>>,
448-
T::Branded: GcSafe, C: RawHandleImplHack<'new_gc, T::Branded> {
449-
type Gc = C::Gc;
440+
where T: GcSafe, T: GcRebrand<'new_gc, CollectorId<C>>, C: RawHandleImpl,
441+
T::Branded: GcSafe {
450442
#[inline]
451-
fn bind_to(&self, context: &'new_gc CollectorContext<C>) -> Self::Gc {
443+
fn bind_to(&self, context: &'new_gc CollectorContext<C>) -> Gc<'new_gc, T::Branded, CollectorId<C>>{
452444
/*
453445
* We can safely assume the object will
454446
* be as valid as long as the context.
@@ -465,16 +457,16 @@ unsafe impl<'new_gc, T, C> GcBindHandle<'new_gc, T> for GcHandle<T, C>
465457
unsafe {
466458
let collector = self.collector.assume_valid();
467459
assert_eq!(
468-
collector.as_ref() as *const C,
460+
collector.as_ptr() as *const C,
469461
context.collector() as *const C,
470462
"Collectors mismatch"
471463
);
472464
let inner = self.inner.as_ref();
473465
let value = inner.value.load(Ordering::Acquire)
474466
as *mut T as *mut T::Branded;
475467
debug_assert!(!value.is_null());
476-
Self::Gc::from_raw(
477-
collector,
468+
Gc::from_raw(
469+
CollectorId { collector },
478470
NonNull::new_unchecked(value)
479471
)
480472
}
@@ -502,7 +494,9 @@ impl<T: GcSafe, C: RawHandleImpl> Clone for GcHandle<T, C> {
502494
fn clone(&self) -> Self {
503495
// NOTE: Dead collector -> invalid handle
504496
let collector = self.collector
505-
.ensure_valid(|id| unsafe { id.weak_ref() });
497+
.ensure_valid(|id| unsafe { WeakCollectorRef {
498+
weak: id.create_weak()
499+
} });
506500
let inner = unsafe { self.inner.as_ref() };
507501
debug_assert!(
508502
!inner.value
@@ -513,7 +507,7 @@ impl<T: GcSafe, C: RawHandleImpl> Clone for GcHandle<T, C> {
513507
let mut old_refcnt = inner.refcnt.load(Ordering::Relaxed);
514508
loop {
515509
assert_ne!(
516-
old_refcnt, isize::max_value() as usize,
510+
old_refcnt, isize::MAX as usize,
517511
"Reference count overflow"
518512
);
519513
/*
@@ -552,7 +546,7 @@ impl<T: GcSafe, C: RawHandleImpl> Drop for GcHandle<T, C> {
552546
*/
553547
return;
554548
},
555-
Some(ref id) => unsafe { id.as_ref() },
549+
Some(ref id) => unsafe { &*id.as_ptr() },
556550
};
557551
let inner = unsafe { self.inner.as_ref() };
558552
debug_assert!(!inner.value
@@ -604,20 +598,19 @@ unsafe impl<T: GcSafe + Sync, C: RawHandleImpl + Sync> Send for GcHandle<T, C> {
604598
unsafe impl<T: GcSafe + Sync, C: RawHandleImpl + Sync> Sync for GcHandle<T, C> {}
605599

606600
/// We support handles
607-
unsafe impl<'gc, 'a, T, C> GcHandleSystem<'gc, 'a, T> for CollectorRef<C>
608-
where C: RawHandleImplHack<'gc, T>,
601+
unsafe impl<'gc, 'a, T, C> GcHandleSystem<'gc, 'a, T> for GarbageCollector<C>
602+
where C: RawHandleImpl,
609603
T: GcSafe + 'gc,
610604
T: GcErase<'a, CollectorId<C>>,
611605
T::Erased: GcSafe {
612-
type Gc = C::Gc;
613606
type Handle = GcHandle<T::Erased, C>;
614607

615608
#[inline]
616-
fn create_handle(gc: Self::Gc) -> Self::Handle {
609+
fn create_handle(gc: Gc<'gc, T, CollectorId<C>>) -> Self::Handle {
617610
unsafe {
618-
let collector = gc.collector_id();
611+
let collector = gc.system();
619612
let value = gc.as_raw_ptr();
620-
let raw = collector.as_ref().handle_list()
613+
let raw = collector.as_raw().handle_list()
621614
.alloc_raw_handle(value as *mut ());
622615
/*
623616
* WARN: Undefined Behavior
@@ -631,7 +624,7 @@ unsafe impl<'gc, 'a, T, C> GcHandleSystem<'gc, 'a, T> for CollectorRef<C>
631624
Ordering::Release
632625
);
633626
raw.refcnt.store(1, Ordering::Release);
634-
let weak_collector = collector.weak_ref();
627+
let weak_collector = collector.as_ref().create_weak();
635628
GcHandle::new(NonNull::from(raw), weak_collector)
636629
}
637630
}

libs/context/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ pub mod handle;
3434

3535
use crate::collector::{RawCollectorImpl};
3636

37-
pub use crate::collector::{WeakCollectorRef, CollectorRef, CollectorId};
37+
pub(crate) use crate::collector::WeakCollectorRef;
38+
pub use crate::collector::{GarbageCollector, CollectorId};
3839
pub use crate::state::{CollectionManager, RawContext};
3940

4041
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
@@ -114,7 +115,7 @@ pub struct CollectorContext<C: RawCollectorImpl> {
114115
root: bool
115116
}
116117
impl<C: RawCollectorImpl> CollectorContext<C> {
117-
pub(crate) unsafe fn register_root(collector: &CollectorRef<C>) -> Self {
118+
pub(crate) unsafe fn register_root(collector: &GarbageCollector<C>) -> Self {
118119
CollectorContext {
119120
raw: Box::into_raw(ManuallyDrop::into_inner(
120121
C::RawContext::register_new(&collector)
@@ -162,7 +163,7 @@ impl<C: RawCollectorImpl> Drop for CollectorContext<C> {
162163
}
163164
}
164165
unsafe impl<C: RawCollectorImpl> GcContext for CollectorContext<C> {
165-
type System = CollectorRef<C>;
166+
type System = GarbageCollector<C>;
166167
type Id = CollectorId<C>;
167168

168169
#[inline]

libs/context/src/state/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::collector::RawCollectorImpl;
2-
use crate::{ContextState, ShadowStack, CollectorRef};
2+
use crate::{ContextState, ShadowStack, GarbageCollector};
33

44
use core::mem::ManuallyDrop;
55
use core::fmt::Debug;
@@ -47,7 +47,7 @@ pub unsafe trait CollectionManager<C>: self::sealed::Sealed
4747
/// even if the collector supports multi-threading.
4848
pub unsafe trait RawContext<C>: Debug + self::sealed::Sealed
4949
where C: RawCollectorImpl<RawContext=Self> {
50-
unsafe fn register_new(collector: &CollectorRef<C>) -> ManuallyDrop<Box<Self>>;
50+
unsafe fn register_new(collector: &GarbageCollector<C>) -> ManuallyDrop<Box<Self>>;
5151
/// Trigger a safepoint for this context.
5252
///
5353
/// This implicitly attempts a collection,

libs/context/src/state/nosync.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ use alloc::boxed::Box;
1414

1515
use slog::{Logger, FnValue, trace, o};
1616

17-
use crate::{CollectorRef, ShadowStack, ContextState};
18-
use crate::collector::RawCollectorImpl;
17+
use crate::{GarbageCollector, ShadowStack, ContextState};
18+
use crate::collector::{RawCollectorImpl, CollectorRef};
1919

2020
/// Manages coordination of garbage collections
2121
///
2222
/// This is factored out of the main code mainly due to
2323
/// differences from single-threaded collection
2424
pub struct CollectionManager<C: RawCollectorImpl> {
2525
/// Implicit collector ref
26-
_marker: PhantomData<CollectorRef<C>>,
26+
_marker: PhantomData<GarbageCollector<C>>,
2727
/// Access to the internal state
2828
state: RefCell<CollectorState>,
2929
/// Whether a collection is currently in progress
@@ -87,7 +87,7 @@ pub struct RawContext<C: RawCollectorImpl> {
8787
/// Since we're the only context, we should (logically)
8888
/// be the only owner.
8989
///
90-
/// This is still an Arc for easier use alongside the
90+
/// This may still be an Arc for easier use alongside the
9191
/// thread-safe implementation
9292
pub(crate) collector: CollectorRef<C>,
9393
// NOTE: We are Send, not Sync
@@ -115,7 +115,7 @@ impl<C: RawCollectorImpl> Debug for RawContext<C> {
115115
impl<C: RawCollectorImpl> super::sealed::Sealed for RawContext<C> {}
116116
unsafe impl<C> super::RawContext<C> for RawContext<C>
117117
where C: RawCollectorImpl<RawContext=Self, Manager=CollectionManager<C>> {
118-
unsafe fn register_new(collector: &CollectorRef<C>) -> ManuallyDrop<Box<Self>> {
118+
unsafe fn register_new(collector: &GarbageCollector<C>) -> ManuallyDrop<Box<Self>> {
119119
assert!(!C::SYNC);
120120
// NOTE: Nosync collector must have only **ONE** context
121121
assert!(
@@ -124,7 +124,7 @@ unsafe impl<C> super::RawContext<C> for RawContext<C>
124124
"Already created a context for the collector!"
125125
);
126126
// Assume ownership
127-
let collector = collector.clone_internal();
127+
let collector = collector.as_ref().clone();
128128
let logger = collector.as_raw().logger().new(o!());
129129
let context = ManuallyDrop::new(Box::new(RawContext {
130130
logger: logger.clone(), collector,
@@ -179,7 +179,7 @@ unsafe impl<C> super::RawContext<C> for RawContext<C>
179179
self.state.replace(ContextState::Active),
180180
ContextState::SafePoint { collection_id }
181181
);
182-
assert!(self.collector.as_raw().manager().collecting.replace(false));
182+
assert!((&*self.collector.as_raw()).manager().collecting.replace(false));
183183
}
184184

185185
#[inline]

libs/context/src/state/sync.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ use parking_lot::{Mutex, RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWrite
1313
use slog::{Logger, FnValue, trace, Drain, o};
1414

1515
use super::{ShadowStack, ContextState};
16-
use crate::{RawCollectorImpl, CollectorRef};
16+
use crate::{RawCollectorImpl, GarbageCollector};
1717
use crate::utils::ThreadId;
18-
use crate::collector::SyncCollector;
18+
use crate::collector::{SyncCollector, CollectorRef};
1919

2020
/// Manages coordination of garbage collections
2121
///
@@ -104,7 +104,7 @@ unsafe impl<C> super::CollectionManager<C> for CollectionManager<C>
104104
* context's shadow stack, so unfreezing it while in progress
105105
* could trigger undefined behavior!!!!!
106106
*/
107-
context.collector.as_raw().prevent_collection(|_| {
107+
(&*context.collector.as_raw()).prevent_collection(|_| {
108108
assert_eq!(context.state.get(), ContextState::Frozen);
109109
context.state.set(ContextState::Active);
110110
})
@@ -150,14 +150,14 @@ impl<C: RawCollectorImpl> Debug for RawContext<C> {
150150
impl<C: SyncCollector> super::sealed::Sealed for RawContext<C> {}
151151
unsafe impl<C> super::RawContext<C> for RawContext<C>
152152
where C: SyncCollector<RawContext=Self, Manager=CollectionManager<C>> {
153-
unsafe fn register_new(collector: &CollectorRef<C>) -> ManuallyDrop<Box<Self>> {
153+
unsafe fn register_new(collector: &GarbageCollector<C>) -> ManuallyDrop<Box<Self>> {
154154
let original_thread = if collector.as_raw().logger().is_trace_enabled() {
155155
ThreadId::current()
156156
} else {
157157
ThreadId::Nop
158158
};
159159
let mut context = ManuallyDrop::new(Box::new(RawContext {
160-
collector: collector.clone_internal(),
160+
collector: collector.as_ref().clone(),
161161
original_thread: original_thread.clone(),
162162
logger: collector.as_raw().logger().new(o!(
163163
"original_thread" => original_thread.clone()
@@ -297,7 +297,7 @@ unsafe impl<C> super::RawContext<C> for RawContext<C>
297297

298298
#[inline]
299299
unsafe fn collector(&self) -> &C {
300-
self.collector.as_raw()
300+
&*self.collector.as_raw()
301301
}
302302

303303
#[inline]

0 commit comments

Comments
 (0)