8000 feat: change gc object's dyn dispatch to static · RustPython/RustPython@d0aa47e · GitHub
[go: up one dir, main page]

Skip to content

Commit d0aa47e

Browse files
committed
feat: change gc object's dyn dispatch to static
1 parent ca1720d commit d0aa47e

File tree

4 files changed

+33
-21
lines changed

4 files changed

+33
-21
lines changed

vm/src/object/core.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,16 +249,25 @@ unsafe impl GcTrace for PyObject {
249249
}
250250
}
251251

252+
impl From<&PyInner<Erased>> for &PyObject {
253+
fn from(inner: &PyInner<Erased>) -> Self {
254+
// Safety: PyObject is #[repr(transparent)], so cast is safe
255+
unsafe {
256+
NonNull::from(inner).cast::<PyObject>().as_ref()
257+
}
258+
}
259+
}
260+
252261
#[cfg(feature = "gc")]
253262
impl GcObjPtr for PyInner<Erased> {
254263
/// call increment() of gc
255264
fn inc(&self) {
256-
self.header().gc.increment(self)
265+
self.header().gc.increment(self.into())
257266
}
258267

259268
/// call decrement() of gc
260269
fn dec(&self) -> GcStatus {
261-
unsafe { self.header().gc.decrement(self) }
270+
unsafe { self.header().gc.decrement(self.into()) }
262271
}
263272

264273
fn rc(&self) -> usize {
@@ -868,6 +877,7 @@ impl PyObjectRef {
868877
}
869878

870879
impl PyObject {
880+
871881
#[inline(always)]
872882
fn weak_ref_list(&self) -> Option<&WeakRefList> {
873883
Some(&self.0.weak_list)

vm/src/object/gc/collector_sync.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::time::Instant;
22
use std::{fmt, ops::Deref, ptr::NonNull};
33

4-
use crate::object::gc::{deadlock_handler, Color, GcObjPtr, GcStatus};
4+
use crate::object::gc::{deadlock_handler, Color, GcObjPtr, GcStatus, GcTrace, GcObj, GcObjRef};
55
use crate::PyObject;
66

77
use rustpython_common::{
@@ -97,7 +97,7 @@ impl From<GcResult> for usize {
9797
}
9898

9999
pub struct CcSync {
100-
roots: PyMutex<Vec<WrappedPtr<dyn GcObjPtr>>>,
100+
roots: PyMutex<Vec<WrappedPtr<GcObj>>>,
101101
/// for stop the world, will be try to check lock every time deref ObjecteRef
102102
/// to achive pausing
103103
pub pause: PyRwLock<()>,
@@ -119,7 +119,7 @@ impl std::fmt::Debug for CcSync {
119119
}
120120

121121
// TODO: change to use PyInner<Erased> directly
122-
type ObjRef<'a> = &'a dyn GcObjPtr;
122+
123123

124124
impl CcSync {
125125
thread_local! {
@@ -184,7 +184,7 @@ impl CcSync {
184184
false
185185
}
186186
}
187-
pub fn increment(&self, obj: ObjRef) {
187+
pub fn increment(&self, obj: GcObjRef) {
188188
if obj.header().is_leaked() {
189189
// by define a leaked object's rc should not change?
190190
return;
@@ -197,7 +197,7 @@ impl CcSync {
197197
/// # Safety
198198
/// if the last ref to a object call decrement() on object,
199199
/// then this object should be considered freed.
200-
pub unsafe fn decrement(&self, obj: ObjRef) -> GcStatus {
200+
pub unsafe fn decrement(&self, obj: GcObjRef) -> GcStatus {
201201
if obj.header().is_leaked() {
202202
// a leaked object should always keep
203203
return GcStatus::ShouldKeep;
@@ -222,7 +222,7 @@ impl CcSync {
222222
}
223223
}
224224

225-
unsafe fn release(&self, obj: ObjRef) -> GcStatus {
225+
unsafe fn release(&self, obj: GcObjRef) -> GcStatus {
226226
// because drop obj itself will drop all ObjRef store by object itself once more,
227227
// so balance out in here
228228
// by doing nothing
@@ -244,7 +244,7 @@ impl CcSync {
244244
}
245245
}
246246

247-
fn possible_root(&self, obj: ObjRef) {
247+
fn possible_root(&self, obj: GcObjRef) {
248248
if obj.header().color() != Color::Purple {
249249
obj.header().set_color(Color::Purple);
250250
// prevent add to buffer for multiple times
@@ -254,7 +254,7 @@ impl CcSync {
254254
// lock here to serialize access to root&gc
255255
let mut roots = self.roots.lock();
256256
*buffered = true;
257-
roots.push(obj.as_ptr().into());
257+
roots.push(NonNull::from(obj).into());
258258
}
259259
}
260260
}
@@ -379,14 +379,14 @@ impl CcSync {
379379

380380
len_white
381381
}
382-
fn collect_white(&self, obj: ObjRef, white: &mut Vec<NonNull<dyn GcObjPtr>>) {
382+
fn collect_white(&self, obj: GcObjRef, white: &mut Vec<NonNull<GcObj>>) {
383383
if obj.header().color() == Color::White && !obj.header().buffered() {
384384
obj.header().set_color(Color::BlackFree);
385385
obj.trace(&mut |ch| self.collect_white(ch, white));
386-
white.push(obj.as_ptr());
386+
white.push(NonNull::from(obj));
387387
}
388388
}
389-
fn mark_gray(&self, obj: ObjRef) {
389+
fn mark_gray(&self, obj: GcObjRef) {
390390
if obj.header().color() != Color::Gray {
391391
obj.header().set_color(Color::Gray);
392392
obj.trace(&mut |ch| {
@@ -395,7 +395,7 @@ impl CcSync {
395395
});
396396
}
397397
}
398-
fn scan(&self, obj: ObjRef) {
398+
fn scan(&self, obj: GcObjRef) {
399399
if obj.header().color() == Color::Gray {
400400
if obj.rc() > 0 {
401401
self.scan_black(obj)
@@ -407,7 +407,7 @@ impl CcSync {
407407
}
408408
}
409409
}
410-
fn scan_black(&self, obj: ObjRef) {
410+
fn scan_black(&self, obj: GcObjRef) {
411411
obj.header().set_color(Color::Black);
412412
obj.trace(&mut |ch| {
413413
ch.header().inc();

vm/src/object/gc/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ pub use collector_sync::GcResult;
88
pub(crate) use collector_sync::{CcSync, GLOBAL_COLLECTOR};
99
pub(crate) use header::{Color, GcHeader};
1010
pub(crate) use trace::{GcObjPtr, GcStatus, GcTrace, TracerFn};
11+
use crate::PyObject;
12+
type GcObj = PyObject;
13+
type GcObjRef<'a> = &'a GcObj;
1114

1215
fn deadlock_handler() -> ! {
1316
error!("Dead lock!");

vm/src/object/gc/trace.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use enum_dispatch::enum_dispatch;
21
use rustpython_common::lock::{PyMutex, PyRwLock};
32

4-
use crate::object::gc::{deadlock_handler, header::GcHeader};
5-
use crate::object::{Erased, PyInner, PyObjectPayload};
6-
use crate::{AsObject, PyObject, PyObjectRef, PyRef};
3+
use crate::object::gc::{deadlock_handler, header::GcHeader, GcObjRef};
4+
use crate::object::PyObjectPayload;
5+
use crate::{AsObject, PyObjectRef, PyRef};
76
use core::ptr::NonNull;
87

98
/// indicate what to do with the object afer calling dec()
@@ -52,12 +51,12 @@ pub unsafe trait GcTrace {
5251

5352
/// A `TracerFn` is a callback function that is invoked for each `PyGcObjectRef` owned
5453
/// by an instance of something.
55-
pub type TracerFn<'a> = dyn FnMut(&PyObject) + 'a;
54+
pub type TracerFn<'a> = dyn FnMut(GcObjRef) + 'a;
5655

5756
unsafe impl GcTrace for PyObjectRef {
5857
#[inline]
5958
fn trace(&self, tracer_fn: &mut TracerFn) {
60-
tracer_fn(self.as_ref())
59+
tracer_fn(self)
6160
}
6261
}
6362

0 commit comments

Comments
 (0)
0