Update some register assignments and the JIT compiler.
This commit is contained in:
parent
4a4389fa50
commit
1e0f88bba4
|
@ -545,9 +545,9 @@ typedef struct compare_context {
|
||||||
#define TMP2 SLJIT_R2
|
#define TMP2 SLJIT_R2
|
||||||
#define TMP3 SLJIT_R3
|
#define TMP3 SLJIT_R3
|
||||||
#endif
|
#endif
|
||||||
#define STR_PTR SLJIT_S0
|
#define STR_PTR SLJIT_R1
|
||||||
#define STR_END SLJIT_S1
|
#define STR_END SLJIT_S0
|
||||||
#define STACK_TOP SLJIT_R1
|
#define STACK_TOP SLJIT_S1
|
||||||
#define STACK_LIMIT SLJIT_S2
|
#define STACK_LIMIT SLJIT_S2
|
||||||
#define COUNT_MATCH SLJIT_S3
|
#define COUNT_MATCH SLJIT_S3
|
||||||
#define ARGUMENTS SLJIT_S4
|
#define ARGUMENTS SLJIT_S4
|
||||||
|
@ -2788,7 +2788,7 @@ if (common->control_head_ptr != 0)
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
|
static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, PCRE2_SPTR skip_arg)
|
||||||
|
@ -2812,7 +2812,7 @@ while (current != NULL)
|
||||||
SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
|
SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
|
||||||
current = (sljit_sw*)current[0];
|
current = (sljit_sw*)current[0];
|
||||||
}
|
}
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
||||||
|
@ -2902,7 +2902,7 @@ static SLJIT_INLINE void return_with_partial_match(compiler_common *common, stru
|
||||||
DEFINE_COMPILER;
|
DEFINE_COMPILER;
|
||||||
sljit_s32 mov_opcode;
|
sljit_s32 mov_opcode;
|
||||||
|
|
||||||
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S1, str_end_must_be_saved_reg2);
|
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0);
|
||||||
SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
|
SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
|
||||||
&& (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
|
&& (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
|
||||||
|
|
||||||
|
@ -2912,19 +2912,19 @@ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),
|
||||||
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
|
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
|
||||||
|
|
||||||
/* Store match begin and end. */
|
/* Store match begin and end. */
|
||||||
OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
|
OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data));
|
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data));
|
||||||
|
|
||||||
mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
|
mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
|
||||||
|
|
||||||
OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S0, 0);
|
OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_S1, 0);
|
||||||
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||||
OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
|
OP2(SLJIT_ASHR, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||||
#endif
|
#endif
|
||||||
OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);
|
OP1(mov_opcode, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(pcre2_match_data, ovector), SLJIT_R2, 0);
|
||||||
|
|
||||||
OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S0, 0);
|
OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_S1, 0);
|
||||||
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
|
||||||
OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);
|
OP2(SLJIT_ASHR, STR_END, 0, STR_END, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||||
#endif
|
#endif
|
||||||
|
@ -7211,7 +7211,7 @@ return cc;
|
||||||
|
|
||||||
#if PCRE2_CODE_UNIT_WIDTH != 32
|
#if PCRE2_CODE_UNIT_WIDTH != 32
|
||||||
|
|
||||||
static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(PCRE2_SPTR cc, jit_arguments *args)
|
static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)
|
||||||
{
|
{
|
||||||
PCRE2_SPTR start_subject = args->begin;
|
PCRE2_SPTR start_subject = args->begin;
|
||||||
PCRE2_SPTR end_subject = args->end;
|
PCRE2_SPTR end_subject = args->end;
|
||||||
|
@ -7269,7 +7269,7 @@ return cc;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(PCRE2_SPTR cc, jit_arguments *args)
|
static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc)
|
||||||
{
|
{
|
||||||
PCRE2_SPTR start_subject = args->begin;
|
PCRE2_SPTR start_subject = args->begin;
|
||||||
PCRE2_SPTR end_subject = args->end;
|
PCRE2_SPTR end_subject = args->end;
|
||||||
|
@ -7499,9 +7499,8 @@ switch(type)
|
||||||
if (check_str_ptr)
|
if (check_str_ptr)
|
||||||
detect_partial_match(common, backtracks);
|
detect_partial_match(common, backtracks);
|
||||||
|
|
||||||
OP1(SLJIT_MOV, SLJIT_R0, 0, STR_PTR, 0);
|
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
|
|
||||||
|
|
||||||
#if PCRE2_CODE_UNIT_WIDTH != 32
|
#if PCRE2_CODE_UNIT_WIDTH != 32
|
||||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
|
||||||
|
@ -7510,7 +7509,6 @@ switch(type)
|
||||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
|
||||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
||||||
|
|
||||||
if (common->mode == PCRE2_JIT_PARTIAL_HARD)
|
if (common->mode == PCRE2_JIT_PARTIAL_HARD)
|
||||||
|
@ -7848,7 +7846,7 @@ else
|
||||||
#if defined SUPPORT_UNICODE
|
#if defined SUPPORT_UNICODE
|
||||||
if (common->utf && *cc == OP_REFI)
|
if (common->utf && *cc == OP_REFI)
|
||||||
{
|
{
|
||||||
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
|
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
||||||
if (ref)
|
if (ref)
|
||||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
|
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
|
||||||
else
|
else
|
||||||
|
@ -7856,25 +7854,26 @@ if (common->utf && *cc == OP_REFI)
|
||||||
|
|
||||||
if (withchecks)
|
if (withchecks)
|
||||||
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
|
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
|
||||||
|
|
||||||
/* No free saved registers so save data on stack. */
|
/* No free saved registers so save data on stack. */
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
|
|
||||||
OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
|
OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
|
||||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
||||||
|
|
||||||
if (common->mode == PCRE2_JIT_COMPLETE)
|
if (common->mode == PCRE2_JIT_COMPLETE)
|
||||||
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
|
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
|
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
|
||||||
nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
|
|
||||||
|
add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
|
||||||
|
|
||||||
|
nopartial = JUMP(SLJIT_NOT_EQUAL);
|
||||||
|
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
|
||||||
check_partial(common, FALSE);
|
check_partial(common, FALSE);
|
||||||
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
|
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
|
||||||
JUMPHERE(nopartial);
|
JUMPHERE(nopartial);
|
||||||
}
|
}
|
||||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* SUPPORT_UNICODE */
|
#endif /* SUPPORT_UNICODE */
|
||||||
|
@ -8298,21 +8297,22 @@ OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_length)
|
||||||
OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);
|
OP1(mov_opcode, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_string_offset), SLJIT_IMM, value3);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
|
||||||
|
|
||||||
|
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
||||||
|
|
||||||
/* Needed to save important temporary registers. */
|
/* Needed to save important temporary registers. */
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
|
||||||
/* SLJIT_R0 = arguments */
|
/* SLJIT_R0 = arguments */
|
||||||
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
|
||||||
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
|
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
|
||||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
||||||
OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
|
||||||
free_stack(common, callout_arg_size);
|
free_stack(common, callout_arg_size);
|
||||||
|
|
||||||
/* Check return value. */
|
/* Check return value. */
|
||||||
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||||
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
|
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
|
||||||
if (common->abort_label == NULL)
|
if (common->abort_label == NULL)
|
||||||
add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
|
add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
|
||||||
else
|
else
|
||||||
JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->abort_label);
|
JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->abort_label);
|
||||||
return cc + callout_length;
|
return cc + callout_length;
|
||||||
|
@ -11544,15 +11544,13 @@ if (common->local_quit_available)
|
||||||
|
|
||||||
if (opcode == OP_SKIP_ARG)
|
if (opcode == OP_SKIP_ARG)
|
||||||
{
|
{
|
||||||
SLJIT_ASSERT(common->control_head_ptr != 0);
|
SLJIT_ASSERT(common->control_head_ptr != 0 && TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
|
|
||||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
|
||||||
|
|
||||||
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_R0, 0);
|
||||||
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
|
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, SLJIT_R0, 0, SLJIT_IMM, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12235,8 +12233,8 @@ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str))
|
||||||
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
|
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
|
||||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||||
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
|
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
|
||||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
|
||||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
||||||
|
|
||||||
|
@ -12465,20 +12463,23 @@ common->quit_label = quit_label;
|
||||||
set_jumps(common->stackalloc, LABEL());
|
set_jumps(common->stackalloc, LABEL());
|
||||||
/* RETURN_ADDR is not a saved register. */
|
/* RETURN_ADDR is not a saved register. */
|
||||||
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
|
|
||||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1);
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
|
||||||
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
|
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0);
|
||||||
OP2(SLJIT_SUB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
|
OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
|
||||||
|
OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
|
||||||
|
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||||
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
|
||||||
|
|
||||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
||||||
jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
|
||||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
|
||||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
|
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
|
||||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||||
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||||
|
|
||||||
/* Allocation failed. */
|
/* Allocation failed. */
|
||||||
JUMPHERE(jump);
|
JUMPHERE(jump);
|
||||||
|
|
|
@ -49,9 +49,9 @@ static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_f
|
||||||
sljit_u8 local_space[MACHINE_STACK_SIZE];
|
sljit_u8 local_space[MACHINE_STACK_SIZE];
|
||||||
struct sljit_stack local_stack;
|
struct sljit_stack local_stack;
|
||||||
|
|
||||||
local_stack.max_limit = local_space;
|
local_stack.min_start = local_space;
|
||||||
local_stack.limit = local_space;
|
local_stack.start = local_space;
|
||||||
local_stack.base = local_space + MACHINE_STACK_SIZE;
|
local_stack.end = local_space + MACHINE_STACK_SIZE;
|
||||||
local_stack.top = local_space + MACHINE_STACK_SIZE;
|
local_stack.top = local_space + MACHINE_STACK_SIZE;
|
||||||
arguments->stack = &local_stack;
|
arguments->stack = &local_stack;
|
||||||
return executable_func(arguments);
|
return executable_func(arguments);
|
||||||
|
|
|
@ -1353,56 +1353,52 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void);
|
||||||
|
|
||||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
||||||
|
|
||||||
/* The sljit_stack is a utility extension of sljit, which provides
|
/* The sljit_stack structure and its manipulation functions provides
|
||||||
a top-down stack. The stack top is stored in base and the stack
|
an implementation for a top-down stack. The stack top is stored
|
||||||
goes down to max_limit, so the memory region for this stack is
|
in the end field of the sljit_stack structure and the stack goes
|
||||||
between max_limit (inclusive) and base (exclusive). However the
|
down to the min_start field, so the memory region reserved for
|
||||||
application can only use the region between limit (inclusive)
|
this stack is between min_start (inclusive) and end (exclusive)
|
||||||
and base (exclusive). The sljit_stack_resize can be used to
|
fields. However the application can only use the region between
|
||||||
extend this region up to max_limit.
|
start (inclusive) and end (exclusive) fields. The sljit_stack_resize
|
||||||
|
function can be used to extend this region up to min_start.
|
||||||
|
|
||||||
This feature uses the "address space reserve" feature of modern
|
This feature uses the "address space reserve" feature of modern
|
||||||
operating systems, so instead of allocating a huge memory block
|
operating systems. Instead of allocating a large memory block
|
||||||
applications can allocate a small region and extend it later
|
applications can allocate a small memory region and extend it
|
||||||
without moving the memory area. Hence the region is never moved
|
later without moving the content of the memory area. Therefore
|
||||||
so pointers are valid after resize. */
|
after a successful resize by sljit_stack_resize all pointers into
|
||||||
|
this region are still valid.
|
||||||
|
|
||||||
/* Note: base and max_limit fields are aligned to PAGE_SIZE bytes
|
Note:
|
||||||
(usually 4 Kbyte or more).
|
this structure may not be supported by all operating systems.
|
||||||
Note: stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more.
|
end and max_limit fields are aligned to PAGE_SIZE bytes (usually
|
||||||
Note: this structure may not be supported by all operating systems.
|
4 Kbyte or more).
|
||||||
Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
|
stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more. */
|
||||||
is not defined. */
|
|
||||||
|
|
||||||
struct sljit_stack {
|
struct sljit_stack {
|
||||||
/* User data, anything can be stored here.
|
/* User data, anything can be stored here.
|
||||||
Starting with the same value as base. */
|
Initialized to the same value as the end field. */
|
||||||
sljit_u8 *top;
|
sljit_u8 *top;
|
||||||
/* These members are read only. */
|
/* These members are read only. */
|
||||||
sljit_u8 *base;
|
/* End address of the stack */
|
||||||
sljit_u8 *limit;
|
sljit_u8 *end;
|
||||||
sljit_u8 *max_limit;
|
/* Current start address of the stack. */
|
||||||
|
sljit_u8 *start;
|
||||||
|
/* Lowest start address of the stack. */
|
||||||
|
sljit_u8 *min_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Returns NULL if unsuccessful.
|
/* Allocates a new stack. Returns NULL if unsuccessful.
|
||||||
|
|
||||||
Note:
|
|
||||||
max_limit field contains the lower bound adress of the stack.
|
|
||||||
limit field contains the current starting address of the stack.
|
|
||||||
base field contains the end address of the stack.
|
|
||||||
top field is initialized to base.
|
|
||||||
|
|
||||||
Note: see sljit_create_compiler for the explanation of allocator_data. */
|
Note: see sljit_create_compiler for the explanation of allocator_data. */
|
||||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data);
|
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data);
|
||||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
|
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
|
||||||
|
|
||||||
/* Can be used to increase (allocate) or decrease (free) the memory area.
|
/* Can be used to increase (extend) or decrease (shrink) the stack
|
||||||
Returns with a non-zero value if unsuccessful. If new_limit is greater than
|
memory area. Returns with new_start if successful and NULL otherwise.
|
||||||
max_limit, it will fail. It is very easy to implement a stack data structure,
|
It always fails if new_start is less than min_start or greater or equal
|
||||||
since the growth ratio can be added to the current limit, and sljit_stack_resize
|
than end fields. The fields of the stack are not changed if the returned
|
||||||
will do all the necessary checks. The fields of the stack are not changed if
|
value is NULL (the current memory content is never lost). */
|
||||||
sljit_stack_resize fails. */
|
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start);
|
||||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_limit);
|
|
||||||
|
|
||||||
#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
|
#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,11 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg,
|
||||||
|
|
||||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
|
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
|
||||||
{
|
{
|
||||||
|
int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
|
||||||
|
|
||||||
/* The relative jump below specialized for this case. */
|
/* The relative jump below specialized for this case. */
|
||||||
SLJIT_ASSERT(reg_map[TMP_REG2] >= 8);
|
SLJIT_ASSERT(reg_map[TMP_REG2] >= 8);
|
||||||
|
|
||||||
int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
|
|
||||||
|
|
||||||
if (type < SLJIT_JUMP) {
|
if (type < SLJIT_JUMP) {
|
||||||
/* Invert type. */
|
/* Invert type. */
|
||||||
*code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
|
*code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
|
||||||
|
|
|
@ -203,7 +203,7 @@ static SLJIT_INLINE sljit_s32 open_dev_zero(void)
|
||||||
/* Planning to make it even more clever in the future. */
|
/* Planning to make it even more clever in the future. */
|
||||||
static sljit_sw sljit_page_align = 0;
|
static sljit_sw sljit_page_align = 0;
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data)
|
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
|
||||||
{
|
{
|
||||||
struct sljit_stack *stack;
|
struct sljit_stack *stack;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
@ -212,7 +212,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SLJIT_UNUSED_ARG(allocator_data);
|
SLJIT_UNUSED_ARG(allocator_data);
|
||||||
if (limit > max_limit || limit < 1)
|
if (start_size > max_size || start_size < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -234,25 +234,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
||||||
if (!stack)
|
if (!stack)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Align max_limit. */
|
/* Align max_size. */
|
||||||
max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
|
max_size = (max_size + sljit_page_align) & ~sljit_page_align;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
|
ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
SLJIT_FREE(stack, allocator_data);
|
SLJIT_FREE(stack, allocator_data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
stack->max_limit = (sljit_u8 *)ptr;
|
|
||||||
stack->base = stack->max_limit + max_limit;
|
stack->min_start = (sljit_u8 *)ptr;
|
||||||
stack->limit = stack->base;
|
stack->end = stack->min_start + max_size;
|
||||||
if (sljit_stack_resize(stack, stack->base - limit)) {
|
stack->start = stack->end;
|
||||||
|
|
||||||
|
if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
|
||||||
sljit_free_stack(stack, allocator_data);
|
sljit_free_stack(stack, allocator_data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef MAP_ANON
|
#ifdef MAP_ANON
|
||||||
ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
#else
|
#else
|
||||||
if (dev_zero < 0) {
|
if (dev_zero < 0) {
|
||||||
if (open_dev_zero()) {
|
if (open_dev_zero()) {
|
||||||
|
@ -260,17 +262,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||||
#endif
|
#endif
|
||||||
if (ptr == MAP_FAILED) {
|
if (ptr == MAP_FAILED) {
|
||||||
SLJIT_FREE(stack, allocator_data);
|
SLJIT_FREE(stack, allocator_data);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
stack->max_limit = (sljit_u8 *)ptr;
|
stack->min_start = (sljit_u8 *)ptr;
|
||||||
stack->base = stack->max_limit + max_limit;
|
stack->end = stack->min_start + max_size;
|
||||||
stack->limit = stack->base - limit;
|
stack->start = stack->end - start_size;
|
||||||
#endif
|
#endif
|
||||||
stack->top = stack->base;
|
stack->top = stack->end;
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,53 +282,50 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *st
|
||||||
{
|
{
|
||||||
SLJIT_UNUSED_ARG(allocator_data);
|
SLJIT_UNUSED_ARG(allocator_data);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
VirtualFree((void*)stack->max_limit, 0, MEM_RELEASE);
|
VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
|
||||||
#else
|
#else
|
||||||
munmap((void*)stack->max_limit, stack->base - stack->max_limit);
|
munmap((void*)stack->min_start, stack->end - stack->min_start);
|
||||||
#endif
|
#endif
|
||||||
SLJIT_FREE(stack, allocator_data);
|
SLJIT_FREE(stack, allocator_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_limit)
|
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
|
||||||
{
|
{
|
||||||
sljit_uw aligned_old_limit;
|
sljit_uw aligned_old_start;
|
||||||
sljit_uw aligned_new_limit;
|
sljit_uw aligned_new_start;
|
||||||
|
|
||||||
|
if ((new_start < stack->min_start) || (new_start >= stack->end))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if ((new_limit < stack->max_limit) || (new_limit >= stack->base))
|
|
||||||
return -1;
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
aligned_new_limit = (sljit_uw)new_limit & ~sljit_page_align;
|
aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
|
||||||
aligned_old_limit = ((sljit_uw)stack->limit) & ~sljit_page_align;
|
aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
|
||||||
if (aligned_new_limit != aligned_old_limit) {
|
if (aligned_new_start != aligned_old_start) {
|
||||||
if (aligned_new_limit < aligned_old_limit) {
|
if (aligned_new_start < aligned_old_start) {
|
||||||
if (!VirtualAlloc((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_COMMIT, PAGE_READWRITE))
|
if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!VirtualFree((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_DECOMMIT))
|
if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack->limit = new_limit;
|
|
||||||
return 0;
|
|
||||||
#else
|
#else
|
||||||
if (new_limit <= stack->limit) {
|
if (stack->start < new_start) {
|
||||||
stack->limit = new_limit;
|
aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
|
||||||
return 0;
|
aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
|
||||||
}
|
/* If madvise is available, we release the unnecessary space. */
|
||||||
aligned_new_limit = (sljit_uw)new_limit & ~sljit_page_align;
|
|
||||||
aligned_old_limit = ((sljit_uw)stack->limit) & ~sljit_page_align;
|
|
||||||
/* If madvise is available, we release the unnecessary space. */
|
|
||||||
#if defined(MADV_DONTNEED)
|
#if defined(MADV_DONTNEED)
|
||||||
if (aligned_new_limit > aligned_old_limit)
|
if (aligned_new_start > aligned_old_start)
|
||||||
madvise((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MADV_DONTNEED);
|
madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
|
||||||
#elif defined(POSIX_MADV_DONTNEED)
|
#elif defined(POSIX_MADV_DONTNEED)
|
||||||
if (aligned_new_limit > aligned_old_limit)
|
if (aligned_new_start > aligned_old_start)
|
||||||
posix_madvise((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, POSIX_MADV_DONTNEED);
|
posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
|
||||||
#endif
|
#endif
|
||||||
stack->limit = new_limit;
|
}
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
stack->start = new_start;
|
||||||
|
return new_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* SLJIT_UTIL_STACK */
|
#endif /* SLJIT_UTIL_STACK */
|
||||||
|
|
Loading…
Reference in New Issue