From 050f2426d881cd50d0819e341c5387596f7428bc Mon Sep 17 00:00:00 2001 From: rozbf Date: Tue, 24 Jan 2023 23:36:38 +0100 Subject: [PATCH] Allow manual heap deallocation with zerolib --- src/zerolib/Internal/Startup.Efi.cs | 2 +- src/zerolib/Internal/Stubs.cs | 24 ++++++++++++++++++++++++ src/zerolib/System/GC.cs | 18 ++++++++++++++++++ src/zerolib/System/IDisposable.cs | 10 ++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/zerolib/System/GC.cs create mode 100644 src/zerolib/System/IDisposable.cs diff --git a/src/zerolib/Internal/Startup.Efi.cs b/src/zerolib/Internal/Startup.Efi.cs index 3377ec0..8832151 100644 --- a/src/zerolib/Internal/Startup.Efi.cs +++ b/src/zerolib/Internal/Startup.Efi.cs @@ -143,7 +143,7 @@ unsafe readonly struct EFI_BOOT_SERVICES private readonly void* pad3; private readonly void* pad4; public readonly delegate* AllocatePool; - private readonly void* pad6; + public readonly delegate* FreePool; private readonly void* pad7; private readonly void* pad8; private readonly void* pad9; diff --git a/src/zerolib/Internal/Stubs.cs b/src/zerolib/Internal/Stubs.cs index 9307f18..4c2a42c 100644 --- a/src/zerolib/Internal/Stubs.cs +++ b/src/zerolib/Internal/Stubs.cs @@ -131,6 +131,15 @@ public static unsafe void RhpAssignRef(void** dst, void* r) *dst = r; } + [RuntimeExport("RhSuppressFinalize")] + public static unsafe void RhSuppressFinalize(object obj) + { + fixed (MethodTable** mt = &obj.m_pMethodTable) + { + FreeObject(mt); + } + } + static unsafe MethodTable** AllocObject(uint size) { #if WINDOWS @@ -148,5 +157,20 @@ public static unsafe void RhpAssignRef(void** dst, void* r) return result; } + + static unsafe void FreeObject(MethodTable** mt) + { +#if WINDOWS + [DllImport("kernel32")] + static extern MethodTable** LocalFree(MethodTable** ptr); + LocalFree(mt); +#elif LINUX + [DllImport("libSystem.Native")] + static extern void SystemNative_Free(MethodTable** ptr); + SystemNative_Free(mt); +#elif UEFI + StartupCodeHelpers.s_efiSystemTable->BootServices->FreePool((void*)mt); +#endif + } } } diff --git a/src/zerolib/System/GC.cs b/src/zerolib/System/GC.cs new file mode 100644 index 0000000..f59d0c2 --- /dev/null +++ b/src/zerolib/System/GC.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Internal.Runtime.CompilerHelpers; + +namespace System +{ + public static class GC + { + public static void SuppressFinalize(object obj) + { + if (obj != null) + { + StartupCodeHelpers.RhSuppressFinalize(obj); + } + } + } +} diff --git a/src/zerolib/System/IDisposable.cs b/src/zerolib/System/IDisposable.cs new file mode 100644 index 0000000..33934c8 --- /dev/null +++ b/src/zerolib/System/IDisposable.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System +{ + public interface IDisposable + { + void Dispose(); + } +}