backend/x64: use mmap for all code allocations on Linux

This commit is contained in:
Liam 2022-04-19 10:42:51 -04:00 committed by merry
parent 78b4ba10c9
commit 898f14b772

View file

@ -52,6 +52,41 @@ constexpr size_t CONSTANT_POOL_SIZE = 2 * 1024 * 1024;
class CustomXbyakAllocator : public Xbyak::Allocator { class CustomXbyakAllocator : public Xbyak::Allocator {
public: public:
#ifndef _WIN32
static constexpr size_t PAGE_SIZE = 4096;
// Can't subclass Xbyak::MmapAllocator because it is not a pure interface
// and doesn't expose its construtor
uint8_t* alloc(size_t size) override {
// Waste a page to store the size
size += PAGE_SIZE;
# if defined(MAP_ANONYMOUS)
int mode = MAP_PRIVATE | MAP_ANONYMOUS;
# elif defined(MAP_ANON)
int mode = MAP_PRIVATE | MAP_ANON;
# else
# error "not supported"
# endif
# ifdef MAP_JIT
mode |= MAP_JIT;
# endif
void* p = mmap(nullptr, size, PROT_READ | PROT_WRITE, mode, -1, 0);
if (p == MAP_FAILED) {
throw Xbyak::Error(Xbyak::ERR_CANT_ALLOC);
}
std::memcpy(p, &size, sizeof(size_t));
return static_cast<uint8_t*>(p) + PAGE_SIZE;
}
void free(uint8_t* p) override {
size_t size;
std::memcpy(&size, p - PAGE_SIZE, sizeof(size_t));
munmap(p - PAGE_SIZE, size);
}
#endif
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT #ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
bool useProtect() const override { return false; } bool useProtect() const override { return false; }
#endif #endif