JIT compiler update.
This commit is contained in:
parent
156a5c4e5f
commit
6f3deee62d
|
@ -90,10 +90,20 @@
|
||||||
|
|
||||||
/* Executable code allocation:
|
/* Executable code allocation:
|
||||||
If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
|
If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should
|
||||||
define both SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. */
|
define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_ENABLE_EXEC. */
|
||||||
#ifndef SLJIT_EXECUTABLE_ALLOCATOR
|
#ifndef SLJIT_EXECUTABLE_ALLOCATOR
|
||||||
/* Enabled by default. */
|
/* Enabled by default. */
|
||||||
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
#define SLJIT_EXECUTABLE_ALLOCATOR 1
|
||||||
|
|
||||||
|
/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
|
||||||
|
an allocator which does not set writable and executable
|
||||||
|
permission flags at the same time. The trade-of is increased
|
||||||
|
memory consumption and disabled dynamic code modifications. */
|
||||||
|
#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
|
||||||
|
/* Disabled by default. */
|
||||||
|
#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Force cdecl calling convention even if a better calling
|
/* Force cdecl calling convention even if a better calling
|
||||||
|
|
|
@ -545,6 +545,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
|
||||||
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
|
#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
|
||||||
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
|
#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
|
||||||
|
|
||||||
|
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_enable_exec(void* from, void *to);
|
||||||
|
#define SLJIT_ENABLE_EXEC(from, to) sljit_enable_exec((from), (to))
|
||||||
|
#else
|
||||||
|
#define SLJIT_ENABLE_EXEC(from, to)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**********************************************/
|
/**********************************************/
|
||||||
|
|
|
@ -242,9 +242,15 @@
|
||||||
#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
#if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||||
|
|
||||||
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
|
||||||
|
|
||||||
|
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||||
|
#include "sljitProtExecAllocator.c"
|
||||||
|
#else
|
||||||
#include "sljitExecAllocator.c"
|
#include "sljitExecAllocator.c"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Argument checking features. */
|
/* Argument checking features. */
|
||||||
|
|
||||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||||
|
@ -283,6 +289,13 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define CHECK_DYN_CODE_MOD(extra_check) \
|
||||||
|
if ((extra_check) && !sljit_is_dyn_code_modification_enabled()) \
|
||||||
|
{ \
|
||||||
|
compiler->error = SLJIT_ERR_DYN_CODE_MOD; \
|
||||||
|
return NULL; \
|
||||||
|
}
|
||||||
|
|
||||||
#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
#elif (defined SLJIT_DEBUG && SLJIT_DEBUG)
|
||||||
|
|
||||||
/* Assertion failure occures if an invalid argument is passed. */
|
/* Assertion failure occures if an invalid argument is passed. */
|
||||||
|
@ -295,6 +308,7 @@
|
||||||
#define CHECK(x) x
|
#define CHECK(x) x
|
||||||
#define CHECK_PTR(x) x
|
#define CHECK_PTR(x) x
|
||||||
#define CHECK_REG_INDEX(x) x
|
#define CHECK_REG_INDEX(x) x
|
||||||
|
#define CHECK_DYN_CODE_MOD(extra_check) SLJIT_ASSERT(!(extra_check) || sljit_is_dyn_code_modification_enabled())
|
||||||
|
|
||||||
#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
#elif (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||||
|
|
||||||
|
@ -304,6 +318,7 @@
|
||||||
#define CHECK(x) x
|
#define CHECK(x) x
|
||||||
#define CHECK_PTR(x) x
|
#define CHECK_PTR(x) x
|
||||||
#define CHECK_REG_INDEX(x) x
|
#define CHECK_REG_INDEX(x) x
|
||||||
|
#define CHECK_DYN_CODE_MOD(extra_check)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -311,6 +326,7 @@
|
||||||
#define CHECK(x)
|
#define CHECK(x)
|
||||||
#define CHECK_PTR(x)
|
#define CHECK_PTR(x)
|
||||||
#define CHECK_REG_INDEX(x)
|
#define CHECK_REG_INDEX(x)
|
||||||
|
#define CHECK_DYN_CODE_MOD(extra_check)
|
||||||
|
|
||||||
#endif /* SLJIT_ARGUMENT_CHECKS */
|
#endif /* SLJIT_ARGUMENT_CHECKS */
|
||||||
|
|
||||||
|
@ -441,6 +457,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
|
||||||
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
compiler->error = SLJIT_ERR_ALLOC_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_dyn_code_modification_enabled(void)
|
||||||
|
{
|
||||||
|
#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
|
||||||
|
&& (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||||
{
|
{
|
||||||
|
@ -1601,6 +1626,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
||||||
sljit_sw tmp_srcw;
|
sljit_sw tmp_srcw;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
|
|
||||||
condition = type & 0xff;
|
condition = type & 0xff;
|
||||||
|
@ -1681,6 +1707,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
|
||||||
sljit_s32 flags, condition;
|
sljit_s32 flags, condition;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
|
|
||||||
condition = type & 0xff;
|
condition = type & 0xff;
|
||||||
|
|
|
@ -99,6 +99,8 @@ of sljitConfigInternal.h */
|
||||||
#define SLJIT_ERR_UNSUPPORTED 4
|
#define SLJIT_ERR_UNSUPPORTED 4
|
||||||
/* An ivalid argument is passed to any SLJIT function. */
|
/* An ivalid argument is passed to any SLJIT function. */
|
||||||
#define SLJIT_ERR_BAD_ARGUMENT 5
|
#define SLJIT_ERR_BAD_ARGUMENT 5
|
||||||
|
/* Dynamic code modification is not enabled. */
|
||||||
|
#define SLJIT_ERR_DYN_CODE_MOD 6
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
/* Registers */
|
/* Registers */
|
||||||
|
@ -455,7 +457,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compile
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Returns with non-zero if dynamic code modification is enabled. */
|
||||||
|
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_is_dyn_code_modification_enabled(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create executable code from the sljit instruction stream. This is the final step
|
||||||
|
of the code generation so no more instructions can be added after this call.
|
||||||
|
*/
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
|
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
|
||||||
|
|
||||||
|
/* Free executable code. */
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -793,6 +793,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_uw);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2402,6 +2403,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2534,6 +2536,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 reg;
|
sljit_s32 reg;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -309,6 +309,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1882,6 +1883,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2020,6 +2022,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 dst_r;
|
sljit_s32 dst_r;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -415,6 +415,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
/* Set thumb mode flag. */
|
/* Set thumb mode flag. */
|
||||||
return (void*)((sljit_uw)code | 0x1);
|
return (void*)((sljit_uw)code | 0x1);
|
||||||
|
@ -1917,6 +1918,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
sljit_ins cc;
|
sljit_ins cc;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2060,6 +2062,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 dst_r;
|
sljit_s32 dst_r;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -477,6 +477,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
#else
|
#else
|
||||||
|
@ -1625,6 +1626,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
sljit_s32 delay_check = UNMOVABLE_INS;
|
sljit_s32 delay_check = UNMOVABLE_INS;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -1742,6 +1744,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
||||||
sljit_ins inst;
|
sljit_ins inst;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
ADJUST_LOCAL_OFFSET(src1, src1w);
|
ADJUST_LOCAL_OFFSET(src1, src1w);
|
||||||
ADJUST_LOCAL_OFFSET(src2, src2w);
|
ADJUST_LOCAL_OFFSET(src2, src2w);
|
||||||
|
@ -1863,6 +1866,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
|
||||||
sljit_s32 if_true;
|
sljit_s32 if_true;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w));
|
||||||
|
|
||||||
compiler->cache_arg = 0;
|
compiler->cache_arg = 0;
|
||||||
|
@ -2121,6 +2125,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 reg;
|
sljit_s32 reg;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -493,6 +493,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
|
|
||||||
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||||
|
@ -2138,6 +2139,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
sljit_ins bo_bi_flags;
|
sljit_ins bo_bi_flags;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
bo_bi_flags = get_bo_bi_flags(type & 0xff);
|
bo_bi_flags = get_bo_bi_flags(type & 0xff);
|
||||||
|
@ -2362,6 +2364,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
sljit_s32 reg;
|
sljit_s32 reg;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -379,6 +379,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -1295,6 +1296,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -1422,6 +1424,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
struct sljit_const *const_;
|
struct sljit_const *const_;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -1113,6 +1113,7 @@ SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compi
|
||||||
|
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
SLJIT_CACHE_FLUSH(code, code_ptr);
|
SLJIT_CACHE_FLUSH(code, code_ptr);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -2412,6 +2413,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compil
|
||||||
flush_buffer(compiler);
|
flush_buffer(compiler);
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||||
|
@ -2510,6 +2512,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_comp
|
||||||
flush_buffer(compiler);
|
flush_buffer(compiler);
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -581,6 +581,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||||
SLJIT_ASSERT(code_ptr <= code + compiler->size);
|
SLJIT_ASSERT(code_ptr <= code + compiler->size);
|
||||||
compiler->error = SLJIT_ERR_COMPILED;
|
compiler->error = SLJIT_ERR_COMPILED;
|
||||||
compiler->executable_size = code_ptr - code;
|
compiler->executable_size = code_ptr - code;
|
||||||
|
SLJIT_ENABLE_EXEC(code, code_ptr);
|
||||||
return (void*)code;
|
return (void*)code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2580,6 +2581,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||||
struct sljit_jump *jump;
|
struct sljit_jump *jump;
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(type & SLJIT_REWRITABLE_JUMP);
|
||||||
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
CHECK_PTR(check_sljit_emit_jump(compiler, type));
|
||||||
|
|
||||||
if (SLJIT_UNLIKELY(compiler->flags_saved)) {
|
if (SLJIT_UNLIKELY(compiler->flags_saved)) {
|
||||||
|
@ -2908,6 +2910,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CHECK_ERROR_PTR();
|
CHECK_ERROR_PTR();
|
||||||
|
CHECK_DYN_CODE_MOD(1);
|
||||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Stack-less Just-In-Time compiler
|
||||||
|
*
|
||||||
|
* Copyright 2009-2012 Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
* permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||||
|
* conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This file contains a simple executable memory allocator where the
|
||||||
|
allocated regions are not writable and executable in the same time.
|
||||||
|
|
||||||
|
This allocator usually uses more memory than sljitExecAllocator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||||
|
{
|
||||||
|
return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||||
|
{
|
||||||
|
SLJIT_UNUSED_ARG(size);
|
||||||
|
VirtualFree(chunk, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SLJIT_INLINE void enable_exec_permission(void* chunk, sljit_uw size)
|
||||||
|
{
|
||||||
|
sljit_uw *uw_ptr = (sljit_uw *)ptr;
|
||||||
|
|
||||||
|
VirtualProtect(chunk, size, PAGE_EXECUTE_READ, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||||
|
{
|
||||||
|
void* retval;
|
||||||
|
|
||||||
|
#ifdef MAP_ANON
|
||||||
|
retval = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
|
#else
|
||||||
|
if (dev_zero < 0) {
|
||||||
|
if (open_dev_zero())
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
retval = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (retval != MAP_FAILED) ? retval : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size)
|
||||||
|
{
|
||||||
|
munmap(chunk, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SLJIT_INLINE void enable_exec_permission(void* chunk, sljit_uw size)
|
||||||
|
{
|
||||||
|
sljit_uw *uw_ptr = (sljit_uw *)chunk;
|
||||||
|
|
||||||
|
mprotect(uw_ptr - 1, size + sizeof(sljit_uw), PROT_READ | PROT_EXEC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
/* Common functions */
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
|
||||||
|
{
|
||||||
|
sljit_uw *ptr = (sljit_uw *)alloc_chunk(size + sizeof (sljit_uw));
|
||||||
|
|
||||||
|
*ptr = size;
|
||||||
|
return (void*)(ptr + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
|
||||||
|
{
|
||||||
|
sljit_uw *uw_ptr = (sljit_uw *)ptr;
|
||||||
|
|
||||||
|
free_chunk(uw_ptr - 1, uw_ptr[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_enable_exec(void* from, void *to)
|
||||||
|
{
|
||||||
|
enable_exec_permission(from, ((sljit_u8 *)to) - ((sljit_u8 *)from));
|
||||||
|
}
|
||||||
|
|
||||||
|
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
|
||||||
|
{
|
||||||
|
}
|
Loading…
Reference in New Issue