diff options
author | Mike Pall <mike> | 2023-08-30 01:10:52 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2023-08-30 01:10:52 +0200 |
commit | 41fb94defa8f830ce69a8122b03f6ac3216d392a (patch) | |
tree | 0c66d794528b585a138f4aea5e598f1d0bbcfd4e /src/lj_asm.c | |
parent | 2f6c451ce8db5b5bc88126c9856e15f25fd5beae (diff) | |
download | luajit-41fb94defa8f830ce69a8122b03f6ac3216d392a.tar.gz luajit-41fb94defa8f830ce69a8122b03f6ac3216d392a.tar.bz2 luajit-41fb94defa8f830ce69a8122b03f6ac3216d392a.zip |
Add randomized register allocation for fuzz testing.
This must be explicitly enabled with: -DLUAJIT_RANDOM_RA
Thanks to Peter Cawley. #1062
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 49 |
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. */ | ||
185 | static 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. */ | ||
195 | static 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 =====")); |