Skip to content

Commit 3623c76

Browse files
committed
Remove in-progress allocation decoding states
1 parent eb72697 commit 3623c76

File tree

1 file changed

+13
-89
lines changed
  • compiler/rustc_middle/src/mir/interpret

1 file changed

+13
-89
lines changed

compiler/rustc_middle/src/mir/interpret/mod.rs

+13-89
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@ use std::fmt;
1212
use std::io;
1313
use std::io::{Read, Write};
1414
use std::num::NonZero;
15-
use std::sync::atomic::{AtomicU32, Ordering};
1615

17-
use smallvec::{smallvec, SmallVec};
1816
use tracing::{debug, trace};
1917

2018
use rustc_ast::LitKind;
2119
use rustc_attr::InlineAttr;
2220
use rustc_data_structures::fx::FxHashMap;
23-
use rustc_data_structures::sync::{HashMapExt, Lock};
21+
use rustc_data_structures::sync::Lock;
2422
use rustc_errors::ErrorGuaranteed;
2523
use rustc_hir::def_id::{DefId, LocalDefId};
2624
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
@@ -159,14 +157,9 @@ pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>>(
159157
}
160158
}
161159

162-
// Used to avoid infinite recursion when decoding cyclic allocations.
163-
type DecodingSessionId = NonZero<u32>;
164-
165160
#[derive(Clone)]
166161
enum State {
167162
Empty,
168-
InProgressNonAlloc(SmallVec<[DecodingSessionId; 1]>),
169-
InProgress(SmallVec<[DecodingSessionId; 1]>, AllocId),
170163
Done(AllocId),
171164
}
172165

