about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-01-29 14:46:30 +0100
committerGitHub <noreply@github.com>2022-01-29 14:46:30 +0100
commit9e86a434a770b453ded7dabd3203efc9c61eb2e5 (patch)
tree9debcae2fcad4bc105599636e6c65d1b3a5173d5 /compiler
parent11898a56c202076a3506928a11fcf402f6e1af3a (diff)
parent9728cc4e26c936e17a107ceeccf029bde4e7e1f0 (diff)
downloadrust-9e86a434a770b453ded7dabd3203efc9c61eb2e5.tar.gz
rust-9e86a434a770b453ded7dabd3203efc9c61eb2e5.zip
Rollup merge of #92274 - woppopo:const_deallocate, r=oli-obk
Add `intrinsics::const_deallocate`

Tracking issue: #79597
Related: #91884

This allows deallocation of a memory allocated by `intrinsics::const_allocate`. At the moment, this can be only used to reduce memory usage, but in the future this may be useful to detect memory leaks (If an allocated memory remains after evaluation, raise an error...?).
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/intrinsic.rs10
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs27
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs5
4 files changed, 43 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
index 3657f80c2de..c654232c10a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs
@@ -369,6 +369,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }
             }
 
+            sym::const_allocate => {
+                // returns a null pointer at runtime.
+                bx.const_null(bx.type_i8p())
+            }
+
+            sym::const_deallocate => {
+                // nop at runtime.
+                return;
+            }
+
             // This requires that atomic intrinsics follow a specific naming pattern:
             // "atomic_<operation>[_<ordering>]", and no ordering means SeqCst
             name if name_str.starts_with("atomic_") => {
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 30e9cbe4403..89717b75f12 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -347,6 +347,33 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
                 )?;
                 ecx.write_pointer(ptr, dest)?;
             }
+            sym::const_deallocate => {
+                let ptr = ecx.read_pointer(&args[0])?;
+                let size = ecx.read_scalar(&args[1])?.to_machine_usize(ecx)?;
+                let align = ecx.read_scalar(&args[2])?.to_machine_usize(ecx)?;
+
+                let size = Size::from_bytes(size);
+                let align = match Align::from_bytes(align) {
+                    Ok(a) => a,
+                    Err(err) => throw_ub_format!("align has to be a power of 2, {}", err),
+                };
+
+                // If an allocation is created in an another const,
+                // we don't deallocate it.
+                let (alloc_id, _, _) = ecx.memory.ptr_get_alloc(ptr)?;
+                let is_allocated_in_another_const = matches!(
+                    ecx.tcx.get_global_alloc(alloc_id),
+                    Some(interpret::GlobalAlloc::Memory(_))
+                );
+
+                if !is_allocated_in_another_const {
+                    ecx.memory.deallocate(
+                        ptr,
+                        Some((size, align)),
+                        interpret::MemoryKind::Machine(MemoryKind::Heap),
+                    )?;
+                }
+            }
             _ => {
                 return Err(ConstEvalErrKind::NeedsRfc(format!(
                     "calling intrinsic `{}`",
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d99bdd3bdd5..9fba9c77d07 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -461,6 +461,7 @@ symbols! {
         const_async_blocks,
         const_compare_raw_pointers,
         const_constructor,
+        const_deallocate,
         const_eval_limit,
         const_eval_select,
         const_eval_select_ct,
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index 4c612ed5be5..74f6f50d412 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -297,6 +297,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             sym::const_allocate => {
                 (0, vec![tcx.types.usize, tcx.types.usize], tcx.mk_mut_ptr(tcx.types.u8))
             }
+            sym::const_deallocate => (
+                0,
+                vec![tcx.mk_mut_ptr(tcx.types.u8), tcx.types.usize, tcx.types.usize],
+                tcx.mk_unit(),
+            ),
 
             sym::ptr_offset_from => {
                 (1, vec![tcx.mk_imm_ptr(param(0)), tcx.mk_imm_ptr(param(0))], tcx.types.isize)