In most cases, all classes loaded by a JVM are subject to a process called ``bytecode verification''. This verification is done to ensure that classes do not perform operations that may cause the JVM to crash. The verification process checks that all arguments on the operand stack are legal. In addition, the verifier ensures that all types of all variables passed to methods are correct, and that all load and store operations have correct types.
To accomplish this task, the verifier must do extensive analysis on the JVM code. This analysis is briefly summarized in [17, pages 128-130]. The analysis is discussed in detail in [11,12,13]. The details of this verification analysis are somewhat beyond the scope of this thesis; however, details are mentioned later in those cases that impact this work directly.
Of course, this verification analysis introduces overhead. The argument is made, though, that this overhead is worthwhile, since JVM code execution can afterwards proceed more quickly without checking types and stack limits. For such quick execution to take place, the JVM must assume that the verifier has checked all these parameters. In addition, the execution process must assume that verification rejects invalid code constructed with malicious intent.
However, bytecode verification is not without disadvantages. The verifier can limit some otherwise valid uses of the JVM. In fact, the first approach used in this project was impeded (and eventually rendered futile) because code was generated that could not pass the verification. Section 4.5 discusses this problem in detail.
Note that JVM bytecode verification is only a subset of those checks performed when an ``applet'' is loaded from the network. In those cases, more extensive checks are done to ensure that access to the local operating system is severely limited.
Copyright © 2000, 2001 Bradley M. Kuhn.
Verbatim copying and distribution of this entire thesis is permitted in any medium, provided this notice is preserved.