@@ -43,72 +43,82 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
43
43
codemap : CachingCodemapView < ' tcx > ,
44
44
}
45
45
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
+
46
55
struct CachingCodemapView < ' tcx > {
47
56
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 ,
51
59
}
52
60
53
61
impl < ' tcx > CachingCodemapView < ' tcx > {
54
62
fn new < ' a > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ) -> CachingCodemapView < ' tcx > {
55
63
let codemap = tcx. sess . codemap ( ) ;
56
64
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
+ } ;
57
72
58
73
CachingCodemapView {
59
74
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 ,
65
77
}
66
78
}
67
79
68
80
fn byte_pos_to_line_and_col ( & mut self ,
69
81
pos : BytePos )
70
82
-> ( Rc < FileMap > , usize , BytePos ) {
83
+ self . time_stamp += 1 ;
84
+
71
85
// 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 ) ;
75
92
}
76
93
}
77
94
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;
94
100
}
95
101
}
96
102
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 ) ;
112
122
}
113
123
}
114
124
0 commit comments