HostedDB - Dedicated UNIX Servers

-->
Internet Security Professional Reference:Java Security
Previous Table of Contents Next


Operands are often more than 8 bits long and need to be divided into two or more bytes. The JVM uses the big endian encoding scheme, in which the larger order bits are stored in the lower ordered memory spaces. This is the standard for Motorola and other RISC chips. Intel chips, however, use little endian encoding, placing the least significant bits in the lowest memory address. The two methods are compared in table 13.2.


Figure 13.2  An 8-bit byte alignment versus a 32- or-64-bit byte alignment.

Table 13.2
Big versus Little Endian Encoding

Memory Address 0 Memory Address 1

Big Endian

Byte 1 * 256 Byte 2

 
Little Endian

Byte 1 Byte 2 * 256

The differences can be confusing when trying to move data between two opposing systems that require larger than 8-bit fragments to be encoded their way.

The instruction set lends a great amount of functionality to the JVM and is specifically designed as an implementation of the Java language. This includes instructions for invoking methods and monitoring multithreading systems. The 8-bit size of the opcode limits the number of instructions to 256, and there are already 160 opcodes that can be used. It is unlikely that this number will ever rise, unless future advances in hardware cannot be managed under the current JVM specification.

The Registers

All processors have registers that hold information that the processor uses to store the current state of the system. Each processor type has different numbers of registers. The more registers a processor has, the more items it can deal with quickly, without having to refer to the stack, or global memory, which would result in a reduction in performance. Because of the wide difference in register variables, it was decided that Java would not have very many. If it had more than any processor it was being ported to, those CPUs would take enormous performance penalties when attempting to mimic the register states in regular memory. Therefore, the register set was limited to the following four registers:

  pc. Program counter
  optop. Pointer to top of the operand stack
  frame. Pointer to current execution environment
  vars. Pointer to the first (0th) local variable of the current execution environment

Each of these registers is 32 bits wide, and some of them might not need to be used in a specific implementation.

The program counter (pc) keeps track of where the program is in execution. This register does not need to be used if recompiling into native code. The optop, frame, and vars registers hold pointers to areas in the Java stack, which is discussed in the next section.

The Java Stack

The Java stack is the principal storage method for the JVM, which is considered a stack-based machine. When the JVM is given the bytecodes of a Java application, it creates a stack frame for each method of a class that holds information about its state. Each frame holds three kinds of information:

  Local variables
  Execution environment
  Operand stack

Local Variables

The local variables in a Java stack frame are an array of 32-bit variables, the beginning of which is marked by the vars register. This effectively is a large store for method variables. When they are needed in the computation of an instruction, they can be loaded onto and stored from the operand stack. When a variable is longer than 32 bits, such as double precision floats and long ints that are 64 bits, it must be spread across two of these local variables. It is still addressed at only the first location, however.

Execution Environment

The execution environment provides information about the current state of the Java stack in reference to the current method. Information stored in the execution environment includes the following:

  Previous method invoked
  Pointer to the local variables
  Pointers to the top and bottom of the operand stack

The execution environment is the control center for an executing method and makes sure that the interpreter or recompiler can find the necessary information that pertains to the current method. If the interpreter was asked to execute an iadd, for example, it would need to know where to find the two numbers required to do the arithmetic. First, it would look to the frame register to find the current execution environment. Next, it would look to the execution environment to find the pointer to the top of the operand stack where it would remove the two required numbers, add them, and then place them back onto the stack.

Operand Stack

The operand stack is a FIFO, or first in, first out, 32-bit-wide stack that holds the arguments necessary for the opcodes in the JVM instruction set. The operand stack is used both for gathering the operands necessary for completion and for the storage of the results. In Java parlance, “the stack” is generally a reference to this area in the Java stack.

The Java stack is the primary area for storage of current status information for the execution of the Java bytecode. It is equivalent to the stack frame in standard programming languages. It provides method implementations of the local variables, the execution environment, and the operand stack.

In addition to the instruction set, registers, and Java stack, there are two remaining elements to the JVM specifications: the garbage collected heap and memory areas.


Previous Table of Contents Next