lightrec: Enable code buffer support
authorPaul Cercueil <paul@crapouillou.net>
Sat, 4 Jun 2022 20:12:14 +0000 (21:12 +0100)
committerPaul Cercueil <paul@crapouillou.net>
Sat, 4 Jun 2022 20:50:22 +0000 (21:50 +0100)
Map a 8 MiB code buffer at (base + 0x80.0000), right after the emulated
RAM. In this code buffer, Lightrec will write the recompiled code for
the host machine.

In general, the code buffer support is very useful when the host
platform has only a small RW+X memory area available for JIT purposes,
like it's the case on the WiiU.

On Linux, this isn't a concern, but having a code buffer does still
bring a benefit: if both the start address and the end address of the
code buffer's address fit in 32 bits, then Lightrec's code LUT can be
shrunk in half (2.5 MiB instead of 5 MiB), as it only needs to store
32-bit pointers.

Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Makefile
include/lightrec/lightrec-config.h
libpcsxcore/lightrec/mem.c
libpcsxcore/lightrec/mem.h
libpcsxcore/lightrec/plugin.c

index 0860c72..3aa06b7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -96,7 +96,7 @@ CFLAGS += -Ideps/lightning/include -Ideps/lightrec -Iinclude/lightning -Iinclude
 deps/lightning/lib/%.o: CFLAGS += -DHAVE_MMAP
 ifeq ($(LIGHTREC_CUSTOM_MAP),1)
 LDLIBS += -lrt
-OBJS += libpcsxcore/lightrec/mem.o
+OBJS += libpcsxcore/lightrec/mem.o deps/lightrec/tlsf/tlsf.o
 endif
 OBJS += libpcsxcore/lightrec/plugin.o
 OBJS += deps/lightning/lib/jit_disasm.o \
index 34ac7a6..2fa750f 100644 (file)
@@ -9,8 +9,7 @@
 #define ENABLE_THREADED_COMPILER 1
 #define ENABLE_FIRST_PASS 1
 #define ENABLE_DISASSEMBLER 0
-#define ENABLE_TINYMM 0
-#define ENABLE_CODE_BUFFER 0
+#define ENABLE_CODE_BUFFER 1
 
 #define HAS_DEFAULT_ELM 1
 
index c3a1421..ff67e3d 100644 (file)
@@ -31,6 +31,8 @@
 #define MFD_HUGETLB 0x0004
 #endif
 
+void *code_buffer;
+
 static const uintptr_t supported_io_bases[] = {
        0x0,
        0x10000000,
@@ -171,8 +173,22 @@ int lightrec_init_mmap(void)
 
        psxH = (s8 *)map;
 
+       map = mmap_huge((void *)(base + 0x800000), CODE_BUFFER_SIZE,
+                       PROT_EXEC | PROT_READ | PROT_WRITE,
+                       MAP_PRIVATE | MAP_FIXED_NOREPLACE | MAP_ANONYMOUS,
+                       0, 0);
+       if (map == MAP_FAILED) {
+               err = -EINVAL;
+               fprintf(stderr, "Unable to mmap code buffer\n");
+               goto err_unmap_scratch;
+       }
+
+       code_buffer = map;
+
        return 0;
 
+err_unmap_scratch:
+       munmap(psxH, 0x10000);
 err_unmap_bios:
        munmap(psxR, 0x80000);
 err_unmap_parallel:
@@ -187,6 +203,7 @@ void lightrec_free_mmap(void)
 {
        unsigned int i;
 
+       munmap(code_buffer, CODE_BUFFER_SIZE);
        munmap(psxH, 0x10000);
        munmap(psxR, 0x80000);
        munmap(psxP, 0x10000);
index 7f04ce5..d747c17 100644 (file)
@@ -6,6 +6,10 @@
 #ifndef __LIGHTREC_MEM_H__
 #define __LIGHTREC_MEM_H__
 
+#define CODE_BUFFER_SIZE (8 * 1024 * 1024)
+
+extern void *code_buffer;
+
 int lightrec_init_mmap(void);
 void lightrec_free_mmap(void);
 
index 4b28c56..00d9c55 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "../frontend/main.h"
 
+#include "mem.h"
+
 #if (defined(__arm__) || defined(__aarch64__)) && !defined(ALLOW_LIGHTREC_ON_ARM)
 #error "Lightrec should not be used on ARM (please specify DYNAREC=ari64 to make)"
 #endif
@@ -289,6 +291,9 @@ static struct lightrec_mem_map lightrec_map[] = {
                .length = 0x200000,
                .mirror_of = &lightrec_map[PSX_MAP_KERNEL_USER_RAM],
        },
+       [PSX_MAP_CODE_BUFFER] = {
+               .length = CODE_BUFFER_SIZE,
+       },
 };
 
 static void lightrec_enable_ram(struct lightrec_state *state, bool enable)
@@ -315,6 +320,7 @@ static int lightrec_plugin_init(void)
                lightrec_map[PSX_MAP_MIRROR1].address = psxM + 0x200000;
                lightrec_map[PSX_MAP_MIRROR2].address = psxM + 0x400000;
                lightrec_map[PSX_MAP_MIRROR3].address = psxM + 0x600000;
+               lightrec_map[PSX_MAP_CODE_BUFFER].address = code_buffer;
        }
 
        lightrec_debug = !!getenv("LIGHTREC_DEBUG");