Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does JIT compilation in Java load dynamically compiled instructions into memory?

In Java, JVMs (e.g. HotSpot) are capable of JIT compilation and this technique is used to speed up execution by compiling bytecode into native code. My question is, how does this technically happen? My understanding was that modern processors mark memory areas into sections that are read-only, and sections that are executable in order to prevent malicious code from executing. So, the JVM can't really write new "executable code" into memory spaces that it has access to (i.e. self modifying code). So, I am guessing that the JVM produces native code, writes it into a file and then uses the operating systems services to dynamically load that native code into memory, and maintains some internal mapping table of the addresses of the native code (function) locations in memory after the operating system has loaded this dynamic code so it can branch out to those native instructions.

I did see this answer: How is JIT compiled code injected in memory and executed?, but I'm confused as to why operating systems would allow user programs READ+EXECUTE memory regions. Do other operating systems i.e. Linux etc offer something similar in order for JIT to work?

Can someone help clarify my understanding?

like image 273
rationalrevolt Avatar asked Jul 11 '13 04:07

rationalrevolt


People also ask

What is JIT compiler how does it execute a compiled Java program?

The JIT compiler is enabled by default, and is activated when a Java method is called. The JIT compiler compiles the bytecodes of that method into native machine code, compiling it "just in time" to run. When a method has been compiled, the JVM calls the compiled code of that method directly instead of interpreting it.

What does JIT during compilation process?

A Just-In-Time (JIT) compiler is a feature of the run-time interpreter, that instead of interpreting bytecode every time a method is invoked, will compile the bytecode into the machine code instructions of the running machine, and then invoke this object code instead.

Which instructions are typically compiled by a JIT compiler?

A JIT compiler runs after the program has started and compiles the code (usually bytecode or some kind of VM instructions) on the fly (or just-in-time, as it's called) into a form that's usually faster, typically the host CPU's native instruction set.

What does git do during compilation process in Java?

The Java programming language uses the compiler named javac. It converts the high-level language code into machine code (bytecode). JIT is a part of the JVM that optimizes the performance of the application. JIT stands for Java-In-Time Compiler.


1 Answers

In Linux, a memory segment can be set up to be writable and executable (and can be later changed on its protections). Look at the mmap(2) and mprotect(2) syscalls.

The JVM will probably produce machine code in memory, without using any disk files. Its JIT machinery probably just write bytes in executable memory.

Notice that the JVM might not want to change the generated machine code protection (it probably could generate all the machine code inside writable and executable memory segments), because since it is generating itself that code, it can be made sure to not doing nasty things (read about proof-carrying code).

Read the Just-in-time compilation and HotSpot and Virtual Memory wiki pages, and try strace-ing some java process...

Some JVMs are free software (e.g. the one inside OpenJdk), you could study their source code.

like image 80
Basile Starynkevitch Avatar answered Oct 23 '22 21:10

Basile Starynkevitch