Skip to content

Commit 106d9d3

Browse files
author
Zoltán Herczeg
committed
Improve memory clearing in JIT.
1 parent 3259082 commit 106d9d3

File tree

6 files changed

+56
-6
lines changed

6 files changed

+56
-6
lines changed

src/pcre2_jit_compile.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,13 +3048,50 @@ else
30483048
static SLJIT_INLINE void reset_fast_fail(compiler_common *common)
30493049
{
30503050
DEFINE_COMPILER;
3051+
sljit_s32 size = common->fast_fail_end_ptr - common->fast_fail_start_ptr;
3052+
sljit_s32 src = SLJIT_IMM;
30513053
sljit_s32 i;
3054+
struct sljit_label *loop;
30523055

30533056
SLJIT_ASSERT(common->fast_fail_start_ptr < common->fast_fail_end_ptr);
30543057

3055-
OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3056-
for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
3057-
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, TMP1, 0);
3058+
if (size == sizeof(sljit_sw))
3059+
{
3060+
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->fast_fail_start_ptr, SLJIT_IMM, 0);
3061+
return;
3062+
}
3063+
3064+
if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER))
3065+
{
3066+
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
3067+
src = TMP3;
3068+
}
3069+
3070+
if (size <= 6 * sizeof(sljit_sw))
3071+
{
3072+
for (i = common->fast_fail_start_ptr; i < common->fast_fail_end_ptr; i += sizeof(sljit_sw))
3073+
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), i, src, 0);
3074+
return;
3075+
}
3076+
3077+
GET_LOCAL_BASE(TMP1, 0, common->fast_fail_start_ptr);
3078+
3079+
i = ((size / (sljit_s32)sizeof(sljit_sw)) % 3) * sizeof(sljit_sw);
3080+
3081+
OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, size - i);
3082+
3083+
loop = LABEL();
3084+
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);
3085+
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
3086+
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -2 * (sljit_sw)sizeof(sljit_sw), src, 0);
3087+
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), -1 * (sljit_sw)sizeof(sljit_sw), src, 0);
3088+
CMPTO(SLJIT_LESS, TMP1, 0, TMP2, 0, loop);
3089+
3090+
if (i >= (sljit_sw)sizeof(sljit_sw))
3091+
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), 0, src, 0);
3092+
3093+
if (i >= 2 * (sljit_sw)sizeof(sljit_sw))
3094+
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), sizeof(sljit_sw), src, 0);
30583095
}
30593096

30603097
static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)

src/sljit/sljitLir.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,14 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
571571
#define SLJIT_HAS_FPU 0
572572
/* [Limitation] Some registers are virtual registers. */
573573
#define SLJIT_HAS_VIRTUAL_REGISTERS 1
574+
/* [Emulated] Has zero register (setting a memory location to zero is efficient). */
575+
#define SLJIT_HAS_ZERO_REGISTER 2
574576
/* [Emulated] Count leading zero is supported. */
575-
#define SLJIT_HAS_CLZ 2
577+
#define SLJIT_HAS_CLZ 3
576578
/* [Emulated] Conditional move is supported. */
577-
#define SLJIT_HAS_CMOV 3
579+
#define SLJIT_HAS_CMOV 4
578580
/* [Emulated] Conditional move is supported. */
579-
#define SLJIT_HAS_PREFETCH 4
581+
#define SLJIT_HAS_PREFETCH 5
580582

581583
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
582584
/* [Not emulated] SSE2 support is available on x86. */

src/sljit/sljitNativeMIPS_common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
684684
#else
685685
#error "FIR check is not implemented for this architecture"
686686
#endif
687+
case SLJIT_HAS_ZERO_REGISTER:
688+
return 1;
687689

688690
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
689691
case SLJIT_HAS_CLZ:

src/sljit/sljitNativePPC_common.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
626626
return 1;
627627
#endif
628628

629+
/* A saved register is set to a zero value. */
630+
case SLJIT_HAS_ZERO_REGISTER:
629631
case SLJIT_HAS_CLZ:
630632
case SLJIT_HAS_PREFETCH:
631633
return 1;

src/sljit/sljitNativeSPARC_common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
451451
return 1;
452452
#endif
453453

454+
case SLJIT_HAS_ZERO_REGISTER:
455+
return 1;
456+
454457
#if (defined SLJIT_CONFIG_SPARC_64 && SLJIT_CONFIG_SPARC_64)
455458
case SLJIT_HAS_CMOV:
456459
return 1;

src/sljit/sljitNativeX86_common.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2316,6 +2316,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
23162316
if (!HAS_FLAGS(op)) {
23172317
if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
23182318
return compiler->error;
2319+
if (SLOW_IS_REG(dst) && src2 == dst) {
2320+
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w));
2321+
return emit_unary(compiler, NEG_rm, dst, 0, dst, 0);
2322+
}
23192323
}
23202324

23212325
if (dst == SLJIT_UNUSED)

0 commit comments

Comments
 (0)