1
- // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
@@ -39,32 +39,23 @@ use core::prelude::*;
39
39
use list:: { MutList , MutCons , MutNil } ;
40
40
41
41
use core:: at_vec;
42
- use core:: cast:: { transmute, transmute_mut , transmute_mut_region} ;
42
+ use core:: cast:: { transmute, transmute_mut_region} ;
43
43
use core:: cast;
44
- use core:: libc:: size_t;
45
44
use core:: ptr;
46
- use core:: sys:: TypeDesc ;
47
45
use core:: sys;
48
46
use core:: uint;
49
47
use core:: vec;
50
48
use core:: unstable:: intrinsics;
49
+ use core:: unstable:: intrinsics:: { TyDesc } ;
51
50
52
- pub mod rustrt {
53
- use core:: libc:: size_t;
54
- use core:: sys:: TypeDesc ;
51
+ #[ cfg( not( stage0) ) ]
52
+ use core:: unstable:: intrinsics:: { get_tydesc} ;
55
53
56
- pub extern {
57
- #[ rust_stack]
58
- unsafe fn rust_call_tydesc_glue ( root : * u8 ,
59
- tydesc : * TypeDesc ,
60
- field : size_t ) ;
61
- }
54
+ #[ cfg( stage0) ]
55
+ unsafe fn get_tydesc < T > ( ) -> * TyDesc {
56
+ intrinsics:: get_tydesc :: < T > ( ) as * TyDesc
62
57
}
63
58
64
- // This probably belongs somewhere else. Needs to be kept in sync with
65
- // changes to glue...
66
- static tydesc_drop_glue_index: size_t = 3 as size_t ;
67
-
68
59
// The way arena uses arrays is really deeply awful. The arrays are
69
60
// allocated, and have capacities reserved, but the fill for the array
70
61
// will always stay at 0.
@@ -74,7 +65,6 @@ struct Chunk {
74
65
is_pod : bool ,
75
66
}
76
67
77
- #[ mutable]
78
68
pub struct Arena {
79
69
// The head is separated out from the list as a unbenchmarked
80
70
// microoptimization, to avoid needing to case on the list to
@@ -125,6 +115,19 @@ fn round_up_to(base: uint, align: uint) -> uint {
125
115
( base + ( align - 1 ) ) & !( align - 1 )
126
116
}
127
117
118
+ #[ inline]
119
+ #[ cfg( not( stage0) ) ]
120
+ unsafe fn call_drop_glue ( tydesc : * TyDesc , data : * i8 ) {
121
+ // This function should be inlined when stage0 is gone
122
+ ( ( * tydesc) . drop_glue ) ( data) ;
123
+ }
124
+
125
+ #[ inline]
126
+ #[ cfg( stage0) ]
127
+ unsafe fn call_drop_glue ( tydesc : * TyDesc , data : * i8 ) {
128
+ ( ( * tydesc) . drop_glue ) ( 0 as * * TyDesc , data) ;
129
+ }
130
+
128
131
// Walk down a chunk, running the destructors for any objects stored
129
132
// in it.
130
133
unsafe fn destroy_chunk ( chunk : & Chunk ) {
@@ -137,19 +140,18 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
137
140
let ( tydesc, is_done) = un_bitpack_tydesc_ptr ( * tydesc_data) ;
138
141
let ( size, align) = ( ( * tydesc) . size , ( * tydesc) . align ) ;
139
142
140
- let after_tydesc = idx + sys:: size_of :: < * TypeDesc > ( ) ;
143
+ let after_tydesc = idx + sys:: size_of :: < * TyDesc > ( ) ;
141
144
142
145
let start = round_up_to ( after_tydesc, align) ;
143
146
144
147
//debug!("freeing object: idx = %u, size = %u, align = %u, done = %b",
145
148
// start, size, align, is_done);
146
149
if is_done {
147
- rustrt:: rust_call_tydesc_glue (
148
- ptr:: offset ( buf, start) , tydesc, tydesc_drop_glue_index) ;
150
+ call_drop_glue ( tydesc, ptr:: offset ( buf, start) as * i8 ) ;
149
151
}
150
152
151
153
// Find where the next tydesc lives
152
- idx = round_up_to ( start + size, sys:: pref_align_of :: < * TypeDesc > ( ) ) ;
154
+ idx = round_up_to ( start + size, sys:: pref_align_of :: < * TyDesc > ( ) ) ;
153
155
}
154
156
}
155
157
@@ -158,12 +160,12 @@ unsafe fn destroy_chunk(chunk: &Chunk) {
158
160
// is necessary in order to properly do cleanup if a failure occurs
159
161
// during an initializer.
160
162
#[ inline]
161
- unsafe fn bitpack_tydesc_ptr ( p : * TypeDesc , is_done : bool ) -> uint {
163
+ unsafe fn bitpack_tydesc_ptr ( p : * TyDesc , is_done : bool ) -> uint {
162
164
let p_bits: uint = transmute ( p) ;
163
165
p_bits | ( is_done as uint )
164
166
}
165
167
#[ inline]
166
- unsafe fn un_bitpack_tydesc_ptr ( p : uint ) -> ( * TypeDesc , bool ) {
168
+ unsafe fn un_bitpack_tydesc_ptr ( p : uint ) -> ( * TyDesc , bool ) {
167
169
( transmute ( p & !1 ) , p & 1 == 1 )
168
170
}
169
171
@@ -203,7 +205,7 @@ impl Arena {
203
205
#[ inline]
204
206
fn alloc_pod < ' a , T > ( & ' a mut self , op : & fn ( ) -> T ) -> & ' a T {
205
207
unsafe {
206
- let tydesc = sys :: get_type_desc :: < T > ( ) ;
208
+ let tydesc = get_tydesc :: < T > ( ) ;
207
209
let ptr = self . alloc_pod_inner ( ( * tydesc) . size , ( * tydesc) . align ) ;
208
210
let ptr: * mut T = transmute ( ptr) ;
209
211
intrinsics:: move_val_init ( & mut ( * ptr) , op ( ) ) ;
@@ -231,13 +233,13 @@ impl Arena {
231
233
let head = transmute_mut_region ( & mut self . head ) ;
232
234
233
235
let tydesc_start = head. fill ;
234
- let after_tydesc = head. fill + sys:: size_of :: < * TypeDesc > ( ) ;
236
+ let after_tydesc = head. fill + sys:: size_of :: < * TyDesc > ( ) ;
235
237
let start = round_up_to ( after_tydesc, align) ;
236
238
let end = start + n_bytes;
237
239
if end > at_vec:: capacity ( head. data ) {
238
240
return self . alloc_nonpod_grow ( n_bytes, align) ;
239
241
}
240
- head. fill = round_up_to ( end, sys:: pref_align_of :: < * TypeDesc > ( ) ) ;
242
+ head. fill = round_up_to ( end, sys:: pref_align_of :: < * TyDesc > ( ) ) ;
241
243
242
244
//debug!("idx = %u, size = %u, align = %u, fill = %u",
243
245
// start, n_bytes, align, head.fill);
@@ -250,7 +252,7 @@ impl Arena {
250
252
#[ inline]
251
253
fn alloc_nonpod < ' a , T > ( & ' a mut self , op : & fn ( ) -> T ) -> & ' a T {
252
254
unsafe {
253
- let tydesc = sys :: get_type_desc :: < T > ( ) ;
255
+ let tydesc = get_tydesc :: < T > ( ) ;
254
256
let ( ty_ptr, ptr) =
255
257
self . alloc_nonpod_inner ( ( * tydesc) . size , ( * tydesc) . align ) ;
256
258
let ty_ptr: * mut uint = transmute ( ty_ptr) ;
@@ -270,22 +272,23 @@ impl Arena {
270
272
271
273
// The external interface
272
274
#[ inline]
273
- pub fn alloc < ' a , T > ( & ' a self , op : & fn ( ) -> T ) -> & ' a T {
275
+ pub fn alloc < ' a , T > ( & ' a mut self , op : & fn ( ) -> T ) -> & ' a T {
274
276
unsafe {
275
277
// XXX: Borrow check
276
- let this = transmute_mut ( self ) ;
277
- if intrinsics:: needs_drop :: < T > ( ) {
278
- this. alloc_nonpod ( op)
279
- } else {
280
- this. alloc_pod ( op)
278
+ let this = transmute_mut_region ( self ) ;
279
+ if !intrinsics:: needs_drop :: < T > ( ) {
280
+ return this. alloc_pod ( op) ;
281
281
}
282
+ // XXX: Borrow check
283
+ let this = transmute_mut_region ( self ) ;
284
+ this. alloc_nonpod ( op)
282
285
}
283
286
}
284
287
}
285
288
286
289
#[ test]
287
290
fn test_arena_destructors ( ) {
288
- let arena = Arena ( ) ;
291
+ let mut arena = Arena ( ) ;
289
292
for uint:: range( 0 , 10 ) |i| {
290
293
// Arena allocate something with drop glue to make sure it
291
294
// doesn't leak.
@@ -300,7 +303,7 @@ fn test_arena_destructors() {
300
303
#[ should_fail]
301
304
#[ ignore( cfg( windows) ) ]
302
305
fn test_arena_destructors_fail( ) {
303
- let arena = Arena ( ) ;
306
+ let mut arena = Arena ( ) ;
304
307
// Put some stuff in the arena.
305
308
for uint:: range( 0 , 10 ) |i| {
306
309
// Arena allocate something with drop glue to make sure it
0 commit comments