Send
Close Add comments:
(status displays here)
Got it! This site "robinsnyder.com" uses cookies. You consent to this by clicking on "Got it!" or by continuing to use this website. Note: This appears on each machine/browser from which this site is accessed.
Compiler generated code: introduction
1. Compiler code
In the old days, a compiler would generate assembly or binary machine code.
For many years now, most compilers generate an intermediate code that can then be converted to binary machine code or run by a fast virtual machine interpreter.
2. Compilers
Suppose one has the following.
n programming languages
m target machines
To have each of
n programming language compile and run on each of
m target machines takes
n*m compilers.
For 4 programming languages and 4 target machines, this is 16 compilers with target machine code generation.
For 10 programming languages and 10 target machines, this is 100 compilers with target machine code generation.
3. Intermediate representations
A compromise is as follows.
Create an intermediate representation code.
Create a compiler for each language to that intermediate code.
Create a intermediate code interpreter or code generation for each target machine.
4. Improvement
The improvement is as follows.
For 4 programming languages and 4 target machines, this is 4 compilers and 4 target machine interpreters
For 10 programming languages and 10 target machines, this is 10 compilers and 10 target machine interpreters.
5. Intermediate codes
Some of these intermediate code machines include the following.
UCSD Pascal (1970's which influenced others used what was called P-Code)
Java byte-code machine, the JVM (Java Virtual Machine)
DotNet byte-code machine, the CLR (Common Language Runtime)
Python byte-code
Lua byte-code
... and so on ...
6. Just in time compiling
A compiler translates a programmer-friendly source program into a machine-friendly object program that can be executed on a computer.
Traditional compilers generate code for a processor (e.g., microprocessor).
C++ to Pentium
C++ to PowerPC
C++ to ...
JIT (Just In Time) compilers generate an abstract intermediate byte code that is compiled on-the-fly as it is needed for the architecture that the code is running on.
Java -> int. code -> Pentium
.NET -> int. code -> Pentium
The Java
JIT compiler compiles the Java byte-codes as they are received into binary machine code that executes faster than the interpreted Java byte-codes.
What is the Java JIT compiler and why is it important?
JIT compilers have allowed the compiled code of programming languages such as Java to be both portable and fast when compared to traditional compiled code which will run only on one particular platform (i.e., processor and operating system).
7. Java object code
We use the javac compiler to transform java source text (legible) code in a java file to java object (illegible) code in a class file.
We can use the javap disassembler to see a text representation of the java class file.
8. Common Language Runtime
In the .NET architecture, source code is compiled to an intermediate code called
MSIL (Microsoft Intermediate Language), also called
meta-data. The meta-data approach avoids the need for information stored in the registry.
In the .NET architecture the
CLR manages the code for the system. When requested, the CLR compiles the intermediate code to binary code for the processor on which the code will run. This concept is called
managed code. Code run outside of the CLR is called
unmanaged code.
The CLR is similar in principle to the
JVM which uses a
JIT compiler.
9. C statements
In the original C language, and many languages that have C-like syntax, there are (at least) three ways to increment a variable (by
1). Assume the variable is an integer called
count1. Here are three ways.
count1++;
count1 += 1;
count1 = count1 + 1;
10. Code increments
One sometimes wants to look at the generated code to see how statements might be written to run faster (i.e, by taking fewer statements)
Here is the Java code [#1]
Here is the output of the Java code.
11. Generated code
From the relevant generated code, we see the following. Here is the Java source code fragment.
count1++;
count1 += 1;
count1 = count1 + 1;
Here is the generated byte-code separated into groups for each source code statement.
// count1++
6: iinc 1, 1
// count1 += 1;
9: iinc 1, 1
// count1 = count1 + 1;
12: iload_1
13: iconst_1
14: iadd
15: istore_1
The first two source code statements generate the same code. The last one generates more code - involving a load and a store. (Some compilers would improve the generated code).
12. Python example
Python does not have the "++" increment operator.
Here is the Python code [#1]
Here is the output of the Python code.
The code appears to be the same size but has two different instructions.
13. Python example
Let us see how Python compiles an arithmetic expression.
Here is the Python code [#2]
The code compiles to and is evaluated by a postfix stack machine.
Here is the output of the Python code.
14. Disassembly of code
Below is a counting loop example in Python using a while loop inside a routine called countFromTo1.
The dis module allows disassembly and output of Python byte code from within Python.
15. Disassembly of code
Such disassembly is useful for a number of reasons.
One can see the code being generated.
One can improve the generated target code by changing the source code.
One can identify parts of code that are taking a lot of time to run (details omitted).
16. Python example
Here is the Python code [#3]
Here is the output of the Python code.
17. Reflection
The programming language term "reflection" is used when a program uses code to look at itself, as in the above Python example.
18. Java example
Here is the Java code [#2]
Here is the output of the Java code.
19. Disassembly of code
Below is the disassembled Java byte code.
The Java source file is goto13_01.java
The target class file is goto13_01.class (input for javap)
The disassembled text file goto13_01.txt (output of javap)
The command is as follows (assuming proper paths) and using pipes at the command line.
javap < goto13_01.class >! goto13_01.txt
20. End of page