1
$\begingroup$

I am trying to understand the lifetime of a procedure, from source code through to being compiled to machine code and being called. I am specifically interested in the context of "live" environments, where (re)compilation can happen at any point during runtime and the new code is seamlessly integrated into an already running program. Good examples of such systems are the SBCL Common Lisp implementation and the live coding language/environment Extempore, meant for live music or otherwise creative performance through live coding.

When a runtime supports the ability to (re)compile a procedure and hot-swap the old version with the new, I assume that involves changing a function pointer to point from one implementation to another. That must mean that the compiled function (in its machine-code form) is simply a sequence of bytes in memory.

That must also mean that the current process must have access to the memory that holds the compiled function. In the case where the compiler lives in the same process, that seems to be straight-forward, as the process already has access to the compiled code data. In the case where the compiler is an external process, the resulting data would somehow have to be loaded. Is that the same thing as dynamically linking with a pre-compiled library object, or is the process a fundamentally different one?

Lastly, what are the steps required to be able to get to a minimal PoC program like the one in the following C++ pseudocode?

// The type that the dynamically compiled procedure will have
using FooType = std::function<int(int)>;

// Assuming that the source code is valid, 
// this would return a pointer to compiled machine code
FooType* compile_footype_proc(std::string source_code) {...}

int main()
{
    FooType* foo;
    
    while (!should_exit())
    {
        // Get some source, compile it, and call it
        std::string user_provided_source = getline();
        foo = compile_footype_proc(user_provided_source);
        cout << "The result is: " << foo(5) << endl;
    }
    return 0;
}

Any resources to learn more about this?

$\endgroup$
2
  • $\begingroup$ I don't understand what your second question is asking. I suggest asking it separately and explain in more detail what you are asking. I don't know what you mean by "get a minimal PoC program like ...", and I'm not sure what kind of answer you are hoping for. $\endgroup$
    – D.W.
    Feb 22 at 5:11
  • $\begingroup$ Wikipedia is your best friend. en.wikipedia.org/wiki/Just-in-time_compilation $\endgroup$ Mar 24 at 8:30

1 Answer 1

-1
$\begingroup$

You asked two questions. The usual rule is to ask only one question per post, so I'll answer your first question.

JIT compilers normally run in the same process as the code that has been compiled, so the issues you identify with loading/linking don't normally arise.

$\endgroup$
2
  • $\begingroup$ Thanks for the answer. I would argue that I asked one question, which is the question clearly stated in the title: "How does JIT-ing work"? Since that on its own is rather broad, I narrowed it down through two example sub-questions about things I would like the answer to touch upon. Your choice to answer only the first is exactly that, a choice. Also, you didn't really answer that question anyway, which was clearly stated as "is the process of loading external JIT compiled code the same as dynamic linking or not?". $\endgroup$
    – Dimitris
    Feb 21 at 23:07
  • $\begingroup$ @Dimitris, "How does JIT-ing work?" is too broad and would not be allowed here. Unfortunately, this site doesn't work well for that kind of question. What can work is to do research and reading on JIT, then identify some specific questions and ask those. $\endgroup$
    – D.W.
    Feb 22 at 5:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.