Skip to content

How to debug the JIT

Unknown W. Brackets edited this page Mar 25, 2018 · 2 revisions

by @unknownbrackets.

(TODO: These are ARM64-specific instructions, can be easily adapted to the other archs).

First you'll need to build it. Hopefully installing Android Studio and the Android NDK works as per the build instructions.

After that, we want to find which instruction is misbehaving. It could be other things, so step 1 is validating this assumption.

In Arm64CompVFPU.cpp you'll see these two lines:

// #define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; }
#define CONDITIONAL_DISABLE ;

Remove "// " from the first one, and put it on the second one instead. This disables all the instructions in the file.

Next, do the same thing in Arm64CompLoadStore.cpp, Arm64CompFPU.cpp, and Arm64CompALU.cpp. Now compile and run - it should be much slower. If the bug doesn't happen, that's a good sign. If it does, time to abort - we're chasing our tail here.

Assuming it was one of those, the next thing to do is narrow down which file. Arm64CompVFPU.cpp is probably most likely, so try undoing the change in the three other files. when you run it this time, it should be much faster. If the bug doesn't happen, it's in that file. If it does happen, then try the other files one by one.

Once you find the file it's in, the next step is finding which function it is. Doing that one by one would take forever, so we'll bisect instead.

Start with the change at the top of the file (so the longer version of CONDITONAL_DISABLE is enabled, and the short one is commented out with //.) Go about halfway down, and look for something like void Arm64Jit::Comp_Vmtvc(MIPSOpcode op) { (the Vmtvc part will differ.) Put this right above it:

#undef CONDITIONAL_DISABLE
#define CONDITIONAL_DISABLE ;

This way we've only disabled the first half of the file. If the bug doesn't happen, it must be somewhere in the first half, so move it up to 1/4 of the file or so, and try again. If the bug does happen, it must be in the lower half, so move it downward to 3/4.

Eventually, you'll find the one function that changes things. It's possible multiple might be involved, so to validate this: undo the changes in the file again, and then put this around the function:

#undef CONDITIONAL_DISABLE
#define CONDITIONAL_DISABLE { fpr.ReleaseSpillLocksAndDiscardTemps(); Comp_Generic(op); return; }

	void Arm64Jit::Comp_SOMETHING(MIPSOpcode op) {
		...
		...
	}

#undef CONDITIONAL_DISABLE
#define CONDITIONAL_DISABLE ;

If the bug is still gone, then we have a good lead on where the bug likely is. It could still be a more complicated register cache bug, but I'm hoping it's just a buggy VFPU instruction.

-[Unknown]