@@ -43,72 +43,82 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
4343 codemap : CachingCodemapView < ' tcx > ,
4444}
4545
46+ #[ derive( Clone ) ]
47+ struct CacheEntry {
48+ time_stamp : usize ,
49+ line_number : usize ,
50+ line_start : BytePos ,
51+ line_end : BytePos ,
52+ file : Rc < FileMap > ,
53+ }
54+
4655struct CachingCodemapView < ' tcx > {
4756 codemap : & ' tcx CodeMap ,
48- // Format: (line number, line-start, line-end, file)
49- line_cache : [ ( usize , BytePos , BytePos , Rc < FileMap > ) ; 4 ] ,
50- eviction_index : usize ,
57+ line_cache : [ CacheEntry ; 3 ] ,
58+ time_stamp : usize ,
5159}
5260
5361impl < ' tcx > CachingCodemapView < ' tcx > {
5462 fn new < ' a > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> CachingCodemapView < ' tcx > {
5563 let codemap = tcx. sess . codemap ( ) ;
5664 let first_file = codemap. files . borrow ( ) [ 0 ] . clone ( ) ;
65+ let entry = CacheEntry {
66+ time_stamp : 0 ,
67+ line_number : 0 ,
68+ line_start : BytePos ( 0 ) ,
69+ line_end : BytePos ( 0 ) ,
70+ file : first_file,
71+ } ;
5772
5873 CachingCodemapView {
5974 codemap : codemap,
60- line_cache : [ ( 0 , BytePos ( 0 ) , BytePos ( 0 ) , first_file. clone ( ) ) ,
61- ( 0 , BytePos ( 0 ) , BytePos ( 0 ) , first_file. clone ( ) ) ,
62- ( 0 , BytePos ( 0 ) , BytePos ( 0 ) , first_file. clone ( ) ) ,
63- ( 0 , BytePos ( 0 ) , BytePos ( 0 ) , first_file. clone ( ) ) ] ,
64- eviction_index : 0 ,
75+ line_cache : [ entry. clone ( ) , entry. clone ( ) , entry. clone ( ) ] ,
76+ time_stamp : 0 ,
6577 }
6678 }
6779
6880 fn byte_pos_to_line_and_col ( & mut self ,
6981 pos : BytePos )
7082 -> ( Rc < FileMap > , usize , BytePos ) {
83+ self . time_stamp += 1 ;
84+
7185 // Check if the position is in one of the cached lines
72- for & ( line, start, end, ref file) in self . line_cache . iter ( ) {
73- if pos >= start && pos < end {
74- return ( file. clone ( ) , line, pos - start) ;
86+ for cache_entry in self . line_cache . iter_mut ( ) {
87+ if pos >= cache_entry. line_start && pos < cache_entry. line_end {
88+ cache_entry. time_stamp = self . time_stamp ;
89+ return ( cache_entry. file . clone ( ) ,
90+ cache_entry. line_number ,
91+ pos - cache_entry. line_start ) ;
7592 }
7693 }
7794
78- // Check whether we have a cached line in the correct file, so we can
79- // overwrite it without having to look up the file again.
80- for & mut ( ref mut line,
81- ref mut start,
82- ref mut end,
83- ref file) in self . line_cache . iter_mut ( ) {
84- if pos >= file. start_pos && pos < file. end_pos {
85- let line_index = file. lookup_line ( pos) . unwrap ( ) ;
86- let ( line_start, line_end) = file. line_bounds ( line_index) ;
87-
88- // Update the cache entry in place
89- * line = line_index + 1 ;
90- * start = line_start;
91- * end = line_end;
92-
93- return ( file. clone ( ) , line_index + 1 , pos - line_start) ;
95+ // No cache hit ...
96+ let mut oldest = 0 ;
97+ for index in 1 .. self . line_cache . len ( ) {
98+ if self . line_cache [ index] . time_stamp < self . line_cache [ oldest] . time_stamp {
99+ oldest = index;
94100 }
95101 }
96102
97- // No cache hit ...
98- let file_index = self . codemap . lookup_filemap_idx ( pos) ;
99- let file = self . codemap . files . borrow ( ) [ file_index] . clone ( ) ;
100- let line_index = file. lookup_line ( pos) . unwrap ( ) ;
101- let ( line_start, line_end) = file. line_bounds ( line_index) ;
102-
103- // Just overwrite some cache entry. If we got this far, all of them
104- // point to the wrong file.
105- self . line_cache [ self . eviction_index ] = ( line_index + 1 ,
106- line_start,
107- line_end,
108- file. clone ( ) ) ;
109- self . eviction_index = ( self . eviction_index + 1 ) % self . line_cache . len ( ) ;
110-
111- return ( file, line_index + 1 , pos - line_start) ;
103+ let cache_entry = & mut self . line_cache [ oldest] ;
104+
105+ // If the entry doesn't point to the correct file, fix it up
106+ if pos < cache_entry. file . start_pos || pos >= cache_entry. file . end_pos {
107+ let file_index = self . codemap . lookup_filemap_idx ( pos) ;
108+ cache_entry. file = self . codemap . files . borrow ( ) [ file_index] . clone ( ) ;
109+ }
110+
111+ let line_index = cache_entry. file . lookup_line ( pos) . unwrap ( ) ;
112+ let line_bounds = cache_entry. file . line_bounds ( line_index) ;
113+
114+ cache_entry. line_number = line_index + 1 ;
115+ cache_entry. line_start = line_bounds. 0 ;
116+ cache_entry. line_end = line_bounds. 1 ;
117+ cache_entry. time_stamp = self . time_stamp ;
118+
119+ return ( cache_entry. file . clone ( ) ,
120+ cache_entry. line_number ,
121+ pos - cache_entry. line_start ) ;
112122 }
113123}
114124
0 commit comments