mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-05-07 03:19:35 -05:00
Combine guest memory and function table into one virtual allocation.
This commit is contained in:
@@ -314,19 +314,18 @@ T GuestToHostFunction(const TFunction& func, TArgs&&... argv)
|
||||
auto& currentCtx = *GetPPCContext();
|
||||
|
||||
PPCContext newCtx; // NOTE: No need for zero initialization, has lots of unnecessary code generation.
|
||||
newCtx.fn = currentCtx.fn;
|
||||
newCtx.r1 = currentCtx.r1;
|
||||
newCtx.r13 = currentCtx.r13;
|
||||
newCtx.fpscr = currentCtx.fpscr;
|
||||
|
||||
_translate_args_to_guest(newCtx, (uint8_t*)g_memory.base, args);
|
||||
_translate_args_to_guest(newCtx, g_memory.base, args);
|
||||
|
||||
SetPPCContext(newCtx);
|
||||
|
||||
if constexpr (std::is_function_v<TFunction>)
|
||||
func(newCtx, (uint8_t*)g_memory.base);
|
||||
func(newCtx, g_memory.base);
|
||||
else
|
||||
(*(PPCFunc**)(newCtx.fn + uint64_t(func) * 2))(newCtx, (uint8_t*)g_memory.base);
|
||||
g_memory.FindFunction(func)(newCtx, g_memory.base);
|
||||
|
||||
currentCtx.fpscr = newCtx.fpscr;
|
||||
SetPPCContext(currentCtx);
|
||||
|
||||
@@ -8,10 +8,7 @@ constexpr size_t RESERVED_END = 0xA0000000;
|
||||
|
||||
void Heap::Init()
|
||||
{
|
||||
g_memory.Alloc(0x20000, RESERVED_BEGIN - 0x20000, MEM_COMMIT);
|
||||
heap = o1heapInit(g_memory.Translate(0x20000), RESERVED_BEGIN - 0x20000);
|
||||
|
||||
g_memory.Alloc(RESERVED_END, 0x100000000 - RESERVED_END, MEM_COMMIT);
|
||||
physicalHeap = o1heapInit(g_memory.Translate(RESERVED_END), 0x100000000 - RESERVED_END);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +1,30 @@
|
||||
#include <stdafx.h>
|
||||
#include "memory.h"
|
||||
|
||||
Memory::Memory(void* address, size_t size) : size(size)
|
||||
Memory::Memory()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
base = (char*)VirtualAlloc(address, size, MEM_RESERVE, PAGE_READWRITE);
|
||||
base = (uint8_t*)VirtualAlloc((void*)0x100000000ull, PPC_MEMORY_SIZE + PPC_FUNC_TABLE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
if (base == nullptr)
|
||||
base = (char*)VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE);
|
||||
#else
|
||||
base = (char*)mmap(address, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
base = (uint8_t*)VirtualAlloc(nullptr, PPC_MEMORY_SIZE + PPC_FUNC_TABLE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
||||
if (base == (char*)MAP_FAILED)
|
||||
base = (char*)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(base, 4096, PAGE_NOACCESS, &oldProtect);
|
||||
#else
|
||||
base = (uint8_t*)mmap((void*)0x100000000ull, PPC_MEMORY_SIZE + PPC_FUNC_TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
|
||||
if (base == (uint8_t*)MAP_FAILED)
|
||||
base = (uint8_t*)mmap(NULL, PPC_MEMORY_SIZE + PPC_FUNC_TABLE_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
|
||||
mprotect(base, 4096, PROT_NONE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void* Memory::Alloc(size_t offset, size_t size, uint32_t type)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return VirtualAlloc(base + offset, size, type, PAGE_READWRITE);
|
||||
#else
|
||||
return base + offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* Memory::Commit(size_t offset, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return Alloc(offset, size, MEM_COMMIT);
|
||||
#else
|
||||
return base + offset;
|
||||
#endif
|
||||
}
|
||||
|
||||
void* Memory::Reserve(size_t offset, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return Alloc(offset, size, MEM_RESERVE);
|
||||
#else
|
||||
return base + offset;
|
||||
#endif
|
||||
for (size_t i = 0; PPCFuncMappings[i].guest != 0; i++)
|
||||
{
|
||||
if (PPCFuncMappings[i].host != nullptr)
|
||||
InsertFunction(PPCFuncMappings[i].guest, PPCFuncMappings[i].host);
|
||||
}
|
||||
}
|
||||
|
||||
void* MmGetHostAddress(uint32_t ptr)
|
||||
|
||||
@@ -5,29 +5,21 @@
|
||||
#define MEM_RESERVE 0x00002000
|
||||
#endif
|
||||
|
||||
class Memory
|
||||
struct Memory
|
||||
{
|
||||
public:
|
||||
char* base{};
|
||||
size_t size{};
|
||||
size_t guestBase{};
|
||||
uint8_t* base{};
|
||||
|
||||
Memory(void* address, size_t size);
|
||||
|
||||
void* Alloc(size_t offset, size_t size, uint32_t type);
|
||||
|
||||
void* Commit(size_t offset, size_t size);
|
||||
void* Reserve(size_t offset, size_t size);
|
||||
Memory();
|
||||
|
||||
bool IsInMemoryRange(const void* host) const noexcept
|
||||
{
|
||||
return host >= base && host < (base + size);
|
||||
return host >= base && host < (base + PPC_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
void* Translate(size_t offset) const noexcept
|
||||
{
|
||||
if (offset)
|
||||
assert(offset < 0x100000000ull);
|
||||
assert(offset < PPC_MEMORY_SIZE);
|
||||
|
||||
return base + offset;
|
||||
}
|
||||
@@ -37,7 +29,17 @@ public:
|
||||
if (host)
|
||||
assert(IsInMemoryRange(host));
|
||||
|
||||
return static_cast<uint32_t>(static_cast<const char*>(host) - base);
|
||||
return static_cast<uint32_t>(static_cast<const uint8_t*>(host) - base);
|
||||
}
|
||||
|
||||
PPCFunc* FindFunction(uint32_t guest) const noexcept
|
||||
{
|
||||
return *reinterpret_cast<PPCFunc**>(base + PPC_FUNC_TABLE_OFFSET + (uint64_t(guest) * 2));
|
||||
}
|
||||
|
||||
void InsertFunction(uint32_t guest, PPCFunc* host)
|
||||
{
|
||||
*reinterpret_cast<PPCFunc**>(base + PPC_FUNC_TABLE_OFFSET + (uint64_t(guest) * 2)) = host;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user