Skip to content

Commit 8cbd6fe

Browse files
ICH: Share codemap cache between subsequent runs of the ICH visitor.
1 parent 2faca22 commit 8cbd6fe

File tree

3 files changed

+111
-86
lines changed

3 files changed

+111
-86
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use rustc::ty::TyCtxt;
12+
use std::rc::Rc;
13+
use syntax::codemap::CodeMap;
14+
use syntax_pos::{BytePos, FileMap};
15+
16+
#[derive(Clone)]
17+
struct CacheEntry {
18+
time_stamp: usize,
19+
line_number: usize,
20+
line_start: BytePos,
21+
line_end: BytePos,
22+
file: Rc<FileMap>,
23+
}
24+
25+
pub struct CachingCodemapView<'tcx> {
26+
codemap: &'tcx CodeMap,
27+
line_cache: [CacheEntry; 3],
28+
time_stamp: usize,
29+
}
30+
31+
impl<'tcx> CachingCodemapView<'tcx> {
32+
pub fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
33+
let codemap = tcx.sess.codemap();
34+
let first_file = codemap.files.borrow()[0].clone();
35+
let entry = CacheEntry {
36+
time_stamp: 0,
37+
line_number: 0,
38+
line_start: BytePos(0),
39+
line_end: BytePos(0),
40+
file: first_file,
41+
};
42+
43+
CachingCodemapView {
44+
codemap: codemap,
45+
line_cache: [entry.clone(), entry.clone(), entry.clone()],
46+
time_stamp: 0,
47+
}
48+
}
49+
50+
pub fn codemap(&self) -> &'tcx CodeMap {
51+
self.codemap
52+
}
53+
54+
pub fn byte_pos_to_line_and_col(&mut self,
55+
pos: BytePos)
56+
-> (Rc<FileMap>, usize, BytePos) {
57+
self.time_stamp += 1;
58+
59+
// Check if the position is in one of the cached lines
60+
for cache_entry in self.line_cache.iter_mut() {
61+
if pos >= cache_entry.line_start && pos < cache_entry.line_end {
62+
cache_entry.time_stamp = self.time_stamp;
63+
return (cache_entry.file.clone(),
64+
cache_entry.line_number,
65+
pos - cache_entry.line_start);
66+
}
67+
}
68+
69+
// No cache hit ...
70+
let mut oldest = 0;
71+
for index in 1 .. self.line_cache.len() {
72+
if self.line_cache[index].time_stamp < self.line_cache[oldest].time_stamp {
73+
oldest = index;
74+
}
75+
}
76+
77+
let cache_entry = &mut self.line_cache[oldest];
78+
79+
// If the entry doesn't point to the correct file, fix it up
80+
if pos < cache_entry.file.start_pos || pos >= cache_entry.file.end_pos {
81+
let file_index = self.codemap.lookup_filemap_idx(pos);
82+
cache_entry.file = self.codemap.files.borrow()[file_index].clone();
83+
}
84+
85+
let line_index = cache_entry.file.lookup_line(pos).unwrap();
86+
let line_bounds = cache_entry.file.line_bounds(line_index);
87+
88+
cache_entry.line_number = line_index + 1;
89+
cache_entry.line_start = line_bounds.0;
90+
cache_entry.line_end = line_bounds.1;
91+
cache_entry.time_stamp = self.time_stamp;
92+
93+
return (cache_entry.file.clone(),
94+
cache_entry.line_number,
95+
pos - cache_entry.line_start);
96+
}
97+
}

src/librustc_incremental/calculate_svh/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ use rustc::session::config::DebugInfoLevel::NoDebugInfo;
4040

4141
use self::def_path_hash::DefPathHashes;
4242
use self::svh_visitor::StrictVersionHashVisitor;
43+
use self::caching_codemap_view::CachingCodemapView;
4344

4445
mod def_path_hash;
4546
mod svh_visitor;
47+
mod caching_codemap_view;
4648

4749
pub type IncrementalHashesMap = FnvHashMap<DepNode<DefId>, u64>;
4850

