Bytecode, JVM, JIT, Classpath



General Information

Bytecode

Here is the bytecode for the class HelloWorld.java
% javap -c HelloWorld
Compiled from HelloWorld.java
class HelloWorld extends java.lang.Object {
    HelloWorld();
    public static void main(java.lang.String[]);
}

Method HelloWorld()
   0 aload_0
   1 invokespecial #6 >Method java.lang.Object()<
   4 return

Method void main(java.lang.String[])
   0 getstatic #7 >Field java.io.PrintStream out<
   3 ldc #1 >String "Hello World!"<
   5 invokevirtual #8 >Method void println(java.lang.String)<
   8 return

Class Path

Setting the class path
Platform
Solaris, Linux
Windows

Bytecode Verification

The Java virtual machine does not assume that the bytecode has been produced by a "friendly" translator. It is prepared to verify each and every class file to ensure that it is properly formed and can do no mischief.

Binary dump of class file: dump (od -t x1 -t a HelloWorld.class).

4 bytes  magic number
4 bytes  minor version, major version
2 bytes  count of items in constant pool
constant pool array
2 bytes  access flags mask
2 bytes  index into the constant pool for this class
2 bytes  index into the constant pool for super class
2 bytes  count of direct super interfaces
interface array
2 bytes count of methods
methods array
2 bytes count of attributes
attribute array

A bad class would not normally be formed on purpose, but it might be created malicoiusly altered. We an editor we can change the bytes and see what happens.

A properly formed class file begins with the "magic" number OxCAFEBABE in the first four bytes, has the number of bytes it says it does, all the internal arrays have the proper form, all indices are within bounds etc.

The verifier also checks:

Using dataflow analysis, the verifier checks: Some checking is done the first time a method is executed.

If we modify the bytecode of HelloWorld.class in various ways and try to run it, the JVM detects it can rejects the class file.

% java -verify HelloWorld
Exception in thread "main" java.lang.ClassFormatError: HelloWorld (Bad magic number)

% java -verify HelloWorld
Exception in thread "main" java.lang.NoClassDefFoundError: jawa/lang/Object

% java -verify HelloWorld
Exception in thread "main" java.lang.VerifyError:
(class: HelloWorld, method: main signature: ([Ljava/lang/String;)V)
Incompatible object argument for function call

Controlling a JIT

A translator of Java bytecode to native machine code is called a JIT-- Just In Time compiler.

You may wish to just interpret the bytecode (and not compile) when developing an application in order to get line numbers in stack traces. In this way you can find the course of exceptions easier.

You can also use the environment variable JAVA_COMPILER or the property java.compiler to the specify that an alternative JIT should be used:
      % setenv JAVA_COMPILER foo
      C:\> set JAVA_COMPILER=foo
      
or
      % java -Djava.compiler=foo myapp
      C:\> java -Djava.compiler=foo myapp
      

The letters lib are prepended to "foo" and an .so filename extension is added, so that the virtual machine will search for a JIT compiler named libfoo.so. The search for the alternative compiler is made in the jre/lib/sparc directory and or in the path specified by the sun.boot.library.path property, if it is set. Here is an example using of using the sun.boot.library.path property to specify an alternative JIT path (the example assumes a JIT named libfoo.so is located in directory /java):

      java -Dsun.boot.libary.path=/jdk1.2.2/jre/lib/sparc:/java -Djava.compiler=foo MyApp
      

Under Windows the library is foo.dll.


Ryan Stansifer <ryan@cs.fit.edu>
Last modified: Thu Jan 25 13:25:58 EST 2007