Skip to content

Commit 4c833a5

Browse files
committed
globally cache statics and promoteds
1 parent dc85b11 commit 4c833a5

File tree

2 files changed

+57
-38
lines changed

2 files changed

+57
-38
lines changed

src/interpreter/mod.rs

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ struct GlobalEvalContext<'a, 'tcx: 'a> {
3737
/// The virtual memory system.
3838
memory: Memory,
3939

40-
/// Precomputed statics and constants
41-
statics: DefIdMap<Pointer>,
40+
/// Precomputed statics, constants and promoteds
41+
statics: HashMap<ConstantId<'tcx>, Pointer>,
4242
}
4343

4444
struct FnEvalContext<'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> {
@@ -92,9 +92,6 @@ struct Frame<'a, 'tcx: 'a> {
9292
/// The offset of the first temporary in `self.locals`.
9393
temp_offset: usize,
9494

95-
/// List of precomputed promoted constants
96-
promoted: HashMap<usize, Pointer>,
97-
9895
/// The index of the currently evaluated statment
9996
stmt: usize,
10097

@@ -136,10 +133,28 @@ enum TerminatorTarget {
136133

137134
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
138135
enum ConstantId<'tcx> {
139-
Promoted { index: usize },
136+
Promoted { def_id: DefId, substs: &'tcx Substs<'tcx>, index: usize },
140137
Static { def_id: DefId, substs: &'tcx Substs<'tcx> },
141138
}
142139

140+
impl<'tcx> ConstantId<'tcx> {
141+
fn substs(&self) -> &'tcx Substs<'tcx> {
142+
use self::ConstantId::*;
143+
match *self {
144+
Promoted { substs, .. } |
145+
Static { substs, .. } => substs
146+
}
147+
}
148+
149+
fn def_id(&self) -> DefId {
150+
use self::ConstantId::*;
151+
match *self {
152+
Promoted { def_id, .. } |
153+
Static { def_id, .. } => def_id,
154+
}
155+
}
156+
}
157+
143158

144159
impl<'a, 'tcx> GlobalEvalContext<'a, 'tcx> {
145160
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'a MirMap<'tcx>) -> Self {
@@ -152,7 +167,7 @@ impl<'a, 'tcx> GlobalEvalContext<'a, 'tcx> {
152167
.uint_type
153168
.bit_width()
154169
.expect("Session::target::uint_type was usize")/8),
155-
statics: DefIdMap(),
170+
statics: HashMap::new(),
156171
}
157172
}
158173

@@ -248,7 +263,6 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
248263
locals: Vec::new(),
249264
var_offset: num_args,
250265
temp_offset: num_args + num_vars,
251-
promoted: HashMap::new(),
252266
span: span,
253267
def_id: def_id,
254268
substs: substs,
@@ -1025,10 +1039,18 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
10251039
if item_ty.ty.is_fn() {
10261040
Err(EvalError::Unimplemented("unimplemented: mentions of function items".to_string()))
10271041
} else {
1028-
Ok(*self.statics.get(&def_id).expect("static should have been cached (rvalue)"))
1042+
let cid = ConstantId::Static{ def_id: def_id, substs: substs };
1043+
Ok(*self.statics.get(&cid).expect("static should have been cached (rvalue)"))
10291044
}
10301045
},
1031-
Promoted { index } => Ok(*self.frame().promoted.get(&index).expect("a promoted constant hasn't been precomputed")),
1046+
Promoted { index } => {
1047+
let cid = ConstantId::Promoted {
1048+
def_id: self.frame().def_id,
1049+
substs: self.substs(),
1050+
index: index,
1051+
};
1052+
Ok(*self.statics.get(&cid).expect("a promoted constant hasn't been precomputed"))
1053+
},
10321054
}
10331055
}
10341056
}
@@ -1043,7 +1065,11 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
10431065
Var(i) => self.frame().locals[self.frame().var_offset + i as usize],
10441066
Temp(i) => self.frame().locals[self.frame().temp_offset + i as usize],
10451067

1046-
Static(def_id) => *self.gecx.statics.get(&def_id).expect("static should have been cached (lvalue)"),
1068+
Static(def_id) => {
1069+
let substs = self.tcx.mk_substs(subst::Substs::empty());
1070+
let cid = ConstantId::Static{ def_id: def_id, substs: substs };
1071+
*self.gecx.statics.get(&cid).expect("static should have been cached (lvalue)")
1072+
},
10471073

