org.jikesrvm.osr
Class BytecodeTraverser

java.lang.Object
  extended by org.jikesrvm.osr.BytecodeTraverser
All Implemented Interfaces:
BytecodeConstants, ClassLoaderConstants, OSRConstants, SizeConstants

public class BytecodeTraverser
extends Object
implements BytecodeConstants, ClassLoaderConstants, OSRConstants

BytecodeTraverser does depth first search on a bytecode array, determines the type information of locals and stacks at Interesting point.

This class only intends to provide type information for on-stack replacement, which needs to know the type of a value. This class can only tells basic type information such as : REFERENCE, LONG, DOUBLE, FLOAT, INT, and ReturnAddress. Not like GCMap which tells GC a value is REFERENCE or NON-REFERENCE we also want to know it is INT or DOUBLE, and takes two words value or one word.

The produced type information has to be adjusted by consulting GC maps because two different types may merge at one program point (REF and non-REF types). Bytecode verifier will make the type info undefined in that case. But this class won't know. So the caller should check the GC map to validate a REF type variable.

More or less, this class needs to do the same work as a bytecode verifier, which tells the type and size of each locals and stacks. The JSR/RET instructions pose the difficulty to our case. However, we can assume the bytecode is verified. We use following assumptions:

  1. After JSR, the stack was not changed, only local variable type needs to merge with FINALLY clause.
  2. We need program-point specific stack type, but only need the summary of local types. Thus, after analysis, local types are same for all PCs.


Field Summary
private  int addr
           
private  BytecodeStream bytecodes
           
private  boolean ignoreGotos
           
private  byte[] ltypes
           
private  int[] retaddr
           
private  byte[] stypes
           
private  boolean TRACE
           
private  byte[] visitedpc
           
 
Fields inherited from interface org.jikesrvm.classloader.BytecodeConstants
JBC_aaload, JBC_aastore, JBC_aconst_null, JBC_aload, JBC_aload_0, JBC_aload_1, JBC_aload_2, JBC_aload_3, JBC_anewarray, JBC_areturn, JBC_arraylength, JBC_astore, JBC_astore_0, JBC_astore_1, JBC_astore_2, JBC_astore_3, JBC_athrow, JBC_baload, JBC_bastore, JBC_bipush, JBC_caload, JBC_castore, JBC_checkcast, JBC_d2f, JBC_d2i, JBC_d2l, JBC_dadd, JBC_daload, JBC_dastore, JBC_dcmpg, JBC_dcmpl, JBC_dconst_0, JBC_dconst_1, JBC_ddiv, JBC_dload, JBC_dload_0, JBC_dload_1, JBC_dload_2, JBC_dload_3, JBC_dmul, JBC_dneg, JBC_drem, JBC_dreturn, JBC_dstore, JBC_dstore_0, JBC_dstore_1, JBC_dstore_2, JBC_dstore_3, JBC_dsub, JBC_dup, JBC_dup_x1, JBC_dup_x2, JBC_dup2, JBC_dup2_x1, JBC_dup2_x2, JBC_f2d, JBC_f2i, JBC_f2l, JBC_fadd, JBC_faload, JBC_fastore, JBC_fcmpg, JBC_fcmpl, JBC_fconst_0, JBC_fconst_1, JBC_fconst_2, JBC_fdiv, JBC_fload, JBC_fload_0, JBC_fload_1, JBC_fload_2, JBC_fload_3, JBC_fmul, JBC_fneg, JBC_frem, JBC_freturn, JBC_fstore, JBC_fstore_0, JBC_fstore_1, JBC_fstore_2, JBC_fstore_3, JBC_fsub, JBC_getfield, JBC_getstatic, JBC_goto, JBC_goto_w, JBC_i2d, JBC_i2f, JBC_i2l, JBC_iadd, JBC_iaload, JBC_iand, JBC_iastore, JBC_iconst_0, JBC_iconst_1, JBC_iconst_2, JBC_iconst_3, JBC_iconst_4, JBC_iconst_5, JBC_iconst_m1, JBC_idiv, JBC_if_acmpeq, JBC_if_acmpne, JBC_if_icmpeq, JBC_if_icmpge, JBC_if_icmpgt, JBC_if_icmple, JBC_if_icmplt, JBC_if_icmpne, JBC_ifeq, JBC_ifge, JBC_ifgt, JBC_ifle, JBC_iflt, JBC_ifne, JBC_ifnonnull, JBC_ifnull, JBC_iinc, JBC_iload, JBC_iload_0, JBC_iload_1, JBC_iload_2, JBC_iload_3, JBC_impdep1, JBC_impdep2, JBC_imul, JBC_ineg, JBC_instanceof, JBC_int2byte, JBC_int2char, JBC_int2short, JBC_invokeinterface, JBC_invokespecial, JBC_invokestatic, JBC_invokevirtual, JBC_ior, JBC_irem, JBC_ireturn, JBC_ishl, JBC_ishr, JBC_istore, JBC_istore_0, JBC_istore_1, JBC_istore_2, JBC_istore_3, JBC_isub, JBC_iushr, JBC_ixor, JBC_jsr, JBC_jsr_w, JBC_l2d, JBC_l2f, JBC_l2i, JBC_ladd, JBC_laload, JBC_land, JBC_lastore, JBC_lcmp, JBC_lconst_0, JBC_lconst_1, JBC_ldc, JBC_ldc_w, JBC_ldc2_w, JBC_ldiv, JBC_length, JBC_lload, JBC_lload_0, JBC_lload_1, JBC_lload_2, JBC_lload_3, JBC_lmul, JBC_lneg, JBC_lookupswitch, JBC_lor, JBC_lrem, JBC_lreturn, JBC_lshl, JBC_lshr, JBC_lstore, JBC_lstore_0, JBC_lstore_1, JBC_lstore_2, JBC_lstore_3, JBC_lsub, JBC_lushr, JBC_lxor, JBC_monitorenter, JBC_monitorexit, JBC_multianewarray, JBC_name, JBC_new, JBC_newarray, JBC_nop, JBC_pop, JBC_pop2, JBC_putfield, JBC_putstatic, JBC_ret, JBC_return, JBC_saload, JBC_sastore, JBC_sipush, JBC_swap, JBC_tableswitch, JBC_wide, JBC_xxxunusedxxx
 
