Skip to content

Commit 0debea1

Browse files
Allow taking an OwningRef of the crate metadata blob.
1 parent 9f85cd6 commit 0debea1

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

Diff for: compiler/rustc_metadata/src/rmeta/decoder.rs

+61-17
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,26 @@ use rustc_span::hygiene::HygieneDecodeContext;
4848

4949
mod cstore_impl;
5050

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+
}
5271

5372
// A map from external crate numbers (as decoded from some crate file) to
5473
// local crate numbers (as generated during this session). Each external
@@ -134,6 +153,7 @@ struct ImportedSourceFile {
134153
pub(super) struct DecodeContext<'a, 'tcx> {
135154
opaque: opaque::Decoder<'a>,
136155
cdata: Option<CrateMetadataRef<'a>>,
156+
blob: &'a MetadataBlob,
137157
sess: Option<&'tcx Session>,
138158
tcx: Option<TyCtxt<'tcx>>,
139159

@@ -148,7 +168,11 @@ pub(super) struct DecodeContext<'a, 'tcx> {
148168

149169
/// Abstract over the various ways one can create metadata decoders.
150170
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+
}
152176
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
153177
None
154178
}
@@ -164,6 +188,7 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
164188
DecodeContext {
165189
opaque: opaque::Decoder::new(self.raw_bytes(), pos),
166190
cdata: self.cdata(),
191+
blob: self.blob(),
167192
sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
168193
tcx,
169194
last_source_file_index: 0,
@@ -176,51 +201,61 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
176201
}
177202

178203
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
181207
}
182208
}
183209

184210
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
188214
}
189215

216+
#[inline]
190217
fn sess(self) -> Option<&'tcx Session> {
191218
let (_, sess) = self;
192219
Some(sess)
193220
}
194221
}
195222

196223
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
199227
}
228+
#[inline]
200229
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
201230
Some(*self)
202231
}
203232
}
204233

205234
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
208238
}
239+
#[inline]
209240
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
210241
Some(*self.0)
211242
}
243+
#[inline]
212244
fn sess(self) -> Option<&'tcx Session> {
213245
Some(&self.1)
214246
}
215247
}
216248

217249
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
220253
}
254+
#[inline]
221255
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
222256
Some(*self.0)
223257
}
258+
#[inline]
224259
fn tcx(self) -> Option<TyCtxt<'tcx>> {
225260
Some(self.1)
226261
}
@@ -246,12 +281,21 @@ impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<[T]> {
246281
}
247282

248283
impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
284+
#[inline]
249285
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()
251288
}
252289

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()
255299
}
256300

257301
fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
@@ -586,7 +630,7 @@ implement_ty_decoder!(DecodeContext<'a, 'tcx>);
586630

587631
impl MetadataBlob {
588632
crate fn new(metadata_ref: MetadataRef) -> MetadataBlob {
589-
MetadataBlob(metadata_ref)
633+
MetadataBlob(Lrc::new(metadata_ref))
590634
}
591635

592636
crate fn is_compatible(&self) -> bool {

Diff for: compiler/rustc_metadata/src/rmeta/table.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ where
199199
debug!("Table::lookup: index={:?} len={:?}", i, self.meta);
200200

201201
let start = self.position.get();
202-
let bytes = &metadata.raw_bytes()[start..start + self.meta];
202+
let bytes = &metadata.blob()[start..start + self.meta];
203203
<Option<T>>::maybe_read_from_bytes_at(bytes, i.index())?
204204
}
205205

0 commit comments

Comments
 (0)