10481074
Projection(ref proj) => {
10491075
let base = self.eval_lvalue(&proj.base)?;

src/interpreter/stepper.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use rustc::ty::subst::{self, Subst};
1010
use rustc::hir::def_id::DefId;
1111
use rustc::mir::visit::{Visitor, LvalueContext};
1212
use syntax::codemap::Span;
13-
use memory::Pointer;
1413
use std::rc::Rc;
1514

1615
pub enum Event {
@@ -73,23 +72,11 @@ impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx
7372
}
7473

7574
fn constant(&mut self) -> EvalResult<()> {
76-
match self.fncx.frame_mut().constants.pop() {
77-
Some((ConstantId::Promoted { index }, span, return_ptr, mir)) => {
78-
trace!("adding promoted constant {}, {:?}", index, span);
79-
let substs = self.fncx.substs();
80-
// FIXME: somehow encode that this is a promoted constant's frame
81-
let def_id = self.fncx.frame().def_id;
82-
self.fncx.push_stack_frame(def_id, span, mir, substs, Some(return_ptr));
83-
self.mir = self.fncx.mir();
84-
},
85-
Some((ConstantId::Static { def_id, substs }, span, return_ptr, mir)) => {
86-
trace!("adding static {:?}, {:?}", def_id, span);
87-
self.fncx.gecx.statics.insert(def_id, return_ptr);
88-
self.fncx.push_stack_frame(def_id, span, mir, substs, Some(return_ptr));
89-
self.mir = self.fncx.mir();
90-
},
91-
None => unreachable!(),
92-
}
75+
let (cid, span, return_ptr, mir) = self.fncx.frame_mut().constants.pop().expect("state machine broken");
76+
let def_id = cid.def_id();
77+
let substs = cid.substs();
78+
self.fncx.push_stack_frame(def_id, span, mir, substs, Some(return_ptr));
79+
self.mir = self.fncx.mir();
9380
Ok(())
9481
}
9582

@@ -164,16 +151,17 @@ struct ConstantExtractor<'a: 'c, 'b: 'a + 'mir + 'c, 'c, 'mir: 'c, 'tcx: 'a + 'b
164151
}
165152

166153
impl<'a, 'b, 'c, 'mir, 'tcx> ConstantExtractor<'a, 'b, 'c, 'mir, 'tcx> {
167-
fn constant(&mut self, def_id: DefId, substs: &'tcx subst::Substs<'tcx>, span: Span) {
168-
if self.fncx.gecx.statics.contains_key(&def_id) {
169-
return;
170-
}
154+
fn static_item(&mut self, def_id: DefId, substs: &'tcx subst::Substs<'tcx>, span: Span) {
171155
let cid = ConstantId::Static {
172156
def_id: def_id,
173157
substs: substs,
174158
};
159+
if self.fncx.gecx.statics.contains_key(&cid) {
160+
return;
161+
}
175162
let mir = self.fncx.load_mir(def_id);
176163
let ptr = self.fncx.alloc_ret_ptr(mir.return_ty).expect("there's no such thing as an unreachable static");
164+
self.fncx.statics.insert(cid.clone(), ptr);
177165
self.fncx.frame_mut().constants.push((cid, span, ptr, mir));
178166
}
179167
}
@@ -189,19 +177,24 @@ impl<'a, 'b, 'c, 'mir, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'c, 'mi
189177
if item_ty.ty.is_fn() {
190178
// unimplemented
191179
} else {
192-
self.constant(def_id, substs, constant.span);
180+
self.static_item(def_id, substs, constant.span);
193181
}
194182
},
195183
mir::Literal::Promoted { index } => {
196-
if self.fncx.frame().promoted.contains_key(&index) {
184+
let cid = ConstantId::Promoted {
185+
def_id: self.fncx.frame().def_id,
186+
substs: self.fncx.substs(),
187+
index: index,
188+
};
189+
if self.fncx.statics.contains_key(&cid) {
197190
return;
198191
}
199192
let mir = self.mir.promoted[index].clone();
200193
let return_ty = mir.return_ty;
201194
let return_ptr = self.fncx.alloc_ret_ptr(return_ty).expect("there's no such thing as an unreachable static");
202-
self.fncx.frame_mut().promoted.insert(index, return_ptr);
203195
let mir = CachedMir::Owned(Rc::new(mir));
204-
self.fncx.frame_mut().constants.push((ConstantId::Promoted { index: index }, constant.span, return_ptr, mir));
196+
self.fncx.statics.insert(cid.clone(), return_ptr);
197+
self.fncx.frame_mut().constants.push((cid, constant.span, return_ptr, mir));
205198
}
206199
}
207200
}
@@ -211,7 +204,7 @@ impl<'a, 'b, 'c, 'mir, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'c, 'mi
211204
if let mir::Lvalue::Static(def_id) = *lvalue {
212205
let substs = self.fncx.tcx.mk_substs(subst::Substs::empty());
213206
let span = self.span;
214-
self.constant(def_id, substs, span);
207+
self.static_item(def_id, substs, span);
215208
}
216209
}
217210
}

0 commit comments

Comments
 (0)