@@ -82,19 +82,35 @@ impl FunctionLocations for VecFunctionLocations {
8282 }
8383}
8484
85- pub type LineNumber = u16 ; // TODO u32, newtype
85+ /// Either the line number, or the bytecode index needed to get it.
86+ #[ derive( Copy , Clone , Serialize , Deserialize , Hash , Eq , PartialEq , Debug ) ]
87+ pub enum LineNumberInfo {
88+ LineNumber ( u32 ) ,
89+ BytecodeIndex ( i32 ) ,
90+ }
91+
92+ impl LineNumberInfo {
93+ fn get_line_number ( & self ) -> u32 {
94+ if let LineNumberInfo :: LineNumber ( lineno) = self {
95+ * lineno
96+ } else {
97+ debug_assert ! ( false , "This should never happen." ) ;
98+ 0
99+ }
100+ }
101+ }
86102
87103/// A specific location: file + function + line number.
88104#[ derive( Clone , Debug , PartialEq , Eq , Copy , Hash , Serialize , Deserialize ) ]
89105pub struct CallSiteId {
90106 /// The function + filename. We use IDs for performance reasons (faster hashing).
91107 function : FunctionId ,
92108 /// Line number within the _file_, 1-indexed.
93- line_number : LineNumber ,
109+ line_number : LineNumberInfo ,
94110}
95111
96112impl CallSiteId {
97- pub fn new ( function : FunctionId , line_number : u16 ) -> CallSiteId {
113+ pub fn new ( function : FunctionId , line_number : LineNumberInfo ) -> CallSiteId {
98114 CallSiteId {
99115 function,
100116 line_number,
@@ -108,7 +124,7 @@ impl CallSiteId {
108124pub struct Callstack {
109125 calls : Vec < CallSiteId > ,
110126 #[ derivative( Hash = "ignore" , PartialEq = "ignore" ) ]
111- cached_callstack_id : Option < ( u16 , CallstackId ) > , // first bit is line number
127+ cached_callstack_id : Option < ( u32 , CallstackId ) > , // first bit is line number
112128}
113129
114130impl Callstack {
@@ -126,10 +142,10 @@ impl Callstack {
126142 }
127143 }
128144
129- pub fn start_call ( & mut self , parent_line_number : u16 , callsite_id : CallSiteId ) {
145+ pub fn start_call ( & mut self , parent_line_number : u32 , callsite_id : CallSiteId ) {
130146 if parent_line_number != 0 {
131147 if let Some ( mut call) = self . calls . last_mut ( ) {
132- call. line_number = parent_line_number;
148+ call. line_number = LineNumberInfo :: LineNumber ( parent_line_number) ;
133149 }
134150 }
135151 self . calls . push ( callsite_id) ;
@@ -141,7 +157,7 @@ impl Callstack {
141157 self . cached_callstack_id = None ;
142158 }
143159
144- pub fn id_for_new_allocation < F > ( & mut self , line_number : u16 , get_callstack_id : F ) -> CallstackId
160+ pub fn id_for_new_allocation < F > ( & mut self , line_number : u32 , get_callstack_id : F ) -> CallstackId
145161 where
146162 F : FnOnce ( & Callstack ) -> CallstackId ,
147163 {
@@ -156,7 +172,7 @@ impl Callstack {
156172 // Set the new line number:
157173 if line_number != 0 {
158174 if let Some ( call) = self . calls . last_mut ( ) {
159- call. line_number = line_number;
175+ call. line_number = LineNumberInfo :: LineNumber ( line_number) ;
160176 }
161177 }
162178
@@ -194,7 +210,8 @@ impl Callstack {
194210 . map ( |( id, ( function, filename) ) | {
195211 if to_be_post_processed {
196212 // Get Python code.
197- let code = linecache. get_source_line ( filename, id. line_number as usize ) ;
213+ let code = linecache
214+ . get_source_line ( filename, id. line_number . get_line_number ( ) as usize ) ;
198215 // Leading whitespace is dropped by SVG, so we'd like to
199216 // replace it with non-breaking space. However, inferno
200217 // trims whitespace
@@ -215,15 +232,15 @@ impl Callstack {
215232 format ! (
216233 "{filename}:{line} ({function});\u{2800} {code}" ,
217234 filename = filename,
218- line = id. line_number,
235+ line = id. line_number. get_line_number ( ) ,
219236 function = function,
220237 code = & code. trim_end( ) ,
221238 )
222239 } else {
223240 format ! (
224241 "{filename}:{line} ({function})" ,
225242 filename = filename,
226- line = id. line_number,
243+ line = id. line_number. get_line_number ( ) ,
227244 function = function,
228245 )
229246 }
@@ -748,6 +765,7 @@ impl<FL: FunctionLocations> AllocationTracker<FL> {
748765mod tests {
749766 use crate :: memorytracking:: { ProcessUid , PARENT_PROCESS } ;
750767
768+ use super :: LineNumberInfo :: LineNumber ;
751769 use super :: {
752770 Allocation , AllocationTracker , CallSiteId , Callstack , CallstackInterner , FunctionId ,
753771 FunctionLocations , VecFunctionLocations , HIGH_32BIT , MIB ,
@@ -815,7 +833,7 @@ mod tests {
815833 let ( process, allocation_size) = * allocated_sizes. get( i) . unwrap( ) ;
816834 let process = ProcessUid ( process) ;
817835 let mut cs = Callstack :: new( ) ;
818- cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , 0 ) ) ;
836+ cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , LineNumber ( 0 ) ) ) ;
819837 let cs_id = tracker. get_callstack_id( & cs) ;
820838 tracker. add_allocation( process, i as usize , allocation_size, cs_id) ;
821839 expected_memory_usage. push_back( allocation_size) ;
@@ -854,7 +872,7 @@ mod tests {
854872 let ( process, allocation_size) = * allocated_sizes. get( i) . unwrap( ) ;
855873 let process = ProcessUid ( process) ;
856874 let mut cs = Callstack :: new( ) ;
857- cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , 0 ) ) ;
875+ cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , LineNumber ( 0 ) ) ) ;
858876 let csid = tracker. get_callstack_id( & cs) ;
859877 tracker. add_anon_mmap( process, addresses[ i] as usize , allocation_size, csid) ;
860878 expected_memory_usage. push_back( allocation_size) ;
@@ -891,7 +909,7 @@ mod tests {
891909 let ( process, allocation_size) = * allocated_sizes. get( i) . unwrap( ) ;
892910 let process = ProcessUid ( process) ;
893911 let mut cs = Callstack :: new( ) ;
894- cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , 0 ) ) ;
912+ cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , LineNumber ( 0 ) ) ) ;
895913 let cs_id = tracker. get_callstack_id( & cs) ;
896914 tracker. add_allocation( process, i as usize , allocation_size, cs_id) ;
897915 expected_memory_usage += allocation_size;
@@ -900,7 +918,7 @@ mod tests {
900918 let ( process, allocation_size) = * allocated_mmaps. get( i) . unwrap( ) ;
901919 let process = ProcessUid ( process) ;
902920 let mut cs = Callstack :: new( ) ;
903- cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , 0 ) ) ;
921+ cs. start_call( 0 , CallSiteId :: new( FunctionId :: new( i as u64 ) , LineNumber ( 0 ) ) ) ;
904922 let csid = tracker. get_callstack_id( & cs) ;
905923 tracker. add_anon_mmap( process, mmap_addresses[ i] as usize , allocation_size, csid) ;
906924 expected_memory_usage += allocation_size;
@@ -933,9 +951,10 @@ mod tests {
933951
934952 // Parent line number does nothing if it's first call:
935953 let mut cs1 = Callstack :: new ( ) ;
936- let id1 = CallSiteId :: new ( fid1, 2 ) ;
937- let id2 = CallSiteId :: new ( fid3, 45 ) ;
938- let id3 = CallSiteId :: new ( fid5, 6 ) ;
954+ // CallSiteId::new($a, $b) ==>> CallSiteId::new($a, LineNumber($b))
955+ let id1 = CallSiteId :: new ( fid1, LineNumber ( 2 ) ) ;
956+ let id2 = CallSiteId :: new ( fid3, LineNumber ( 45 ) ) ;
957+ let id3 = CallSiteId :: new ( fid5, LineNumber ( 6 ) ) ;
939958 cs1. start_call ( 123 , id1) ;
940959 assert_eq ! ( cs1. calls, vec![ id1] ) ;
941960
@@ -950,7 +969,11 @@ mod tests {
950969 cs2. start_call ( 12 , id3) ;
951970 assert_eq ! (
952971 cs2. calls,
953- vec![ CallSiteId :: new( fid1, 10 ) , CallSiteId :: new( fid3, 12 ) , id3]
972+ vec![
973+ CallSiteId :: new( fid1, LineNumber ( 10 ) ) ,
974+ CallSiteId :: new( fid3, LineNumber ( 12 ) ) ,
975+ id3
976+ ]
954977 ) ;
955978 }
956979
@@ -960,10 +983,10 @@ mod tests {
960983 let fid3 = FunctionId :: new ( 3u64 ) ;
961984
962985 let mut cs1 = Callstack :: new ( ) ;
963- cs1. start_call ( 0 , CallSiteId :: new ( fid1, 2 ) ) ;
986+ cs1. start_call ( 0 , CallSiteId :: new ( fid1, LineNumber ( 2 ) ) ) ;
964987 let cs1b = cs1. clone ( ) ;
965988 let mut cs2 = Callstack :: new ( ) ;
966- cs2. start_call ( 0 , CallSiteId :: new ( fid3, 4 ) ) ;
989+ cs2. start_call ( 0 , CallSiteId :: new ( fid3, LineNumber ( 4 ) ) ) ;
967990 let cs3 = Callstack :: new ( ) ;
968991 let cs3b = Callstack :: new ( ) ;
969992
@@ -1014,7 +1037,7 @@ mod tests {
10141037
10151038 let fid1 = FunctionId :: new ( 1u64 ) ;
10161039
1017- cs1. start_call ( 0 , CallSiteId :: new ( fid1, 2 ) ) ;
1040+ cs1. start_call ( 0 , CallSiteId :: new ( fid1, LineNumber ( 2 ) ) ) ;
10181041 let id1 =
10191042 cs1. id_for_new_allocation ( 1 , |cs| interner. get_or_insert_id ( Cow :: Borrowed ( & cs) , || ( ) ) ) ;
10201043 let id2 =
@@ -1025,7 +1048,7 @@ mod tests {
10251048 assert_ne ! ( id2, id0) ;
10261049 assert_ne ! ( id2, id1) ;
10271050
1028- cs1. start_call ( 3 , CallSiteId :: new ( fid1, 2 ) ) ;
1051+ cs1. start_call ( 3 , CallSiteId :: new ( fid1, LineNumber ( 2 ) ) ) ;
10291052 let id3 =
10301053 cs1. id_for_new_allocation ( 4 , |cs| interner. get_or_insert_id ( Cow :: Borrowed ( & cs) , || ( ) ) ) ;
10311054 assert_ne ! ( id3, id0) ;
@@ -1041,7 +1064,7 @@ mod tests {
10411064 assert_eq ! ( id1, id1c) ;
10421065
10431066 // Check for cache invalidation in start_call:
1044- cs1. start_call ( 1 , CallSiteId :: new ( fid1, 1 ) ) ;
1067+ cs1. start_call ( 1 , CallSiteId :: new ( fid1, LineNumber ( 1 ) ) ) ;
10451068 let id4 =
10461069 cs1. id_for_new_allocation ( 1 , |cs| interner. get_or_insert_id ( Cow :: Borrowed ( & cs) , || ( ) ) ) ;
10471070 assert_ne ! ( id4, id0) ;
@@ -1063,9 +1086,9 @@ mod tests {
10631086
10641087 let mut tracker = new_tracker ( ) ;
10651088 let mut cs1 = Callstack :: new ( ) ;
1066- cs1. start_call ( 0 , CallSiteId :: new ( fid1, 2 ) ) ;
1089+ cs1. start_call ( 0 , CallSiteId :: new ( fid1, LineNumber ( 2 ) ) ) ;
10671090 let mut cs2 = Callstack :: new ( ) ;
1068- cs2. start_call ( 0 , CallSiteId :: new ( fid3, 4 ) ) ;
1091+ cs2. start_call ( 0 , CallSiteId :: new ( fid3, LineNumber ( 4 ) ) ) ;
10691092
10701093 let cs1_id = tracker. get_callstack_id ( & cs1) ;
10711094
@@ -1156,12 +1179,12 @@ mod tests {
11561179 . functions
11571180 . add_function ( "c" . to_string ( ) , "cf" . to_string ( ) ) ;
11581181
1159- let id1 = CallSiteId :: new ( fid1, 1 ) ;
1182+ let id1 = CallSiteId :: new ( fid1, LineNumber ( 1 ) ) ;
11601183 // Same function, different line number—should be different item:
1161- let id1_different = CallSiteId :: new ( fid1, 7 ) ;
1162- let id2 = CallSiteId :: new ( fid2, 2 ) ;
1184+ let id1_different = CallSiteId :: new ( fid1, LineNumber ( 7 ) ) ;
1185+ let id2 = CallSiteId :: new ( fid2, LineNumber ( 2 ) ) ;
11631186
1164- let id3 = CallSiteId :: new ( fid3, 3 ) ;
1187+ let id3 = CallSiteId :: new ( fid3, LineNumber ( 3 ) ) ;
11651188 let mut cs1 = Callstack :: new ( ) ;
11661189 cs1. start_call ( 0 , id1) ;
11671190 cs1. start_call ( 0 , id2. clone ( ) ) ;
0 commit comments