Fields inherited from interface org.jikesrvm.osr.OSRConstants
ACONST, BCI_MASK, BCI_SHIFT, CLEANREFS, DOUBLE, FLOAT, GETREFAT, HIGH_64BIT, ICONST, IEI_MASK, IEI_SHIFT, INT, INVALID_BCI, INVALID_IEI, KIND_MASK, KIND_SHIFT, LCONST, LOCAL, LONG, NEXT_BIT, NO_OSR_ENTRY, NUM_MASK, NUM_SHIFT, OFFSET_MASK, OFFSET_SHIFT, OSRI_MASK, OSRI_SHIFT, PHYREG, PSEUDO_CheckCast, PSEUDO_InvokeCompiledMethod, PSEUDO_InvokeStatic, PSEUDO_LoadDoubleConst, PSEUDO_LoadFloatConst, PSEUDO_LoadIntConst, PSEUDO_LoadLongConst, PSEUDO_LoadRetAddrConst, PSEUDO_LoadWordConst, PSEUDO_ParamInitEnd, REF, RET_ADDR, ReturnAddressTypeCode, SPILL, STACK, TCODE_MASK, TCODE_SHIFT, VTYPE_MASK, VTYPE_SHIFT, WORD, WordTypeCode
 
Fields inherited from interface org.jikesrvm.SizeConstants
BITS_IN_ADDRESS, BITS_IN_BOOLEAN, BITS_IN_BYTE, BITS_IN_CHAR, BITS_IN_DOUBLE, BITS_IN_EXTENT, BITS_IN_FLOAT, BITS_IN_INT, BITS_IN_LONG, BITS_IN_OFFSET, BITS_IN_PAGE, BITS_IN_SHORT, BITS_IN_WORD, BYTES_IN_ADDRESS, BYTES_IN_BOOLEAN, BYTES_IN_BYTE, BYTES_IN_CHAR, BYTES_IN_DOUBLE, BYTES_IN_EXTENT, BYTES_IN_FLOAT, BYTES_IN_INT, BYTES_IN_LONG, BYTES_IN_OFFSET, BYTES_IN_PAGE, BYTES_IN_SHORT, BYTES_IN_WORD, LOG_BITS_IN_ADDRESS, LOG_BITS_IN_BOOLEAN, LOG_BITS_IN_BYTE, LOG_BITS_IN_CHAR, LOG_BITS_IN_DOUBLE, LOG_BITS_IN_EXTENT, LOG_BITS_IN_FLOAT, LOG_BITS_IN_INT, LOG_BITS_IN_LONG, LOG_BITS_IN_OFFSET, LOG_BITS_IN_PAGE, LOG_BITS_IN_SHORT, LOG_BITS_IN_WORD, LOG_BYTES_IN_ADDRESS, LOG_BYTES_IN_BOOLEAN, LOG_BYTES_IN_BYTE, LOG_BYTES_IN_CHAR, LOG_BYTES_IN_DOUBLE, LOG_BYTES_IN_EXTENT, LOG_BYTES_IN_FLOAT, LOG_BYTES_IN_INT, LOG_BYTES_IN_LONG, LOG_BYTES_IN_OFFSET, LOG_BYTES_IN_PAGE, LOG_BYTES_IN_SHORT, LOG_BYTES_IN_WORD
 
