3535#[ allow( missing_doc) ] ;
3636
3737
38- use list:: { MutList , MutCons , MutNil } ;
38+ use list:: { List , Cons , Nil } ;
39+ use list;
3940
4041use std:: at_vec;
4142use std:: cast:: { transmute, transmute_mut, transmute_mut_region} ;
4243use std:: cast;
44+ use std:: cell:: { Cell , RefCell } ;
4345use std:: num;
4446use std:: ptr;
4547use std:: mem;
@@ -50,10 +52,11 @@ use std::unstable::intrinsics::{TyDesc, get_tydesc};
5052// The way arena uses arrays is really deeply awful. The arrays are
5153// allocated, and have capacities reserved, but the fill for the array
5254// will always stay at 0.
55+ #[ deriving( Clone ) ]
5356struct Chunk {
54- data : @[ u8 ] ,
55- fill : uint ,
56- is_pod : bool ,
57+ data : RefCell < @[ u8 ] > ,
58+ fill : Cell < uint > ,
59+ is_pod : Cell < bool > ,
5760}
5861
5962#[ no_freeze]
@@ -63,7 +66,7 @@ pub struct Arena {
6366 // access the head.
6467 priv head : Chunk ,
6568 priv pod_head : Chunk ,
66- priv chunks : @ mut MutList < Chunk > ,
69+ priv chunks : RefCell < @ List < Chunk > > ,
6770}
6871
6972impl Arena {
@@ -75,7 +78,7 @@ impl Arena {
7578 Arena {
7679 head : chunk ( initial_size, false ) ,
7780 pod_head : chunk ( initial_size, true ) ,
78- chunks : @ mut MutNil ,
81+ chunks : RefCell :: new ( @ Nil ) ,
7982 }
8083 }
8184}
@@ -84,9 +87,9 @@ fn chunk(size: uint, is_pod: bool) -> Chunk {
8487 let mut v: @[ u8 ] = @[ ] ;
8588 unsafe { at_vec:: raw:: reserve ( & mut v, size) ; }
8689 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) ,
9093 }
9194}
9295
@@ -95,8 +98,9 @@ impl Drop for Arena {
9598 fn drop ( & mut self ) {
9699 unsafe {
97100 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 ( ) {
100104 destroy_chunk ( chunk) ;
101105 }
102106 true
@@ -114,8 +118,11 @@ fn round_up_to(base: uint, align: uint) -> uint {
114118// in it.
115119unsafe fn destroy_chunk ( chunk : & Chunk ) {
116120 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 ( ) ;
119126
120127 while idx < fill {
121128 let tydesc_data: * uint = transmute ( ptr:: offset ( buf, idx as int ) ) ;
@@ -155,9 +162,9 @@ impl Arena {
155162 // Functions for the POD part of the arena
156163 fn alloc_pod_grow ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
157164 // 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 ( ) ) ;
159166 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 ( ) ) ) ;
161168 self . pod_head =
162169 chunk ( uint:: next_power_of_two ( new_min_chunk_size + 1 u) , true ) ;
163170
@@ -168,17 +175,17 @@ impl Arena {
168175 fn alloc_pod_inner ( & mut self , n_bytes : uint , align : uint ) -> * u8 {
169176 unsafe {
170177 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) ;
172179 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 ( ) ) {
174181 return this. alloc_pod_grow ( n_bytes, align) ;
175182 }
176- this. pod_head . fill = end;
183+ this. pod_head . fill . set ( end) ;
177184
178185 //debug!("idx = {}, size = {}, align = {}, fill = {}",
179- // start, n_bytes, align, head.fill);
186+ // start, n_bytes, align, head.fill.get() );
180187
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 )
182189 }
183190 }
184191
@@ -197,9 +204,9 @@ impl Arena {
197204 fn alloc_nonpod_grow ( & mut self , n_bytes : uint , align : uint )
198205 -> ( * u8 , * u8 ) {
199206 // 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 ( ) ) ;
201208 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 ( ) ) ) ;
203210 self . head =
204211 chunk ( uint:: next_power_of_two ( new_min_chunk_size + 1 u) , false ) ;
205212
@@ -218,23 +225,23 @@ impl Arena {
218225 {
219226 let head = transmute_mut_region ( & mut self . head ) ;
220227
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 > ( ) ;
223230 start = round_up_to ( after_tydesc, align) ;
224231 end = start + n_bytes;
225232 }
226233
227- if end > at_vec:: capacity ( self . head . data ) {
234+ if end > at_vec:: capacity ( self . head . data . get ( ) ) {
228235 return self . alloc_nonpod_grow ( n_bytes, align) ;
229236 }
230237
231238 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 > ( ) ) ) ;
233240
234241 //debug!("idx = {}, size = {}, align = {}, fill = {}",
235242 // start, n_bytes, align, head.fill);
236243
237- let buf = self . head . data . as_ptr ( ) ;
244+ let buf = self . head . data . get ( ) . as_ptr ( ) ;
238245 return ( ptr:: offset ( buf, tydesc_start as int ) , ptr:: offset ( buf, start as int ) ) ;
239246 }
240247 }
0 commit comments