From 8ad5f2c50648c333c3c46f89533e200a39bf6ca8 Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 13 Dec 2023 15:32:25 -0500 Subject: common: use memory holepunching when clearing memory --- src/common/host_memory.cpp | 38 +++++++++++++++++++++++++++++--------- src/common/host_memory.h | 2 ++ 2 files changed, 31 insertions(+), 9 deletions(-) (limited to 'src/common') diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 4bfc64f2d..e540375b8 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -11,10 +11,6 @@ #elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv -#ifdef ANDROID -#include -#endif - #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif @@ -193,6 +189,11 @@ public: } } + bool ClearBackingRegion(size_t physical_offset, size_t length) { + // TODO: This does not seem to be possible on Windows. + return false; + } + void EnableDirectMappedAddress() { // TODO UNREACHABLE(); @@ -442,9 +443,7 @@ public: } // Backing memory initialization -#ifdef ANDROID - fd = ASharedMemory_create("HostMemory", backing_size); -#elif defined(__FreeBSD__) && __FreeBSD__ < 13 +#if defined(__FreeBSD__) && __FreeBSD__ < 13 // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30 fd = shm_open(SHM_ANON, O_RDWR, 0600); #else @@ -455,7 +454,6 @@ public: throw std::bad_alloc{}; } -#ifndef ANDROID // Defined to extend the file with zeros int ret = ftruncate(fd, backing_size); if (ret != 0) { @@ -463,7 +461,6 @@ public: strerror(errno)); throw std::bad_alloc{}; } -#endif backing_base = static_cast( mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); @@ -552,6 +549,19 @@ public: ASSERT_MSG(ret == 0, "mprotect failed: {}", strerror(errno)); } + bool ClearBackingRegion(size_t physical_offset, size_t length) { +#ifdef __linux__ + // Set MADV_REMOVE on backing map to destroy it instantly. + // This also deletes the area from the backing file. + int ret = madvise(backing_base + physical_offset, length, MADV_REMOVE); + ASSERT_MSG(ret == 0, "madvise failed: {}", strerror(errno)); + + return true; +#else + return false; +#endif + } + void EnableDirectMappedAddress() { virtual_base = nullptr; } @@ -623,6 +633,10 @@ public: void Protect(size_t virtual_offset, size_t length, bool read, bool write, bool execute) {} + bool ClearBackingRegion(size_t physical_offset, size_t length) { + return false; + } + void EnableDirectMappedAddress() {} u8* backing_base{nullptr}; @@ -698,6 +712,12 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool w impl->Protect(virtual_offset + virtual_base_offset, length, read, write, execute); } +void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) { + if (!impl || fill_value != 0 || !impl->ClearBackingRegion(physical_offset, length)) { + std::memset(backing_base + physical_offset, fill_value, length); + } +} + void HostMemory::EnableDirectMappedAddress() { if (impl) { impl->EnableDirectMappedAddress(); diff --git a/src/common/host_memory.h b/src/common/host_memory.h index cebfacab2..747c5850c 100644 --- a/src/common/host_memory.h +++ b/src/common/host_memory.h @@ -48,6 +48,8 @@ public: void EnableDirectMappedAddress(); + void ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value); + [[nodiscard]] u8* BackingBasePointer() noexcept { return backing_base; } -- cgit v1.2.3