File tree 3 files changed +43
-7
lines changed
3 files changed +43
-7
lines changed Original file line number Diff line number Diff line change @@ -23,6 +23,11 @@ pub struct Allocator {
23
23
24
24
impl Allocator {
25
25
/// Invokes `f` in a scope where the allocations are done in this allocator.
26
+ ///
27
+ /// # Safety
28
+ ///
29
+ /// [Allocator] must be dropped after dropping all [crate::boxed::Box] and
30
+ /// [crate::vec::Vec] created in the scope.
26
31
#[ inline( always) ]
27
32
pub fn scope < ' a , F , R > ( & ' a self , f : F ) -> R
28
33
where
@@ -116,11 +121,6 @@ unsafe impl allocator_api2::alloc::Allocator for FastAlloc {
116
121
unsafe fn deallocate ( & self , ptr : NonNull < u8 > , layout : Layout ) {
117
122
#[ cfg( feature = "scoped" ) ]
118
123
if self . alloc . is_some ( ) {
119
- debug_assert ! (
120
- ALLOC . get( ) . is_some( ) ,
121
- "Deallocating a pointer allocated with arena mode with a non-arena mode allocator"
122
- ) ;
123
-
124
124
self . with_allocator ( |alloc, _| alloc. deallocate ( ptr, layout) ) ;
125
125
return ;
126
126
}
Original file line number Diff line number Diff line change 19
19
//! [crate::vec::Vec] very fast.
20
20
//!
21
21
//! In this mode, you need to be careful while using [crate::boxed::Box] and
22
- //! [crate::vec::Vec]. Be sure to use same [Allocator] for allocation and
23
- //! deallocation .
22
+ //! [crate::vec::Vec]. You should ensure that [Allocator] outlives all
23
+ //! [crate::boxed::Box] and [crate::vec::Vec] created in the scope .
24
24
//!
25
25
//! Recommened way to use this mode is to wrap the whole operations in
26
26
//! a call to [Allocator::scope].
@@ -61,3 +61,15 @@ pub struct FastAlloc {
61
61
#[ cfg( feature = "scoped" ) ]
62
62
alloc : Option < & ' static Allocator > ,
63
63
}
64
+
65
+ impl FastAlloc {
66
+ /// [crate::boxed::Box] or [crate::vec::Vec] created with this instance is
67
+ /// managed by the global allocator and it can outlive the
68
+ /// [crate::Allocator] instance used for [Allocator::scope].
69
+ pub const fn global ( ) -> Self {
70
+ Self {
71
+ #[ cfg( feature = "scoped" ) ]
72
+ alloc : None ,
73
+ }
74
+ }
75
+ }
Original file line number Diff line number Diff line change
1
+ use swc_allocator:: { boxed:: Box , Allocator , FastAlloc } ;
2
+
3
+ #[ test]
4
+ fn escape ( ) {
5
+ let allocator = Allocator :: default ( ) ;
6
+
7
+ let obj = allocator. scope ( || Box :: new ( 1234 ) ) ;
8
+
9
+ assert_eq ! ( * obj, 1234 ) ;
10
+ // It should not segfault, because the allocator is still alive.
11
+ drop ( obj) ;
12
+ }
13
+
14
+ #[ test]
15
+ fn global_allocator ( ) {
16
+ let allocator = Allocator :: default ( ) ;
17
+
18
+ let obj = allocator. scope ( || Box :: new_in ( 1234 , FastAlloc :: global ( ) ) ) ;
19
+
20
+ assert_eq ! ( * obj, 1234 ) ;
21
+ drop ( allocator) ;
22
+ // Object created with global allocator should outlive the allocator.
23
+ drop ( obj) ;
24
+ }
You can’t perform that action at this time.
0 commit comments