This section lists various C preprocessor flags, definitions and macros that are defined in VmCommon/h/main.h
. Understanding the meaning of these flags helps you in porting efforts, so please read the documentation below and in file VmCommon/h/main.h
.
VmCommon/h/main.h
, these values should be preferably be overridden in your port-specific machine_md.h
file.
For each definition, we give a brief summary and its default definition. These flags and macros are documented also in VmCommon/h/main.h
.
The following definitions control the general platform-dependent compiler options that you must set before starting your porting efforts. Incorrect settings typically cause the virtual machine to malfunction.
Turn this flag on if your compiler has support for long (64 bit) integers.
Instructs the KVM to know that your host operating system and compiler generally assume all 64-bit integers to be aligned on eight-byte boundaries.
Instructs the KVM to know that your host operating system and compiler generally assume all double floating point numbers to be aligned on eight-byte boundaries (this flag is meaningful only if floating point support is turned on.)
Additional notes. The compiler generates better code if it knows the “endianness” of your machine. You should set one of the following two variables to “1” in your machine-specific header file.
It is unnecessary to set one of these “endian” variables to “1” if you reset COMPILER_SUPPORTS_LONG
to zero. (See Chapter 9 for more details.)
Also note that if your compiler supports 64-bit integer arithmetic and you have set the flag
you should supply definitions for the types long64
and ulong64
. If your compiler does not support 64-bit integers (or you have set the flag to 0
for some other reason), structure definitions of these two types are created for you automatically. (See Chapter 9.)
The following definitions allow you to control which components and features to include in your port.
Turns floating point support in KVM on or off. Should be ‘1’ in those implementations that are compliant with CLDC Specification version 1.1, and ‘0’ in those implementations that are compliant with CLDC Specification version 1.0.
Path separator character used in CLASSPATH. This definition is meaningful only when utilizing the default class loader for command line based systems. (Defined in VmCommon/h/loader.h
.)
Turns class prelinking/preloading (JavaCodeCompact) support on or off. If this option is turned on, KVM prelinks all the system classes directly in the virtual machine, speeding up application startup considerably. Refer to Chapter 14 for details.
Includes or excludes the optional Java Application Manager (JAM) component in the virtual machine. Refer to Chapter 15 for details.
Instructs the KVM to use optional asynchronous native functions. Refer to Section 11.4 "Asynchronous native methods” and Chapter 12 for details.
This option was introduced in KVM 1.0.4. When enabled, the system will include some code that is needed by the K Native Interface (KNI). If you do not intend to use KNI (you should!), we recommend you to turn this option off, because old-style native functions will run slightly faster with this option turned off. Refer to the KNI Specification for further information on KNI.
The following definitions allow you to control certain Palm-specific system configuration options. All these features were originally designed for the Palm OS version of KVM, but they may be useful also for other ports.
Instructs the KVM to use a Palm-specific optimization in which certain immutable runtime data structures are moved from “dynamic RAM” to “storage RAM” to conserve Java heap space. A fake implementation of this mechanism is available also for the Windows and Solaris versions of KVM (for debugging purposes.)
Instructs the KVM to use an optimization which allows the KVM to allocate the Java heap in multiple chunks or segments. This makes it possible for the virtual machine to allocate more heap space on certain platforms such as Palm OS.
Instructs the KVM to use an optimization in which the prelinked system classes are stored using a relocatable (movable) representation. This allows romized (JavaCodeCompacted) system classes to be stored in devices such as Palm OS.
The following definitions affect the amount of memory KVM allocates.
The Java heap size that KVM allocates upon virtual machine startup. This value is commonly overridden from makefiles. Note that, starting from KVM 1.0.3, it is possible to override the heap size value from the command line (in those ports that support command line operation.) The heap size value must be a number that is divisible by four. The number must be in the range of 16k to 64 M.
The size of a special inline cache area that KVM reserves upon virtual machine startup if the ENABLEFASTBYTECODES
option is turned on. The inline caching mechanism speeds up method lookups in the KVM by utilizing a technique popularized by Deutsch & Schiffman in the early 1980s. The size here is expressed as a number of inline cache entries (each entry requires 12-16 bytes depending on your target platform.)
The execution stacks of Java threads inside the KVM grow and shrink automatically as necessary. This value defines the default size of a new stack frame chunk when a new stack chunk needs to be allocated. Reducing the default stack chunk size will make the creation of new Java threads less expensive, but will slow down the execution of the VM when running programs that require a lot of stack space (that is, programs that have a lot of nested method calls.)
The size (in bytes) of a statically allocated area that the virtual machine uses internally in various string operations.
The following option turns on compacting garbage collection. Note that currently compaction cannot be used on those platforms that have a segmented (non-contiguous) memory architecture.
The following option, if set to a non-zero value, causes a garbage collection to occur on every allocation. This makes it easier to find garbage collection problems. Since this option makes the virtual machine run extremely slowly, the option should be turned off in production builds.
Some KVM ports may want to forbid any new classes from being loaded into any system package. The following macro defines whether a package name is one of these restricted packages. By default, the system prevents dynamic class loading to java.*
and javax.*
packages.
#define IS_RESTRICTED_PACKAGE_NAME(name) \ ((strncmp(name, "java/", 5) == 0) || \ (strncmp(name, "javax/", 6) == 0))
The following macros allow you to turn on and off certain features controlling interpreter execution. The default values for a production release are shown below.
Turns runtime bytecode replacement and method inline caching on or off. This option improves the performance of the virtual machine by about 10-20%, but increases the size of the virtual machine by a few kilobytes. Note that bytecode replacement cannot be performed on those target platforms in which bytecodes are stored in non-volatile memory such as ROM.
Instructs the virtual machine to verify the types of constant pool entries at runtime when performing constant pool lookups. Reduces runtime performance slightly, but is generally recommended to be kept on for safety and security reasons.
Additional definitions and interpreter macros:
The value of this variable determines the basic frequency (as a number of bytecodes executed) in which the virtual machine performs thread switching, event notification and other periodically needed operations. A smaller number reduces event handling and thread switching latency, but causes the interpreter to run more slowly.
A compiler macro, defined in interpret.h
, that is used to find the modulus of two floating point numbers.
This macro makes the virtual machine sleep until the current time (as indicated by the return value of the function CurrentTime_md()
) is greater than or equal to the wakeup time. The default implementation of SLEEP_UNTIL
is a busy loop. Most ports should usually provide a more efficient implementation for battery conservation reasons. Refer to Section 12.4 "Battery power conservation” for further details.
Since the release 1.0.2, KVM has an interpreter design that gives up to 15-30% better performance than KVM 1.0 without any loss of ANSI C portability. The actual performance improvement percentage depends on the target platform and the capabilities of the C compiler that is used for compiling the KVM. The performance improvement is the result of the following four techniques that can be used independently of each other:
These techniques do not depend on any compiler-specific features, and are therefore portable across a wide variety of C compilers. Each of the techniques and the corresponding macros are discussed in more detail below.
The virtual machine registers of the KVM (ip
, sp
, lp
, fp
, cp
) are accessed very frequently when bytecodes are being executed. In KVM 1.0, all these virtual machine registers are defined as global C variables. Starting from KVM 1.0.2, these registers are still principally defined as global variables, but if the LOCALVMREGISTERS
option is on, they are copied to local variables when the interpreter is executing. A good C compiler will then optimize the interpreter loop so that these local variables are put into machine registers for substantially faster execution.
Turns the localization of virtual machine registers on or off.
These macros allow you to control specifically which of the virtual machine registers should be used locally by the interpreter loop. These macros have been added to provide better control over register allocation, as many resource-constrained platforms may not have many physical hardware registers available.
The optimal selection of these options for a specific platform will require careful examination of the machine code produced by the compiler, along with a good deal of experimentation. By default, ip
(instruction pointer), and sp
(stack pointer) are allocated locally, while lp
(locals pointer), fp
(frame pointer) and cp
(constant pool pointer) are kept in global variables.
LOCALVMREGISTERS
option and you want to make further changes to the code implementing Java bytecodes, the single most important thing to remember is to make sure that the local copies of the virtual machine registers are copied back to their global variables before calling functions in the virtual machine that expects them to be in their global variables. Failure to do so will lead to obscure bugs. The virtual machine registers can be saved to their global variables by using the macro VMSAVE
. They are restored back to their local variables by using the macro VMRESTORE
. For instance the RETURN
bytecodes may need to call monitorExit()
, and to do this the call must be done as follows:VMSAVE
result = monitorExit(...);
VMRESTORE
The KVM 1.0 interpreter had the code for all the Java bytecodes in a single large switch statement. However, a majority of Java bytecodes are executed very rarely. If the code for the more frequently and less frequently used bytecodes is placed in separate routines, the C compiler can often do a better job optimizing the resulting smaller interpreter loops. This also helps the compiler find hardware registers for the virtual machine registers more easily when the LOCALVMREGISTERS
option is in use.
Turning this option on allows the C compiler to generate separate interpreter loops for the frequently and infrequently used bytecodes.
Note that the code to process the bytecodes is now contained in a file called bytecodes.c. The code for all the bytecodes is kept here and is selectively compiled by utilizing a number of internal macro definitions (STANDARDBYTECODES
, INFREQUENTSTANDARDBYTECODES
, FLOATBYTECODES
and FASTBYTECODES
).
The code in bytecodes.c
is executed from another new file called execute.c
. If the SPLITINFREQUENTBYTECODES
option is enabled, the file bytecodes.c
is included twice into execute.c
: once for the routine called SlowInterpret()
and once for the routine Interpret()
. The four macros mentioned above are used to control the expansion of the appropriate bytecodes into the correct subroutines.
The old KVM 1.0 interpreter tested for the need to reschedule (switch threads) before the execution of each bytecode. The performance of the interpreter was improved by about 5% by changing the location of this test so that the test is performed only after every branch, goto, call and return instruction.
Thread scheduling in the old interpreter took place when a certain number of bytecodes had been executed. This number was, by default, 100 times the priority of the thread. In the new interpreter, thread rescheduling occurs by default when 1000 times the number of branch, call, or return bytecodes have been executed.
Turning this option on changes the thread switching mechanism so that tests for thread switching are moved to branchpoints. Note that enabling this option affects the value of the BASETIMESLICE
macro inherited from KVM 1.0. When this option is off, thread scheduling operates as in KVM 1.0.
The Java Virtual Machine Specification defines 200 standard bytecodes, plus additionally reserves four other bytecodes for other use. However, many C compilers produce better code when the size of the bytecode (switch) table is exactly 256.
Turning this option on will pad the interpreter switch tables so that the number of instructions is 256. This will increase the size of the virtual machine, but allows the interpreter to run faster on some platforms.
The KVM 1.0.2 release introduced a new Java-level debugger interface that allows the KVM to be plugged into third party Java debugger environments and integrated development environments (IDEs) that supports the JDWP (Java Debug Wire Protocol) protocol. The macros in this subsection are related to the Java-level debugger options.
Includes a large amount of debugger support code that is needed for plugging KVM into a third-party Java debugger or integrated development environment such as Forte or Borland JBuilder.
More information about the Java-level debugger facilities and the KDWP interface is provided in Chapter 16, "Java-Level Debugging Support (KDWP).”
KVM provides a large number of debugging and tracing facilities that can be used for inspecting the behavior of the KVM itself at the native (C) code level. These facilities can be extremely helpful during porting efforts.
All the VM-level debugging and tracing options should be turned off in a production release.
Includes a large amount of debugging and logging code that is useful when porting the virtual machine onto a new platform. This option should be turned off in production builds.
Turns on or off certain profiling features that allow you to monitor virtual machine execution and get execution statistics. Turning this option on slows down the virtual machine execution speed considerably. This option should be turned off in production builds.
In KVM 1.0, all the tracing options were compilation flags that could be changed only by recompiling the virtual machine. In KVM 1.0.2, all these tracing options were changed into global variables that can be controlled from the command line. This makes it much easier to turn individual tracing options on and off. These global variables (and command line switches) are available only if the virtual machine has been compiled with the INCLUDEDEBUGCODE
mode turned on.
If your target platform does not support command line operation, you can control these options directly by changing their default values in file VmCommon/src/global.c
, or by defining a graphical user interface that sets and resets these options.
Additionally, you can control whether the tracing messages printed out are terse or more verbose by modifying the following option:
KVM also contains a stack trace printing facility that can be turned on to help debugging of exceptions and errors in more detail (at the cost of some additional memory footprint). By default, this mode is turned on automatically when the INCLUDEDEBUGCODE
flag is turned on.
The interpreter uses the internal error handling macros shown in CODE EXAMPLE 1.
If there is a call to the macro THROW(error)
, anywhere inside the “normal code,” the VM jumps immediately to error handling code. Uses of this macro can be nested, either lexically or dynamically. The THROW
jumps to the innermost CATCH
error handling code. (The various TRY
, THROW
, and CATCH
macros are defined in VmCommon/h/global.h
.)
By default, this behavior is emulated using setjmp
and longjmp
. However, platforms (such as PalmOS) that already provide a similar mechanism should use the native mechanism.
KVM 1.1 also has new macros for controlling the shutdown of the virtual machine. These macros have been illustrated in CODE EXAMPLE 2
VM_START {
normal VM code} VM_FINISH (value) {
code to execute before VM shuts down} VM_END_FINISH
Rather than calling the normal C exit
function, the proper way to exit from the VM is to call macro VM_EXIT(value)
. Calling this macro will cause the control of the VM to be immediately transferred to the code that follows the VM_FINISH(value)
macro. The value to be passed to this code typically represents the exit code that the VM will return when it shuts down.
Some functions in the reference implementation take arguments that they do not use. Some compilers issue warnings; others do not. For those compilers that do issue warnings, they differ in how you indicate that the non-use of the variable is intentional and that you do not wish to get a warning. This macro should do whatever is necessary to get your compiler to remain quiet.
The following parameters are commonly used when using gnumake to build the KVM.
Build the KVM with romizing disabled. That is, do not link all the system classes statically into the KVM executable. (The default is to build the KVM with romizing enabled.)
Build the KVM with the Java-level debugger and VM-internal debugging code enabled.
Build the KVM with the Java Application Manager (JAM) enabled.
Use GNU C compiler instead of the standard Sun compiler (on Solaris.)
GCC=true is the default option when developing on Linux, and this is the setting for compiling on Windows using CygWin tools.
Build the KVM without the K Native Interface (KNI) functionality. (The default is to build the KVM with KNI enabled.)
KVM Porting Guide , CLDC 1.1 |
Copyright © 2003 Sun Microsystems, Inc. All rights reserved.