Advertisement: Support JavaWorld, click here!
June 1996
HOME FEATURED TUTORIALS COLUMNS NEWS & REVIEWS FORUM JW RESOURCES ABOUT JW






ARCHIVE

TOPICAL INDEX
Core Java
Enterprise Java
Micro Java
Applied Java
Java Community

JAVA Q&A INDEX

JAVA TIPS INDEX


JAVA BOOK INDEX


JavaWorld Services

Newsletters

Special Offers

ProductFinder

Education Resources

White Paper Library

Under the Hood

The lean, mean, virtual machine

An introduction to the basic structure and functionality of the Java Virtual Machine


Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend


Page 2 of 2

Advertisement

The proud, the few, the registers
The JVM has a program counter and three registers that manage the stack. It has few registers because the bytecode instructions of the JVM operate primarily on the stack. This stack-oriented design helps keep the JVM's instruction set and implementation small.

The JVM uses the program counter, or pc register, to keep track of where in memory it should be executing instructions. The other three registers -- optop register, frame register, and vars register -- point to various parts of the stack frame of the currently executing method. The stack frame of an executing method holds the state (local variables, intermediate results of calculations, etc.) for a particular invocation of the method.

The method area and the program counter
The method area is where the bytecodes reside. The program counter always points to (contains the address of) some byte in the method area. The program counter is used to keep track of the thread of execution. After a bytecode instruction has been executed, the program counter will contain the address of the next instruction to execute. After execution of an instruction, the JVM sets the program counter to the address of the instruction that immediately follows the previous one, unless the previous one specifically demanded a jump.

The Java stack and related registers
The Java stack is used to store parameters for and results of bytecode instructions, to pass parameters to and return values from methods, and to keep the state of each method invocation. The state of a method invocation is called its stack frame. The vars, frame, and optop registers point to different parts of the current stack frame.

There are three sections in a Java stack frame: the local variables, the execution environment, and the operand stack. The local variables section contains all the local variables being used by the current method invocation. It is pointed to by the vars register. The execution environment section is used to maintain the operations of the stack itself. It is pointed to by the frame register. The operand stack is used as a work space by bytecode instructions. It is here that the parameters for bytecode instructions are placed, and results of bytecode instructions are found. The top of the operand stack is pointed to by the optop register.

The execution environment is usually sandwiched between the local variables and the operand stack. The operand stack of the currently executing method is always the topmost stack section, and the optop register therefore always points to the top of the entire Java stack.

The garbage-collected heap
The heap is where the objects of a Java program live. Any time you allocate memory with the new operator, that memory comes from the heap. The Java language doesn't allow you to free allocated memory directly. Instead, the runtime environment keeps track of the references to each object on the heap, and automatically frees the memory occupied by objects that are no longer referenced -- a process called garbage collection.

Eternal math: a JVM simulation
The applet below simulates a JVM executing a few bytecode instructions. The instructions in the simulation were generated by the javac compiler given the following java code:


class Act {
    public static void doMathForever() {
        int i = 0;
        while (true) {
            i += 1;
            i *= 2;
        }
    }
}

The instructions in the simulation represent the body of the doMathForever() method. These instructions were chosen because they are a short sequence of bytecodes that do something mildly interesting on the stack. This simulation stars the registers, the stack, and the method area. The heap is not involved in this bytecode sequence, so it is not shown as part of the applet's user interface. All numbers in the simulation are shown in hex.

As our story opens, the program counter (pc register) is pointing to an iconst_0 instruction. The iconst_0 instruction is in the method area, where bytecodes like to hang out.

When you press the Step button, the JVM will execute the single instruction that is being pointed to by the program counter. So, the first time you press the Step button, the iconst_0 instruction, which pushes a zero onto the stack, will be executed. After this instruction has executed,the program counter will be pointing to the next instruction to execute.Subsequent presses of the Step button will execute subsequent instructions and the program counter will lead the way. Pressing the Reset button will cause the simulation to start over at the beginning.

The value of each register is shown two ways. The contents of each register, a 32-bit address, is shown in hex across the top of the simulation. Additionally, I put a small pointer to the address contained in each register next to the address in either the stack or the method area. The address contained by the program counter, for example, has a pc> next to it in the method area.

The Java stack is word-based. Each time something is pushed onto the Java stack, it goes on as a word (although longs and doubles actually go on as two words). In the simulation, the Java stack is shown as an upside-down tower of words. It is shown growing down the panel (up in memory addresses) as words are pushed onto it. The stack recedes back up the panel as words are popped from it. In this implementation of the JVM, the optop register always points to the next available slot on the Java stack.

All three sections of the stack frame for the currently executing method-- the local variables, the execution environment, and the operand stack -- are shown in the simulation. Only the local variables and operand stack take part in this simulation, though. The execution environment isn't involved in this particular bytecode sequence, so it is shown filled with zeros.

The local variables section of the Java stack is treated as an array of words starting at the location pointed to by the vars register. Bytecodes that deal with local variables generally include an array index, which is an offset from the vars register. The address of the nth local variable is (vars + (n * 4)). You must multiply n by 4, because each word is 4 bytes long.

The doMathForever() method has only one local variable, i. It is therefore at array position zero and is pointed to directly by the vars register. For example, the iinc instruction takes two byte-sized operands, a local variable index and an amount. In the simulation, "iinc 0 1" increments by one the integer at local variable array position zero. This instruction implements the "i += 1;" statement from doMathForever().

With enough patience and clicks of the Step button, you can get an arithmetic overflow. When the JVM encounters such a condition, it just truncates, as is shown by this simulation. No exceptions are thrown. (Actually, I am just displaying the result of a multiply operation performed by the "real" JVM in your browser.)

I put a text description of each step at the bottom of the applet, which I hope will help to carry you through the simulation with clarity and deep understanding. Happy clicking.

Click here for the source code.

The small print: "The Lean, Mean Virtual Machine" Article Copyright (c) 1996 Bill Venners. All rights reserved. "Eternal Math" Applet Copyright (c) 1996 Artima Software Company. All rights reserved.


Page 1 The lean, mean, virtual machine
Page 2 The proud, the few, the registers

Printer-friendly version Printer-friendly version | Send this article to a friend Mail this to a friend

About the author
Bill Venners is president and chief propeller-head of Artima Software Company. Through Artima, he does custom software development and consulting.


Top Offers

T-Mobile Cell Phone Plans Motorola Free Cell Phones T-Mobile Cell Phone Plans Motorola Free Cell Phones

Personal Loans - Offers credit applications to a range of mortgage loans, auto loans, personal loans and credit cards.

Bad Credit Loans - Offers bad credit loan applications to a range of personal loans, mortgage loans, home equity, refinance and debt consolidation loans.

www.spammingbureau.com Spamming Bureau

Refinance Mortgage Mortgage refinancing, home loans and home equity loans

PriceSCAN Unbiased Price Comparisons, Vendor Ratings and User Reviews. Don't Buy It Before You PriceSCAN It!

Mortgage Leads Internet Mortgage Loan Leads Generation

California Home Loan California refinance mortgage lender and home equity loans.

Cheap Premium Tickets Your one stop shop for all sold out Sports, Concerts and Theatre events. Cheap Premium Tickets has seating for every venue across the country.

-->
Advertisement: Support JavaWorld, click here!


HOME |  FEATURED TUTORIALS |  COLUMNS |  NEWS & REVIEWS |  FORUM |  JW RESOURCES |  ABOUT JW |  FEEDBACK

Copyright © 2004 JavaWorld.com, an IDG company