@@ -180,13 +173,7 @@ pub struct AllocDecodingState {
180173
impl AllocDecodingState {
181174
#[inline]
182175
pub fn new_decoding_session(&self) -> AllocDecodingSession<'_> {
183-
static DECODER_SESSION_ID: AtomicU32 = AtomicU32::new(0);
184-
let counter = DECODER_SESSION_ID.fetch_add(1, Ordering::SeqCst);
185-
186-
// Make sure this is never zero.
187-
let session_id = DecodingSessionId::new((counter & 0x7FFFFFFF) + 1).unwrap();
188-
189-
AllocDecodingSession { state: self, session_id }
176+
AllocDecodingSession { state: self }
190177
}
191178

192179
pub fn new(data_offsets: Vec<u64>) -> Self {
@@ -200,7 +187,6 @@ impl AllocDecodingState {
200187
#[derive(Copy, Clone)]
201188
pub struct AllocDecodingSession<'s> {
202189
state: &'s AllocDecodingState,
203-
session_id: DecodingSessionId,
204190
}
205191

206192
impl<'s> AllocDecodingSession<'s> {
@@ -222,104 +208,48 @@ impl<'s> AllocDecodingSession<'s> {
222208

223209
// Check the decoding state to see if it's already decoded or if we should
224210
// decode it here.
225-
let alloc_id = {
226-
let mut entry = self.state.decoding_state[idx].lock();
227-
228-
match *entry {
229-
State::Done(alloc_id) => {
230-
return alloc_id;
231-
}
232-
ref mut entry @ State::Empty => {
233-
// We are allowed to decode.
234-
match alloc_kind {
235-
AllocDiscriminant::Alloc => {
236-
// If this is an allocation, we need to reserve an
237-
// `AllocId` so we can decode cyclic graphs.
238-
let alloc_id = decoder.interner().reserve_alloc_id();
239-
*entry = State::InProgress(smallvec![self.session_id], alloc_id);
240-
Some(alloc_id)
241-
}
242-
AllocDiscriminant::Fn
243-
| AllocDiscriminant::Static
244-
| AllocDiscriminant::VTable => {
245-
// Fns and statics cannot be cyclic, and their `AllocId`
246-
// is determined later by interning.
247-
*entry = State::InProgressNonAlloc(smallvec![self.session_id]);
248-
None
249-
}
250-
}
251-
}
252-
State::InProgressNonAlloc(ref mut sessions) => {
253-
if sessions.contains(&self.session_id) {
254-
bug!("this should be unreachable");
255-
} else {
256-
// Start decoding concurrently.
257-
sessions.push(self.session_id);
258-
None
259-
}
260-
}
261-
State::InProgress(ref mut sessions, alloc_id) => {
262-
if sessions.contains(&self.session_id) {
263-
// Don't recurse.
264-
return alloc_id;
265-
} else {
266-
// Start decoding concurrently.
267-
sessions.push(self.session_id);
268-
Some(alloc_id)
269-
}
270-
}
271-
}
272-
};
211+
let mut entry = self.state.decoding_state[idx].lock();
212+
if let State::Done(alloc_id) = *entry {
213+
return alloc_id;
214+
}
273215

274216
// Now decode the actual data.
275217
let alloc_id = decoder.with_position(pos, |decoder| {
276218
match alloc_kind {
277219
AllocDiscriminant::Alloc => {
220+
trace!("creating memory alloc ID");
278221
let alloc = <ConstAllocation<'tcx> as Decodable<_>>::decode(decoder);
279-
// We already have a reserved `AllocId`.
280-
let alloc_id = alloc_id.unwrap();
281-
trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
282-
decoder.interner().set_alloc_id_same_memory(alloc_id, alloc);
283-
alloc_id
222+
trace!("decoded alloc {:?}", alloc);
223+
decoder.interner().reserve_and_set_memory_alloc(alloc)
284224
}
285225
AllocDiscriminant::Fn => {
286-
assert!(alloc_id.is_none());
287226
trace!("creating fn alloc ID");
288227
let instance = ty::Instance::decode(decoder);
289228
trace!("decoded fn alloc instance: {:?}", instance);
290229
let unique = bool::decode(decoder);
291230
// Here we cannot call `reserve_and_set_fn_alloc` as that would use a query, which
292231
// is not possible in this context. That's why the allocation stores
293232
// whether it is unique or not.
294-
let alloc_id =
295-
decoder.interner().reserve_and_set_fn_alloc_internal(instance, unique);
296-
alloc_id
233+
decoder.interner().reserve_and_set_fn_alloc_internal(instance, unique)
297234
}
298235
AllocDiscriminant::VTable => {
299-
assert!(alloc_id.is_none());
300236
trace!("creating vtable alloc ID");
301237
let ty = <Ty<'_> as Decodable<D>>::decode(decoder);
302238
let poly_trait_ref =
303239
<Option<ty::PolyExistentialTraitRef<'_>> as Decodable<D>>::decode(decoder);
304240
trace!("decoded vtable alloc instance: {ty:?}, {poly_trait_ref:?}");
305-
let alloc_id =
306-
decoder.interner().reserve_and_set_vtable_alloc(ty, poly_trait_ref);
307-
alloc_id
241+
decoder.interner().reserve_and_set_vtable_alloc(ty, poly_trait_ref)
308242
}
309243
AllocDiscriminant::Static => {
310-
assert!(alloc_id.is_none());
311244
trace!("creating extern static alloc ID");
312245
let did = <DefId as Decodable<D>>::decode(decoder);
313246
trace!("decoded static def-ID: {:?}", did);
314-
let alloc_id = decoder.interner().reserve_and_set_static_alloc(did);
315-
alloc_id
247+
decoder.interner().reserve_and_set_static_alloc(did)
316248
}
317249
}
318250
});
319251

320-
self.state.decoding_state[idx].with_lock(|entry| {
321-
*entry = State::Done(alloc_id);
322-
});
252+
*entry = State::Done(alloc_id);
323253

324254
alloc_id
325255
}
@@ -558,12 +488,6 @@ impl<'tcx> TyCtxt<'tcx> {
558488
bug!("tried to set allocation ID {id:?}, but it was already existing as {old:#?}");
559489
}
560490
}
561-
562-
/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
563-
/// twice for the same `(AllocId, Allocation)` pair.
564-
fn set_alloc_id_same_memory(self, id: AllocId, mem: ConstAllocation<'tcx>) {
565-
self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
566-
}
567491
}
568492

569493
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)