Using the code that it has just produced, the JIT::Compiler can build an
ELF image so that we can attach meaningful symbols to JITted code, and
thus enable GDB to display more information about the code that we're
running.
Instead of allocating these in a mixture of ways, we now always put
them on the malloc heap, and keep an intrusive linked list of them
that we can iterate for GC marking purposes.
If Interpreter::run_and_return_frame is called with a specific entry
point we now map that to a native instruction address, which the JIT
code jumps to after the function prologue.
The previous implementation was calling `backtrace()` for every
function call, which is quite slow.
Instead, this implementation provides VM::stack_trace() which unwinds
the native stack, maps it through NativeExecutable::get_source_range
and combines it with source ranges from interpreted call frames.
This works by walking a backtrace until the currently executing
native executable is found, and then mapping the native address
to its bytecode instruction.