aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c49
1 files changed, 49 insertions, 0 deletions
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 ====="));