1
- use super :: allocator:: { align_allocation_no_fill, fill_alignment_gap} ;
2
1
use crate :: util:: Address ;
3
2
4
3
use crate :: util:: alloc:: Allocator ;
@@ -17,25 +16,44 @@ const BLOCK_MASK: usize = BLOCK_SIZE - 1;
17
16
pub struct BumpAllocator < VM : VMBinding > {
18
17
/// [`VMThread`] associated with this allocator instance
19
18
pub tls : VMThread ,
20
- /// Current cursor for bump pointer
21
- cursor : Address ,
22
- /// Limit for bump pointer
23
- limit : Address ,
19
+ /// Bump-pointer itself.
20
+ pub ( in crate :: util:: alloc) bump_pointer : BumpPointer ,
24
21
/// [`Space`](src/policy/space/Space) instance associated with this allocator instance.
25
22
space : & ' static dyn Space < VM > ,
26
23
/// [`Plan`] instance that this allocator instance is associated with.
27
24
plan : & ' static dyn Plan < VM = VM > ,
28
25
}
29
26
27
+ /// A common fast-path bump-pointer allocator shared across different allocator implementations
28
+ /// that use bump-pointer allocation.
29
+ #[ repr( C ) ]
30
+ pub struct BumpPointer {
31
+ pub cursor : Address ,
32
+ pub limit : Address ,
33
+ }
34
+
35
+ impl BumpPointer {
36
+ pub const fn new ( start : Address , end : Address ) -> Self {
37
+ BumpPointer {
38
+ cursor : start,
39
+ limit : end,
40
+ }
41
+ }
42
+
43
+ pub fn reset ( & mut self , start : Address , end : Address ) {
44
+ self . cursor = start;
45
+ self . limit = end;
46
+ }
47
+ }
48
+
30
49
impl < VM : VMBinding > BumpAllocator < VM > {
31
50
pub fn set_limit ( & mut self , start : Address , limit : Address ) {
32
- self . cursor = start;
33
- self . limit = limit;
51
+ self . bump_pointer . reset ( start, limit) ;
34
52
}
35
53
36
54
pub fn reset ( & mut self ) {
37
- self . cursor = unsafe { Address :: zero ( ) } ;
38
- self . limit = unsafe { Address :: zero ( ) } ;
55
+ let zero = unsafe { Address :: zero ( ) } ;
56
+ self . bump_pointer . reset ( zero , zero) ;
39
57
}
40
58
41
59
pub fn rebind ( & mut self , space : & ' static dyn Space < VM > ) {
@@ -44,6 +62,9 @@ impl<VM: VMBinding> BumpAllocator<VM> {
44
62
}
45
63
}
46
64
65
+ use crate :: util:: alloc:: allocator:: align_allocation_no_fill;
66
+ use crate :: util:: alloc:: fill_alignment_gap;
67
+
47
68
impl < VM : VMBinding > Allocator < VM > for BumpAllocator < VM > {
48
69
fn get_space ( & self ) -> & ' static dyn Space < VM > {
49
70
self . space
@@ -63,21 +84,21 @@ impl<VM: VMBinding> Allocator<VM> for BumpAllocator<VM> {
63
84
64
85
fn alloc ( & mut self , size : usize , align : usize , offset : usize ) -> Address {
65
86
trace ! ( "alloc" ) ;
66
- let result = align_allocation_no_fill :: < VM > ( self . cursor , align, offset) ;
87
+ let result = align_allocation_no_fill :: < VM > ( self . bump_pointer . cursor , align, offset) ;
67
88
let new_cursor = result + size;
68
89
69
- if new_cursor > self . limit {
90
+ if new_cursor > self . bump_pointer . limit {
70
91
trace ! ( "Thread local buffer used up, go to alloc slow path" ) ;
71
92
self . alloc_slow ( size, align, offset)
72
93
} else {
73
- fill_alignment_gap :: < VM > ( self . cursor , result) ;
74
- self . cursor = new_cursor;
94
+ fill_alignment_gap :: < VM > ( self . bump_pointer . cursor , result) ;
95
+ self . bump_pointer . cursor = new_cursor;
75
96
trace ! (
76
97
"Bump allocation size: {}, result: {}, new_cursor: {}, limit: {}" ,
77
98
size,
78
99
result,
79
- self . cursor,
80
- self . limit
100
+ self . bump_pointer . cursor,
101
+ self . bump_pointer . limit
81
102
) ;
82
103
result
83
104
}
@@ -108,24 +129,24 @@ impl<VM: VMBinding> Allocator<VM> for BumpAllocator<VM> {
108
129
}
109
130
110
131
trace ! ( "alloc_slow stress_test" ) ;
111
- let result = align_allocation_no_fill :: < VM > ( self . cursor , align, offset) ;
132
+ let result = align_allocation_no_fill :: < VM > ( self . bump_pointer . cursor , align, offset) ;
112
133
let new_cursor = result + size;
113
134
114
135
// For stress test, limit is [0, block_size) to artificially make the
115
136
// check in the fastpath (alloc()) fail. The real limit is recovered by
116
137
// adding it to the current cursor.
117
- if new_cursor > self . cursor + self . limit . as_usize ( ) {
138
+ if new_cursor > self . bump_pointer . cursor + self . bump_pointer . limit . as_usize ( ) {
118
139
self . acquire_block ( size, align, offset, true )
119
140
} else {
120
- fill_alignment_gap :: < VM > ( self . cursor , result) ;
121
- self . limit -= new_cursor - self . cursor ;
122
- self . cursor = new_cursor;
141
+ fill_alignment_gap :: < VM > ( self . bump_pointer . cursor , result) ;
142
+ self . bump_pointer . limit -= new_cursor - self . bump_pointer . cursor ;
143
+ self . bump_pointer . cursor = new_cursor;
123
144
trace ! (
124
145
"alloc_slow: Bump allocation size: {}, result: {}, new_cursor: {}, limit: {}" ,
125
146
size,
126
147
result,
127
- self . cursor,
128
- self . limit
148
+ self . bump_pointer . cursor,
149
+ self . bump_pointer . limit
129
150
) ;
130
151
result
131
152
}
@@ -144,8 +165,7 @@ impl<VM: VMBinding> BumpAllocator<VM> {
144
165
) -> Self {
145
166
BumpAllocator {
146
167
tls,
147
- cursor : unsafe { Address :: zero ( ) } ,
148
- limit : unsafe { Address :: zero ( ) } ,
168
+ bump_pointer : unsafe { BumpPointer :: new ( Address :: zero ( ) , Address :: zero ( ) ) } ,
149
169
space,
150
170
plan,
151
171
}
0 commit comments