@@ -19,6 +19,7 @@ use sys;
19
19
use unstable:: exchange_alloc;
20
20
use cast:: transmute;
21
21
use task:: rt:: rust_get_task;
22
+ use option:: { Some , None } ;
22
23
23
24
#[ allow( non_camel_case_types) ]
24
25
pub type rust_task = c_void ;
@@ -71,6 +72,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
71
72
}
72
73
}
73
74
75
+ #[ deriving( Eq ) ]
74
76
struct BorrowRecord {
75
77
box : * mut BoxRepr ,
76
78
file : * c_char ,
@@ -108,7 +110,7 @@ pub fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
108
110
str:: raw:: from_c_str ( entry. file )
109
111
} ;
110
112
str:: push_str ( & mut msg, filename) ;
111
- str:: push_str ( & mut msg, fmt ! ( ":%u" , line as uint) ) ;
113
+ str:: push_str ( & mut msg, fmt ! ( ":%u" , entry . line as uint) ) ;
112
114
sep = " and at " ;
113
115
}
114
116
}
@@ -208,15 +210,36 @@ fn add_borrow_to_task_list(a: *mut BoxRepr, file: *c_char, line: size_t) {
208
210
}
209
211
}
210
212
213
+ fn remove_borrow_from_task_list( a : * mut BoxRepr , file : * c_char , line : size_t ) {
214
+ do swap_task_borrow_list |borrow_list| {
215
+ let mut borrow_list = borrow_list;
216
+ let br = BorrowRecord { box : a, file : file, line : line} ;
217
+ match borrow_list. rposition_elem ( & br) {
218
+ Some ( idx) => {
219
+ borrow_list. remove ( idx) ;
220
+ borrow_list
221
+ }
222
+ None => {
223
+ let err = fmt ! ( "no borrow found, br=%?, borrow_list=%?" ,
224
+ br, borrow_list) ;
225
+ do str:: as_buf ( err) |msg_p, _| {
226
+ fail_( msg_p as * c_char, file, line)
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+
211
233
#[ cfg( not( stage0) ) ]
212
234
#[ lang="borrow_as_imm" ]
213
235
#[ inline( always) ]
214
236
pub unsafe fn borrow_as_imm( a: * u8, file: * c_char, line: size_t) -> uint {
215
237
let a: * mut BoxRepr = transmute( a) ;
216
238
let ref_count = ( * a) . header. ref_count;
217
239
218
- debug_ptr ( "borrow_as_imm (ptr): " , a) ;
219
- debug_ptr ( "borrow_as_imm (ref): " , ref_count as * ( ) ) ;
240
+ debug_ptr( "borrow_as_imm (ptr) :" , a) ;
241
+ debug_ptr( " (ref) :" , ref_count as * ( ) ) ;
242
+ debug_ptr( " (line): " , line as * ( ) ) ;
220
243
221
244
if ( ref_count & MUT_BIT ) != 0 {
222
245
fail_borrowed( a, file, line) ;
@@ -236,7 +259,7 @@ pub unsafe fn borrow_as_mut(a: *u8, file: *c_char, line: size_t) -> uint {
236
259
let a: * mut BoxRepr = transmute ( a) ;
237
260
238
261
debug_ptr ( "borrow_as_mut (ptr): " , a) ;
239
- debug_ptr ( "borrow_as_mut (line): " , line as * ( ) ) ;
262
+ debug_ptr ( " (line): " , line as * ( ) ) ;
240
263
241
264
let ref_count = ( * a) . header . ref_count ;
242
265
if ( ref_count & ( MUT_BIT |FROZEN_BIT ) ) != 0 {
@@ -265,18 +288,25 @@ pub unsafe fn return_to_mut(a: *u8) {
265
288
#[ cfg ( not ( stage0) ) ]
266
289
#[ lang="return_to_mut" ]
267
290
#[ inline ( always) ]
268
- pub unsafe fn return_to_mut ( a : * u8 , old_ref_count : uint ) {
291
+ pub unsafe fn return_to_mut( a: * u8, old_ref_count: uint,
292
+ file: * c_char, line: size_t) {
269
293
// Sometimes the box is null, if it is conditionally frozen.
270
294
// See e.g. #4904.
271
295
if !a. is_null ( ) {
272
296
let a: * mut BoxRepr = transmute ( a) ;
297
+ let ref_count = ( * a) . header . ref_count ;
298
+ let combined = ( ref_count & !ALL_BITS ) | ( old_ref_count & ALL_BITS ) ;
299
+ ( * a) . header . ref_count = combined;
273
300
274
- debug_ptr ( "return_to_mut (ptr): " , a) ;
275
- debug_ptr ( "return_to_mut (ref): " , old_ref_count as * ( ) ) ;
301
+ debug_ptr ( "return_to_mut (ptr) : " , a) ;
302
+ debug_ptr ( " (line): " , line as * ( ) ) ;
303
+ debug_ptr ( " (old) : " , old_ref_count as * ( ) ) ;
304
+ debug_ptr ( " (new) : " , ref_count as * ( ) ) ;
305
+ debug_ptr ( " (comb): " , combined as * ( ) ) ;
276
306
277
- let ref_count = ( * a ) . header . ref_count & ! ALL_BITS ;
278
- let old_bits = old_ref_count & ALL_BITS ;
279
- ( * a ) . header . ref_count = ref_count | old_bits ;
307
+ if :: rt :: env :: get ( ) . debug_borrows {
308
+ remove_borrow_from_task_list ( a , file , line ) ;
309
+ }
280
310
}
281
311
}
282
312
0 commit comments