@@ -27,28 +27,38 @@ extern mod extra;
27
27
use extra:: list:: { List , Cons , Nil } ;
28
28
use extra:: list;
29
29
30
- use std:: at_vec;
31
30
use std:: cast:: { transmute, transmute_mut, transmute_mut_region} ;
32
31
use std:: cast;
33
32
use std:: cell:: { Cell , RefCell } ;
34
33
use std:: num;
35
34
use std:: ptr;
36
35
use std:: kinds:: marker;
37
36
use std:: mem;
37
+ use std:: rc:: Rc ;
38
38
use std:: rt:: global_heap;
39
39
use std:: unstable:: intrinsics:: { TyDesc , get_tydesc} ;
40
40
use std:: unstable:: intrinsics;
41
41
use std:: util;
42
+ use std:: vec;
42
43
43
44
// The way arena uses arrays is really deeply awful. The arrays are
44
45
// allocated, and have capacities reserved, but the fill for the array
45
46
// will always stay at 0.
46
47
#[ deriving( Clone ) ]
47
48
struct Chunk {
48
- data : RefCell < @ [ u8 ] > ,
49
+ data : Rc < RefCell < ~ [ u8 ] > > ,
49
50
fill : Cell < uint > ,
50
51
is_pod : Cell < bool > ,
51
52
}
53
+ impl Chunk {
54
+ fn capacity ( & self ) -> uint {
55
+ self . data . borrow ( ) . borrow ( ) . get ( ) . capacity ( )
56
+ }
57
+
58
+ unsafe fn as_ptr ( & self ) -> * u8 {
59
+ self . data . borrow ( ) . borrow ( ) . get ( ) . as_ptr ( )
60
+ }
61
+ }
52
62
53
63
// Arenas are used to quickly allocate objects that share a
54
64
// lifetime. The arena uses ~[u8] vectors as a backing store to
@@ -97,10 +107,8 @@ impl Arena {
97
107
}
98
108
99
109
fn chunk ( size : uint , is_pod : bool ) -> Chunk {
100
- let mut v: @[ u8 ] = @[ ] ;
101
- unsafe { at_vec:: raw:: reserve ( & mut v, size) ; }
102
110
Chunk {
103
- data : RefCell :: new ( unsafe { cast :: transmute ( v ) } ) ,
111
+ data : Rc :: new ( RefCell :: new ( vec :: with_capacity ( size ) ) ) ,
104
112
fill : Cell :: new ( 0 u) ,
105
113
is_pod : Cell :: new ( is_pod) ,
106
114
}
@@ -131,10 +139,7 @@ fn round_up(base: uint, align: uint) -> uint {
131
139
// in it.
132
140
unsafe fn destroy_chunk ( chunk : & Chunk ) {
133
141
let mut idx = 0 ;
134
- let buf = {
135
- let data = chunk. data . borrow ( ) ;
136
- data. get ( ) . as_ptr ( )
137
- } ;
142
+ let buf = chunk. as_ptr ( ) ;
138
143
let fill = chunk. fill . get ( ) ;
139
144
140
145
while idx < fill {
@@ -172,11 +177,13 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TyDesc, bool) {
172
177
}
173
178
174
179
impl Arena {
180
+ fn chunk_size ( & self ) -> uint {
181
+ self . pod_head . capacity ( )
182
+ }
175
183
// Functions for the POD part of the arena
176
184
fn alloc_pod_grow ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
177
185
// Allocate a new chunk.
178
- let chunk_size = at_vec:: capacity ( self . pod_head . data . get ( ) ) ;
179
- let new_min_chunk_size = num:: max ( n_bytes, chunk_size) ;
186
+ let new_min_chunk_size = num:: max ( n_bytes, self . chunk_size ( ) ) ;
180
187
self . chunks . set ( @Cons ( self . pod_head . clone ( ) , self . chunks . get ( ) ) ) ;
181
188
self . pod_head =
182
189
chunk ( num:: next_power_of_two ( new_min_chunk_size + 1 u) , true ) ;
@@ -190,15 +197,15 @@ impl Arena {
190
197
let this = transmute_mut_region ( self ) ;
191
198
let start = round_up ( this. pod_head . fill . get ( ) , align) ;
192
199
let end = start + n_bytes;
193
- if end > at_vec :: capacity ( this . pod_head . data . get ( ) ) {
200
+ if end > self . chunk_size ( ) {
194
201
return this. alloc_pod_grow ( n_bytes, align) ;
195
202
}
196
203
this. pod_head . fill . set ( end) ;
197
204
198
205
//debug!("idx = {}, size = {}, align = {}, fill = {}",
199
206
// start, n_bytes, align, head.fill.get());
200
207
201
- ptr :: offset ( this. pod_head . data . get ( ) . as_ptr ( ) , start as int )
208
+ this. pod_head . as_ptr ( ) . offset ( start as int )
202
209
}
203
210
}
204
211
@@ -217,8 +224,7 @@ impl Arena {
217
224
fn alloc_nonpod_grow ( & mut self , n_bytes : uint , align : uint )
218
225
-> ( * u8 , * u8 ) {
219
226
// Allocate a new chunk.
220
- let chunk_size = at_vec:: capacity ( self . head . data . get ( ) ) ;
221
- let new_min_chunk_size = num:: max ( n_bytes, chunk_size) ;
227
+ let new_min_chunk_size = num:: max ( n_bytes, self . chunk_size ( ) ) ;
222
228
self . chunks . set ( @Cons ( self . head . clone ( ) , self . chunks . get ( ) ) ) ;
223
229
self . head =
224
230
chunk ( num:: next_power_of_two ( new_min_chunk_size + 1 u) , false ) ;
@@ -244,7 +250,7 @@ impl Arena {
244
250
end = start + n_bytes;
245
251
}
246
252
247
- if end > at_vec :: capacity ( self . head . data . get ( ) ) {
253
+ if end > self . head . capacity ( ) {
248
254
return self . alloc_nonpod_grow ( n_bytes, align) ;
249
255
}
250
256
@@ -254,7 +260,7 @@ impl Arena {
254
260
//debug!("idx = {}, size = {}, align = {}, fill = {}",
255
261
// start, n_bytes, align, head.fill);
256
262
257
- let buf = self . head . data . get ( ) . as_ptr ( ) ;
263
+ let buf = self . head . as_ptr ( ) ;
258
264
return ( ptr:: offset ( buf, tydesc_start as int ) , ptr:: offset ( buf, start as int ) ) ;
259
265
}
260
266
}
@@ -606,5 +612,3 @@ mod test {
606
612
} )
607
613
}
608
614
}
609
-
610
-
0 commit comments