JIT compiler update.

This commit is contained in:
Zoltán Herczeg 2020-04-14 05:04:32 +00:00
parent 28f92c8596
commit cf670e3bb9
4 changed files with 62 additions and 18 deletions

View File

@ -2633,11 +2633,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
} }
else { else {
if (is_type1_transfer) { if (is_type1_transfer) {
if (memw > 4095 && memw < -4095) if (memw > 4095 || memw < -4095)
return SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED;
} }
else { else {
if (memw > 255 && memw < -255) if (memw > 255 || memw < -255)
return SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED;
} }
} }

View File

@ -1878,7 +1878,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
CHECK_ERROR(); CHECK_ERROR();
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw)); CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256)) if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
return SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP) if (type & SLJIT_MEM_SUPP)
@ -1928,7 +1928,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
CHECK_ERROR(); CHECK_ERROR();
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw)); CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -256)) if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -256))
return SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP) if (type & SLJIT_MEM_SUPP)

View File

@ -2274,7 +2274,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
CHECK_ERROR(); CHECK_ERROR();
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw)); CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255)) if ((mem & OFFS_REG_MASK) || (memw > 255 || memw < -255))
return SLJIT_ERR_UNSUPPORTED; return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_MEM_SUPP) if (type & SLJIT_MEM_SUPP)

View File

@ -70,7 +70,6 @@
struct chunk_header { struct chunk_header {
void *executable; void *executable;
int fd;
}; };
/* /*
@ -96,8 +95,18 @@ struct chunk_header {
#endif #endif
#endif #endif
#if !(defined(__NetBSD__) && defined(MAP_REMAPDUP))
int mkostemp(char *template, int flags); int mkostemp(char *template, int flags);
#if !defined(__NetBSD__)
#ifdef __NetBSD__
/*
* this is a workaround for NetBSD < 8 that lacks a system provided
* secure_getenv function.
* ideally this should never be used, as the standard allocator is
* a preferred option for those systems and should be used instead.
*/
#define secure_getenv(name) issetugid() ? NULL : getenv(name)
#else
char *secure_getenv(const char *name); char *secure_getenv(const char *name);
#endif #endif
@ -110,6 +119,13 @@ static SLJIT_INLINE int create_tempfile(void)
char *dir; char *dir;
size_t len; size_t len;
#ifdef HAVE_MEMFD_CREATE
/* this is a GNU extension, make sure to use -D_GNU_SOURCE */
fd = memfd_create("sljit", MFD_CLOEXEC);
if (fd != -1)
return fd;
#endif
#ifdef P_tmpdir #ifdef P_tmpdir
len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0; len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0;
@ -126,11 +142,8 @@ static SLJIT_INLINE int create_tempfile(void)
tmp_name_len = 4; tmp_name_len = 4;
#endif #endif
#if defined(__NetBSD__)
dir = getenv("TMPDIR");
#else
dir = secure_getenv("TMPDIR"); dir = secure_getenv("TMPDIR");
#endif
if (dir) { if (dir) {
len = strlen(dir); len = strlen(dir);
if (len > 0 && len < sizeof(tmp_name)) { if (len > 0 && len < sizeof(tmp_name)) {
@ -195,23 +208,50 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0);
if (retval->executable == MAP_FAILED) { if (retval->executable == MAP_FAILED) {
munmap(retval, size); munmap((void *)retval, size);
close(fd); close(fd);
return NULL; return NULL;
} }
retval->fd = fd; close(fd);
return retval; return retval;
} }
#else
static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
{
struct chunk_header *retval;
void *maprx;
retval = (struct chunk_header *)mmap(NULL, size,
PROT_MPROTECT(PROT_EXEC|PROT_WRITE|PROT_READ),
MAP_ANON, -1, 0);
if (retval == MAP_FAILED)
return NULL;
maprx = mremap(retval, size, NULL, size, MAP_REMAPDUP);
if (maprx == MAP_FAILED) {
munmap((void *)retval, size);
return NULL;
}
if (mprotect(retval, size, PROT_READ | PROT_WRITE) == -1 ||
mprotect(maprx, size, PROT_READ | PROT_EXEC) == -1) {
munmap(maprx, size);
munmap((void *)retval, size);
return NULL;
}
retval->executable = maprx;
return retval;
}
#endif /* NetBSD >= 8 */
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{ {
struct chunk_header *header = ((struct chunk_header *)chunk) - 1; struct chunk_header *header = ((struct chunk_header *)chunk) - 1;
int fd = header->fd;
munmap(header->executable, size); munmap(header->executable, size);
munmap(header, size); munmap((void *)header, size);
close(fd);
} }
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
@ -391,7 +431,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
if (total_size - free_block->size > (allocated_size * 3 / 2)) { if (total_size - free_block->size > (allocated_size * 3 / 2)) {
total_size -= free_block->size; total_size -= free_block->size;
sljit_remove_free_block(free_block); sljit_remove_free_block(free_block);
free_chunk(free_block, free_block->size + sizeof(struct block_header)); free_chunk(free_block, free_block->size +
sizeof(struct chunk_header) +
sizeof(struct block_header));
} }
} }
@ -412,7 +454,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
total_size -= free_block->size; total_size -= free_block->size;
sljit_remove_free_block(free_block); sljit_remove_free_block(free_block);
free_chunk(free_block, free_block->size + sizeof(struct block_header)); free_chunk(free_block, free_block->size +
sizeof(struct chunk_header) +
sizeof(struct block_header));
} }
free_block = next_free_block; free_block = next_free_block;
} }