⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manual.html

📁 一个用于对.class文件进行插桩的开源工具
💻 HTML
📖 第 1 页 / 共 5 页
字号:
  <a name="Figure 2">  <img src="images/classfile.gif" />  <br />  Figure 2: Java class file format</a>  </p>                                                <p>    Because all of the information needed to dynamically resolve the    symbolic references to classes, fields and methods at run-time is    coded with string constants, the constant pool contains in fact    the largest portion of an average class file, approximately    60%. In fact, this makes the constant pool an easy target for code    manipulation issues. The byte code instructions themselves just    make up 12%.  </p>                                                <p>    The right upper box shows a "zoomed" excerpt of the constant pool,    while the rounded box below depicts some instructions that are    contained within a method of the example class. These    instructions represent the straightforward translation of the    well-known statement:  </p>                                                <p align="center">    <source>System.out.println("Hello, world");</source>  </p>                                                <p>    The first instruction loads the contents of the field <tt>out</tt>    of class <tt>java.lang.System</tt> onto the operand stack. This is    an instance of the class <tt>java.io.PrintStream</tt>. The    <tt>ldc</tt> ("Load constant") pushes a reference to the string    "Hello world" on the stack. The next instruction invokes the    instance method <tt>println</tt> which takes both values as    parameters (Instance methods always implicitly take an instance    reference as their first argument).  </p>                                                <p>    Instructions, other data structures within the class file and    constants themselves may refer to constants in the constant pool.    Such references are implemented via fixed indexes encoded directly    into the instructions. This is illustrated for some items of the    figure emphasized with a surrounding box.  </p>                                                <p>    For example, the <tt>invokevirtual</tt> instruction refers to a    <tt>MethodRef</tt> constant that contains information about the    name of the called method, the signature (i.e., the encoded    argument and return types), and to which class the method belongs.    In fact, as emphasized by the boxed value, the <tt>MethodRef</tt>    constant itself just refers to other entries holding the real    data, e.g., it refers to a <tt>ConstantClass</tt> entry containing    a symbolic reference to the class <tt>java.io.PrintStream</tt>.    To keep the class file compact, such constants are typically    shared by different instructions and other constant pool    entries. Similarly, a field is represented by a <tt>Fieldref</tt>    constant that includes information about the name, the type and    the containing class of the field.  </p>                                                <p>    The constant pool basically holds the following types of    constants: References to methods, fields and classes, strings,    integers, floats, longs, and doubles.  </p>                            </blockquote>        </p>      </td></tr>      <tr><td><br/></td></tr>    </table>                                                <table border="0" cellspacing="0" cellpadding="2" width="100%">      <tr><td bgcolor="#525D76">        <font color="#ffffff" face="arial,helvetica,sanserif">          <a name="2.2 Byte code instruction set"><strong>2.2 Byte code instruction set</strong></a>        </font>      </td></tr>      <tr><td>        <blockquote>                                    <p>    The JVM is a stack-oriented interpreter that creates a local stack    frame of fixed size for every method invocation. The size of the    local stack has to be computed by the compiler. Values may also be    stored intermediately in a frame area containing <em>local    variables</em> which can be used like a set of registers. These    local variables are numbered from 0 to 65535, i.e., you have a    maximum of 65536 of local variables per method. The stack frames    of caller and callee method are overlapping, i.e., the caller    pushes arguments onto the operand stack and the called method    receives them in local variables.  </p>                                                <p>    The byte code instruction set currently consists of 212    instructions, 44 opcodes are marked as reserved and may be used    for future extensions or intermediate optimizations within the    Virtual Machine. The instruction set can be roughly grouped as    follows:  </p>                                                <p>    <b>Stack operations:</b> Constants can be pushed onto the stack     either by loading them from the constant pool with the     <tt>ldc</tt> instruction or with special "short-cut"     instructions where the operand is encoded into the instructions,     e.g.,  <tt>iconst_0</tt> or <tt>bipush</tt> (push byte value).  </p>                                                <p>    <b>Arithmetic operations:</b> The instruction set of the Java       Virtual Machine distinguishes its operand types using different       instructions to operate on values of specific type. Arithmetic       operations starting with <tt>i</tt>, for example, denote an       integer operation. E.g., <tt>iadd</tt> that adds two integers       and pushes the result back on the stack. The Java types       <tt>boolean</tt>, <tt>byte</tt>, <tt>short</tt>, and       <tt>char</tt> are handled as integers by the JVM.  </p>                                                <p>    <b>Control flow:</b> There are branch instructions like     <tt>goto</tt>, and <tt>if_icmpeq</tt>, which compares two integers     for equality. There is also a <tt>jsr</tt> (jump to sub-routine)     and <tt>ret</tt> pair of instructions that is used to implement     the <tt>finally</tt> clause of <tt>try-catch</tt> blocks.     Exceptions may be thrown with the <tt>athrow</tt> instruction.     Branch targets are coded as offsets from the current byte code     position, i.e., with an integer number.  </p>                                                <p>    <b>Load and store operations</b> for local variables like      <tt>iload</tt> and <tt>istore</tt>. There are also array      operations like <tt>iastore</tt> which stores an integer value      into an array.  </p>                                                <p>    <b>Field access:</b> The value of an instance field may be     retrieved with <tt>getfield</tt> and written with     <tt>putfield</tt>. For static fields, there are     <tt>getstatic</tt> and <tt>putstatic</tt> counterparts.  </p>                                                <p>    <b>Method invocation:</b> Static Methods may either be called via     <tt>invokestatic</tt> or be bound virtually with the     <tt>invokevirtual</tt> instruction. Super class methods and     private methods are invoked with <tt>invokespecial</tt>. A     special case are interface methods which are invoked with     <tt>invokeinterface</tt>.  </p>                                                <p>    <b>Object allocation:</b> Class instances are allocated with the      <tt>new</tt> instruction, arrays of basic type like      <tt>int[]</tt> with <tt>newarray</tt>, arrays of references like      <tt>String[][]</tt> with <tt>anewarray</tt> or      <tt>multianewarray</tt>.  </p>                                                <p>    <b>Conversion and type checking:</b> For stack operands of basic      type there exist casting operations like <tt>f2i</tt> which      converts a float value into an integer. The validity of a type      cast may be checked with <tt>checkcast</tt> and the      <tt>instanceof</tt> operator can be directly mapped to the      equally named instruction.  </p>                                                <p>    Most instructions have a fixed length, but there are also some    variable-length instructions: In particular, the    <tt>lookupswitch</tt> and <tt>tableswitch</tt> instructions, which    are used to implement <tt>switch()</tt> statements.  Since the    number of <tt>case</tt> clauses may vary, these instructions    contain a variable number of statements.  </p>                                                <p>    We will not list all byte code instructions here, since these are    explained in detail in the <a href="http://java.sun.com/docs/books/vmspec/index.html">JVM    specification</a>. The opcode names are mostly self-explaining,    so understanding the following code examples should be fairly    intuitive.  </p>                            </blockquote>        </p>      </td></tr>      <tr><td><br/></td></tr>    </table>                                                <table border="0" cellspacing="0" cellpadding="2" width="100%">      <tr><td bgcolor="#525D76">        <font color="#ffffff" face="arial,helvetica,sanserif">          <a name="2.3 Method code"><strong>2.3 Method code</strong></a>        </font>      </td></tr>      <tr><td>        <blockquote>                                    <p>    Non-abstract (and non-native) methods contain an attribute    "<tt>Code</tt>" that holds the following data: The maximum size of    the method's stack frame, the number of local variables and an    array of byte code instructions. Optionally, it may also contain    information about the names of local variables and source file    line numbers that can be used by a debugger.  </p>                                                <p>    Whenever an exception is raised during execution, the JVM performs    exception handling by looking into a table of exception    handlers. The table marks handlers, i.e., code chunks, to be    responsible for exceptions of certain types that are raised within    a given area of the byte code. When there is no appropriate    handler the exception is propagated back to the caller of the    method. The handler information is itself stored in an attribute    contained within the <tt>Code</tt> attribute.  </p>                            </blockquote>        </p>      </td></tr>      <tr><td><br/></td></tr>    </table>                                                <table border="0" cellspacing="0" cellpadding="2" width="100%">      <tr><td bgcolor="#525D76">        <font color="#ffffff" face="arial,helvetica,sanserif">          <a name="2.4 Byte code offsets"><strong>2.4 Byte code offsets</strong></a>        </font>      </td></tr>      <tr><td>        <blockquote>                                    <p>    Targets of branch instructions like <tt>goto</tt> are encoded as    relative offsets in the array of byte codes. Exception handlers    and local variables refer to absolute addresses within the byte    code.  The former contains references to the start and the end of    the <tt>try</tt> block, and to the instruction handler code. The    latter marks the range in which a local variable is valid, i.e.,    its scope. This makes it difficult to insert or delete code areas    on this level of abstraction, since one has to recompute the    offsets every time and update the referring objects. We will see    in <a href="#3.3 ClassGen">section 3.3</a> how <font face="helvetica,arial">BCEL</font> remedies this restriction.  </p>                            </blockquote>        </p>      </td></tr>      <tr><td><br/></td></tr>    </table>                                                <table border="0" cellspacing="0" cellpadding="2" width="100%">      <tr><td bgcolor="#525D76">        <font color="#ffffff" face="arial,helvetica,sanserif">          <a name="2.5 Type information"><strong>2.5 Type information</strong></a>        </font>      </td></tr>      <tr><td>        <blockquote>                                    <p>    Java is a type-safe language and the information about the types    of fields, local variables, and methods is stored in so called    <em>signatures</em>. These are strings stored in the constant pool    and encoded in a special format. For example the argument and    return types of the <tt>main</tt> method  </p>                                                <p align="center">  <source>public static void main(String[] argv)</source>  </p>                                                <p>  are represented by the signature  </p>                                                <p align="center">  <source>([java/lang/String;)V</source>  </p>                                                <p>    Classes are internally represented by strings like    <tt>"java/lang/String"</tt>, basic types like <tt>float</tt> by an

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -