35
35
#[ allow( missing_doc) ] ;
36
36
37
37
38
- use list:: { MutList , MutCons , MutNil } ;
38
+ use list:: { List , Cons , Nil } ;
39
+ use list;
39
40
40
41
use std:: at_vec;
41
42
use std:: cast:: { transmute, transmute_mut, transmute_mut_region} ;
42
43
use std:: cast;
44
+ use std:: cell:: { Cell , RefCell } ;
43
45
use std:: num;
44
46
use std:: ptr;
45
47
use std:: mem;
@@ -50,10 +52,11 @@ use std::unstable::intrinsics::{TyDesc, get_tydesc};
50
52
// The way arena uses arrays is really deeply awful. The arrays are
51
53
// allocated, and have capacities reserved, but the fill for the array
52
54
// will always stay at 0.
55
+ #[ deriving( Clone ) ]
53
56
struct Chunk {
54
- data : @[ u8 ] ,
55
- fill : uint ,
56
- is_pod : bool ,
57
+ data : RefCell < @[ u8 ] > ,
58
+ fill : Cell < uint > ,
59
+ is_pod : Cell < bool > ,
57
60
}
58
61
59
62
#[ no_freeze]
@@ -63,7 +66,7 @@ pub struct Arena {
63
66
// access the head.
64
67
priv head : Chunk ,
65
68
priv pod_head : Chunk ,
66
- priv chunks : @ mut MutList < Chunk > ,
69
+ priv chunks : RefCell < @ List < Chunk > > ,
67
70
}
68
71
69
72
impl Arena {
@@ -75,7 +78,7 @@ impl Arena {
75
78
Arena {
76
79
head : chunk ( initial_size, false ) ,
77
80
pod_head : chunk ( initial_size, true ) ,
78
- chunks : @ mut MutNil ,
81
+ chunks : RefCell :: new ( @ Nil ) ,
79
82
}
80
83
}
81
84
}
@@ -84,9 +87,9 @@ fn chunk(size: uint, is_pod: bool) -> Chunk {
84
87
let mut v: @[ u8 ] = @[ ] ;
85
88
unsafe { at_vec:: raw:: reserve ( & mut v, size) ; }
86
89
Chunk {
87
- data : unsafe { cast:: transmute ( v) } ,
88
- fill : 0 u ,
89
- is_pod : is_pod,
90
+ data : RefCell :: new ( unsafe { cast:: transmute ( v) } ) ,
91
+ fill : Cell :: new ( 0 u ) ,
92
+ is_pod : Cell :: new ( is_pod) ,
90
93
}
91
94
}
92
95
@@ -95,8 +98,9 @@ impl Drop for Arena {
95
98
fn drop ( & mut self ) {
96
99
unsafe {
97
100
destroy_chunk ( & self . head ) ;
98
- self . chunks . each ( |chunk| {
99
- if !chunk. is_pod {
101
+
102
+ list:: each ( self . chunks . get ( ) , |chunk| {
103
+ if !chunk. is_pod . get ( ) {
100
104
destroy_chunk ( chunk) ;
101
105
}
102
106
true
@@ -114,8 +118,11 @@ fn round_up_to(base: uint, align: uint) -> uint {
114
118
// in it.
115
119
unsafe fn destroy_chunk ( chunk : & Chunk ) {
116
120
let mut idx = 0 ;
117
- let buf = chunk. data . as_ptr ( ) ;
118
- let fill = chunk. fill ;
121
+ let buf = {
122
+ let data = chunk. data . borrow ( ) ;
123
+ data. get ( ) . as_ptr ( )
124
+ } ;
125
+ let fill = chunk. fill . get ( ) ;
119
126
120
127
while idx < fill {
121
128
let tydesc_data: * uint = transmute ( ptr:: offset ( buf, idx as int ) ) ;
@@ -155,9 +162,9 @@ impl Arena {
155
162
// Functions for the POD part of the arena
156
163
fn alloc_pod_grow ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
157
164
// Allocate a new chunk.
158
- let chunk_size = at_vec:: capacity ( self . pod_head . data ) ;
165
+ let chunk_size = at_vec:: capacity ( self . pod_head . data . get ( ) ) ;
159
166
let new_min_chunk_size = num:: max ( n_bytes, chunk_size) ;
160
- self . chunks = @ mut MutCons ( self . pod_head , self . chunks ) ;
167
+ self . chunks . set ( @ Cons ( self . pod_head . clone ( ) , self . chunks . get ( ) ) ) ;
161
168
self . pod_head =
162
169
chunk ( uint:: next_power_of_two ( new_min_chunk_size + 1 u) , true ) ;
163
170
@@ -168,17 +175,17 @@ impl Arena {
168
175
fn alloc_pod_inner ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
169
176
unsafe {
170
177
let this = transmute_mut_region ( self ) ;
171
- let start = round_up_to ( this. pod_head . fill , align) ;
178
+ let start = round_up_to ( this. pod_head . fill . get ( ) , align) ;
172
179
let end = start + n_bytes;
173
- if end > at_vec:: capacity ( this. pod_head . data ) {
180
+ if end > at_vec:: capacity ( this. pod_head . data . get ( ) ) {
174
181
return this. alloc_pod_grow ( n_bytes, align) ;
175
182
}
176
- this. pod_head . fill = end;
183
+ this. pod_head . fill . set ( end) ;
177
184
178
185
//debug!("idx = {}, size = {}, align = {}, fill = {}",
179
- // start, n_bytes, align, head.fill);
186
+ // start, n_bytes, align, head.fill.get() );
180
187
181
- ptr:: offset ( this. pod_head . data . as_ptr ( ) , start as int )
188
+ ptr:: offset ( this. pod_head . data . get ( ) . as_ptr ( ) , start as int )
182
189
}
183
190
}
184
191
@@ -197,9 +204,9 @@ impl Arena {
197
204
fn alloc_nonpod_grow ( & mut self , n_bytes : uint , align : uint )
198
205
-> ( * u8 , * u8 ) {
199
206
// Allocate a new chunk.
200
- let chunk_size = at_vec:: capacity ( self . head . data ) ;
207
+ let chunk_size = at_vec:: capacity ( self . head . data . get ( ) ) ;
201
208
let new_min_chunk_size = num:: max ( n_bytes, chunk_size) ;
202
- self . chunks = @ mut MutCons ( self . head , self . chunks ) ;
209
+ self . chunks . set ( @ Cons ( self . head . clone ( ) , self . chunks . get ( ) ) ) ;
203
210
self . head =
204
211
chunk ( uint:: next_power_of_two ( new_min_chunk_size + 1 u) , false ) ;
205
212
@@ -218,23 +225,23 @@ impl Arena {
218
225
{
219
226
let head = transmute_mut_region ( & mut self . head ) ;
220
227
221
- tydesc_start = head. fill ;
222
- after_tydesc = head. fill + mem:: size_of :: < * TyDesc > ( ) ;
228
+ tydesc_start = head. fill . get ( ) ;
229
+ after_tydesc = head. fill . get ( ) + mem:: size_of :: < * TyDesc > ( ) ;
223
230
start = round_up_to ( after_tydesc, align) ;
224
231
end = start + n_bytes;
225
232
}
226
233
227
- if end > at_vec:: capacity ( self . head . data ) {
234
+ if end > at_vec:: capacity ( self . head . data . get ( ) ) {
228
235
return self . alloc_nonpod_grow ( n_bytes, align) ;
229
236
}
230
237
231
238
let head = transmute_mut_region ( & mut self . head ) ;
232
- head. fill = round_up_to ( end, mem:: pref_align_of :: < * TyDesc > ( ) ) ;
239
+ head. fill . set ( round_up_to ( end, mem:: pref_align_of :: < * TyDesc > ( ) ) ) ;
233
240
234
241
//debug!("idx = {}, size = {}, align = {}, fill = {}",
235
242
// start, n_bytes, align, head.fill);
236
243
237
- let buf = self . head . data . as_ptr ( ) ;
244
+ let buf = self . head . data . get ( ) . as_ptr ( ) ;
238
245
return ( ptr:: offset ( buf, tydesc_start as int ) , ptr:: offset ( buf, start as int ) ) ;
239
246
}
240
247
}
0 commit comments