Yevano/JVML-JIT — pull request #51 by ElvishJerricco (2014-11-19 10:55:00+00:00)
Title: Closes #47

I wanted to put this up for review before putting it on the master branch. There are four new functions added in jit.lua
```lua
setRegisterNullCheck(register, boolean)
getRegisterNullCheck(register)
setRegisterNullCheckParent(register, register)
getRegisterNullCheckParent(register)
```
There are two tables dealing with null check data. The registerNullChecks table relates registers with whether that register has been checked for null or not. The registerNullChecksParents table relates registers with a register lower on the stack that it was created from. The parents table lets us set null check data on all registers from top to bottom that share the same object.

Also, whenever a register is freed, its null check data is automatically wiped. Aside from this, all the null check stuff has to be done manually. Forgetting to include code in an instruction for null checking could prove disastrous, creating bugs that could be *very* hard to track down.

However, I ran some numbers on this change, attempting to measure performance changes. Here are the results.
```
trials without smart null checking {
(emit time, compile time)
7.8, 8.85
8.15, 9.05
7.8, 9.35
7.75, 8.95
7.95, 9.25
}
tests.jar compiled to 69121 lines in the debug file

average emit time = 7.89
average compile time = 9.09
average total time = 16.98

trials with smart null checking {
(emit time, compile time)
7.05, 6.75
7.1, 7.2
6.95, 7.15
7, 7.05
7.05, 7.05
}
tests.jar compiled to 55365 lines in the debug file

average emit time = 7.03
average compile time = 7.04
average total time = 14.07

percent difference in number of lines = 20%
percent difference in emit+compile time = 17%
```

I didn't measure the performance gains in runtime performance, but the change in number of instructions emitted and time spent compiling is significant enough.