mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-10 05:38:49 +00:00
Core: physical backing for flexible and pooled memory allocations (#3639)
* Fix isDevKit Previously, isDevKit could increase the physical memory used above the length we reserve in the backing file. * Physical backing for flexible allocations I took the simple approach here, creating a separate map for flexible allocations and pretty much just copying over the logic used in the direct memory map. * Various fixups * Fix mistake #1 * Assert + clang * Fix 2 * Clang * Fix CanMergeWith Validate physical base for flexible mappings * Clang * Physical backing for pooled memory * Allow VMA splitting in NameVirtualRange This should be safe, since with the changes in this PR, the only issues that come from discrepancies between address space and vma_map are issues related to vmas being larger than address space mappings. NameVirtualRange will only ever shrink VMAs by naming part of one. * Fix * Fix NameVirtualRange * Revert NameVirtualRange changes Seems like it doesn't play nice for Windows * Clean up isDevKit logic We already log both isNeo and isDevKit in Emulator::Run, so the additional logging in MemoryManager::SetupMemoryRegions isn't really necessary. I've also added a separate constant for non-pro devkit memory, as suggested. Finally I've changed a couple constants to use the ORBIS prefix we generally follow here, instead of the SCE prefix. * Erase flexible memory contents from physical memory on unmap Flexible memory should not be preserved on unmap, so erase flexible contents from the physical backing when unmapping. * Expand flexible memory map Some games will end up fragmenting the physical backing space used for flexible memory. To reduce the frequency of this happening under normal circumstances, allocate the entirety of the remaining physical backing to the flexible memory map. This is effectively a workaround to the problem, but at the moment I think this should suffice. * Clang
This commit is contained in:
@@ -67,6 +67,7 @@ struct DirectMemoryArea {
|
||||
u64 size = 0;
|
||||
s32 memory_type = 0;
|
||||
bool is_pooled = false;
|
||||
bool is_committed = false;
|
||||
bool is_free = true;
|
||||
|
||||
PAddr GetEnd() const {
|
||||
@@ -80,6 +81,27 @@ struct DirectMemoryArea {
|
||||
if (memory_type != next.memory_type) {
|
||||
return false;
|
||||
}
|
||||
if (is_free != next.is_free || is_pooled != next.is_pooled ||
|
||||
is_committed != next.is_committed) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct FlexibleMemoryArea {
|
||||
PAddr base = 0;
|
||||
u64 size = 0;
|
||||
bool is_free = true;
|
||||
|
||||
PAddr GetEnd() const {
|
||||
return base + size;
|
||||
}
|
||||
|
||||
bool CanMergeWith(const FlexibleMemoryArea& next) const {
|
||||
if (base + size != next.base) {
|
||||
return false;
|
||||
}
|
||||
if (is_free != next.is_free) {
|
||||
return false;
|
||||
}
|
||||
@@ -117,7 +139,8 @@ struct VirtualMemoryArea {
|
||||
if (base + size != next.base) {
|
||||
return false;
|
||||
}
|
||||
if (type == VMAType::Direct && phys_base + size != next.phys_base) {
|
||||
if ((type == VMAType::Direct || type == VMAType::Flexible || type == VMAType::Pooled) &&
|
||||
phys_base + size != next.phys_base) {
|
||||
return false;
|
||||
}
|
||||
if (prot != next.prot || type != next.type) {
|
||||
@@ -131,6 +154,9 @@ class MemoryManager {
|
||||
using DMemMap = std::map<PAddr, DirectMemoryArea>;
|
||||
using DMemHandle = DMemMap::iterator;
|
||||
|
||||
using FMemMap = std::map<PAddr, FlexibleMemoryArea>;
|
||||
using FMemHandle = FMemMap::iterator;
|
||||
|
||||
using VMAMap = std::map<VAddr, VirtualMemoryArea>;
|
||||
using VMAHandle = VMAMap::iterator;
|
||||
|
||||
@@ -238,6 +264,10 @@ private:
|
||||
return std::prev(dmem_map.upper_bound(target));
|
||||
}
|
||||
|
||||
FMemHandle FindFmemArea(PAddr target) {
|
||||
return std::prev(fmem_map.upper_bound(target));
|
||||
}
|
||||
|
||||
template <typename Handle>
|
||||
Handle MergeAdjacent(auto& handle_map, Handle iter) {
|
||||
const auto next_vma = std::next(iter);
|
||||
@@ -258,16 +288,25 @@ private:
|
||||
return iter;
|
||||
}
|
||||
|
||||
bool HasPhysicalBacking(VirtualMemoryArea vma) {
|
||||
return vma.type == VMAType::Direct || vma.type == VMAType::Flexible ||
|
||||
vma.type == VMAType::Pooled;
|
||||
}
|
||||
|
||||
VAddr SearchFree(VAddr virtual_addr, u64 size, u32 alignment = 0);
|
||||
|
||||
VMAHandle CarveVMA(VAddr virtual_addr, u64 size);
|
||||
|
||||
DMemHandle CarveDmemArea(PAddr addr, u64 size);
|
||||
|
||||
FMemHandle CarveFmemArea(PAddr addr, u64 size);
|
||||
|
||||
VMAHandle Split(VMAHandle vma_handle, u64 offset_in_vma);
|
||||
|
||||
DMemHandle Split(DMemHandle dmem_handle, u64 offset_in_area);
|
||||
|
||||
FMemHandle Split(FMemHandle fmem_handle, u64 offset_in_area);
|
||||
|
||||
u64 UnmapBytesFromEntry(VAddr virtual_addr, VirtualMemoryArea vma_base, u64 size);
|
||||
|
||||
s32 UnmapMemoryImpl(VAddr virtual_addr, u64 size);
|
||||
@@ -275,6 +314,7 @@ private:
|
||||
private:
|
||||
AddressSpace impl;
|
||||
DMemMap dmem_map;
|
||||
FMemMap fmem_map;
|
||||
VMAMap vma_map;
|
||||
std::mutex mutex;
|
||||
u64 total_direct_size{};
|
||||
|
||||
Reference in New Issue
Block a user