JIT compiler update.

This commit is contained in:
Zoltán Herczeg 2021-02-12 07:45:12 +00:00
parent 25029849c3
commit b6acebe497
3 changed files with 87 additions and 71 deletions

View File

@ -158,6 +158,8 @@ extern "C" {
#define SLJIT_CONFIG_MIPS_64 1 #define SLJIT_CONFIG_MIPS_64 1
#elif defined(__sparc__) || defined(__sparc) #elif defined(__sparc__) || defined(__sparc)
#define SLJIT_CONFIG_SPARC_32 1 #define SLJIT_CONFIG_SPARC_32 1
#elif defined(__s390x__)
#define SLJIT_CONFIG_S390X 1
#else #else
/* Unsupported architecture */ /* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1 #define SLJIT_CONFIG_UNSUPPORTED 1

View File

@ -79,6 +79,7 @@
*/ */
#ifdef _WIN32 #ifdef _WIN32
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
static SLJIT_INLINE void* alloc_chunk(sljit_uw size) static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{ {
@ -91,65 +92,76 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
VirtualFree(chunk, 0, MEM_RELEASE); VirtualFree(chunk, 0, MEM_RELEASE);
} }
#else #else /* POSIX */
#ifdef __APPLE__
#ifdef MAP_ANON
/* Configures TARGET_OS_OSX when appropriate */
#include <TargetConditionals.h>
#if TARGET_OS_OSX && defined(MAP_JIT)
#include <sys/utsname.h>
#endif /* TARGET_OS_OSX && MAP_JIT */
#ifdef MAP_JIT
#if defined(__APPLE__) && defined(MAP_JIT)
/* /*
On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
version where it's OK to have more than one JIT block. version where it's OK to have more than one JIT block or where MAP_JIT is
required.
On non-macOS systems, returns MAP_JIT if it is defined. On non-macOS systems, returns MAP_JIT if it is defined.
*/ */
#include <TargetConditionals.h>
#if TARGET_OS_OSX
#if defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86
#ifdef MAP_ANON
#include <sys/utsname.h>
#include <stdlib.h>
#define SLJIT_MAP_JIT (get_map_jit_flag())
static SLJIT_INLINE int get_map_jit_flag() static SLJIT_INLINE int get_map_jit_flag()
{ {
#if TARGET_OS_OSX sljit_sw page_size;
sljit_sw page_size = get_page_alignment() + 1;
void *ptr; void *ptr;
struct utsname name;
static int map_jit_flag = -1; static int map_jit_flag = -1;
/* if (map_jit_flag < 0) {
The following code is thread safe because multiple initialization
sets map_jit_flag to the same value and the code has no side-effects.
Changing the kernel version witout system restart is (very) unlikely.
*/
if (map_jit_flag == -1) {
struct utsname name;
map_jit_flag = 0; map_jit_flag = 0;
uname(&name); uname(&name);
/* Kernel version for 10.14.0 (Mojave) */ /* Kernel version for 10.14.0 (Mojave) or later */
if (atoi(name.release) >= 18) { if (atoi(name.release) >= 18) {
page_size = get_page_alignment() + 1;
/* Only use MAP_JIT if a hardened runtime is used */ /* Only use MAP_JIT if a hardened runtime is used */
ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); if (ptr != MAP_FAILED)
if (ptr == MAP_FAILED) {
map_jit_flag = MAP_JIT;
} else {
munmap(ptr, page_size); munmap(ptr, page_size);
} else
map_jit_flag = MAP_JIT;
} }
} }
return map_jit_flag; return map_jit_flag;
#else /* !TARGET_OS_OSX */
return MAP_JIT;
#endif /* TARGET_OS_OSX */
} }
#endif /* MAP_JIT */
#endif /* MAP_ANON */ #endif /* MAP_ANON */
#endif /* __APPLE__ */ #else /* !SLJIT_CONFIG_X86 */
#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
#error Unsupported architecture
#endif /* SLJIT_CONFIG_ARM */
#include <pthread.h>
#define SLJIT_MAP_JIT (MAP_JIT)
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
apple_update_wx_flags(enable_exec)
static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec)
{
pthread_jit_write_protect_np(enable_exec);
}
#endif /* SLJIT_CONFIG_X86 */
#else /* !TARGET_OS_OSX */
#define SLJIT_MAP_JIT (MAP_JIT)
#endif /* TARGET_OS_OSX */
#endif /* __APPLE__ && MAP_JIT */
#ifndef SLJIT_UPDATE_WX_FLAGS
#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
#endif /* !SLJIT_UPDATE_WX_FLAGS */
#ifndef SLJIT_MAP_JIT
#define SLJIT_MAP_JIT (0)
#endif /* !SLJIT_MAP_JIT */
static SLJIT_INLINE void* alloc_chunk(sljit_uw size) static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{ {
@ -157,12 +169,7 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
const int prot = PROT_READ | PROT_WRITE | PROT_EXEC; const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
#ifdef MAP_ANON #ifdef MAP_ANON
int flags = MAP_PRIVATE | MAP_ANON | SLJIT_MAP_JIT;
int flags = MAP_PRIVATE | MAP_ANON;
#ifdef MAP_JIT
flags |= get_map_jit_flag();
#endif
retval = mmap(NULL, size, prot, flags, -1, 0); retval = mmap(NULL, size, prot, flags, -1, 0);
#else /* !MAP_ANON */ #else /* !MAP_ANON */
@ -173,14 +180,15 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
#endif /* MAP_ANON */ #endif /* MAP_ANON */
if (retval == MAP_FAILED) if (retval == MAP_FAILED)
retval = NULL; return NULL;
else {
if (mprotect(retval, size, prot) < 0) { if (mprotect(retval, size, prot) < 0) {
munmap(retval, size); munmap(retval, size);
retval = NULL; return NULL;
}
} }
SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0);
return retval; return retval;
} }
@ -189,7 +197,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
munmap(chunk, size); munmap(chunk, size);
} }
#endif #endif /* windows */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/* Common functions */ /* Common functions */
@ -261,6 +269,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
while (free_block) { while (free_block) {
if (free_block->size >= size) { if (free_block->size >= size) {
chunk_size = free_block->size; chunk_size = free_block->size;
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
if (chunk_size > size + 64) { if (chunk_size > size + 64) {
/* We just cut a block from the end of the free block. */ /* We just cut a block from the end of the free block. */
chunk_size -= size; chunk_size -= size;
@ -326,6 +335,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
allocated_size -= header->size; allocated_size -= header->size;
/* Connecting free blocks together if possible. */ /* Connecting free blocks together if possible. */
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
/* If header->prev_size == 0, free_block will equal to header. /* If header->prev_size == 0, free_block will equal to header.
In this case, free_block->header.size will be > 0. */ In this case, free_block->header.size will be > 0. */
@ -358,6 +368,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
} }
} }
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK(); SLJIT_ALLOCATOR_UNLOCK();
} }
@ -367,6 +378,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
struct free_block* next_free_block; struct free_block* next_free_block;
SLJIT_ALLOCATOR_LOCK(); SLJIT_ALLOCATOR_LOCK();
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
free_block = free_blocks; free_block = free_blocks;
while (free_block) { while (free_block) {
@ -381,5 +393,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
} }
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK(); SLJIT_ALLOCATOR_UNLOCK();
} }

