@@ -20,6 +20,7 @@ use unstable::exchange_alloc;
20
20
use cast:: transmute;
21
21
use task:: rt:: rust_get_task;
22
22
use option:: { Option , Some , None } ;
23
+ use io;
23
24
24
25
#[ allow( non_camel_case_types) ]
25
26
pub type rust_task = c_void ;
@@ -109,8 +110,8 @@ pub unsafe fn clear_task_borrow_list() {
109
110
let _ = try_take_task_borrow_list ( ) ;
110
111
}
111
112
112
- fn fail_borrowed ( box : * mut BoxRepr , file : * c_char , line : size_t ) {
113
- debug_ptr ( "fail_borrowed: " , box) ;
113
+ unsafe fn fail_borrowed ( box : * mut BoxRepr , file : * c_char , line : size_t ) {
114
+ debug_borrow ( "fail_borrowed: " , box, 0 , 0 , file , line ) ;
114
115
115
116
match try_take_task_borrow_list ( ) {
116
117
None => { // not recording borrows
@@ -145,42 +146,95 @@ fn fail_borrowed(box: *mut BoxRepr, file: *c_char, line: size_t) {
145
146
#[ inline( always) ]
146
147
pub unsafe fn exchange_malloc ( td : * c_char , size : uintptr_t ) -> * c_char {
147
148
let result = transmute ( exchange_alloc:: malloc ( transmute ( td) , transmute ( size) ) ) ;
148
- debug_ptr ( "exchange_malloc: " , result) ;
149
+ debug_mem ( "exchange_malloc: " , result) ;
149
150
return result;
150
151
}
151
152
152
153
/// Because this code is so perf. sensitive, use a static constant so that
153
154
/// debug printouts are compiled out most of the time.
154
- static ENABLE_DEBUG_PTR : bool = true ;
155
+ static ENABLE_DEBUG : bool = true ;
155
156
156
157
#[ inline]
157
- pub fn debug_ptr < T > ( tag : & ' static str , p : * const T ) {
158
+ pub fn debug_mem < T > ( tag : & ' static str , p : * const T ) {
158
159
//! A useful debugging function that prints a pointer + tag + newline
159
160
//! without allocating memory.
160
161
161
- if ENABLE_DEBUG_PTR && :: rt:: env:: get ( ) . debug_mem {
162
- debug_ptr_slow ( tag, p) ;
162
+ if ENABLE_DEBUG && :: rt:: env:: get ( ) . debug_mem {
163
+ debug_mem_slow ( tag, p) ;
163
164
}
164
165
165
- fn debug_ptr_slow < T > ( tag : & ' static str , p : * const T ) {
166
- use io;
166
+ fn debug_mem_slow < T > ( tag : & ' static str , p : * const T ) {
167
167
let dbg = STDERR_FILENO as io:: fd_t ;
168
- let letters = [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' ,
169
- '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ] ;
170
168
dbg. write_str ( tag) ;
169
+ dbg. write_hex ( p as uint ) ;
170
+ dbg. write_str ( "\n " ) ;
171
+ }
172
+ }
173
+
174
+ #[ inline]
175
+ unsafe fn debug_borrow < T > ( tag : & ' static str ,
176
+ p : * const T ,
177
+ old_bits : uint ,
178
+ new_bits : uint ,
179
+ filename : * c_char ,
180
+ line : size_t ) {
181
+ //! A useful debugging function that prints a pointer + tag + newline
182
+ //! without allocating memory.
183
+
184
+ if ENABLE_DEBUG && :: rt:: env:: get ( ) . debug_borrow {
185
+ debug_borrow_slow ( tag, p, old_bits, new_bits, filename, line) ;
186
+ }
187
+
188
+ unsafe fn debug_borrow_slow < T > ( tag : & ' static str ,
189
+ p : * const T ,
190
+ old_bits : uint ,
191
+ new_bits : uint ,
192
+ filename : * c_char ,
193
+ line : size_t ) {
194
+ let dbg = STDERR_FILENO as io:: fd_t ;
195
+ dbg. write_str ( tag) ;
196
+ dbg. write_hex ( p as uint ) ;
197
+ dbg. write_str ( " " ) ;
198
+ dbg. write_hex ( old_bits) ;
199
+ dbg. write_str ( " " ) ;
200
+ dbg. write_hex ( new_bits) ;
201
+ dbg. write_str ( " " ) ;
202
+ dbg. write_cstr ( filename) ;
203
+ dbg. write_str ( ":" ) ;
204
+ dbg. write_hex ( line as uint ) ;
205
+ dbg. write_str ( "\n " ) ;
206
+ }
207
+ }
208
+
209
+ trait DebugPrints {
210
+ fn write_hex ( & self , val : uint ) ;
211
+ unsafe fn write_cstr ( & self , str : * c_char ) ;
212
+ }
171
213
214
+ impl DebugPrints for io:: fd_t {
215
+ fn write_hex ( & self , mut i : uint ) {
216
+ let letters = [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' ,
217
+ '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ] ;
172
218
static uint_nibbles: uint = :: uint:: bytes << 1 ;
173
219
let mut buffer = [ 0_u8 , ..uint_nibbles+1 ] ;
174
- let mut i = p as uint ;
175
220
let mut c = uint_nibbles;
176
221
while c > 0 {
177
222
c -= 1 ;
178
223
buffer[ c] = letters[ i & 0xF ] as u8 ;
179
224
i >>= 4 ;
180
225
}
181
- dbg. write ( buffer. slice ( 0 , uint_nibbles) ) ;
226
+ self . write ( buffer. slice ( 0 , uint_nibbles) ) ;
227
+ }
182
228
183
- dbg. write_str ( "\n " ) ;
229
+ unsafe fn write_cstr ( & self , p : * c_char ) {
230
+ use libc:: strlen;
231
+ use vec;
232
+
233
+ let len = strlen ( p) ;
234
+ let p: * u8 = transmute ( p) ;
235
+ do vec:: raw:: buf_as_slice ( p, len as uint ) |s| {
236
+ self . write ( s) ;
237
+ }
184
238
}
185
239
}
186
240
@@ -190,15 +244,15 @@ pub fn debug_ptr<T>(tag: &'static str, p: *const T) {
190
244
#[ lang="exchange_free" ]
191
245
#[ inline( always) ]
192
246
pub unsafe fn exchange_free ( ptr : * c_char ) {
193
- debug_ptr ( "exchange_free: " , ptr) ;
247
+ debug_mem ( "exchange_free: " , ptr) ;
194
248
exchange_alloc:: free ( transmute ( ptr) )
195
249
}
196
250
197
251
#[ lang="malloc" ]
198
252
#[ inline( always) ]
199
253
pub unsafe fn local_malloc ( td : * c_char , size : uintptr_t ) -> * c_char {
200
254
let result = rustrt:: rust_upcall_malloc_noswitch ( td, size) ;
201
- debug_ptr ( "local_malloc: " , result) ;
255
+ debug_mem ( "local_malloc: " , result) ;
202
256
return result;
203
257
}
204
258
@@ -208,7 +262,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
208
262
#[ lang="free" ]
209
263
#[ inline( always) ]
210
264
pub unsafe fn local_free ( ptr : * c_char ) {
211
- debug_ptr ( "local_free: " , ptr) ;
265
+ debug_mem ( "local_free: " , ptr) ;
212
266
rustrt:: rust_upcall_free_noswitch ( ptr) ;
213
267
}
214
268
@@ -225,38 +279,37 @@ pub unsafe fn borrow_as_imm(a: *u8) {
225
279
#[ inline( always) ]
226
280
pub unsafe fn borrow_as_imm ( a : * u8 , file : * c_char , line : size_t ) -> uint {
227
281
let a: * mut BoxRepr = transmute ( a) ;
228
- let ref_count = ( * a) . header . ref_count ;
282
+ let old_ref_count = ( * a) . header . ref_count ;
283
+ let new_ref_count = old_ref_count | FROZEN_BIT ;
229
284
230
- debug_ptr ( "borrow_as_imm (ptr) :" , a) ;
231
- debug_ptr ( " (ref) :" , ref_count as * ( ) ) ;
232
- debug_ptr ( " (line): " , line as * ( ) ) ;
285
+ debug_borrow ( "borrow_as_imm:" , a, old_ref_count, new_ref_count, file, line) ;
233
286
234
- if ( ref_count & MUT_BIT ) != 0 {
287
+ if ( old_ref_count & MUT_BIT ) != 0 {
235
288
fail_borrowed ( a, file, line) ;
236
289
}
237
290
238
- ( * a) . header . ref_count = ref_count | FROZEN_BIT ;
291
+ ( * a) . header . ref_count = new_ref_count ;
239
292
240
- ref_count
293
+ old_ref_count
241
294
}
242
295
243
296
#[ cfg( not( stage0) ) ]
244
297
#[ lang="borrow_as_mut" ]
245
298
#[ inline( always) ]
246
299
pub unsafe fn borrow_as_mut ( a : * u8 , file : * c_char , line : size_t ) -> uint {
247
300
let a: * mut BoxRepr = transmute ( a) ;
301
+ let old_ref_count = ( * a) . header . ref_count ;
302
+ let new_ref_count = old_ref_count | MUT_BIT | FROZEN_BIT ;
248
303
249
- debug_ptr ( "borrow_as_mut (ptr): " , a) ;
250
- debug_ptr ( " (line): " , line as * ( ) ) ;
304
+ debug_borrow ( "borrow_as_mut:" , a, old_ref_count, new_ref_count, file, line) ;
251
305
252
- let ref_count = ( * a) . header . ref_count ;
253
- if ( ref_count & ( MUT_BIT |FROZEN_BIT ) ) != 0 {
306
+ if ( old_ref_count & ( MUT_BIT |FROZEN_BIT ) ) != 0 {
254
307
fail_borrowed ( a, file, line) ;
255
308
}
256
309
257
- ( * a) . header . ref_count = ref_count | MUT_BIT | FROZEN_BIT ;
310
+ ( * a) . header . ref_count = new_ref_count ;
258
311
259
- ref_count
312
+ old_ref_count
260
313
}
261
314
262
315
@@ -267,6 +320,7 @@ pub unsafe fn record_borrow(a: *u8, old_ref_count: uint,
267
320
if ( old_ref_count & ALL_BITS ) == 0 {
268
321
// was not borrowed before
269
322
let a: * mut BoxRepr = transmute ( a) ;
323
+ debug_borrow ( "record_borrow:" , a, old_ref_count, 0 , file, line) ;
270
324
do swap_task_borrow_list |borrow_list| {
271
325
let mut borrow_list = borrow_list;
272
326
borrow_list. push ( BorrowRecord { box : a, file : file, line : line} ) ;
@@ -282,6 +336,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
282
336
if ( old_ref_count & ALL_BITS ) == 0 {
283
337
// was not borrowed before
284
338
let a: * mut BoxRepr = transmute ( a) ;
339
+ debug_borrow ( "unrecord_borrow:" , a, old_ref_count, 0 , file, line) ;
285
340
do swap_task_borrow_list |borrow_list| {
286
341
let mut borrow_list = borrow_list;
287
342
let br = BorrowRecord { box : a, file : file, line : line} ;
@@ -317,21 +372,20 @@ pub unsafe fn return_to_mut(a: *u8) {
317
372
#[ cfg( not( stage0) ) ]
318
373
#[ lang="return_to_mut" ]
319
374
#[ inline( always) ]
320
- pub unsafe fn return_to_mut ( a: * u8, old_ref_count : uint,
375
+ pub unsafe fn return_to_mut ( a: * u8, orig_ref_count : uint,
321
376
file: * c_char, line: size_t) {
322
377
// Sometimes the box is null, if it is conditionally frozen.
323
378
// See e.g. #4904.
324
379
if !a. is_null ( ) {
325
380
let a: * mut BoxRepr = transmute ( a) ;
326
- let ref_count = ( * a) . header . ref_count ;
327
- let combined = ( ref_count & !ALL_BITS ) | ( old_ref_count & ALL_BITS ) ;
328
- ( * a) . header . ref_count = combined;
329
-
330
- debug_ptr ( "return_to_mut (ptr) : " , a) ;
331
- debug_ptr ( " (line): " , line as * ( ) ) ;
332
- debug_ptr ( " (old) : " , old_ref_count as * ( ) ) ;
333
- debug_ptr ( " (new) : " , ref_count as * ( ) ) ;
334
- debug_ptr ( " (comb): " , combined as * ( ) ) ;
381
+ let old_ref_count = ( * a) . header . ref_count ;
382
+ let new_ref_count =
383
+ ( old_ref_count & !ALL_BITS ) | ( orig_ref_count & ALL_BITS ) ;
384
+
385
+ debug_borrow ( "return_to_mut:" ,
386
+ a, old_ref_count, new_ref_count, file, line) ;
387
+
388
+ ( * a) . header . ref_count = new_ref_count;
335
389
}
336
390
}
337
391
@@ -355,10 +409,7 @@ pub unsafe fn check_not_borrowed(a: *u8,
355
409
line : size_t ) {
356
410
let a: * mut BoxRepr = transmute ( a) ;
357
411
let ref_count = ( * a) . header . ref_count ;
358
- debug_ptr ( "check_not_borrowed (ptr) : " , a) ;
359
- debug_ptr ( " (line): " , line as * ( ) ) ;
360
- debug_ptr ( " (rc) : " , ref_count as * ( ) ) ;
361
-
412
+ debug_borrow ( "check_not_borrowed:" , a, ref_count, 0 , file, line) ;
362
413
if ( ref_count & FROZEN_BIT ) != 0 {
363
414
fail_borrowed ( a, file, line) ;
364
415
}
0 commit comments