@@ -252,8 +252,8 @@ void IRJit::RunLoopUntil(u64 globalticks) {
252
252
while (mips->downcount >= 0 ) {
253
253
u32 inst = Memory::ReadUnchecked_U32 (mips->pc );
254
254
u32 opcode = inst & 0xFF000000 ;
255
- u32 offset = inst & 0x00FFFFFF ;
256
255
if (opcode == MIPS_EMUHACK_OPCODE) {
256
+ u32 offset = inst & 0x00FFFFFF ; // Alternatively, inst - opcode
257
257
mips->pc = IRInterpret (mips, blocks_.GetArenaPtr () + offset);
258
258
// Note: this will "jump to zero" on a badly constructed block missing exits.
259
259
if (!Memory::IsValid4AlignedAddress (mips->pc )) {
@@ -297,13 +297,43 @@ void IRBlockCache::Clear() {
297
297
arena_.shrink_to_fit ();
298
298
}
299
299
300
+ IRBlockCache::IRBlockCache () {
301
+ // For whatever reason, this makes things go slower?? Probably just a CPU cache alignment fluke.
302
+ // arena_.reserve(1024 * 1024 * 2);
303
+ }
304
+
300
305
int IRBlockCache::GetBlockNumFromOffset (int offset) const {
306
+ // Block offsets are always in rising order (we don't go back and replace them when invalidated). So we can binary search.
307
+ int low = 0 ;
308
+ int high = (int )blocks_.size () - 1 ;
309
+ int found = -1 ;
310
+ while (low <= high) {
311
+ int mid = low + (high - low) / 2 ;
312
+ const int blockOffset = blocks_[mid].GetInstructionOffset ();
313
+ if (blockOffset == offset) {
314
+ found = mid;
315
+ break ;
316
+ }
317
+ if (blockOffset < offset) {
318
+ low = mid + 1 ;
319
+ } else {
320
+ high = mid - 1 ;
321
+ }
322
+ }
323
+
324
+ #ifndef _DEBUG
325
+ // Then, in debug builds, cross check the result.
326
+ return found;
327
+ #else
301
328
// TODO: Optimize if we need to call this often.
302
329
for (int i = 0 ; i < (int )blocks_.size (); i++) {
303
330
if (blocks_[i].GetInstructionOffset () == offset) {
331
+ _dbg_assert_ (i == found);
304
332
return i;
305
333
}
306
334
}
335
+ #endif
336
+ _dbg_assert_ (found == -1 );
307
337
return -1 ;
308
338
}
309
339
@@ -377,12 +407,13 @@ int IRBlockCache::FindByCookie(int cookie) {
377
407
if (blocks_[0 ].GetTargetOffset () < 0 )
378
408
return GetBlockNumFromOffset (cookie);
379
409
410
+ // TODO: Now that we are using offsets in pure IR mode too, we can probably unify
411
+ // the two paradigms. Or actually no, we still need two offsets..
380
412
for (int i = 0 ; i < GetNumBlocks (); ++i) {
381
413
int offset = blocks_[i].GetTargetOffset ();
382
414
if (offset == cookie)
383
415
return i;
384
416
}
385
-
386
417
return -1 ;
387
418
}
388
419
0 commit comments