Skip to content

Commit b84f6fe

Browse files
committed
Add a .bss-like scheme for encoded const allocs
1 parent 4229b80 commit b84f6fe

File tree

1 file changed

+49
-2
lines changed

1 file changed

+49
-2
lines changed

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

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use provenance_map::*;
1515
use rustc_abi::{Align, HasDataLayout, Size};
1616
use rustc_ast::Mutability;
1717
use rustc_data_structures::intern::Interned;
18-
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
18+
use rustc_macros::HashStable;
1919

2020
use super::{
2121
AllocId, BadBytesAccess, CtfeProvenance, InterpErrorKind, InterpResult, Pointer,
@@ -77,7 +77,7 @@ impl AllocBytes for Box<[u8]> {
7777
/// module provides higher-level access.
7878
// Note: for performance reasons when interning, some of the `Allocation` fields can be partially
7979
// hashed. (see the `Hash` impl below for more details), so the impl is not derived.
80-
#[derive(Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
80+
#[derive(Clone, Eq, PartialEq)]
8181
#[derive(HashStable)]
8282
pub struct Allocation<Prov: Provenance = CtfeProvenance, Extra = (), Bytes = Box<[u8]>> {
8383
/// The actual bytes of the allocation.
@@ -101,6 +101,53 @@ pub struct Allocation<Prov: Provenance = CtfeProvenance, Extra = (), Bytes = Box
101101
pub extra: Extra,
102102
}
103103

104+
use rustc_serialize::{Decodable, Encodable};
105+
use rustc_type_ir::{TyDecoder, TyEncoder};
106+
107+
impl<Prov: Provenance, Extra, Bytes, E: TyEncoder> Encodable<E> for Allocation<Prov, Extra, Bytes>
108+
where
109+
Bytes: AllocBytes,
110+
ProvenanceMap<Prov>: Encodable<E>,
111+
Extra: Encodable<E>,
112+
{
113+
fn encode(&self, encoder: &mut E) {
114+
let len = self.bytes.len() << 1;
115+
let all_zero = self.bytes.iter().all(|b| *b == 0);
116+
encoder.emit_usize(len | all_zero as usize);
117+
if !all_zero {
118+
encoder.emit_raw_bytes(&self.bytes);
119+
}
120+
self.provenance.encode(encoder);
121+
self.init_mask.encode(encoder);
122+
self.align.encode(encoder);
123+
self.mutability.encode(encoder);
124+
self.extra.encode(encoder);
125+
}
126+
}
127+
128+
impl<Prov: Provenance, Extra, Bytes, D: TyDecoder> Decodable<D> for Allocation<Prov, Extra, Bytes>
129+
where
130+
Bytes: AllocBytes,
131+
ProvenanceMap<Prov>: Decodable<D>,
132+
Extra: Decodable<D>,
133+
{
134+
fn decode(decoder: &mut D) -> Self {
135+
let len = decoder.read_usize();
136+
let all_zero = (len & 0b1) == 1;
137+
let len = len >> 1;
138+
let bytes = if all_zero { vec![0u8; len] } else { decoder.read_raw_bytes(len).to_vec() };
139+
140+
let provenance = Decodable::decode(decoder);
141+
let init_mask = Decodable::decode(decoder);
142+
let align = Decodable::decode(decoder);
143+
let mutability = Decodable::decode(decoder);
144+
let extra = Decodable::decode(decoder);
145+
let bytes = Bytes::from_bytes(bytes, align);
146+
147+
Self { bytes, provenance, init_mask, align, mutability, extra }
148+
}
149+
}
150+
104151
/// This is the maximum size we will hash at a time, when interning an `Allocation` and its
105152
/// `InitMask`. Note, we hash that amount of bytes twice: at the start, and at the end of a buffer.
106153
/// Used when these two structures are large: we only partially hash the larger fields in that

0 commit comments

Comments
 (0)