I have a question on the LLVM JIT
I did some brief memory reading one day and I found that a call to a non-library function is resolved by the X86CompilationCallback, but the X86CompilationCallback is reached through a trampoline. why can not the generated code jump to the X86CompilationCallback function directly ?
0x2b0a6a4d103b: mov $0x2b0a6a561010,%rax
0x2b0a6a4d1045: callq *%rax // call foo
The address of the callee may be more than 2 GB away in memory, which
cannot be encoded as an immediate offset in the call instruction. So,
the value is first materialized with a mov instruction which can
encode the immediate and then jumped to through a register.
I understand that we need to push the address to a register then branch using the register. But i am asking why there is a trampoline there such that a call to foo is first branched to an snippet and the snippet branches to the X86CompilationCallback. is this snippet necessary ?
This is to support lazy compilation, so that when a new function is
invoked it is codegen'd and the trampoline is hotpatched to jump to
the new code. This way all the callsites don't have to be updated.