@@ -55,7 +57,8 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
5557
tcx: tcx,
5658
hashes: FnvHashMap(),
5759
def_path_hashes: DefPathHashes::new(tcx),
58-
hash_spans: hash_spans
60+
codemap: CachingCodemapView::new(tcx),
61+
hash_spans: hash_spans,
5962
};
6063
record_time(&tcx.sess.perf_stats.incr_comp_hashes_time, || {
6164
visitor.calculate_def_id(DefId::local(CRATE_DEF_INDEX),
@@ -69,6 +72,7 @@ pub fn compute_incremental_hashes_map<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
6972
struct HashItemsVisitor<'a, 'tcx: 'a> {
7073
tcx: TyCtxt<'a, 'tcx, 'tcx>,
7174
def_path_hashes: DefPathHashes<'a, 'tcx>,
75+
codemap: CachingCodemapView<'tcx>,
7276
hashes: IncrementalHashesMap,
7377
hash_spans: bool,
7478
}
@@ -92,6 +96,7 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
9296
walk_op(&mut StrictVersionHashVisitor::new(&mut state,
9397
self.tcx,
9498
&mut self.def_path_hashes,
99+
&mut self.codemap,
95100
self.hash_spans));
96101
let item_hash = state.finish();
97102
self.hashes.insert(DepNode::Hir(def_id), item_hash);
@@ -132,6 +137,7 @@ impl<'a, 'tcx> HashItemsVisitor<'a, 'tcx> {
132137
let mut visitor = StrictVersionHashVisitor::new(&mut crate_state,
133138
self.tcx,
134139
&mut self.def_path_hashes,
140+
&mut self.codemap,
135141
self.hash_spans);
136142
visitor.hash_attributes(&krate.attrs);
137143
}

src/librustc_incremental/calculate_svh/svh_visitor.rs

+7-85
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,17 @@ use self::SawExprComponent::*;
1717
use self::SawAbiComponent::*;
1818
use syntax::ast::{self, Name, NodeId, Attribute};
1919
use syntax::parse::token;
20-
use syntax::codemap::CodeMap;
21-
use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos, FileMap};
20+
use syntax_pos::{Span, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
2221
use rustc::hir;
2322
use rustc::hir::*;
2423
use rustc::hir::def::{Def, PathResolution};
2524
use rustc::hir::def_id::DefId;
2625
use rustc::hir::intravisit as visit;
2726
use rustc::ty::TyCtxt;
28-
use std::rc::Rc;
2927
use std::hash::{Hash, SipHasher};
3028

3129
use super::def_path_hash::DefPathHashes;
30+
use super::caching_codemap_view::CachingCodemapView;
3231

3332
const IGNORED_ATTRIBUTES: &'static [&'static str] = &["cfg",
3433
"rustc_clean",
@@ -40,100 +39,22 @@ pub struct StrictVersionHashVisitor<'a, 'hash: 'a, 'tcx: 'hash> {
4039
// collect a deterministic hash of def-ids that we have seen
4140
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
4241
hash_spans: bool,
43-
codemap: CachingCodemapView<'tcx>,
44-
}
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-
55-
struct CachingCodemapView<'tcx> {
56-
codemap: &'tcx CodeMap,
57-
line_cache: [CacheEntry; 3],
58-
time_stamp: usize,
59-
}
60-
61-
impl<'tcx> CachingCodemapView<'tcx> {
62-
fn new<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CachingCodemapView<'tcx> {
63-
let codemap = tcx.sess.codemap();
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-
};
72-
73-
CachingCodemapView {
74-
codemap: codemap,
75-
line_cache: [entry.clone(), entry.clone(), entry.clone()],
76-
time_stamp: 0,
77-
}
78-
}
79-
80-
fn byte_pos_to_line_and_col(&mut self,
81-
pos: BytePos)
82-
-> (Rc<FileMap>, usize, BytePos) {
83-
self.time_stamp += 1;
84-
85-
// Check if the position is in one of the cached lines
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);
92-
}
93-
}
94-
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;
100-
}
101-
}
102-
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);
122-
}
42+
codemap: &'a mut CachingCodemapView<'tcx>,
12343
}
12444

12545
impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
12646
pub fn new(st: &'a mut SipHasher,
12747
tcx: TyCtxt<'hash, 'tcx, 'tcx>,
12848
def_path_hashes: &'a mut DefPathHashes<'hash, 'tcx>,
49+
codemap: &'a mut CachingCodemapView<'tcx>,
12950
hash_spans: bool)
13051
-> Self {
13152
StrictVersionHashVisitor {
13253
st: st,
13354
tcx: tcx,
13455
def_path_hashes: def_path_hashes,
13556
hash_spans: hash_spans,
136-
codemap: CachingCodemapView::new(tcx),
57+
codemap: codemap,
13758
}
13859
}
13960

@@ -178,7 +99,8 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
17899
expansion_kind).hash(self.st);
179100

180101
if expansion_kind == SawSpanExpnKind::SomeExpansion {
181-
self.hash_span(self.codemap.codemap.source_callsite(span));
102+
let call_site = self.codemap.codemap().source_callsite(span);
103+
self.hash_span(call_site);
182104
}
183105
}
184106

0 commit comments

Comments
 (0)