32
32
// overhead when initializing plain-old-data and means we don't need
33
33
// to waste time running the destructors of POD.
34
34
35
- use list:: { MutList , MutCons , MutNil } ;
36
35
use list;
36
+ use list:: { List , Cons , Nil } ;
37
37
38
38
use core:: at_vec;
39
- use core:: cast:: { transmute, transmute_mut_region } ;
39
+ use core:: cast:: transmute;
40
40
use core:: cast;
41
41
use core:: libc:: size_t;
42
42
use core:: ptr;
@@ -74,28 +74,26 @@ static tydesc_drop_glue_index: size_t = 3 as size_t;
74
74
// will always stay at 0.
75
75
struct Chunk {
76
76
data : @[ u8 ] ,
77
- fill : uint ,
77
+ mut fill : uint ,
78
78
is_pod : bool ,
79
79
}
80
80
81
81
pub struct Arena {
82
82
// The head is seperated out from the list as a unbenchmarked
83
83
// microoptimization, to avoid needing to case on the list to
84
84
// access the head.
85
- priv head : Chunk ,
86
- priv pod_head : Chunk ,
87
- priv chunks : @mut MutList < Chunk > ,
85
+ priv mut head : Chunk ,
86
+ priv mut pod_head : Chunk ,
87
+ priv mut chunks : @List < Chunk > ,
88
88
}
89
89
90
90
#[ unsafe_destructor]
91
91
impl Drop for Arena {
92
92
fn finalize ( & self ) {
93
93
unsafe {
94
94
destroy_chunk ( & self . head ) ;
95
- for self . chunks. each |chunk| {
96
- if !chunk. is_pod {
97
- destroy_chunk ( chunk) ;
98
- }
95
+ for list:: each( self . chunks) |chunk| {
96
+ if !chunk. is_pod { destroy_chunk ( chunk) ; }
99
97
}
100
98
}
101
99
}
@@ -115,7 +113,7 @@ pub fn arena_with_size(initial_size: uint) -> Arena {
115
113
Arena {
116
114
head : chunk ( initial_size, false ) ,
117
115
pod_head : chunk ( initial_size, true ) ,
118
- chunks : @mut MutNil ,
116
+ chunks : @Nil ,
119
117
}
120
118
}
121
119
@@ -172,40 +170,39 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
172
170
173
171
pub impl Arena {
174
172
// Functions for the POD part of the arena
175
- priv fn alloc_pod_grow ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
173
+ priv fn alloc_pod_grow ( & self , n_bytes : uint , align : uint ) -> * u8 {
176
174
// Allocate a new chunk.
177
175
let chunk_size = at_vec:: capacity ( self . pod_head . data ) ;
178
176
let new_min_chunk_size = uint:: max ( n_bytes, chunk_size) ;
179
- self . chunks = @mut MutCons ( copy self . pod_head , self . chunks ) ;
177
+ self . chunks = @Cons ( copy self . pod_head , self . chunks ) ;
180
178
self . pod_head =
181
179
chunk ( uint:: next_power_of_two ( new_min_chunk_size + 1 u) , true ) ;
182
180
183
181
return self . alloc_pod_inner ( n_bytes, align) ;
184
182
}
185
183
186
184
#[ inline( always) ]
187
- priv fn alloc_pod_inner ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
188
- unsafe {
189
- // XXX: Borrow check
190
- let head = transmute_mut_region ( & mut self . pod_head ) ;
185
+ priv fn alloc_pod_inner ( & self , n_bytes : uint , align : uint ) -> * u8 {
186
+ let head = & mut self . pod_head ;
191
187
192
- let start = round_up_to ( head. fill , align) ;
193
- let end = start + n_bytes;
194
- if end > at_vec:: capacity ( head. data ) {
195
- return self . alloc_pod_grow ( n_bytes, align) ;
196
- }
197
- head. fill = end;
188
+ let start = round_up_to ( head. fill , align) ;
189
+ let end = start + n_bytes;
190
+ if end > at_vec:: capacity ( head. data ) {
191
+ return self . alloc_pod_grow ( n_bytes, align) ;
192
+ }
193
+ head. fill = end;
198
194
199
- //debug!("idx = %u, size = %u, align = %u, fill = %u",
200
- // start, n_bytes, align, head.fill);
195
+ //debug!("idx = %u, size = %u, align = %u, fill = %u",
196
+ // start, n_bytes, align, head.fill);
201
197
198
+ unsafe {
202
199
ptr:: offset ( vec:: raw:: to_ptr ( head. data ) , start)
203
200
}
204
201
}
205
202
206
203
#[ inline( always) ]
207
204
#[ cfg( stage0) ]
208
- priv fn alloc_pod < T > ( & mut self , op : & fn ( ) -> T ) -> & ' self T {
205
+ priv fn alloc_pod < T > ( & self , op : & fn ( ) -> T ) -> & ' self T {
209
206
unsafe {
210
207
let tydesc = sys:: get_type_desc :: < T > ( ) ;
211
208
let ptr = self . alloc_pod_inner ( ( * tydesc) . size , ( * tydesc) . align ) ;
@@ -219,7 +216,7 @@ pub impl Arena {
219
216
#[ cfg( stage1) ]
220
217
#[ cfg( stage2) ]
221
218
#[ cfg( stage3) ]
222
- priv fn alloc_pod < ' a , T > ( & ' a mut self , op : & fn ( ) -> T ) -> & ' a T {
219
+ priv fn alloc_pod < ' a , T > ( & ' a self , op : & fn ( ) -> T ) -> & ' a T {
223
220
unsafe {
224
221
let tydesc = sys:: get_type_desc :: < T > ( ) ;
225
222
let ptr = self . alloc_pod_inner ( ( * tydesc) . size , ( * tydesc) . align ) ;
@@ -230,44 +227,42 @@ pub impl Arena {
230
227
}
231
228
232
229
// Functions for the non-POD part of the arena
233
- priv fn alloc_nonpod_grow ( & mut self , n_bytes : uint , align : uint )
234
- -> ( * u8 , * u8 ) {
230
+ priv fn alloc_nonpod_grow ( & self , n_bytes : uint , align : uint ) -> ( * u8 , * u8 ) {
235
231
// Allocate a new chunk.
236
232
let chunk_size = at_vec:: capacity ( self . head . data ) ;
237
233
let new_min_chunk_size = uint:: max ( n_bytes, chunk_size) ;
238
- self . chunks = @mut MutCons ( copy self . head , self . chunks ) ;
234
+ self . chunks = @Cons ( copy self . head , self . chunks ) ;
239
235
self . head =
240
236
chunk ( uint:: next_power_of_two ( new_min_chunk_size + 1 u) , false ) ;
241
237
242
238
return self . alloc_nonpod_inner ( n_bytes, align) ;
243
239
}
244
240
245
241
#[ inline( always) ]
246
- priv fn alloc_nonpod_inner ( & mut self , n_bytes : uint , align : uint )
247
- -> ( * u8 , * u8 ) {
248
- unsafe {
249
- let head = transmute_mut_region ( & mut self . head ) ;
250
-
251
- let tydesc_start = head. fill ;
252
- let after_tydesc = head. fill + sys:: size_of :: < * TypeDesc > ( ) ;
253
- let start = round_up_to ( after_tydesc, align) ;
254
- let end = start + n_bytes;
255
- if end > at_vec:: capacity ( head. data ) {
256
- return self . alloc_nonpod_grow ( n_bytes, align) ;
257
- }
258
- head. fill = round_up_to ( end, sys:: pref_align_of :: < * TypeDesc > ( ) ) ;
242
+ priv fn alloc_nonpod_inner ( & self , n_bytes : uint , align : uint ) -> ( * u8 , * u8 ) {
243
+ let head = & mut self . head ;
259
244
260
- //debug!("idx = %u, size = %u, align = %u, fill = %u",
261
- // start, n_bytes, align, head.fill);
245
+ let tydesc_start = head. fill ;
246
+ let after_tydesc = head. fill + sys:: size_of :: < * TypeDesc > ( ) ;
247
+ let start = round_up_to ( after_tydesc, align) ;
248
+ let end = start + n_bytes;
249
+ if end > at_vec:: capacity ( head. data ) {
250
+ return self . alloc_nonpod_grow ( n_bytes, align) ;
251
+ }
252
+ head. fill = round_up_to ( end, sys:: pref_align_of :: < * TypeDesc > ( ) ) ;
253
+
254
+ //debug!("idx = %u, size = %u, align = %u, fill = %u",
255
+ // start, n_bytes, align, head.fill);
262
256
257
+ unsafe {
263
258
let buf = vec:: raw:: to_ptr ( head. data ) ;
264
259
return ( ptr:: offset ( buf, tydesc_start) , ptr:: offset ( buf, start) ) ;
265
260
}
266
261
}
267
262
268
263
#[ inline( always) ]
269
264
#[ cfg( stage0) ]
270
- priv fn alloc_nonpod < T > ( & mut self , op : & fn ( ) -> T ) -> & ' self T {
265
+ priv fn alloc_nonpod < T > ( & self , op : & fn ( ) -> T ) -> & ' self T {
271
266
unsafe {
272
267
let tydesc = sys:: get_type_desc :: < T > ( ) ;
273
268
let ( ty_ptr, ptr) =
@@ -291,7 +286,7 @@ pub impl Arena {
291
286
#[ cfg( stage1) ]
292
287
#[ cfg( stage2) ]
293
288
#[ cfg( stage3) ]
294
- priv fn alloc_nonpod < ' a , T > ( & ' a mut self , op : & fn ( ) -> T ) -> & ' a T {
289
+ priv fn alloc_nonpod < ' a , T > ( & ' a self , op : & fn ( ) -> T ) -> & ' a T {
295
290
unsafe {
296
291
let tydesc = sys:: get_type_desc :: < T > ( ) ;
297
292
let ( ty_ptr, ptr) =
@@ -314,16 +309,13 @@ pub impl Arena {
314
309
// The external interface
315
310
#[ inline( always) ]
316
311
#[ cfg( stage0) ]
317
- fn alloc < T > ( & mut self , op : & fn ( ) -> T ) -> & ' self T {
312
+ fn alloc < T > ( & self , op : & fn ( ) -> T ) -> & ' self T {
318
313
unsafe {
319
- // XXX: Borrow check
320
- let this = transmute_mut_region ( self ) ;
321
314
if !rusti:: needs_drop :: < T > ( ) {
322
- return this. alloc_pod ( op) ;
315
+ self . alloc_pod ( op)
316
+ } else {
317
+ self . alloc_nonpod ( op)
323
318
}
324
- // XXX: Borrow check
325
- let this = transmute_mut_region ( self ) ;
326
- this. alloc_nonpod ( op)
327
319
}
328
320
}
329
321
@@ -332,16 +324,13 @@ pub impl Arena {
332
324
#[ cfg( stage1) ]
333
325
#[ cfg( stage2) ]
334
326
#[ cfg( stage3) ]
335
- fn alloc < ' a , T > ( & ' a mut self , op : & fn ( ) -> T ) -> & ' a T {
327
+ fn alloc < ' a , T > ( & ' a self , op : & fn ( ) -> T ) -> & ' a T {
336
328
unsafe {
337
- // XXX: Borrow check
338
- let this = transmute_mut_region ( self ) ;
339
329
if !rusti:: needs_drop :: < T > ( ) {
340
- return this. alloc_pod ( op) ;
330
+ self . alloc_pod ( op)
331
+ } else {
332
+ self . alloc_nonpod ( op)
341
333
}
342
- // XXX: Borrow check
343
- let this = transmute_mut_region ( self ) ;
344
- this. alloc_nonpod ( op)
345
334
}
346
335
}
347
336
}
@@ -359,9 +348,7 @@ fn test_arena_destructors() {
359
348
}
360
349
}
361
350
362
- #[ test]
363
- #[ should_fail]
364
- #[ ignore( cfg( windows) ) ]
351
+ #[ test] #[ should_fail] #[ ignore( cfg( windows) ) ]
365
352
fn test_arena_destructors_fail( ) {
366
353
let arena = Arena ( ) ;
367
354
// Put some stuff in the arena.
0 commit comments