11
11
//! Runtime calls emitted by the compiler.
12
12
13
13
use cast:: transmute;
14
- use libc:: { c_char, c_uchar, c_void, size_t, uintptr_t, c_int} ;
14
+ use libc:: { c_char, c_uchar, c_void, size_t, uintptr_t, c_int, STDERR_FILENO } ;
15
15
use managed:: raw:: BoxRepr ;
16
16
use str;
17
17
use sys;
@@ -74,7 +74,44 @@ pub fn fail_borrowed() {
74
74
#[ lang="exchange_malloc" ]
75
75
#[ inline( always) ]
76
76
pub unsafe fn exchange_malloc ( td : * c_char , size : uintptr_t ) -> * c_char {
77
- transmute ( exchange_alloc:: malloc ( transmute ( td) , transmute ( size) ) )
77
+ let result = transmute ( exchange_alloc:: malloc ( transmute ( td) , transmute ( size) ) ) ;
78
+ debug_ptr ( "exchange_malloc: " , result) ;
79
+ return result;
80
+ }
81
+
82
+ /// Because this code is so perf. sensitive, use a static constant so that
83
+ /// debug printouts are compiled out most of the time.
84
+ static ENABLE_DEBUG_PTR : bool = false ;
85
+
86
+ #[ inline]
87
+ pub fn debug_ptr < T > ( tag : & ' static str , p : * T ) {
88
+ //! A useful debugging function that prints a pointer + tag + newline
89
+ //! without allocating memory.
90
+
91
+ if ENABLE_DEBUG_PTR && :: rt:: env:: get ( ) . debug_mem {
92
+ debug_ptr_slow ( tag, p) ;
93
+ }
94
+
95
+ fn debug_ptr_slow < T > ( tag : & ' static str , p : * T ) {
96
+ use io;
97
+ let dbg = STDERR_FILENO as io:: fd_t ;
98
+ let letters = [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' ,
99
+ '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ] ;
100
+ dbg. write_str ( tag) ;
101
+
102
+ static uint_nibbles: uint = :: uint:: bytes << 1 ;
103
+ let mut buffer = [ 0_u8 , ..uint_nibbles+1 ] ;
104
+ let mut i = p as uint ;
105
+ let mut c = uint_nibbles;
106
+ while c > 0 {
107
+ c -= 1 ;
108
+ buffer[ c] = letters[ i & 0xF ] as u8 ;
109
+ i >>= 4 ;
110
+ }
111
+ dbg. write ( buffer. slice ( 0 , uint_nibbles) ) ;
112
+
113
+ dbg. write_str ( "\n " ) ;
114
+ }
78
115
}
79
116
80
117
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -83,13 +120,16 @@ pub unsafe fn exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
83
120
#[ lang="exchange_free" ]
84
121
#[ inline( always) ]
85
122
pub unsafe fn exchange_free ( ptr : * c_char ) {
123
+ debug_ptr ( "exchange_free: " , ptr) ;
86
124
exchange_alloc:: free ( transmute ( ptr) )
87
125
}
88
126
89
127
#[ lang="malloc" ]
90
128
#[ inline( always) ]
91
129
pub unsafe fn local_malloc ( td : * c_char , size : uintptr_t ) -> * c_char {
92
- return rustrt:: rust_upcall_malloc_noswitch ( td, size) ;
130
+ let result = rustrt:: rust_upcall_malloc_noswitch ( td, size) ;
131
+ debug_ptr ( "local_malloc: " , result) ;
132
+ return result;
93
133
}
94
134
95
135
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
@@ -98,6 +138,7 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
98
138
#[ lang="free" ]
99
139
#[ inline( always) ]
100
140
pub unsafe fn local_free ( ptr : * c_char ) {
141
+ debug_ptr ( "local_free: " , ptr) ;
101
142
rustrt:: rust_upcall_free_noswitch ( ptr) ;
102
143
}
103
144
0 commit comments