Fields inherited from interface org.jikesrvm.classloader.ClassLoaderConstants
ACC_ABSTRACT, ACC_ANNOTATION, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_TRANSIENT, ACC_VOLATILE, APPLICABLE_TO_CLASSES, APPLICABLE_TO_FIELDS, APPLICABLE_TO_METHODS, ArrayTypeCode, BooleanTypeCode, BRIDGE, ByteTypeCode, CharTypeCode, CLASS_INITIALIZED, CLASS_INITIALIZER_FAILED, CLASS_INITIALIZING, CLASS_INSTANTIATED, CLASS_LOADED, CLASS_RESOLVED, CLASS_VACANT, ClassTypeCode, CP_CLASS, CP_DOUBLE, CP_FLOAT, CP_INT, CP_LONG, CP_MEMBER, CP_STRING, CP_UTF, DoubleTypeCode, FloatTypeCode, IntTypeCode, LongTypeCode, ShortTypeCode, TAG_DOUBLE, TAG_FIELDREF, TAG_FLOAT, TAG_INT, TAG_INTERFACE_METHODREF, TAG_LONG, TAG_MEMBERNAME_AND_DESCRIPTOR, TAG_METHODREF, TAG_STRING, TAG_TYPEREF, TAG_UNUSED, TAG_UTF, VARARGS, VoidTypeCode
 
Constructor Summary
BytecodeTraverser()
           
 
Method Summary
 boolean computeLocalStackTypes(NormalMethod method, int bcpoint)
          Computes types of local variable and stack slots at an interesting point for future querying.
 void computeStackHeights(NormalMethod method, BytecodeStream bcodes, int[] stackHeights, boolean adjustExptable)
           
 byte[] getLocalTypes()
          Returns an array of type information of locals at the registered program point.
private  byte getReturnCodeFromSignature(String sig)
           
 byte[] getStackTypes()
          Returns an array of type information of stacks at a program point.
 void prologueStackHeights(NormalMethod method, BytecodeStream bcodes, int[] stackHeights)
          Compute stack heights of bytecode stream (used for osr prologue)
private  boolean scanBlocks(NormalMethod method, BytecodeStream bytecodes, boolean doDFS, int pcs, byte[] ltypes, byte[] stypes, int startpc, TypeStack S, int[] stackHeights)
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

retaddr

private int[] retaddr

addr

private int addr

visitedpc

private byte[] visitedpc

TRACE

private boolean TRACE

ignoreGotos

private boolean ignoreGotos

bytecodes

private BytecodeStream bytecodes

ltypes

private byte[] ltypes

stypes

private byte[] stypes
Constructor Detail

BytecodeTraverser

public BytecodeTraverser()
Method Detail

computeLocalStackTypes

public boolean computeLocalStackTypes(NormalMethod method,
                                      int bcpoint)
Computes types of local variable and stack slots at an interesting point for future querying. Computing type info and retrieval should not be reentered. The type info of local variable is not accurate about reference types, see JVM SPEC (2nd edition) p 146. The caller can consult GC map to verify if a local is a reference or not.

Parameters:
method - whose bytecode to be queried
bcpoint - the bytecode index which is the interesting point at the mean time, we only support one PC.
Returns:
whether the pc is a valid program point of the method

getLocalTypes

public byte[] getLocalTypes()
Returns an array of type information of locals at the registered program point. The size of array is fixed by MAX_LOCALS, the type descriptor can be found in "ClassLoadConstants.java".

Returns:
an array of type information, or null

getStackTypes

public byte[] getStackTypes()
Returns an array of type information of stacks at a program point. The size of array is fixed by MAX_STACKS, the type descriptor can be found in "ClassLoadConstants.java".

Returns:
an array of type information, or null

computeStackHeights

public void computeStackHeights(NormalMethod method,
                                BytecodeStream bcodes,
                                int[] stackHeights,
                                boolean adjustExptable)

prologueStackHeights

public void prologueStackHeights(NormalMethod method,
                                 BytecodeStream bcodes,
                                 int[] stackHeights)
Compute stack heights of bytecode stream (used for osr prologue)


getReturnCodeFromSignature

private byte getReturnCodeFromSignature(String sig)

scanBlocks

private boolean scanBlocks(NormalMethod method,
                           BytecodeStream bytecodes,
                           boolean doDFS,
                           int pcs,
                           byte[] ltypes,
                           byte[] stypes,
                           int startpc,
                           TypeStack S,
                           int[] stackHeights)