I suppose this is only tangentially related to lisp, but I thought about
it while watching sbcl recompile mcclim for the (+ n 1)th time.
How does dynamic compilation work with modern processors (and OS's)? In
assembly, on simple processors, I've written to a series of memory
locations and then jumped to the first one (shazam-- data becomes code).
Allowing that as a process running on an OS I would have to stay within
allocated memory, is the process above sufficient to load (and run)
dynamically compiled code on these new-fangled PCs.
Thanks,
Matt
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.
Matthew D Swank wrote:
> I suppose this is only tangentially related to lisp, but I thought about
> it while watching sbcl recompile mcclim for the (+ n 1)th time.
>
> How does dynamic compilation work with modern processors (and OS's)?
There is nothing mystical about dynamic compilation.
Typing ``cc *.c'' in your Unix shell command line and then typing
``./a.out'' is a kind of dynamic compilation. You are creating a
machine language executable within the environment, loading it and
running it.
> In assembly, on simple processors, I've written to a series of memory
> locations and then jumped to the first one (shazam-- data becomes code).
Or you can write a file according to the executable or shared library
format and use a system call like exec(), dlopen(), LoadLibrary(),
CreateProcessEx() or whatever.
Data becomes code, yes: that's the Von Neumann general idea. :)
The one thing you have to watch out for is having stale data in the
instruction caches. Processors that have separate caches for
instruction and data typically don't keep them coherent. It would be a
waste of circuitry to snoop whether data writes affect anything in the
instruction cache.
So before you jump to code that has been poked into memory, you have to
be sure that the instruction cache has nothing stale corresponding to
any part of that memory, and the simplest way to do that is to simply
invalidate the whole thing before jumping to the new code.
On some architectures, the memory management hardware is capable of
execute-protecting pages, so that's another thing you have to take care
of: the pages where you allocate code have to be marked executable in
the page tables.
On Wed, 30 Nov 2005 23:29:14 -0800, Kaz Kylheku wrote:
> Typing ``cc *.c'' in your Unix shell command line and then typing
> ``./a.out'' is a kind of dynamic compilation. You are creating a
> machine language executable within the environment, loading it and
> running it.
>
...
> Or you can write a file according to the executable or shared library
> format and use a system call like exec(), dlopen(), LoadLibrary(),
> CreateProcessEx() or whatever.
>
Yes. Mostly I was thinking about Lisp environments that load code
into an existing process.
For Lisps that use a VM of course, this is not an issue; all "code"
is data to be processed by the machine interpreter (unless the byte-code
is then JITed).
Matt
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.
On 9310 day of my life Matthew D. Swank wrote:
> How does dynamic compilation work with modern processors (and OS's)? In
> assembly, on simple processors, I've written to a series of memory
> locations and then jumped to the first one (shazam-- data becomes code).
You can use basically same approach, but you have to inform OS that
particular chunk of memory is code:
mprotect(addr, len, PROT_READ | PROT_WRITE | PROT_EXEC);
^^^^
(This is for POSIX OSes -- Linux, *BSD, Solaris etc.)
--
Ivan Boldyrev
Life! Don't talk to me about life.