mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-10 14:07:25 +00:00
5f142c7926
Reduces the page entries from 32 bytes to 8 and rewrites `VirtualBuffer` to be more efficient in memory usage and specifically for large zero regions. The page table will now only reserve 1GiB instead of 4GiB and of this memory it should only use at most ~8MiB. This PR has the side effect of using Eden on Windows on low memory systems much more plausible since it would previously require ~10GiB of committable memory at front (despite using ~5-6 at most, inadvertently stalling other processes) where as now it should only require around the amount that it'll actually use. Co-authored-by: Lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4219 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: lizzie <lizzie@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
92 lines
2.6 KiB
C++
92 lines
2.6 KiB
C++
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <optional>
|
|
#include "common/common_funcs.h"
|
|
#include "common/common_types.h"
|
|
|
|
namespace Common {
|
|
|
|
enum class MemoryPermission : u32 {
|
|
Read = 1 << 0,
|
|
Write = 1 << 1,
|
|
ReadWrite = Read | Write,
|
|
Execute = 1 << 2,
|
|
};
|
|
DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission)
|
|
|
|
/**
|
|
* A low level linear memory buffer, which supports multiple mappings
|
|
* Its purpose is to rebuild a given sparse memory layout, including mirrors.
|
|
*/
|
|
class HostMemory {
|
|
public:
|
|
explicit HostMemory(size_t backing_size_, size_t virtual_size_);
|
|
~HostMemory();
|
|
|
|
/**
|
|
* Copy constructors. They shall return a copy of the buffer without the mappings.
|
|
* TODO: Implement them with COW if needed.
|
|
*/
|
|
HostMemory(const HostMemory& other) = delete;
|
|
HostMemory& operator=(const HostMemory& other) = delete;
|
|
|
|
/**
|
|
* Move constructors. They will move the buffer and the mappings to the new object.
|
|
*/
|
|
HostMemory(HostMemory&& other) noexcept;
|
|
HostMemory& operator=(HostMemory&& other) noexcept;
|
|
|
|
void Map(size_t virtual_offset, size_t host_offset, size_t length, MemoryPermission perms,
|
|
bool separate_heap);
|
|
|
|
void Unmap(size_t virtual_offset, size_t length, bool separate_heap);
|
|
|
|
void Protect(size_t virtual_offset, size_t length, MemoryPermission perms);
|
|
|
|
void EnableDirectMappedAddress();
|
|
|
|
void ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value);
|
|
|
|
[[nodiscard]] u8* BackingBasePointer() noexcept {
|
|
return backing_base;
|
|
}
|
|
[[nodiscard]] const u8* BackingBasePointer() const noexcept {
|
|
return backing_base;
|
|
}
|
|
|
|
[[nodiscard]] u8* VirtualBasePointer() noexcept {
|
|
return virtual_base;
|
|
}
|
|
[[nodiscard]] const u8* VirtualBasePointer() const noexcept {
|
|
return virtual_base;
|
|
}
|
|
|
|
bool IsInVirtualRange(void* address) const noexcept {
|
|
return address >= virtual_base && address < virtual_base + virtual_size;
|
|
}
|
|
|
|
private:
|
|
size_t backing_size{};
|
|
size_t virtual_size{};
|
|
|
|
#if !(defined(__OPENORBIS__) || defined(__managarm__))
|
|
// Low level handler for the platform dependent memory routines
|
|
class Impl;
|
|
std::unique_ptr<Impl> impl;
|
|
#endif
|
|
u8* backing_base{};
|
|
u8* virtual_base{};
|
|
size_t virtual_base_offset{};
|
|
// Windows requires it for kernels whom lack proper support for some functions!
|
|
bool fallback_buffer{false};
|
|
};
|
|
|
|
} // namespace Common
|