Java Virtual Machine

powered by FreeFind

Modified: 

ONLINE RESOURCES

DOWNLOAD RESOURCES

OVERVIEW

The Java Virtual Machine (JVM) is an abstract computing machine based on a stack-oriented architecture with method access to a single, current frame.

Operands are on the stack, for example: 27 - 4

    


   Stack    
     
   
TOS  
21
34
15
  bipush 27
  bipush 4

    Stack  
     
   
   
   
TOS  
21
34
15
27
4
  isub


   Stack   
 
 
 
TOS
21
34
15
23

The following set of examples illustrate the organization of the JVM and the form code generation must produce in order to be compatible for execution. The approach will be to present Java source code and the corresponding assembly code for the JVM.

Two tools are very useful for our task of generating correct assembly code:

The JVM implements a pure stack-based architecture - generally there are no accessible registers, only access to the stack and the frame of the currently executing method.

It is important to recognize that stack and frame frame operations are independent; stack operations do not affect the frame except when moving data between the two.

      Frame  
this    0
  1
  2
  3
  4
21
34
15
-4
27
   Stack   
 
 
 
 
TOS
21
34
15
-4
27
Memory   
19
20
21
22
23
45
98
105
62
111

Stack and frame operations include:

Exercise - What is the result of each of the above on the Stack?

Exercise - What is the significance of this in object-oriented programming?

 

STACKS and FRAMES

A key insight is that the stack of the caller is the frame of the callee (at least the parameter portion) when a method is called.

Consider the following example in Java and the corresponding JVM assembly:

