1- use super :: allocator:: { align_allocation_no_fill, fill_alignment_gap} ;
21use crate :: util:: Address ;
32
43use crate :: util:: alloc:: Allocator ;
@@ -17,25 +16,44 @@ const BLOCK_MASK: usize = BLOCK_SIZE - 1;
1716pub struct BumpAllocator < VM : VMBinding > {
1817 /// [`VMThread`] associated with this allocator instance
1918 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 ,
2421 /// [`Space`](src/policy/space/Space) instance associated with this allocator instance.
2522 space : & ' static dyn Space < VM > ,
2623 /// [`Plan`] instance that this allocator instance is associated with.
2724 plan : & ' static dyn Plan < VM = VM > ,
2825}
2926
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+
3049impl < VM : VMBinding > BumpAllocator < VM > {
3150 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) ;
3452 }
3553
3654 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) ;
3957 }
4058
4159 pub fn rebind ( & mut self , space : & ' static dyn Space < VM > ) {
@@ -44,6 +62,9 @@ impl<VM: VMBinding> BumpAllocator<VM> {
4462 }
4563}
4664
65+ use crate :: util:: alloc:: allocator:: align_allocation_no_fill;
66+ use crate :: util:: alloc:: fill_alignment_gap;
67+
4768impl < VM : VMBinding > Allocator < VM > for BumpAllocator < VM > {
4869 fn get_space ( & self ) -> & ' static dyn Space < VM > {
4970 self . space
@@ -63,21 +84,21 @@ impl<VM: VMBinding> Allocator<VM> for BumpAllocator<VM> {
6384
6485 fn alloc ( & mut self , size : usize , align : usize , offset : usize ) -> Address {
6586 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) ;
6788 let new_cursor = result + size;
6889
69- if new_cursor > self . limit {
90+ if new_cursor > self . bump_pointer . limit {
7091 trace ! ( "Thread local buffer used up, go to alloc slow path" ) ;
7192 self . alloc_slow ( size, align, offset)
7293 } 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;
7596 trace ! (
7697 "Bump allocation size: {}, result: {}, new_cursor: {}, limit: {}" ,
7798 size,
7899 result,
79- self . cursor,
80- self . limit
100+ self . bump_pointer . cursor,
101+ self . bump_pointer . limit
81102 ) ;
82103 result
83104 }
@@ -108,24 +129,24 @@ impl<VM: VMBinding> Allocator<VM> for BumpAllocator<VM> {
108129 }
109130
110131 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) ;
112133 let new_cursor = result + size;
113134
114135 // For stress test, limit is [0, block_size) to artificially make the
115136 // check in the fastpath (alloc()) fail. The real limit is recovered by
116137 // 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 ( ) {
118139 self . acquire_block ( size, align, offset, true )
119140 } 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;
123144 trace ! (
124145 "alloc_slow: Bump allocation size: {}, result: {}, new_cursor: {}, limit: {}" ,
125146 size,
126147 result,
127- self . cursor,
128- self . limit
148+ self . bump_pointer . cursor,
149+ self . bump_pointer . limit
129150 ) ;
130151 result
131152 }
@@ -144,8 +165,7 @@ impl<VM: VMBinding> BumpAllocator<VM> {
144165 ) -> Self {
145166 BumpAllocator {
146167 tls,
147- cursor : unsafe { Address :: zero ( ) } ,
148- limit : unsafe { Address :: zero ( ) } ,
168+ bump_pointer : unsafe { BumpPointer :: new ( Address :: zero ( ) , Address :: zero ( ) ) } ,
149169 space,
150170 plan,
151171 }
0 commit comments