@@ -48,7 +48,26 @@ use rustc_span::hygiene::HygieneDecodeContext;
48
48
49
49
mod cstore_impl;
50
50
51
- crate struct MetadataBlob ( MetadataRef ) ;
51
+ /// A reference to the raw binary version of crate metadata.
52
+ /// A `MetadataBlob` internally is just a reference counted pointer to
53
+ /// the actual data, so cloning it is cheap.
54
+ #[ derive( Clone ) ]
55
+ crate struct MetadataBlob ( Lrc < MetadataRef > ) ;
56
+
57
+ // This is needed so we can create an OwningRef into the blob.
58
+ // The data behind a `MetadataBlob` has a stable address because it
59
+ // contained within an Rc/Arc.
60
+ unsafe impl rustc_data_structures:: owning_ref:: StableAddress for MetadataBlob { }
61
+
62
+ // This is needed so we can create an OwningRef into the blob.
63
+ impl std:: ops:: Deref for MetadataBlob {
64
+ type Target = [ u8 ] ;
65
+
66
+ #[ inline]
67
+ fn deref ( & self ) -> & [ u8 ] {
68
+ & self . 0 [ ..]
69
+ }
70
+ }
52
71
53
72
// A map from external crate numbers (as decoded from some crate file) to
54
73
// local crate numbers (as generated during this session). Each external
@@ -134,6 +153,7 @@ struct ImportedSourceFile {
134
153
pub ( super ) struct DecodeContext < ' a , ' tcx > {
135
154
opaque : opaque:: Decoder < ' a > ,
136
155
cdata : Option < CrateMetadataRef < ' a > > ,
156
+ blob : & ' a MetadataBlob ,
137
157
sess : Option < & ' tcx Session > ,
138
158
tcx : Option < TyCtxt < ' tcx > > ,
139
159
@@ -148,7 +168,11 @@ pub(super) struct DecodeContext<'a, 'tcx> {
148
168
149
169
/// Abstract over the various ways one can create metadata decoders.
150
170
pub ( super ) trait Metadata < ' a , ' tcx > : Copy {
151
- fn raw_bytes ( self ) -> & ' a [ u8 ] ;
171
+ fn blob ( self ) -> & ' a MetadataBlob ;
172
+ #[ inline]
173
+ fn raw_bytes ( self ) -> & ' a [ u8 ] {
174
+ self . blob ( )
175
+ }
152
176
fn cdata ( self ) -> Option < CrateMetadataRef < ' a > > {
153
177
None
154
178
}
@@ -164,6 +188,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
164
188
DecodeContext {
165
189
opaque : opaque:: Decoder :: new ( self . raw_bytes ( ) , pos) ,
166
190
cdata : self . cdata ( ) ,
191
+ blob : self . blob ( ) ,
167
192
sess : self . sess ( ) . or ( tcx. map ( |tcx| tcx. sess ) ) ,
168
193
tcx,
169
194
last_source_file_index : 0 ,
@@ -176,51 +201,61 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
176
201
}
177
202
178
203
impl < ' a , ' tcx > Metadata < ' a , ' tcx > for & ' a MetadataBlob {
179
- fn raw_bytes ( self ) -> & ' a [ u8 ] {
180
- & self . 0
204
+ #[ inline]
205
+ fn blob ( self ) -> & ' a MetadataBlob {
206
+ self
181
207
}
182
208
}
183
209
184
210
impl < ' a , ' tcx > Metadata < ' a , ' tcx > for ( & ' a MetadataBlob , & ' tcx Session ) {
185
- fn raw_bytes ( self ) -> & ' a [ u8 ] {
186
- let ( blob, _ ) = self ;
187
- & blob . 0
211
+ # [ inline ]
212
+ fn blob ( self ) -> & ' a MetadataBlob {
213
+ self . 0
188
214
}
189
215
216
+ #[ inline]
190
217
fn sess ( self ) -> Option < & ' tcx Session > {
191
218
let ( _, sess) = self ;
192
219
Some ( sess)
193
220
}
194
221
}
195
222
196
223
impl < ' a , ' tcx > Metadata < ' a , ' tcx > for & ' a CrateMetadataRef < ' a > {
197
- fn raw_bytes ( self ) -> & ' a [ u8 ] {
198
- self . blob . raw_bytes ( )
224
+ #[ inline]
225
+ fn blob ( self ) -> & ' a MetadataBlob {
226
+ & self . blob
199
227
}
228
+ #[ inline]
200
229
fn cdata ( self ) -> Option < CrateMetadataRef < ' a > > {
201
230
Some ( * self )
202
231
}
203
232
}
204
233
205
234
impl < ' a , ' tcx > Metadata < ' a , ' tcx > for ( & ' a CrateMetadataRef < ' a > , & ' tcx Session ) {
206
- fn raw_bytes ( self ) -> & ' a [ u8 ] {
207
- self . 0 . raw_bytes ( )
235
+ #[ inline]
236
+ fn blob ( self ) -> & ' a MetadataBlob {
237
+ & self . 0 . blob
208
238
}
239
+ #[ inline]
209
240
fn cdata ( self ) -> Option < CrateMetadataRef < ' a > > {
210
241
Some ( * self . 0 )
211
242
}
243
+ #[ inline]
212
244
fn sess ( self ) -> Option < & ' tcx Session > {
213
245
Some ( & self . 1 )
214
246
}
215
247
}
216
248
217
249
impl < ' a , ' tcx > Metadata < ' a , ' tcx > for ( & ' a CrateMetadataRef < ' a > , TyCtxt < ' tcx > ) {
218
- fn raw_bytes ( self ) -> & ' a [ u8 ] {
219
- self . 0 . raw_bytes ( )
250
+ #[ inline]
251
+ fn blob ( self ) -> & ' a MetadataBlob {
252
+ & self . 0 . blob
220
253
}
254
+ #[ inline]
221
255
fn cdata ( self ) -> Option < CrateMetadataRef < ' a > > {
222
256
Some ( * self . 0 )
223
257
}
258
+ #[ inline]
224
259
fn tcx ( self ) -> Option < TyCtxt < ' tcx > > {
225
260
Some ( self . 1 )
226
261
}
@@ -246,12 +281,21 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<[T]> {
246
281
}
247
282
248
283
impl < ' a , ' tcx > DecodeContext < ' a , ' tcx > {
284
+ #[ inline]
249
285
fn tcx ( & self ) -> TyCtxt < ' tcx > {
250
- self . tcx . expect ( "missing TyCtxt in DecodeContext" )
286
+ debug_assert ! ( self . tcx. is_some( ) , "missing TyCtxt in DecodeContext" ) ;
287
+ self . tcx . unwrap ( )
251
288
}
252
289
253
- fn cdata ( & self ) -> CrateMetadataRef < ' a > {
254
- self . cdata . expect ( "missing CrateMetadata in DecodeContext" )
290
+ #[ inline]
291
+ pub fn blob ( & self ) -> & ' a MetadataBlob {
292
+ self . blob
293
+ }
294
+
295
+ #[ inline]
296
+ pub fn cdata ( & self ) -> CrateMetadataRef < ' a > {
297
+ debug_assert ! ( self . cdata. is_some( ) , "missing CrateMetadata in DecodeContext" ) ;
298
+ self . cdata . unwrap ( )
255
299
}
256
300
257
301
fn map_encoded_cnum_to_current ( & self , cnum : CrateNum ) -> CrateNum {
@@ -586,7 +630,7 @@ implement_ty_decoder!(DecodeContext<'a, 'tcx>);
586
630
587
631
impl MetadataBlob {
588
632
crate fn new ( metadata_ref : MetadataRef ) -> MetadataBlob {
589
- MetadataBlob ( metadata_ref)
633
+ MetadataBlob ( Lrc :: new ( metadata_ref) )
590
634
}
591
635
592
636
crate fn is_compatible ( & self ) -> bool {
0 commit comments