Caller Callee
new B().m(11, 12); class B {
   void m(int a, int b) { }
                                     Caller Stack
new B                             
bipush            11
bipush            12

invokevirtual   B/m(II)V
reference to B object
11
12
                                 Callee Frame
this                            
a            11
b            12
 
0 reference to B object
1 11
2 12

Another example illustrates the interaction between methods using the stack to return results. The callee always leaves a method result at the TOS for the caller.

Caller Callee
int x;
x = new B().m(11, 12);
class B {
   int m(int a, int b) { return 13; }
                                     Caller Stack before call
new B                             
bipush            11
bipush            12

invokevirtual   B/m(II)I
reference to B object
11
12

Caller Stack after call

 
13
TOS
                     Callee Frame
this
a            11    
b            12
0 reference to B object
1 11
2 12
 
                    Callee Stack
.method public m(II)I    
   bipush   13   
   ireturn
.end method 
 
13

TOS

Exercise - What does the following mean?

  1. .method public m(II)I
  2. invokevirtual   C/m(II)I
  3. bipush   13
  4. ireturn

Example - Accessing a parameter.

Frame and parameter passing: note that method stack operations do not affect frame references of that method.

  1. public class ex1 {
  2.     public static void main(String [] args) {
  3.        new ex2().f2( 100 );
  4.     }
  5. }
  1. class ex2 {
  2.    public void f2( int n ) {           
  3.        int i;
  4.        i = n;
  5.    }
  6. }
Frame
0 this = ex2
1 n = 100
2 i
  1. .source ex1.java
  2. .class public ex1
  3. .super java/lang/Object
     
  4. .method public <init>()V
  5. .limit stack 1
  6. .limit locals 1
  7. .line 1
  8.    aload_0                                ; 'this'
  9.    invokespecial java/lang/Object/<init>()V 
  10.    return
  11.  .end method
     
  12.  .method public static main([Ljava/lang/String;)V
  13.  .limit stack 2
  14.  .limit locals 1                            ;    STACK
  15.  .line 3                                     ;  ____________
  16.     new ex2                               ; | ex2 reference |
  17.     dup                                     ; | ex2 reference |
  18.     invokespecial ex2/<init>()V    ;  ____________
  19.     bipush  100                        ; | ex2 reference |
  20.     invokevirtual ex2/f2(I)V         ;| 100                |
     .line 4
  21.     return                                
  22.  .end method
  1.  .source ex1.java
  2.  .class ex2
  3.  .super java/lang/Object
     
  4.  .method <init>()V
  5.  .limit stack 1
  6.  .limit locals 1
  7.  .line 7
  8.    aload_0
  9.    invokespecial java/lang/Object/<init>()V
  10.    return
  11.  .end method
     
  12.  .method public f2(I)V
  13.  .limit stack 1
  14.  .limit locals 3
  15.  .line 9
  16.    iload_1                       ; n -> TOS
  17.    istore_2                      ; TOS -> i
  18.  .line 10
  19.    return
  20.  .end method
 

Exercise - What does the following mean?

  1. dup
  2. .limit stack 2
  3. istore 2
  4. iload 1

Exercise - Explain in .method public f2(I)V

  1. .limit stack 1
  2. .limit locals 3

 

Instance variables - instance variables (fields) are not part of the frame or stack but are accessed by this and field name.

Example - Returning a result and instance variables (fields).

  1.        aload_0                               ; this
  2.        iload_2                                ; m
  3.        putfield              ex2/j I    ; j = m

Recall that this is at frame offset 0, and m at offset 2.

Where the return value is at TOS.

  1. public class ex1 {
  2.    public static void main(String [] args) {
  3.      new ex2().f2( 100, 200 );
  4.    }
  5. }
  1. class ex2 {
  2.    int j;
     
  3.    public int f2( int n, int m ) {      
  4.      int i = n;
  5.      j = m;
  6.      j = j + i;
  7.      return j;
  8.   }
  9. }
Frame
0 this
1 n
2 m
3 i

 

  1. .source               ex1.java
  2. .class                  public ex1
  3. .super                 java/lang/Object
     
  1. .method               public <init>()V
  2. .limit stack       1
  3. .limit locals       1
  4. .line                 1
  5.     aload_0               
  6.     invokespecial     java/lang/Object/<init>()V
  7.     return               
  8.  .end method             
     
  1.  .method               public static main([Ljava/lang/String;)V
  2.  .limit stack      3
  3.  .limit locals      1
  4.  .line               3
  5.     new                  ex2
  6.     dup                  
  7.     invokespecial      ex2/<init>()V
  8.     bipush                100
  9.     sipush                200
  10.     invokevirtual       ex2/f2(II)I
  11.     pop                  
  12.  .line                 4
  13.     return               
  14.  .end method             

 

  1.  .source                ex1.java
  2.  .class                   ex2
  3.  .super                  java/lang/Object
     
  4.  .field                    j I
     
  5.  .method               public <init>()V
  6.  .limit stack           1
  7.  .limit locals           1
  8.  .line                    10
  9.      aload_0              
  10.      invokespecial    java/lang/Object/<init>()V
  11.      return               
  12.  .end method
     
  13.  .method                public f2(II)I
  14.  .limit stack            3
  15.  .limit locals            4
  16.  .line                     13
  17.      iload_1              
  18.      istore_3             
  19.  .line                     14
  20.      aload_0              
  21.      iload_2              
  22.      putfield           ex2/j I
  23.  .line                     15
  24.      aload_0              
  25.      aload_0              
  26.      getfield             ex2/j I
  27.      iload_3              
  28.      iadd                 
  29.      putfield             ex2/j I
  30.  .line                      16
  31.      aload_0              
  32.      getfield              ex2/j I
  33.      ireturn              
  34.  .end method             

 

Exercise

  1. Explain lines 49-54. Specifically, where and what are the operands of line 53? Draw the stack to illustrate your answer.
  2. What is the effect of line 54?
  3. Explain lines 56-57.
  4. Why is local limit 4?
  5. Why is the stack limit 3?

 

FRAMES IN THE MiniJava COMPILER

The text presents a model for frames closely connected with later subjects of optimization and code production for an intermediate language.

We will first consider frame, class and method generation for the JVM architecture only; allowing us to examine many of the remaining steps in compilation in a simpler context before tackling the more general approach of the text.

Recall the SymbolTable package implementation which holds declaration information such as the name and type of variables.

Frames are only associated with methods and constructors, since MiniJava has only the default constructor, we are concerned only with frames for methods. The following classifies each declaration part of a MiniJava program as it relates to frames.

Class - Class data (i.e. name, parent, methods, globals) is recorded in the SymbolTable but is not part of the frame.

Class generation is straightforward consisting of:

  1.  .source                ex1.java
  2.  .class                   ex2
  3.  .super                  java/lang/Object
     
  4.  .field                    j I
     
  5.  .method               public <init>()V
  6.  .limit stack           1
  7.  .limit locals           1
  8.  .line                    10
  9.      aload_0              
  10.      invokespecial    java/lang/Object/<init>()V
  11.      return               
  12.  .end method
class ex2 {

   int j;

Globals

Globals name (fields) and type are recorded in the SymbolTable but are not part of the frame. The example above illustrates how globals must be defined as part of the class.

Methods

  1.    public int f2( int n, int m ) {      
  2.      int i = n;
  3.      j = m;
  4.      j = j + i;
  5.      return j;
  6.   }
  7. }
  1.  .method                public f2(II)I
  2.  .limit stack            3
  3.  .limit locals            4
  4.  .line                     13
  5.      iload_1              
  6.      istore_3             
  7.  .line                     14
  8.      aload_0              
  9.      iload_2              
  10.      putfield           ex2/j I
  11.  .line                     15
  12.      aload_0              
  13.      aload_0              
  14.      getfield             ex2/j I
  15.      iload_3              
  16.      iadd                 
  17.      putfield             ex2/j I
  18.  .line                      16
  19.      aload_0              
  20.      getfield              ex2/j I
  21.      ireturn              
  22.  .end method             
Frame
0 this
1 n
2 m
3 i

 

A frame must be determined for each method, the essential data for compiling a method is:

this

this is allocated first in the frame at location 0. Before an instance method call such as at Line 28, requires placing this at location 0 of the callee frame. The following constructs the frame for the putfield method that appears as:

  1.      aload_0               
  2.      bipush              12             
  3.      putfield           ex2/j I
Frame
0 this
1  12

Parameters/Variables

Parameters are allocated in the frame immediately after this. Variables immediately follow parameters.

Caller - constructs the frame by placing the object passed to this followed by parameters on the stack; then invoke the method. Notice that values are represented as bytes, etc. and extended when copied to the frame where possible:

bipush 100 has the following description:

  • The immediate byte is sign-extended to an int value. That value is pushed onto the operand stack.

sipush 200

  • The immediate unsigned byte1 and byte2 values are assembled into an intermediate short where the value of the short is (byte1 << 8) | byte2. The intermediate value is then sign-extended to an int value. That value is pushed onto the operand stack.
new ex2().f2( 100, 200 );
  1.     new                   ex2
  2.     bipush                100
  3.     sipush                200
  4.     invokevirtual       ex2/f2(II)I

Callee - defines the frame size by limit described above. Parameters and variable values are accessed from the frame.

  1.    public int f2( int n, int m ) {      
  2.      int i = n;
  3.      j = m;
  4.      return i + j;

 

  1.  .method                public f2(II)I
  2.  .limit stack            3
  3.  .limit locals            4
  4.  .line                     13
  5.      iload_1              
  6.      istore_3             
  7.  .line                     14
  8.      aload_0              
  9.      iload_2              
  10.      putfield           ex2/j I
  11.  .line                     15
  12.      aload_0              
  13.      getfield             ex2/j I
  14.      iload_3                   ; i
  15.      iadd                       ; TOS = i + j
  16.      ireturn                   ; returns TOS

DOWNLOAD RESOURCES

  1. Compile the Java program file  to assembly language.
  2. Assemble a class file to assembly, using example.j
     
    • Home: java -jar \jasmin\jasmin.jar example.j
                java -cp . example.class
       
    • IUS:    java -jar v:\common\user\C431\jasmin.jar example.j
                java -cp . example.class