Skip to content

Commit 7ebd748

Browse files
committed
Avoid creating a helper allocation for creating new TypeId values in the interpreter
1 parent ee00432 commit 7ebd748

File tree

1 file changed

+29
-38
lines changed

1 file changed

+29
-38
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use std::assert_matches::assert_matches;
66

77
use rustc_abi::{FieldIdx, Size};
88
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
9-
use rustc_ast::Mutability;
10-
use rustc_middle::mir::interpret::{AllocId, AllocInit, alloc_range};
119
use rustc_middle::mir::{self, BinOp, ConstValue, NonDivergingIntrinsic};
1210
use rustc_middle::ty::layout::TyAndLayout;
1311
use rustc_middle::ty::{Ty, TyCtxt};
@@ -30,39 +28,35 @@ pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAll
3028
let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes(), ());
3129
tcx.mk_const_alloc(alloc)
3230
}
33-
34-
pub(crate) fn alloc_type_id<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> AllocId {
35-
let size = Size::from_bytes(16);
36-
let align = tcx.data_layout.pointer_align;
37-
let mut alloc = Allocation::new(size, *align, AllocInit::Uninit, ());
38-
let ptr_size = tcx.data_layout.pointer_size;
39-
let type_id_hash = tcx.type_id_hash(ty).as_u128();
40-
alloc
41-
.write_scalar(
42-
&tcx,
43-
alloc_range(Size::ZERO, Size::from_bytes(16)),
44-
Scalar::from_u128(type_id_hash),
45-
)
46-
.unwrap();
47-
48-
// Give the first pointer-size bytes provenance that knows about the type id
49-
50-
let alloc_id = tcx.reserve_and_set_type_id_alloc(ty);
51-
let offset = alloc
52-
.read_scalar(&tcx, alloc_range(Size::ZERO, ptr_size), false)
53-
.unwrap()
54-
.to_target_usize(&tcx)
55-
.unwrap();
56-
let ptr = Pointer::new(alloc_id.into(), Size::from_bytes(offset));
57-
let val = Scalar::from_pointer(ptr, &tcx);
58-
alloc.write_scalar(&tcx, alloc_range(Size::ZERO, ptr_size), val).unwrap();
59-
60-
alloc.mutability = Mutability::Not;
61-
62-
tcx.reserve_and_set_memory_alloc(tcx.mk_const_alloc(alloc))
63-
}
64-
6531
impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
32+
/// Generates a value of `TypeId` for `ty` in-place.
33+
pub(crate) fn write_type_id(
34+
&mut self,
35+
ty: Ty<'tcx>,
36+
dest: &PlaceTy<'tcx, M::Provenance>,
37+
) -> InterpResult<'tcx, ()> {
38+
let tcx = self.tcx;
39+
let type_id_hash = tcx.type_id_hash(ty).as_u128();
40+
let op = self.const_val_to_op(
41+
ConstValue::Scalar(Scalar::from_u128(type_id_hash)),
42+
tcx.types.u128,
43+
None,
44+
)?;
45+
self.copy_op_allow_transmute(&op, dest)?;
46+
47+
// Give the first pointer-size bytes provenance that knows about the type id.
48+
// Here we rely on `TypeId` being a newtype around an array of pointers, so we
49+
// first project to its only field and then the first array element.
50+
let alloc_id = tcx.reserve_and_set_type_id_alloc(ty);
51+
let first = self.project_field(dest, FieldIdx::ZERO)?;
52+
let first = self.project_index(&first, 0)?;
53+
let offset = self.read_scalar(&first)?.to_target_usize(&tcx)?;
54+
let ptr = Pointer::new(alloc_id.into(), Size::from_bytes(offset));
55+
let ptr = self.global_root_pointer(ptr)?;
56+
let val = Scalar::from_pointer(ptr, &tcx);
57+
self.write_scalar(val, &first)
58+
}
59+
6660
/// Returns `true` if emulation happened.
6761
/// Here we implement the intrinsics that are common to all Miri instances; individual machines can add their own
6862
/// intrinsic handling.
@@ -96,10 +90,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
9690
sym::type_id => {
9791
let tp_ty = instance.args.type_at(0);
9892
ensure_monomorphic_enough(tcx, tp_ty)?;
99-
let alloc_id = alloc_type_id(tcx, tp_ty);
100-
let val = ConstValue::Indirect { alloc_id, offset: Size::ZERO };
101-
let val = self.const_val_to_op(val, dest.layout.ty, Some(dest.layout))?;
102-
self.copy_op(&val, dest)?;
93+
self.write_type_id(tp_ty, dest)?;
10394
}
10495
sym::type_id_eq => {
10596
// Both operands are `TypeId`, which is a newtype around an array of pointers.

0 commit comments

Comments
 (0)