What is OOL (Out of line) code? I've found it in ION compiler but can't understand what is going on.
bool CodeGeneratorShared::generateOutOfLineCode() {
for (size_t i = 0; i < outOfLineCode_.length(); i++) {
// Add native => bytecode mapping entries for OOL sites.
// Not enabled on asm.js yet since asm doesn't contain bytecode mappings.
if (!gen->compilingAsmJS()) {
if (!addNativeToBytecodeEntry(outOfLineCode_[i]->bytecodeSite()))
return false;
}
if (!gen->alloc().ensureBallast())
return false;
JitSpew(JitSpew_Codegen, "# Emitting out of line code");
masm.setFramePushed(outOfLineCode_[i]->framePushed());
lastPC_ = outOfLineCode_[i]->pc();
outOfLineCode_[i]->bind(&masm);
outOfLineCode_[i]->generate(this);
}
return !masm.oom();
}
I've tried to use google to found information about it, but didn't have a success. Maybe you can give me some idea what it is? Thank you :)
I looked into the source, and it seems that "out of line" here means code that's generated after the normal code/function.
See e.g. CodeGenerator::generate
basically looks like this:
generateProlog();
generateBody();
generateEpilog();
generateOutOfLineCode();
So out of line code is generated after the code's end. This is often used for exceptional control flow and to keep the code that invokes deoptimization, throws exception, etc. out of the instruction cache and the "normal" program code.
Let's assume we have a function int f(int a, int b) { return a / b; }
and the languages semantics force us to throw an Exception if the divisor is 0. This is the code in pseudo assembly:
cmp b, 0
jump-if-not-zero lbl1
call throw_exception
lbl1:
div c, a, b
ret c
You can see that normal program flow needs to jump over the code that throws the exception. Usually b is non-zero in almost all cases so that seems kind of wasteful. With out of line code we can generate more efficient code:
cmp b, 0
jump-if-zero out-of-line1
div c, a, b
ret c
out-of-line1:
call throw_exception
Here we only jump for zero values which should be rare. The cmp
and div
instruction are also nearer to each other which is good for instruction cache usage.
In my JIT I am generating out of line code for null pointer exception throwing, failing asserts, etc. JS and IonMonkey may use it for different operations. One example for out of line code I've found is class OutOfLineTruncateF32OrF64ToI32
for WASM, that extends OutOfLineCode
the base class of all out of line code.
What's also nice is that out of line code in IonMonkey can use the field rejoin
to jump back to normal code flow.