aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/Makefile.dep2
-rw-r--r--src/lj_asm.c49
-rw-r--r--src/lj_target.h10
-rw-r--r--src/lj_target_x86.h4
4 files changed, 58 insertions, 7 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index 400ef8b0..fda77c83 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -55,7 +55,7 @@ lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
55 lj_buf.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h \ 55 lj_buf.h lj_str.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_ir.h \
56 lj_jit.h lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h \ 56 lj_jit.h lj_ircall.h lj_iropt.h lj_mcode.h lj_trace.h lj_dispatch.h \
57 lj_traceerr.h lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h \ 57 lj_traceerr.h lj_snap.h lj_asm.h lj_vm.h lj_target.h lj_target_*.h \
58 lj_emit_*.h lj_asm_*.h 58 lj_prng.h lj_emit_*.h lj_asm_*.h
59lj_assert.o: lj_assert.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h 59lj_assert.o: lj_assert.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h
60lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \ 60lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
61 lj_bcdef.h 61 lj_bcdef.h
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 71079b30..c02a1b9e 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -29,6 +29,7 @@
29#include "lj_dispatch.h" 29#include "lj_dispatch.h"
30#include "lj_vm.h" 30#include "lj_vm.h"
31#include "lj_target.h" 31#include "lj_target.h"
32#include "lj_prng.h"
32 33
33#ifdef LUA_USE_ASSERT 34#ifdef LUA_USE_ASSERT
34#include <stdio.h> 35#include <stdio.h>
@@ -93,6 +94,12 @@ typedef struct ASMState {
93 MCode *flagmcp; /* Pending opportunity to merge flag setting ins. */ 94 MCode *flagmcp; /* Pending opportunity to merge flag setting ins. */
94 MCode *realign; /* Realign loop if not NULL. */ 95 MCode *realign; /* Realign loop if not NULL. */
95 96
97#ifdef LUAJIT_RANDOM_RA
98 /* Randomize register allocation. OK for fuzz testing, not for production. */
99 uint64_t prngbits;
100 PRNGState prngstate;
101#endif
102
96#ifdef RID_NUM_KREF 103#ifdef RID_NUM_KREF
97 intptr_t krefk[RID_NUM_KREF]; 104 intptr_t krefk[RID_NUM_KREF];
98#endif 105#endif
@@ -173,6 +180,41 @@ IRFLDEF(FLOFS)
173 0 180 0
174}; 181};
175 182
183#ifdef LUAJIT_RANDOM_RA
184/* Return a fixed number of random bits from the local PRNG state. */
185static uint32_t ra_random_bits(ASMState *as, uint32_t nbits) {
186 uint64_t b = as->prngbits;
187 uint32_t res = (1u << nbits) - 1u;
188 if (b <= res) b = lj_prng_u64(&as->prngstate) | (1ull << 63);
189 res &= (uint32_t)b;
190 as->prngbits = b >> nbits;
191 return res;
192}
193
194/* Pick a random register from a register set. */
195static Reg rset_pickrandom(ASMState *as, RegSet rs)
196{
197 Reg r = rset_pickbot_(rs);
198 rs >>= r;
199 if (rs > 1) { /* More than one bit set? */
200 while (1) {
201 /* We need to sample max. the GPR or FPR half of the set. */
202 uint32_t d = ra_random_bits(as, RSET_BITS-1);
203 if ((rs >> d) & 1) {
204 r += d;
205 break;
206 }
207 }
208 }
209 return r;
210}
211#define rset_picktop(rs) rset_pickrandom(as, rs)
212#define rset_pickbot(rs) rset_pickrandom(as, rs)
213#else
214#define rset_picktop(rs) rset_picktop_(rs)
215#define rset_pickbot(rs) rset_pickbot_(rs)
216#endif
217
176/* -- Target-specific instruction emitter --------------------------------- */ 218/* -- Target-specific instruction emitter --------------------------------- */
177 219
178#if LJ_TARGET_X86ORX64 220#if LJ_TARGET_X86ORX64
@@ -2442,6 +2484,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
2442 as->realign = NULL; 2484 as->realign = NULL;
2443 as->loopinv = 0; 2485 as->loopinv = 0;
2444 as->parent = J->parent ? traceref(J, J->parent) : NULL; 2486 as->parent = J->parent ? traceref(J, J->parent) : NULL;
2487#ifdef LUAJIT_RANDOM_RA
2488 (void)lj_prng_u64(&J2G(J)->prng); /* Ensure PRNG step between traces. */
2489#endif
2445 2490
2446 /* Reserve MCode memory. */ 2491 /* Reserve MCode memory. */
2447 as->mctop = as->mctoporig = lj_mcode_reserve(J, &as->mcbot); 2492 as->mctop = as->mctoporig = lj_mcode_reserve(J, &as->mcbot);
@@ -2483,6 +2528,10 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
2483#endif 2528#endif
2484 as->ir = J->curfinal->ir; /* Use the copied IR. */ 2529 as->ir = J->curfinal->ir; /* Use the copied IR. */
2485 as->curins = J->cur.nins = as->orignins; 2530 as->curins = J->cur.nins = as->orignins;
2531#ifdef LUAJIT_RANDOM_RA
2532 as->prngstate = J2G(J)->prng; /* Must (re)start from identical state. */
2533 as->prngbits = 0;
2534#endif
2486 2535
2487 RA_DBG_START(); 2536 RA_DBG_START();
2488 RA_DBGX((as, "===== STOP =====")); 2537 RA_DBGX((as, "===== STOP ====="));
diff --git a/src/lj_target.h b/src/lj_target.h
index 2f4d21c1..09d19bd9 100644
--- a/src/lj_target.h
+++ b/src/lj_target.h
@@ -57,8 +57,10 @@ typedef uint32_t RegSP;
57*/ 57*/
58#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64 58#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64
59typedef uint64_t RegSet; 59typedef uint64_t RegSet;
60#define RSET_BITS 6
60#else 61#else
61typedef uint32_t RegSet; 62typedef uint32_t RegSet;
63#define RSET_BITS 5
62#endif 64#endif
63 65
64#define RID2RSET(r) (((RegSet)1) << (r)) 66#define RID2RSET(r) (((RegSet)1) << (r))
@@ -70,11 +72,11 @@ typedef uint32_t RegSet;
70#define rset_clear(rs, r) (rs &= ~RID2RSET(r)) 72#define rset_clear(rs, r) (rs &= ~RID2RSET(r))
71#define rset_exclude(rs, r) (rs & ~RID2RSET(r)) 73#define rset_exclude(rs, r) (rs & ~RID2RSET(r))
72#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64 74#if LJ_TARGET_PPC || LJ_TARGET_MIPS || LJ_TARGET_ARM64
73#define rset_picktop(rs) ((Reg)(__builtin_clzll(rs)^63)) 75#define rset_picktop_(rs) ((Reg)(__builtin_clzll(rs)^63))
74#define rset_pickbot(rs) ((Reg)__builtin_ctzll(rs)) 76#define rset_pickbot_(rs) ((Reg)__builtin_ctzll(rs))
75#else 77#else
76#define rset_picktop(rs) ((Reg)lj_fls(rs)) 78#define rset_picktop_(rs) ((Reg)lj_fls(rs))
77#define rset_pickbot(rs) ((Reg)lj_ffs(rs)) 79#define rset_pickbot_(rs) ((Reg)lj_ffs(rs))
78#endif 80#endif
79 81
80/* -- Register allocation cost -------------------------------------------- */ 82/* -- Register allocation cost -------------------------------------------- */
diff --git a/src/lj_target_x86.h b/src/lj_target_x86.h
index 7b8d62ad..3482309b 100644
--- a/src/lj_target_x86.h
+++ b/src/lj_target_x86.h
@@ -116,8 +116,8 @@ enum {
116 116
117#if LJ_64 117#if LJ_64
118/* Prefer the low 8 regs of each type to reduce REX prefixes. */ 118/* Prefer the low 8 regs of each type to reduce REX prefixes. */
119#undef rset_picktop 119#undef rset_picktop_
120#define rset_picktop(rs) (lj_fls(lj_bswap(rs)) ^ 0x18) 120#define rset_picktop_(rs) (lj_fls(lj_bswap(rs)) ^ 0x18)
121#endif 121#endif
122 122
123/* -- Spill slots --------------------------------------------------------- */ 123/* -- Spill slots --------------------------------------------------------- */