Hello! Andy Wingo <wi...@pobox.com> skribis:
> The news is that the VM has been completely converted over to call out > to the Guile runtime through an "intrinsics" vtable. For some > intrinsics, the compiler will emit specialized call-intrinsic opcodes. > (There's one of these opcodes for each intrinsic function type.) For > others that are a bit more specialized, like the intrinsic used in > call-with-prompt, the VM calls out directly to the intrinsic. > > The upshot is that we're now ready to do JIT compilation. JIT-compiled > code will use the intrinsics vtable to embed references to runtime > routines. In some future, AOT-compiled code can keep the intrinsics > vtable in a register, and call indirectly through that register. Exciting! It sounds like a really good strategy because it means that the complex instructions don’t have to be implemented in lightning assembly by hand, which would be a pain. > My current plan is that the frame overhead will still be two slots: the > saved previous FP, and the saved return address. Right now the return > address is always a bytecode address. In the future it will be bytecode > or native code. Guile will keep a runtime routine marking regions of > native code so it can know if it needs to if an RA is bytecode or native > code, for debugging reasons; but in most operation, Guile won't need to > know. The interpreter will tier up to JIT code through an adapter frame > that will do impedance matching over virtual<->physical addresses. To > tier down to the interpreter (e.g. when JIT code calls interpreted > code), the JIT will simply return to the interpreter, which will pick up > state from the virtual IP, SP, and FP saved in the VM state. What will the “adapter frame” look like? > We do walk the stack from Scheme sometimes, notably when making a > backtrace. So, we'll make the runtime translate the JIT return > addresses to virtual return addresses in the frame API. To Scheme, it > will be as if all things were interpreted. Currently you can inspect the locals of a stack frame. Will that be possible with frames corresponding to native code? (I suppose that’d be difficult.) > My current problem is knowing when a callee has JIT code. Say you're in > JITted function F which calls G. Can you directly jump to G's native > code, or is G not compiled yet and you need to use the interpreter? I > haven't solved this yet. "Known calls" that use call-label and similar > can of course eagerly ensure their callees are JIT-compiled, at > compilation time. Unknown calls are the problem. I don't know whether > to consider reserving another word in scm_tc7_program objects for JIT > code. I have avoided JIT overhead elsewhere and would like to do so > here as well! In the absence of a native code pointer in scm_tc7_program objects, how will libguile find the native code for a given program? Thanks for sharing this plan! Good times ahead! Ludo’.