@@ -12,15 +12,13 @@ use std::fmt;
12
12
use std:: io;
13
13
use std:: io:: { Read , Write } ;
14
14
use std:: num:: NonZero ;
15
- use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
16
15
17
- use smallvec:: { smallvec, SmallVec } ;
18
16
use tracing:: { debug, trace} ;
19
17
20
18
use rustc_ast:: LitKind ;
21
19
use rustc_attr:: InlineAttr ;
22
20
use rustc_data_structures:: fx:: FxHashMap ;
23
- use rustc_data_structures:: sync:: { HashMapExt , Lock } ;
21
+ use rustc_data_structures:: sync:: Lock ;
24
22
use rustc_errors:: ErrorGuaranteed ;
25
23
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
26
24
use rustc_macros:: { HashStable , TyDecodable , TyEncodable , TypeFoldable , TypeVisitable } ;
@@ -159,14 +157,9 @@ pub fn specialized_encode_alloc_id<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>>(
159
157
}
160
158
}
161
159
162
- // Used to avoid infinite recursion when decoding cyclic allocations.
163
- type DecodingSessionId = NonZero < u32 > ;
164
-
165
160
#[ derive( Clone ) ]
166
161
enum State {
167
162
Empty ,
168
- InProgressNonAlloc ( SmallVec < [ DecodingSessionId ; 1 ] > ) ,
169
- InProgress ( SmallVec < [ DecodingSessionId ; 1 ] > , AllocId ) ,
170
163
Done ( AllocId ) ,
171
164
}
172
165
@@ -180,13 +173,7 @@ pub struct AllocDecodingState {
180
173
impl AllocDecodingState {
181
174
#[ inline]
182
175
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 }
190
177
}
191
178
192
179
pub fn new ( data_offsets : Vec < u64 > ) -> Self {
@@ -200,7 +187,6 @@ impl AllocDecodingState {
200
187
#[ derive( Copy , Clone ) ]
201
188
pub struct AllocDecodingSession < ' s > {
202
189
state : & ' s AllocDecodingState ,
203
- session_id : DecodingSessionId ,
204
190
}
205
191
206
192
impl < ' s > AllocDecodingSession < ' s > {
@@ -222,104 +208,48 @@ impl<'s> AllocDecodingSession<'s> {
222
208
223
209
// Check the decoding state to see if it's already decoded or if we should
224
210
// 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
+ }
273
215
274
216
// Now decode the actual data.
275
217
let alloc_id = decoder. with_position ( pos, |decoder| {
276
218
match alloc_kind {
277
219
AllocDiscriminant :: Alloc => {
220
+ trace ! ( "creating memory alloc ID" ) ;
278
221
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)
284
224
}
285
225
AllocDiscriminant :: Fn => {
286
- assert ! ( alloc_id. is_none( ) ) ;
287
226
trace ! ( "creating fn alloc ID" ) ;
288
227
let instance = ty:: Instance :: decode ( decoder) ;
289
228
trace ! ( "decoded fn alloc instance: {:?}" , instance) ;
290
229
let unique = bool:: decode ( decoder) ;
291
230
// Here we cannot call `reserve_and_set_fn_alloc` as that would use a query, which
292
231
// is not possible in this context. That's why the allocation stores
293
232
// 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)
297
234
}
298
235
AllocDiscriminant :: VTable => {
299
- assert ! ( alloc_id. is_none( ) ) ;
300
236
trace ! ( "creating vtable alloc ID" ) ;
301
237
let ty = <Ty < ' _ > as Decodable < D > >:: decode ( decoder) ;
302
238
let poly_trait_ref =
303
239
<Option < ty:: PolyExistentialTraitRef < ' _ > > as Decodable < D > >:: decode ( decoder) ;
304
240
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)
308
242
}
309
243
AllocDiscriminant :: Static => {
310
- assert ! ( alloc_id. is_none( ) ) ;
311
244
trace ! ( "creating extern static alloc ID" ) ;
312
245
let did = <DefId as Decodable < D > >:: decode ( decoder) ;
313
246
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)
316
248
}
317
249
}
318
250
} ) ;
319
251
320
- self . state . decoding_state [ idx] . with_lock ( |entry| {
321
- * entry = State :: Done ( alloc_id) ;
322
- } ) ;
252
+ * entry = State :: Done ( alloc_id) ;
323
253
324
254
alloc_id
325
255
}
@@ -558,12 +488,6 @@ impl<'tcx> TyCtxt<'tcx> {
558
488
bug ! ( "tried to set allocation ID {id:?}, but it was already existing as {old:#?}" ) ;
559
489
}
560
490
}
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
- }
567
491
}
568
492
569
493
////////////////////////////////////////////////////////////////////////////////
0 commit comments