1
- use std:: any:: { Any , TypeId } ;
2
- use std:: cell:: Cell ;
3
- use std:: cmp:: Ordering ;
4
- use std:: collections:: hash_map:: Entry ;
5
- use std:: collections:: VecDeque ;
6
- use std:: fmt;
7
- use std:: hash:: { Hash , Hasher } ;
8
- use std:: marker:: PhantomData ;
9
- use std:: mem;
10
- use std:: ops:: { Deref , DerefMut } ;
11
- use std:: ptr;
12
- use std:: sync:: Arc ;
1
+ use std:: {
2
+ any:: { Any , TypeId } ,
3
+ cell:: Cell ,
4
+ cmp:: Ordering ,
5
+ collections:: hash_map:: Entry ,
6
+ collections:: VecDeque ,
7
+ fmt,
8
+ hash:: { Hash , Hasher } ,
9
+ marker:: PhantomData ,
10
+ mem,
11
+ ops:: { Deref , DerefMut } ,
12
+ ptr:: { self , NonNull } ,
13
+ sync:: Arc ,
14
+ } ;
13
15
14
16
use crate :: base:: fnv:: FnvMap ;
15
17
use crate :: interner:: InternedStr ;
@@ -341,10 +343,7 @@ impl GcHeader {
341
343
///
342
344
/// It is only safe to access data through a `GcPtr` if the value is rooted (stored in a place
343
345
/// where the garbage collector will find it during the mark phase).
344
- pub struct GcPtr < T : ?Sized > {
345
- // TODO Use NonZero to allow for better optimizing
346
- ptr : * const T ,
347
- }
346
+ pub struct GcPtr < T : ?Sized > ( NonNull < T > ) ;
348
347
349
348
unsafe impl < T : ?Sized + Send + Sync > Send for GcPtr < T > { }
350
349
unsafe impl < T : ?Sized + Send + Sync > Sync for GcPtr < T > { }
@@ -353,14 +352,14 @@ impl<T: ?Sized> Copy for GcPtr<T> {}
353
352
354
353
impl < T : ?Sized > Clone for GcPtr < T > {
355
354
fn clone ( & self ) -> GcPtr < T > {
356
- GcPtr { ptr : self . ptr }
355
+ GcPtr ( self . 0 )
357
356
}
358
357
}
359
358
360
359
impl < T : ?Sized > Deref for GcPtr < T > {
361
360
type Target = T ;
362
361
fn deref ( & self ) -> & T {
363
- unsafe { & * self . ptr }
362
+ unsafe { self . 0 . as_ref ( ) }
364
363
}
365
364
}
366
365
@@ -411,12 +410,12 @@ impl<T: ?Sized> GcPtr<T> {
411
410
/// Unsafe as it is up to the caller to ensure that this pointer is not referenced somewhere
412
411
/// else
413
412
pub unsafe fn as_mut ( & mut self ) -> & mut T {
414
- & mut * ( self . ptr as * mut T )
413
+ self . 0 . as_mut ( )
415
414
}
416
415
417
416
/// Unsafe as `ptr` must have been allocted by this garbage collector
418
417
pub unsafe fn from_raw ( ptr : * const T ) -> GcPtr < T > {
419
- GcPtr { ptr }
418
+ GcPtr ( NonNull :: new_unchecked ( ptr as * mut _ ) )
420
419
}
421
420
422
421
pub fn generation ( & self ) -> Generation {
@@ -444,13 +443,8 @@ impl<T: ?Sized> GcPtr<T> {
444
443
}
445
444
446
445
fn header ( & self ) -> & GcHeader {
447
- // Use of transmute_copy allows us to get the pointer
448
- // to the data regardless of wether T is unsized or not
449
- // (DST is structured as (ptr, len))
450
- // This function should always be safe to call as GcPtr's should always have a header
451
- // TODO: Better way of doing this?
452
446
unsafe {
453
- let p: * mut u8 = mem :: transmute_copy ( & self . ptr ) ;
447
+ let p = self . 0 . as_ptr ( ) as * mut u8 ;
454
448
let header = p. offset ( -( GcHeader :: value_offset ( ) as isize ) ) ;
455
449
& * ( header as * const GcHeader )
456
450
}
@@ -460,8 +454,9 @@ impl<T: ?Sized> GcPtr<T> {
460
454
impl < ' a , T : Traverseable + Send + Sync + ' a > GcPtr < T > {
461
455
/// Coerces `self` to a `Traverseable` trait object
462
456
pub fn as_traverseable ( self ) -> GcPtr < Traverseable + Send + Sync + ' a > {
463
- GcPtr {
464
- ptr : self . ptr as * const ( Traverseable + Send + Sync ) ,
457
+ unsafe {
458
+ let ptr: & ( Traverseable + Send + Sync ) = self . 0 . as_ref ( ) ;
459
+ GcPtr ( NonNull :: new_unchecked ( ptr as * const _ as * mut _ ) )
465
460
}
466
461
}
467
462
}
@@ -470,8 +465,10 @@ impl GcPtr<str> {
470
465
pub fn as_traverseable_string ( self ) -> GcPtr < Traverseable + Send + Sync > {
471
466
// As there is nothing to traverse in a str we can safely cast it to *const u8 and use
472
467
// u8's Traverseable impl
473
- GcPtr {
474
- ptr : self . as_ptr ( ) as * const ( Traverseable + Send + Sync ) ,
468
+ unsafe {
469
+ GcPtr ( NonNull :: new_unchecked (
470
+ self . as_ptr ( ) as * const ( Traverseable + Send + Sync ) as * mut _ ,
471
+ ) )
475
472
}
476
473
}
477
474
}
@@ -791,7 +788,7 @@ impl Gc {
791
788
// that the pointer was initialized
792
789
assert ! ( ret == p) ;
793
790
self . values = Some ( ptr) ;
794
- GcPtr { ptr : p }
791
+ GcPtr ( NonNull :: new_unchecked ( p ) )
795
792
}
796
793
}
797
794
0 commit comments