View File

@ -42,7 +42,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
typedef sljit_uw sljit_ins; typedef sljit_uw sljit_ins;
/* Instruction tags (most significant halfword). */ /* Instruction tags (most significant halfword). */
const sljit_ins sljit_ins_const = (sljit_ins)1 << 48; static const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = { static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1
@ -66,22 +66,22 @@ typedef sljit_uw sljit_gpr;
* will be retired ASAP (TODO: carenas) * will be retired ASAP (TODO: carenas)
*/ */
const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */ static const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */ static const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */ static const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */
const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */ static const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */
const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */ static const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */
const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */ static const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */
const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */ static const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */
const sljit_gpr r7 = 7; /* reg_map[6] */ static const sljit_gpr r7 = 7; /* reg_map[6] */
const sljit_gpr r8 = 8; /* reg_map[7] */ static const sljit_gpr r8 = 8; /* reg_map[7] */
const sljit_gpr r9 = 9; /* reg_map[8] */ static const sljit_gpr r9 = 9; /* reg_map[8] */
const sljit_gpr r10 = 10; /* reg_map[9] */ static const sljit_gpr r10 = 10; /* reg_map[9] */
const sljit_gpr r11 = 11; /* reg_map[10] */ static const sljit_gpr r11 = 11; /* reg_map[10] */
const sljit_gpr r12 = 12; /* reg_map[11]: GOT */ static const sljit_gpr r12 = 12; /* reg_map[11]: GOT */
const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */ static const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */
const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */ static const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */
const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */ static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */ /* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */
/* TODO(carenas): r12 might conflict in PIC code, reserve? */ /* TODO(carenas): r12 might conflict in PIC code, reserve? */
@ -100,8 +100,8 @@ const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack point
/* Link registers. The normal link register is r14, but since /* Link registers. The normal link register is r14, but since
we use that for flags we need to use r0 instead to do fast we use that for flags we need to use r0 instead to do fast
calls so that flags are preserved. */ calls so that flags are preserved. */
const sljit_gpr link_r = 14; /* r14 */ static const sljit_gpr link_r = 14; /* r14 */
const sljit_gpr fast_link_r = 0; /* r0 */ static const sljit_gpr fast_link_r = 0; /* r0 */
/* Flag register layout: /* Flag register layout:
@ -110,7 +110,7 @@ const sljit_gpr fast_link_r = 0; /* r0 */
| ZERO | 0 | 0 | C C |///////| | ZERO | 0 | 0 | C C |///////|
+---------------+---+---+-------+-------+ +---------------+---+---+-------+-------+
*/ */
const sljit_gpr flag_r = 14; /* r14 */ static const sljit_gpr flag_r = 14; /* r14 */
struct sljit_s390x_const { struct sljit_s390x_const {
struct sljit_const const_; /* must be first */ struct sljit_const const_; /* must be first */
@ -1465,7 +1465,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
op = GET_OPCODE(op) | (op & SLJIT_I32_OP); op = GET_OPCODE(op) | (op & SLJIT_I32_OP);
switch (op) { switch (op) {
case SLJIT_BREAKPOINT: case SLJIT_BREAKPOINT:
/* TODO(mundaym): insert real breakpoint? */ /* The following invalid instruction is emitted by gdb. */
return push_inst(compiler, 0x0001 /* 2-byte trap */);
case SLJIT_NOP: case SLJIT_NOP:
return push_inst(compiler, 0x0700 /* 2-byte nop */); return push_inst(compiler, 0x0700 /* 2-byte nop */);
case SLJIT_LMUL_UW: case SLJIT_LMUL_UW: