Search in sources :

Example 1 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BuildReferenceMaps method buildReferenceMaps.

/**
 * After the analysis of the blocks of a method, examine the byte codes again, to
 * determine the reference maps for the gc points. Record the maps with
 * referenceMaps.
 *
 * @param method the method whose bytecodes are to be examined again
 * @param stackHeights height of the expression stack at each bytecode
 * @param localTypes the types that the locals can take
 * @param referenceMaps the reference map. NB: the map's constructor is still running
 *  while this method is called!
 * @param buildBB the buildBB instance that contains the results from the
 *  previous analysis
 *
 * @see BaselineCompiler#localTypes
 * @see TemplateCompilerFramework#stackHeights
 */
public void buildReferenceMaps(NormalMethod method, int[] stackHeights, byte[] localTypes, ReferenceMaps referenceMaps, BuildBB buildBB) {
    // ****************************************************************//
    // These were calculated by BuildBB.determineTheBasicBlocks    //
    // ****************************************************************//
    int gcPointCount = buildBB.gcPointCount;
    short[] byteToBlockMap = buildBB.byteToBlockMap;
    BasicBlock[] basicBlocks = buildBB.basicBlocks;
    int jsrCount = buildBB.numJsrs;
    // The starting map for each block, a block is not
    byte[][] bbMaps;
    // processed until it has a starting map.
    // For each block, track where its current stack top is.
    int[] blockStkTop;
    // Block number of block currently being processed
    int currBBNum;
    // The current map, used during processing thru a block
    byte[] currBBMap;
    // Stack top for the current map
    int currBBStkTop;
    // Level when stack is empty - value depends on number of locals
    final int currBBStkEmpty;
    // Number of parameters to the method being processed
    int paramCount;
    // Variables for processing JSR instructions, RET instructions and JSR subroutines
    PendingRETInfo[] bbPendingRETs = null;
    PendingRETInfo currPendingRET;
    JSRSubroutineInfo[] JSRSubs = null;
    // Blocks that need to be processed are put on the workStk
    short[] workStk;
    // Track whether a block has already been seen once. Any recording of maps done
    // within such a block will be processed as a "rerecording" instead of a new map.
    // 
    boolean[] blockSeen;
    // blocks that represent "catch" blocks need special processing. Catch blocks
    // also referred to as handlers
    // 
    // exception table class for method being processed
    ExceptionHandlerMap exceptions;
    // array of try start indicesinto byte code table
    int[] tryStartPC;
    // array of try end indices into byte code table
    int[] tryEndPC;
    // array of try handlers start indices into bytecode
    int[] tryHandlerPC;
    // length of try handlers array
    int tryHandlerLength;
    // array of reachable handlers from a given try block
    int[] reachableHandlerBBNums;
    // Number of reachable handlers
    int reachableHandlersCount;
    // Handler blocks are processed after the normal flow. As
    boolean[] handlerProcessed;
    // they may be nested, they need to be handled
    // individually. This array is used to track which
    // have been processed.
    boolean handlersAllDone;
    // Other local variables
    // 
    // byte codes for the method
    BytecodeStream bcodes;
    // For processing branches, need block number of target
    short brBBNum;
    final boolean debug = false;
    // Note that the mapping done here is "double mapping" of parameters.
    // Double mapping is when the parameters for a method are included in the map of
    // the method as well as in the map of the caller of the method. The original
    // intent was that with double mapping call sites that are tricks
    // (e.g. Magic.callFunctionReturnVoid ) would at least be correctly mapped on one
    // of the two sides. However with more recent changes to the runtime stack frame
    // layout, the parameters specified on the caller side occupy different
    // locations than the parameters on the callee side for the baseline compiler.
    // Thus both need to be described.
    // 
    // Initialization
    // 
    // Determine what stack empty looks like
    paramCount = method.getParameterWords();
    if (!method.isStatic())
        paramCount++;
    currBBStkEmpty = TemplateCompilerFramework.stackHeightForEmptyBasicBlock(method);
    if (debug) {
        VM.sysWriteln("getLocalWords() : " + method.getLocalWords());
        VM.sysWriteln("getOperandWords() : " + method.getOperandWords());
        VM.sysWriteln("getParameterWords() : " + method.getParameterWords());
    }
    // Get information from the method being processed
    bcodes = method.getBytecodes();
    // Set up the array of maps per block; block 0 is not used
    int numBB = buildBB.bbf.getNumberofBlocks();
    bbMaps = new byte[numBB + 1][];
    blockStkTop = new int[bbMaps.length];
    blockSeen = new boolean[bbMaps.length];
    // Try Handler processing initialization
    exceptions = method.getExceptionHandlerMap();
    if (exceptions != null) {
        tryStartPC = exceptions.getStartPC();
        tryEndPC = exceptions.getEndPC();
        tryHandlerPC = exceptions.getHandlerPC();
        tryHandlerLength = tryHandlerPC.length;
        reachableHandlerBBNums = new int[tryStartPC.length];
        handlerProcessed = new boolean[tryStartPC.length];
        if (jsrCount > 0) {
            JSRSubs = new JSRSubroutineInfo[jsrCount];
            JSRSubNext = 0;
            bbPendingRETs = new PendingRETInfo[bbMaps.length];
        }
        handlersAllDone = (tryHandlerLength == 0);
        // write poison values to help distinguish different errors
        for (int ii = 0; ii < reachableHandlerBBNums.length; ii++) {
            reachableHandlerBBNums[ii] = -1;
        }
    } else {
        tryHandlerLength = 0;
        handlersAllDone = true;
        tryStartPC = null;
        tryEndPC = null;
        tryHandlerPC = null;
        reachableHandlerBBNums = null;
        handlerProcessed = null;
    }
    reachableHandlersCount = 0;
    // Start a new set of maps with the reference Map class.
    // 3rd argument is parameter count included with the maps
    referenceMaps.startNewMaps(gcPointCount, jsrCount, paramCount);
    // Set up the Work stack
    workStk = new short[10 + tryHandlerLength];
    // Start by putting the first block on the work stack
    workStkTop = 0;
    workStk[workStkTop] = byteToBlockMap[0];
    currBBMap = new byte[method.getOperandWords() + currBBStkEmpty + 1];
    // 
    // Need to include the parameters of this method in the map
    // 
    TypeReference[] parameterTypes = method.getParameterTypes();
    int paramStart;
    if (!method.isStatic()) {
        // implicit "this" object
        currBBMap[0] = REFERENCE;
        localTypes[0] = ADDRESS_TYPE;
        paramStart = 1;
    } else {
        paramStart = 0;
    }
    for (int i = 0; i < parameterTypes.length; i++, paramStart++) {
        TypeReference parameterType = parameterTypes[i];
        if (parameterType.isReferenceType()) {
            localTypes[paramStart] = ADDRESS_TYPE;
            currBBMap[paramStart] = REFERENCE;
        } else {
            currBBMap[paramStart] = NON_REFERENCE;
            if (parameterType.getStackWords() == 2) {
                if (parameterType.isLongType()) {
                    localTypes[paramStart] = LONG_TYPE;
                } else {
                    localTypes[paramStart] = DOUBLE_TYPE;
                }
                paramStart++;
            } else if (parameterType.isFloatType()) {
                localTypes[paramStart] = FLOAT_TYPE;
            } else if (parameterType.isIntLikeType()) {
                localTypes[paramStart] = INT_TYPE;
            } else {
                localTypes[paramStart] = ADDRESS_TYPE;
            }
        }
    }
    // The map for the start of the first block, is stack empty, with none
    // of the locals set yet
    // 
    currBBStkTop = currBBStkEmpty;
    bbMaps[byteToBlockMap[0]] = currBBMap;
    blockStkTop[byteToBlockMap[0]] = currBBStkTop;
    // For all methods, record a map at the start of the method for the corresponding
    // conditional call to "yield".
    referenceMaps.recordStkMap(0, currBBMap, currBBStkTop, false);
    currBBMap = new byte[currBBMap.length];
    // ----------------------------------------------------------
    while (workStkTop > -1) {
        // Get the next item off the work stack
        currBBNum = workStk[workStkTop];
        workStkTop--;
        boolean inJSRSub = false;
        if (bbMaps[currBBNum] != null) {
            currBBStkTop = blockStkTop[currBBNum];
            for (int k = 0; k <= currBBStkTop; k++) {
                currBBMap[k] = bbMaps[currBBNum][k];
            }
            if (jsrCount > 0 && basicBlocks[currBBNum].isInJSR()) {
                inJSRSub = true;
            }
        } else {
            VM.sysWrite("BuildReferenceMaps, error: found a block on work stack with");
            VM.sysWrite(" no starting map. The block number is ");
            VM.sysWrite(basicBlocks[currBBNum].getBlockNumber());
            VM.sysWriteln();
            VM.sysFail("BuildReferenceMaps work stack failure");
        }
        int start = basicBlocks[currBBNum].getStart();
        int end = basicBlocks[currBBNum].getEnd();
        if (jsrCount > 0 && inJSRSub) {
            currPendingRET = bbPendingRETs[currBBNum];
            if (basicBlocks[currBBNum].isTryStart()) {
                for (int k = 0; k < tryHandlerLength; k++) {
                    if (tryStartPC[k] == start) {
                        int handlerBBNum = byteToBlockMap[tryHandlerPC[k]];
                        bbPendingRETs[handlerBBNum] = new PendingRETInfo(currPendingRET);
                    }
                }
            }
            if (currPendingRET == null) {
                int[] preds = basicBlocks[currBBNum].getPredecessors();
                for (int i = 0; i < preds.length; i++) {
                    int predBB = preds[i];
                    if (bbPendingRETs[predBB] != null) {
                        currPendingRET = bbPendingRETs[predBB];
                        break;
                    }
                }
            }
            if (VM.VerifyAssertions) {
                if (currPendingRET == null) {
                    String msg = "No pending return found in block " + currBBNum;
                    VM._assert(VM.NOT_REACHED, msg);
                }
            }
        } else {
            currPendingRET = null;
        }
        boolean inTryBlock;
        if (basicBlocks[currBBNum].isTryBlock()) {
            inTryBlock = true;
            reachableHandlersCount = 0;
            for (int i = 0; i < tryHandlerLength; i++) {
                if (start <= tryEndPC[i] && end >= tryStartPC[i]) {
                    reachableHandlerBBNums[reachableHandlersCount] = byteToBlockMap[tryHandlerPC[i]];
                    reachableHandlersCount++;
                    int handlerBBNum = byteToBlockMap[tryHandlerPC[i]];
                    if (bbMaps[handlerBBNum] == null) {
                        bbMaps[handlerBBNum] = new byte[currBBMap.length];
                        for (int k = 0; k <= currBBStkEmpty; k++) {
                            bbMaps[handlerBBNum][k] = currBBMap[k];
                        }
                        bbMaps[handlerBBNum][currBBStkEmpty + 1] = REFERENCE;
                        blockStkTop[handlerBBNum] = currBBStkEmpty + 1;
                    } else {
                        if (inJSRSub && basicBlocks[handlerBBNum].isInJSR()) {
                            // Ensure SET_TO_NONREFERENCE is carried across
                            for (int k = 0; k <= currBBStkEmpty; k++) {
                                if (currBBMap[k] == SET_TO_NONREFERENCE && bbMaps[handlerBBNum][k] != SET_TO_NONREFERENCE) {
                                    handlerProcessed[i] = false;
                                    bbMaps[handlerBBNum][k] = SET_TO_NONREFERENCE;
                                }
                            }
                        } else if (inJSRSub) {
                            // realise JSR and SET_TO_NONREFERENCE becomes NON_REFERENCE
                            for (int k = 0; k <= currBBStkEmpty; k++) {
                                if (currBBMap[k] == SET_TO_NONREFERENCE && bbMaps[handlerBBNum][k] != NON_REFERENCE) {
                                    handlerProcessed[i] = false;
                                    bbMaps[handlerBBNum][k] = NON_REFERENCE;
                                }
                            }
                        } else {
                            // No JSRs involved, simply ensure NON_REFERENCE is carried over
                            for (int k = 0; k <= currBBStkEmpty; k++) {
                                if (currBBMap[k] == NON_REFERENCE && bbMaps[handlerBBNum][k] != NON_REFERENCE) {
                                    handlerProcessed[i] = false;
                                    bbMaps[handlerBBNum][k] = NON_REFERENCE;
                                }
                            }
                        }
                    }
                }
            }
        } else {
            inTryBlock = false;
        }
        boolean processNextBlock = true;
        bcodes.reset(start);
        while (bcodes.index() <= end) {
            int biStart = bcodes.index();
            int opcode = bcodes.nextInstruction();
            if (stackHeights != null) {
                if (VM.VerifyAssertions) {
                    if (currBBStkTop < currBBStkEmpty) {
                        String msg = "Stack height for current basic block is " + currBBStkTop + " which is less than the stack height for " + "an empty block (" + currBBStkEmpty + ").";
                        VM._assert(VM.NOT_REACHED, msg);
                    }
                }
                stackHeights[biStart] = currBBStkTop;
            }
            if (debug) {
                VM.sysWriteln("bytecode: " + JBC_name(opcode) + " (opcode : " + opcode + ")");
                VM.sysWrite("current map: ");
                for (int j = 0; j <= currBBStkTop; j++) {
                    VM.sysWrite(currBBMap[j]);
                }
                VM.sysWriteln();
            }
            switch(opcode) {
                case JBC_nop:
                    {
                        break;
                    }
                case JBC_aconst_null:
                    {
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = REFERENCE;
                        break;
                    }
                case JBC_aload_0:
                    {
                        int localNumber = 0;
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = inJSRSub ? REFERENCE : currBBMap[localNumber];
                        break;
                    }
                case JBC_aload_1:
                    {
                        int localNumber = 1;
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = inJSRSub ? REFERENCE : currBBMap[localNumber];
                        break;
                    }
                case JBC_aload_2:
                    {
                        int localNumber = 2;
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = inJSRSub ? REFERENCE : currBBMap[localNumber];
                        break;
                    }
                case JBC_aload_3:
                    {
                        int localNumber = 3;
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = inJSRSub ? REFERENCE : currBBMap[localNumber];
                        break;
                    }
                case JBC_aload:
                    {
                        int localNumber = bcodes.getLocalNumber();
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = inJSRSub ? REFERENCE : currBBMap[localNumber];
                        break;
                    }
                case JBC_iconst_m1:
                case JBC_iconst_0:
                case JBC_iconst_1:
                case JBC_iconst_2:
                case JBC_iconst_3:
                case JBC_iconst_4:
                case JBC_iconst_5:
                case JBC_fconst_0:
                case JBC_fconst_1:
                case JBC_fconst_2:
                case JBC_iload_0:
                case JBC_iload_1:
                case JBC_iload_2:
                case JBC_iload_3:
                case JBC_fload_0:
                case JBC_fload_1:
                case JBC_fload_2:
                case JBC_fload_3:
                case JBC_bipush:
                case JBC_iload:
                case JBC_fload:
                case JBC_sipush:
                case JBC_i2l:
                case JBC_i2d:
                case JBC_f2l:
                case JBC_f2d:
                    {
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = NON_REFERENCE;
                        // contains mix of 1,2,3 byte bytecodes
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_lconst_0:
                case JBC_lconst_1:
                case JBC_dconst_0:
                case JBC_dconst_1:
                case JBC_lload_0:
                case JBC_lload_1:
                case JBC_lload_2:
                case JBC_lload_3:
                case JBC_dload_0:
                case JBC_dload_1:
                case JBC_dload_2:
                case JBC_dload_3:
                case JBC_ldc2_w:
                case JBC_lload:
                case JBC_dload:
                    {
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = NON_REFERENCE;
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = NON_REFERENCE;
                        // mix of 1, 2, and 3 byte bytecodes
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_ldc:
                    {
                        currBBStkTop++;
                        int cpi = bcodes.getConstantIndex();
                        int type = bcodes.getConstantType(cpi);
                        if (type == CP_STRING || type == CP_CLASS) {
                            currBBMap[currBBStkTop] = REFERENCE;
                        } else {
                            currBBMap[currBBStkTop] = NON_REFERENCE;
                        }
                        break;
                    }
                case JBC_ldc_w:
                    {
                        currBBStkTop++;
                        int cpi = bcodes.getWideConstantIndex();
                        int type = bcodes.getConstantType(cpi);
                        if (type == CP_STRING || type == CP_CLASS) {
                            currBBMap[currBBStkTop] = REFERENCE;
                        } else {
                            currBBMap[currBBStkTop] = NON_REFERENCE;
                        }
                        break;
                    }
                case JBC_istore:
                    {
                        int index = bcodes.getLocalNumber();
                        if (!inJSRSub) {
                            currBBMap[index] = NON_REFERENCE;
                        } else {
                            currBBMap[index] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(index, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[index] |= INT_TYPE;
                        break;
                    }
                case JBC_fstore:
                    {
                        int index = bcodes.getLocalNumber();
                        if (!inJSRSub) {
                            currBBMap[index] = NON_REFERENCE;
                        } else {
                            currBBMap[index] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(index, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[index] |= FLOAT_TYPE;
                        break;
                    }
                case JBC_lstore:
                    {
                        int index = bcodes.getLocalNumber();
                        if (!inJSRSub) {
                            currBBMap[index] = NON_REFERENCE;
                            currBBMap[index + 1] = NON_REFERENCE;
                        } else {
                            currBBMap[index] = SET_TO_NONREFERENCE;
                            currBBMap[index + 1] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(index, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[index] |= LONG_TYPE;
                        break;
                    }
                case JBC_dstore:
                    {
                        int index = bcodes.getLocalNumber();
                        if (!inJSRSub) {
                            currBBMap[index] = NON_REFERENCE;
                            currBBMap[index + 1] = NON_REFERENCE;
                        } else {
                            currBBMap[index] = SET_TO_NONREFERENCE;
                            currBBMap[index + 1] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(index, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[index] |= DOUBLE_TYPE;
                        break;
                    }
                case JBC_astore:
                    {
                        int index = bcodes.getLocalNumber();
                        // may be a reference or a return address
                        currBBMap[index] = currBBMap[currBBStkTop];
                        if (inJSRSub) {
                            if (currBBMap[index] == RETURN_ADDRESS) {
                                currPendingRET.updateReturnAddressLocation(index);
                            }
                            if (inTryBlock) {
                                if (currBBMap[index] == REFERENCE) {
                                    setHandlersMapsRef(index, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                } else {
                                    setHandlersMapsReturnAddress(index, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                }
                            }
                        }
                        currBBStkTop--;
                        localTypes[index] |= ADDRESS_TYPE;
                        break;
                    }
                case JBC_istore_0:
                    {
                        if (!inJSRSub) {
                            currBBMap[0] = NON_REFERENCE;
                        } else {
                            currBBMap[0] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(0, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[0] |= INT_TYPE;
                        break;
                    }
                case JBC_fstore_0:
                    {
                        if (!inJSRSub) {
                            currBBMap[0] = NON_REFERENCE;
                        } else {
                            currBBMap[0] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(0, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[0] |= FLOAT_TYPE;
                        break;
                    }
                case JBC_istore_1:
                    {
                        if (!inJSRSub) {
                            currBBMap[1] = NON_REFERENCE;
                        } else {
                            currBBMap[1] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(1, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[1] |= INT_TYPE;
                        break;
                    }
                case JBC_fstore_1:
                    {
                        if (!inJSRSub) {
                            currBBMap[1] = NON_REFERENCE;
                        } else {
                            currBBMap[1] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(1, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[1] |= FLOAT_TYPE;
                        break;
                    }
                case JBC_istore_2:
                    {
                        if (!inJSRSub) {
                            currBBMap[2] = NON_REFERENCE;
                        } else {
                            currBBMap[2] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(2, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[2] |= INT_TYPE;
                        break;
                    }
                case JBC_fstore_2:
                    {
                        if (!inJSRSub) {
                            currBBMap[2] = NON_REFERENCE;
                        } else {
                            currBBMap[2] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(2, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[2] |= FLOAT_TYPE;
                        break;
                    }
                case JBC_istore_3:
                    {
                        if (!inJSRSub) {
                            currBBMap[3] = NON_REFERENCE;
                        } else {
                            currBBMap[3] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(3, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[3] |= INT_TYPE;
                        break;
                    }
                case JBC_fstore_3:
                    {
                        if (!inJSRSub) {
                            currBBMap[3] = NON_REFERENCE;
                        } else {
                            currBBMap[3] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(3, PrimitiveSize.ONEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop--;
                        localTypes[3] |= FLOAT_TYPE;
                        break;
                    }
                case JBC_lstore_0:
                    {
                        if (inJSRSub) {
                            currBBMap[0] = NON_REFERENCE;
                            currBBMap[1] = NON_REFERENCE;
                        } else {
                            currBBMap[0] = SET_TO_NONREFERENCE;
                            currBBMap[1] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(0, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[0] |= LONG_TYPE;
                        break;
                    }
                case JBC_dstore_0:
                    {
                        if (inJSRSub) {
                            currBBMap[0] = NON_REFERENCE;
                            currBBMap[1] = NON_REFERENCE;
                        } else {
                            currBBMap[0] = SET_TO_NONREFERENCE;
                            currBBMap[1] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(0, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[0] |= DOUBLE_TYPE;
                        break;
                    }
                case JBC_lstore_1:
                    {
                        if (!inJSRSub) {
                            currBBMap[1] = NON_REFERENCE;
                            currBBMap[2] = NON_REFERENCE;
                        } else {
                            currBBMap[1] = SET_TO_NONREFERENCE;
                            currBBMap[2] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(1, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[1] |= LONG_TYPE;
                        break;
                    }
                case JBC_dstore_1:
                    {
                        if (!inJSRSub) {
                            currBBMap[1] = NON_REFERENCE;
                            currBBMap[2] = NON_REFERENCE;
                        } else {
                            currBBMap[1] = SET_TO_NONREFERENCE;
                            currBBMap[2] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(1, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[1] |= DOUBLE_TYPE;
                        break;
                    }
                case JBC_lstore_2:
                    {
                        if (!inJSRSub) {
                            currBBMap[2] = NON_REFERENCE;
                            currBBMap[3] = NON_REFERENCE;
                        } else {
                            currBBMap[2] = SET_TO_NONREFERENCE;
                            currBBMap[3] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(2, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[2] |= LONG_TYPE;
                        break;
                    }
                case JBC_dstore_2:
                    {
                        if (!inJSRSub) {
                            currBBMap[2] = NON_REFERENCE;
                            currBBMap[3] = NON_REFERENCE;
                        } else {
                            currBBMap[2] = SET_TO_NONREFERENCE;
                            currBBMap[3] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(2, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[2] |= DOUBLE_TYPE;
                        break;
                    }
                case JBC_lstore_3:
                    {
                        if (!inJSRSub) {
                            currBBMap[3] = NON_REFERENCE;
                            currBBMap[4] = NON_REFERENCE;
                        } else {
                            currBBMap[3] = SET_TO_NONREFERENCE;
                            currBBMap[4] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(3, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[3] |= LONG_TYPE;
                        break;
                    }
                case JBC_dstore_3:
                    {
                        if (!inJSRSub) {
                            currBBMap[3] = NON_REFERENCE;
                            currBBMap[4] = NON_REFERENCE;
                        } else {
                            currBBMap[3] = SET_TO_NONREFERENCE;
                            currBBMap[4] = SET_TO_NONREFERENCE;
                        }
                        if (inTryBlock) {
                            setHandlersMapsNonRef(3, PrimitiveSize.DOUBLEWORD, reachableHandlerBBNums, reachableHandlersCount, inJSRSub, bbMaps);
                        }
                        currBBStkTop = currBBStkTop - 2;
                        localTypes[3] |= DOUBLE_TYPE;
                        break;
                    }
                case JBC_astore_0:
                    {
                        currBBMap[0] = currBBMap[currBBStkTop];
                        if (inJSRSub) {
                            if (currBBMap[0] == RETURN_ADDRESS) {
                                currPendingRET.updateReturnAddressLocation(0);
                            }
                            if (inTryBlock) {
                                if (currBBMap[0] == REFERENCE) {
                                    setHandlersMapsRef(0, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                } else {
                                    setHandlersMapsReturnAddress(0, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                }
                            }
                        }
                        currBBStkTop--;
                        localTypes[0] |= ADDRESS_TYPE;
                        break;
                    }
                case JBC_astore_1:
                    {
                        currBBMap[1] = currBBMap[currBBStkTop];
                        if (inJSRSub) {
                            if (currBBMap[1] == RETURN_ADDRESS) {
                                currPendingRET.updateReturnAddressLocation(1);
                            }
                            if (inTryBlock) {
                                if (currBBMap[1] == REFERENCE) {
                                    setHandlersMapsRef(1, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                } else {
                                    setHandlersMapsReturnAddress(1, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                }
                            }
                        }
                        currBBStkTop--;
                        localTypes[1] |= ADDRESS_TYPE;
                        break;
                    }
                case JBC_astore_2:
                    {
                        currBBMap[2] = currBBMap[currBBStkTop];
                        if (inJSRSub) {
                            if (currBBMap[2] == RETURN_ADDRESS) {
                                currPendingRET.updateReturnAddressLocation(2);
                            }
                            if (inTryBlock) {
                                if (currBBMap[2] == REFERENCE) {
                                    setHandlersMapsRef(2, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                } else {
                                    setHandlersMapsReturnAddress(2, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                }
                            }
                        }
                        currBBStkTop--;
                        localTypes[2] |= ADDRESS_TYPE;
                        break;
                    }
                case JBC_astore_3:
                    {
                        currBBMap[3] = currBBMap[currBBStkTop];
                        if (inJSRSub) {
                            if (currBBMap[3] == RETURN_ADDRESS) {
                                currPendingRET.updateReturnAddressLocation(3);
                            }
                            if (inTryBlock) {
                                if (currBBMap[3] == REFERENCE) {
                                    setHandlersMapsRef(3, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                } else {
                                    setHandlersMapsReturnAddress(3, reachableHandlerBBNums, reachableHandlersCount, bbMaps);
                                }
                            }
                        }
                        currBBStkTop--;
                        localTypes[3] |= ADDRESS_TYPE;
                        break;
                    }
                case JBC_dup:
                    {
                        currBBMap[currBBStkTop + 1] = currBBMap[currBBStkTop];
                        currBBStkTop++;
                        break;
                    }
                case JBC_dup2:
                    {
                        currBBMap[currBBStkTop + 1] = currBBMap[currBBStkTop - 1];
                        currBBMap[currBBStkTop + 2] = currBBMap[currBBStkTop];
                        currBBStkTop = currBBStkTop + 2;
                        break;
                    }
                case JBC_dup_x1:
                    {
                        currBBMap[currBBStkTop + 1] = currBBMap[currBBStkTop];
                        currBBMap[currBBStkTop] = currBBMap[currBBStkTop - 1];
                        currBBMap[currBBStkTop - 1] = currBBMap[currBBStkTop + 1];
                        currBBStkTop++;
                        break;
                    }
                case JBC_dup2_x1:
                    {
                        currBBMap[currBBStkTop + 2] = currBBMap[currBBStkTop];
                        currBBMap[currBBStkTop + 1] = currBBMap[currBBStkTop - 1];
                        currBBMap[currBBStkTop] = currBBMap[currBBStkTop - 2];
                        currBBMap[currBBStkTop - 1] = currBBMap[currBBStkTop + 2];
                        currBBMap[currBBStkTop - 2] = currBBMap[currBBStkTop + 1];
                        currBBStkTop = currBBStkTop + 2;
                        break;
                    }
                case JBC_dup_x2:
                    {
                        currBBMap[currBBStkTop + 1] = currBBMap[currBBStkTop];
                        currBBMap[currBBStkTop] = currBBMap[currBBStkTop - 1];
                        currBBMap[currBBStkTop - 1] = currBBMap[currBBStkTop - 2];
                        currBBMap[currBBStkTop - 2] = currBBMap[currBBStkTop + 1];
                        currBBStkTop++;
                        break;
                    }
                case JBC_dup2_x2:
                    {
                        currBBMap[currBBStkTop + 2] = currBBMap[currBBStkTop];
                        currBBMap[currBBStkTop + 1] = currBBMap[currBBStkTop - 1];
                        currBBMap[currBBStkTop] = currBBMap[currBBStkTop - 2];
                        currBBMap[currBBStkTop - 1] = currBBMap[currBBStkTop - 3];
                        currBBMap[currBBStkTop - 2] = currBBMap[currBBStkTop + 2];
                        currBBMap[currBBStkTop - 3] = currBBMap[currBBStkTop + 1];
                        currBBStkTop = currBBStkTop + 2;
                        break;
                    }
                case JBC_swap:
                    {
                        byte temp;
                        temp = currBBMap[currBBStkTop];
                        currBBMap[currBBStkTop] = currBBMap[currBBStkTop - 1];
                        currBBMap[currBBStkTop - 1] = temp;
                        break;
                    }
                case JBC_pop:
                case JBC_iadd:
                case JBC_fadd:
                case JBC_isub:
                case JBC_fsub:
                case JBC_imul:
                case JBC_fmul:
                case JBC_fdiv:
                case JBC_frem:
                case JBC_ishl:
                case JBC_ishr:
                case JBC_iushr:
                // long shifts that int shift value
                case JBC_lshl:
                case JBC_lshr:
                case JBC_lushr:
                case JBC_iand:
                case JBC_ior:
                case JBC_ixor:
                case JBC_l2i:
                case JBC_l2f:
                case JBC_d2i:
                case JBC_d2f:
                case JBC_fcmpl:
                case JBC_fcmpg:
                    {
                        currBBStkTop--;
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_irem:
                case JBC_idiv:
                    {
                        // record map after 2 integers popped off stack
                        currBBStkTop = currBBStkTop - 2;
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop++;
                        break;
                    }
                case JBC_ladd:
                case JBC_dadd:
                case JBC_lsub:
                case JBC_dsub:
                case JBC_lmul:
                case JBC_dmul:
                case JBC_ddiv:
                case JBC_drem:
                case JBC_land:
                case JBC_lor:
                case JBC_lxor:
                case JBC_pop2:
                    {
                        currBBStkTop = currBBStkTop - 2;
                        break;
                    }
                case JBC_lrem:
                case JBC_ldiv:
                    {
                        // record map after 2 longs popped off stack
                        currBBStkTop = currBBStkTop - 4;
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop = currBBStkTop + 2;
                        break;
                    }
                case JBC_ineg:
                case JBC_lneg:
                case JBC_fneg:
                case JBC_dneg:
                case JBC_iinc:
                case JBC_i2f:
                case JBC_l2d:
                case JBC_f2i:
                case JBC_d2l:
                case JBC_int2byte:
                case JBC_int2char:
                case JBC_int2short:
                    {
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_lcmp:
                case JBC_dcmpl:
                case JBC_dcmpg:
                    {
                        currBBStkTop = currBBStkTop - 3;
                        break;
                    }
                case JBC_ifeq:
                case JBC_ifne:
                case JBC_iflt:
                case JBC_ifge:
                case JBC_ifgt:
                case JBC_ifle:
                    {
                        int offset = bcodes.getBranchOffset();
                        if (offset <= 0) {
                            if (!inJSRSub) {
                                referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                            } else {
                                // in a jsr subroutine
                                referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                            }
                        }
                        // process the basic block logic
                        currBBStkTop--;
                        if (offset <= 0) {
                            short fallThruBBNum = byteToBlockMap[biStart + 3];
                            workStk = processBranchBB(fallThruBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                            processNextBlock = false;
                        }
                        brBBNum = byteToBlockMap[biStart + offset];
                        workStk = processBranchBB(brBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        break;
                    }
                case JBC_if_icmpeq:
                case JBC_if_icmpne:
                case JBC_if_icmplt:
                case JBC_if_icmpge:
                case JBC_if_icmpgt:
                case JBC_if_icmple:
                case JBC_if_acmpeq:
                case JBC_if_acmpne:
                    {
                        int offset = bcodes.getBranchOffset();
                        if (offset <= 0) {
                            if (!inJSRSub) {
                                referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                            } else {
                                // in a jsr subroutine
                                referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                            }
                        }
                        // process the basic blocks
                        currBBStkTop = currBBStkTop - 2;
                        if (offset <= 0) {
                            short fallThruBBNum = byteToBlockMap[biStart + 3];
                            workStk = processBranchBB(fallThruBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                            processNextBlock = false;
                        }
                        brBBNum = byteToBlockMap[biStart + offset];
                        workStk = processBranchBB(brBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        break;
                    }
                case JBC_ifnull:
                case JBC_ifnonnull:
                    {
                        int offset = bcodes.getBranchOffset();
                        if (offset <= 0) {
                            if (!inJSRSub) {
                                referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                            } else {
                                // in a jsr subroutine
                                referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                            }
                        }
                        // process the basic block logic
                        currBBStkTop--;
                        if (offset <= 0) {
                            short fallThruBBNum = byteToBlockMap[biStart + 3];
                            workStk = processBranchBB(fallThruBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                            processNextBlock = false;
                        }
                        brBBNum = byteToBlockMap[biStart + offset];
                        workStk = processBranchBB(brBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        break;
                    }
                case JBC_goto:
                    {
                        int offset = bcodes.getBranchOffset();
                        if (offset <= 0) {
                            // Register the reference map
                            if (!inJSRSub) {
                                referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                            } else {
                                // in a jsr subroutine
                                referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                            }
                        }
                        // process the basic block logic
                        brBBNum = byteToBlockMap[biStart + offset];
                        workStk = processBranchBB(brBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        processNextBlock = false;
                        break;
                    }
                case JBC_goto_w:
                    {
                        int offset = bcodes.getWideBranchOffset();
                        if (offset <= 0) {
                            if (!inJSRSub) {
                                referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                            } else {
                                // in a jsr subroutine
                                referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                            }
                        }
                        // process basic block structures
                        brBBNum = byteToBlockMap[biStart + offset];
                        workStk = processBranchBB(brBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        processNextBlock = false;
                        break;
                    }
                case JBC_tableswitch:
                    {
                        currBBStkTop--;
                        bcodes.alignSwitch();
                        // get default offset and process branch to default branch point
                        int def = bcodes.getDefaultSwitchOffset();
                        workStk = processBranchBB(byteToBlockMap[biStart + def], currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        int low = bcodes.getLowSwitchValue();
                        int high = bcodes.getHighSwitchValue();
                        int n = high - low + 1;
                        // generate labels for offsets
                        for (int k = 0; k < n; k++) {
                            int offset = bcodes.getTableSwitchOffset(k);
                            workStk = processBranchBB(byteToBlockMap[biStart + offset], currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        }
                        bcodes.skipTableSwitchOffsets(n);
                        processNextBlock = false;
                        break;
                    }
                case JBC_lookupswitch:
                    {
                        currBBStkTop--;
                        bcodes.alignSwitch();
                        // get default offset and process branch to default branch point
                        int def = bcodes.getDefaultSwitchOffset();
                        workStk = processBranchBB(byteToBlockMap[biStart + def], currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        int npairs = bcodes.getSwitchLength();
                        // generate label for each offset in table
                        for (int k = 0; k < npairs; k++) {
                            int offset = bcodes.getLookupSwitchOffset(k);
                            workStk = processBranchBB(byteToBlockMap[biStart + offset], currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
                        }
                        bcodes.skipLookupSwitchPairs(npairs);
                        processNextBlock = false;
                        break;
                    }
                case JBC_jsr:
                    {
                        processNextBlock = false;
                        int offset = bcodes.getBranchOffset();
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkEmpty, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkEmpty, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = RETURN_ADDRESS;
                        workStk = processJSR(byteToBlockMap[biStart], biStart + offset, byteToBlockMap[biStart + offset], byteToBlockMap[biStart + 3], bbMaps, currBBStkTop, currBBMap, currBBStkEmpty, blockStkTop, bbPendingRETs, currPendingRET, JSRSubs, workStk);
                        break;
                    }
                case JBC_jsr_w:
                    {
                        processNextBlock = false;
                        int offset = bcodes.getWideBranchOffset();
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkEmpty, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkEmpty, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = RETURN_ADDRESS;
                        workStk = processJSR(byteToBlockMap[biStart], biStart + offset, byteToBlockMap[biStart + offset], byteToBlockMap[biStart + 5], bbMaps, currBBStkTop, currBBMap, currBBStkEmpty, blockStkTop, bbPendingRETs, currPendingRET, JSRSubs, workStk);
                        break;
                    }
                case JBC_ret:
                    {
                        int index = bcodes.getLocalNumber();
                        // Can not be used again as a return addr.
                        // 
                        currBBMap[index] = SET_TO_NONREFERENCE;
                        processNextBlock = false;
                        int subStart = currPendingRET.JSRSubStartByteIndex;
                        int k;
                        for (k = 0; k < JSRSubNext; k++) {
                            if (JSRSubs[k].subroutineByteCodeStart == subStart) {
                                JSRSubs[k].newEndMaps(currBBMap, currBBStkTop);
                                break;
                            }
                        }
                        boolean JSRisinJSRSub = bbPendingRETs[currPendingRET.JSRBBNum] != null;
                        workStk = computeJSRNextMaps(currPendingRET.JSRNextBBNum, currBBMap.length, k, JSRisinJSRSub, bbMaps, blockStkTop, JSRSubs, currBBStkEmpty, workStk);
                        if (JSRisinJSRSub && bbPendingRETs[currPendingRET.JSRNextBBNum] == null) {
                            bbPendingRETs[currPendingRET.JSRNextBBNum] = new PendingRETInfo(bbPendingRETs[currPendingRET.JSRBBNum]);
                        }
                        break;
                    }
                case JBC_invokevirtual:
                case JBC_invokespecial:
                    {
                        MethodReference target = bcodes.getMethodReference();
                        currBBStkTop = processInvoke(target, biStart, currBBStkTop, currBBMap, false, inJSRSub, referenceMaps, currPendingRET, blockSeen[currBBNum], currBBStkEmpty);
                        break;
                    }
                case JBC_invokeinterface:
                    {
                        MethodReference target = bcodes.getMethodReference();
                        bcodes.alignInvokeInterface();
                        currBBStkTop = processInvoke(target, biStart, currBBStkTop, currBBMap, false, inJSRSub, referenceMaps, currPendingRET, blockSeen[currBBNum], currBBStkEmpty);
                        break;
                    }
                case JBC_invokestatic:
                    {
                        MethodReference target = bcodes.getMethodReference();
                        currBBStkTop = processInvoke(target, biStart, currBBStkTop, currBBMap, true, inJSRSub, referenceMaps, currPendingRET, blockSeen[currBBNum], currBBStkEmpty);
                        break;
                    }
                case JBC_ireturn:
                case JBC_lreturn:
                case JBC_freturn:
                case JBC_dreturn:
                case JBC_areturn:
                case JBC_return:
                    {
                        if (VM.UseEpilogueYieldPoints || method.isSynchronized()) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        }
                        processNextBlock = false;
                        break;
                    }
                case JBC_getstatic:
                    {
                        // Register the reference map (could cause dynamic linking)
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        TypeReference fieldType = bcodes.getFieldReference().getFieldContentsType();
                        currBBMap[++currBBStkTop] = fieldType.isPrimitiveType() ? NON_REFERENCE : REFERENCE;
                        if (fieldType.getStackWords() == 2) {
                            currBBMap[++currBBStkTop] = NON_REFERENCE;
                        }
                        break;
                    }
                case JBC_putstatic:
                    {
                        // Register the reference map (could cause dynamic linking)
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        TypeReference fieldType = bcodes.getFieldReference().getFieldContentsType();
                        currBBStkTop--;
                        if (fieldType.getStackWords() == 2) {
                            currBBStkTop--;
                        }
                        break;
                    }
                case JBC_getfield:
                    {
                        TypeReference fieldType = bcodes.getFieldReference().getFieldContentsType();
                        // Register the reference map (could cause dynamic linking..if so there will be a NPE, but the linking happens first.)
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        // pop object pointer
                        currBBStkTop--;
                        currBBMap[++currBBStkTop] = fieldType.isPrimitiveType() ? NON_REFERENCE : REFERENCE;
                        if (fieldType.getStackWords() == 2) {
                            currBBMap[++currBBStkTop] = NON_REFERENCE;
                        }
                        break;
                    }
                case JBC_putfield:
                    {
                        TypeReference fieldType = bcodes.getFieldReference().getFieldContentsType();
                        // note: putfield could result in a call to the classloader
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        // remove objectref and one value
                        currBBStkTop -= 2;
                        if (fieldType.getStackWords() == 2) {
                            currBBStkTop--;
                        }
                        break;
                    }
                case JBC_checkcast:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_instanceof:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBMap[currBBStkTop] = NON_REFERENCE;
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_new:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop++;
                        currBBMap[currBBStkTop] = REFERENCE;
                        bcodes.skipInstruction();
                        break;
                    }
                // altered yet.
                case JBC_iaload:
                case JBC_faload:
                case JBC_baload:
                case JBC_caload:
                case JBC_saload:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop--;
                        currBBMap[currBBStkTop] = NON_REFERENCE;
                        break;
                    }
                case JBC_laload:
                case JBC_daload:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBMap[currBBStkTop - 1] = NON_REFERENCE;
                        break;
                    }
                case JBC_aaload:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop--;
                        break;
                    }
                // Stack has not been modified at this point.
                case JBC_iastore:
                case JBC_fastore:
                case JBC_aastore:
                case JBC_bastore:
                case JBC_castore:
                case JBC_sastore:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop = currBBStkTop - 3;
                        break;
                    }
                case JBC_lastore:
                case JBC_dastore:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop = currBBStkTop - 4;
                        break;
                    }
                case JBC_newarray:
                case JBC_anewarray:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBMap[currBBStkTop] = REFERENCE;
                        bcodes.skipInstruction();
                        break;
                    }
                case JBC_multianewarray:
                    {
                        bcodes.getTypeReference();
                        int dim = bcodes.getArrayDimension();
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop = currBBStkTop - dim + 1;
                        currBBMap[currBBStkTop] = REFERENCE;
                        break;
                    }
                case JBC_arraylength:
                    {
                        currBBMap[currBBStkTop] = NON_REFERENCE;
                        break;
                    }
                case JBC_athrow:
                    {
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        currBBStkTop = currBBStkEmpty + 1;
                        currBBMap[currBBStkTop] = REFERENCE;
                        processNextBlock = false;
                        break;
                    }
                case JBC_monitorenter:
                case JBC_monitorexit:
                    {
                        currBBStkTop--;
                        if (!inJSRSub) {
                            referenceMaps.recordStkMap(biStart, currBBMap, currBBStkTop, blockSeen[currBBNum]);
                        } else {
                            referenceMaps.recordJSRSubroutineMap(biStart, currBBMap, currBBStkTop, currPendingRET.returnAddressLocation, blockSeen[currBBNum]);
                        }
                        break;
                    }
                case JBC_wide:
                    {
                        int widecode = bcodes.getWideOpcode();
                        int index = bcodes.getWideLocalNumber();
                        switch(widecode) {
                            case JBC_iload:
                            case JBC_fload:
                                {
                                    currBBStkTop++;
                                    currBBMap[currBBStkTop] = NON_REFERENCE;
                                    break;
                                }
                            case JBC_lload:
                            case JBC_dload:
                                {
                                    currBBStkTop++;
                                    currBBMap[currBBStkTop] = NON_REFERENCE;
                                    currBBStkTop++;
                                    currBBMap[currBBStkTop] = NON_REFERENCE;
                                    break;
                                }
                            case JBC_aload:
                                {
                                    currBBStkTop++;
                                    currBBMap[currBBStkTop] = currBBMap[index];
                                    break;
                                }
                            case JBC_istore:
                                {
                                    if (!inJSRSub) {
                                        currBBMap[index] = NON_REFERENCE;
                                    } else {
                                        currBBMap[index] = SET_TO_NONREFERENCE;
                                    }
                                    currBBStkTop--;
                                    localTypes[index] |= INT_TYPE;
                                    break;
                                }
                            case JBC_fstore:
                                {
                                    if (!inJSRSub) {
                                        currBBMap[index] = NON_REFERENCE;
                                    } else {
                                        currBBMap[index] = SET_TO_NONREFERENCE;
                                    }
                                    currBBStkTop--;
                                    localTypes[index] |= FLOAT_TYPE;
                                    break;
                                }
                            case JBC_lstore:
                                {
                                    if (!inJSRSub) {
                                        currBBMap[index] = NON_REFERENCE;
                                        currBBMap[index + 1] = NON_REFERENCE;
                                    } else {
                                        currBBMap[index] = SET_TO_NONREFERENCE;
                                        currBBMap[index + 1] = SET_TO_NONREFERENCE;
                                    }
                                    currBBStkTop = currBBStkTop - 2;
                                    localTypes[index] |= LONG_TYPE;
                                    break;
                                }
                            case JBC_dstore:
                                {
                                    if (!inJSRSub) {
                                        currBBMap[index] = NON_REFERENCE;
                                        currBBMap[index + 1] = NON_REFERENCE;
                                    } else {
                                        currBBMap[index] = SET_TO_NONREFERENCE;
                                        currBBMap[index + 1] = SET_TO_NONREFERENCE;
                                    }
                                    currBBStkTop = currBBStkTop - 2;
                                    localTypes[index] |= DOUBLE_TYPE;
                                    break;
                                }
                            case JBC_astore:
                                {
                                    currBBMap[index] = currBBMap[currBBStkTop];
                                    currBBStkTop--;
                                    localTypes[index] |= ADDRESS_TYPE;
                                    break;
                                }
                            case JBC_iinc:
                                {
                                    bcodes.getWideIncrement();
                                    break;
                                }
                            case JBC_ret:
                                {
                                    // Can not be used again as a return addr.
                                    // 
                                    currBBMap[index] = SET_TO_NONREFERENCE;
                                    processNextBlock = false;
                                    int subStart = currPendingRET.JSRSubStartByteIndex;
                                    int k;
                                    for (k = 0; k < JSRSubNext; k++) {
                                        if (JSRSubs[k].subroutineByteCodeStart == subStart) {
                                            JSRSubs[k].newEndMaps(currBBMap, currBBStkTop);
                                            break;
                                        }
                                    }
                                    boolean JSRisinJSRSub = bbPendingRETs[currPendingRET.JSRBBNum] != null;
                                    workStk = computeJSRNextMaps(currPendingRET.JSRNextBBNum, currBBMap.length, k, JSRisinJSRSub, bbMaps, blockStkTop, JSRSubs, currBBStkEmpty, workStk);
                                    if (JSRisinJSRSub && bbPendingRETs[currPendingRET.JSRNextBBNum] == null) {
                                        bbPendingRETs[currPendingRET.JSRNextBBNum] = new PendingRETInfo(bbPendingRETs[currPendingRET.JSRBBNum]);
                                    }
                                    break;
                                }
                            default:
                                // switch on widecode
                                if (VM.VerifyAssertions)
                                    VM._assert(VM.NOT_REACHED);
                        }
                        break;
                    }
                default:
                    {
                        VM.sysFail("Unknown opcode:" + opcode);
                    }
            }
        // end switch (opcode)
        }
        // for start to end
        blockSeen[currBBNum] = true;
        if (processNextBlock) {
            short fallThruBBNum = byteToBlockMap[bcodes.index()];
            workStk = processBranchBB(fallThruBBNum, currBBStkTop, currBBMap, currBBStkEmpty, inJSRSub, bbMaps, blockStkTop, currPendingRET, bbPendingRETs, workStk);
        }
        // 
        if ((workStkTop == -1) && !handlersAllDone) {
            int i;
            for (i = 0; i < tryHandlerLength; i++) {
                // the try block must be in one of the other handlers
                if (!handlerProcessed[i] && bbMaps[byteToBlockMap[tryHandlerPC[i]]] != null)
                    break;
            }
            if (i == tryHandlerLength) {
                handlersAllDone = true;
            } else {
                int considerIndex = i;
                while (i != tryHandlerLength) {
                    int tryStart = tryStartPC[considerIndex];
                    int tryEnd = tryEndPC[considerIndex];
                    for (i = 0; i < tryHandlerLength; i++) {
                        // I'm not entirely convinced this is right, but don't know what else we can do. --dave
                        if (i == considerIndex)
                            continue;
                        // we are considering working on.
                        if (!handlerProcessed[i] && tryStart <= tryHandlerPC[i] && tryHandlerPC[i] < tryEnd && bbMaps[byteToBlockMap[tryHandlerPC[i]]] != null) {
                            break;
                        }
                    }
                    if (i != tryHandlerLength) {
                        considerIndex = i;
                    }
                }
                short blockNum = byteToBlockMap[tryHandlerPC[considerIndex]];
                handlerProcessed[considerIndex] = true;
                workStk = addToWorkStk(blockNum, workStk);
            }
        }
    }
    // while workStk not empty
    // Indicate that any temporaries can be freed
    referenceMaps.recordingComplete();
}
Also used : ExceptionHandlerMap(org.jikesrvm.classloader.ExceptionHandlerMap) BytecodeStream(org.jikesrvm.classloader.BytecodeStream) MethodReference(org.jikesrvm.classloader.MethodReference) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 2 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class VM method runClassInitializer.

/**
 * Run {@code <clinit>} method of specified class, if that class appears
 * in bootimage and actually has a clinit method (we are flexible to
 * allow one list of classes to work with different bootimages and
 * different version of classpath (eg 0.05 vs. cvs head).
 * <p>
 * This method is called only while the VM boots.
 *
 * @param className class whose initializer needs to be run
 */
@Interruptible
static void runClassInitializer(String className) {
    if (verboseBoot >= 2) {
        sysWrite("running class initializer for ");
        sysWriteln(className);
    }
    Atom classDescriptor = Atom.findOrCreateAsciiAtom(className.replace('.', '/')).descriptorFromClassName();
    TypeReference tRef = TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), classDescriptor);
    RVMClass cls = (RVMClass) tRef.peekType();
    if (null == cls) {
        sysWrite("Failed to run class initializer for ");
        sysWrite(className);
        sysWriteln(" as the class does not exist.");
    } else if (!cls.isInBootImage()) {
        sysWrite("Failed to run class initializer for ");
        sysWrite(className);
        sysWriteln(" as the class is not in the boot image.");
    } else {
        RVMMethod clinit = cls.getClassInitializerMethod();
        if (clinit != null) {
            clinit.compile();
            if (verboseBoot >= 10)
                VM.sysWriteln("invoking method " + clinit);
            try {
                Magic.invokeClassInitializer(clinit.getCurrentEntryCodeArray());
            } catch (Error e) {
                throw e;
            } catch (Throwable t) {
                ExceptionInInitializerError eieio = new ExceptionInInitializerError(t);
                throw eieio;
            }
            // <clinit> is no longer needed: reclaim space by removing references to it
            clinit.invalidateCompiledMethod(clinit.getCurrentCompiledMethod());
        } else {
            if (verboseBoot >= 10)
                VM.sysWriteln("has no clinit method ");
        }
        cls.setAllFinalStaticJTOCEntries();
    }
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) TypeReference(org.jikesrvm.classloader.TypeReference) Atom(org.jikesrvm.classloader.Atom) RVMClass(org.jikesrvm.classloader.RVMClass) Interruptible(org.vmmagic.pragma.Interruptible)

Example 3 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class Class method getDeclaredClasses.

public Class<?>[] getDeclaredClasses() throws SecurityException {
    checkMemberAccess(Member.DECLARED);
    if (!type.isClassType())
        return new Class[0];
    // Get array of declared classes from RVMClass object
    RVMClass cls = type.asClass();
    TypeReference[] declaredClasses = cls.getDeclaredClasses();
    // The array can be null if the class has no declared inner class members
    if (declaredClasses == null)
        return new Class[0];
    // Count the number of actual declared inner and static classes.
    // (The array may contain null elements, which we want to skip.)
    int count = 0;
    int length = declaredClasses.length;
    for (int i = 0; i < length; ++i) {
        if (declaredClasses[i] != null) {
            ++count;
        }
    }
    // Now build actual result array.
    Class<?>[] result = new Class[count];
    count = 0;
    for (int i = 0; i < length; ++i) {
        if (declaredClasses[i] != null) {
            result[count++] = declaredClasses[i].resolve().getClassForType();
        }
    }
    return result;
}
Also used : RVMClass(org.jikesrvm.classloader.RVMClass) TypeReference(org.jikesrvm.classloader.TypeReference) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 4 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BulkCompile method compileAllMethods.

/**
 * Compile all methods nominated in the compiler advice,
 * which should have been provided in a .ca advice file.<p>
 *
 * This method will be called at boot time (via notifyStartup())
 * if ENABLE_PRECOMPILE is true.  For replay compilation, this
 * method needs to be called explicitly from within the application
 * or benchmark harness. Typical usage in a benchmarking context
 * would be to call this method at the end of the first iteration
 * of the benchmark so that all/most classes were loaded, and
 * compilation could occur prior to the second iteration.
 */
public static void compileAllMethods() {
    if (!(Controller.options.ENABLE_BULK_COMPILE || Controller.options.ENABLE_PRECOMPILE)) {
        /* should not be here */
        VM.sysFail("Attempt to perform bulk compilation without setting either -X:aos:enable_bulk_compile=true or -X:aos:enable_precompile=true");
    }
    EdgeCounts.loadCountsFromFileIfAvailable(VM.EdgeCounterFile);
    CompilerAdvice.readCompilerAdvice();
    if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
        VM.sysWriteln(Controller.options.ENABLE_PRECOMPILE ? "Start precompile" : "Start bulk compile");
    for (CompilerAdviceAttribute value : CompilerAdviceAttribute.values()) {
        if (value.getOptLevel() == -1) {
            if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                VM.sysWriteln("Skipping base method: ", value.toString());
            } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                VM.sysWrite(".");
            }
            continue;
        }
        ClassLoader cl = RVMClassLoader.findWorkableClassloader(value.getClassName());
        if (cl == null)
            continue;
        TypeReference tRef = TypeReference.findOrCreate(cl, value.getClassName());
        RVMClass cls = (RVMClass) tRef.peekType();
        if (cls != null) {
            // Ensure the class is properly loaded
            if (!cls.isInstantiated()) {
                if (!cls.isResolved()) {
                    if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                        VM.sysWriteln("Resolving class: ", cls.toString());
                    } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                        VM.sysWrite("R");
                    }
                    cls.resolve();
                }
                if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                    VM.sysWriteln("Instantiating class: ", cls.toString());
                } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                    VM.sysWrite("I");
                }
                cls.instantiate();
            }
            // Find the method
            RVMMethod method = cls.findDeclaredMethod(value.getMethodName(), value.getMethodSig());
            // If found, compile it
            if ((method != null) && !method.hasNoOptCompileAnnotation() && (method instanceof org.jikesrvm.classloader.NormalMethod)) {
                // if user's requirement is higher than advice
                if (value.getOptLevel() > Controller.options.DERIVED_MAX_OPT_LEVEL) {
                    if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                        VM.sysWrite("Replay advice overriden by default opt levels.  Wanted ");
                        VM.sysWrite(value.getOptLevel());
                        VM.sysWrite(", but Controller.options.DERIVED_MAX_OPT_LEVEL: ");
                        VM.sysWrite(Controller.options.DERIVED_MAX_OPT_LEVEL);
                        VM.sysWrite(" ");
                        VM.sysWriteln(value.toString());
                    } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                        VM.sysWrite(value.getOptLevel(), "!");
                    }
                    method.compile();
                } else {
                    CompilationPlan compPlan;
                    if (Controller.options.counters()) {
                        // for invocation counter, we only use one optimization level
                        compPlan = InvocationCounts.createCompilationPlan((NormalMethod) method);
                        AOSLogging.logger.recompilationStarted(compPlan);
                        if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                            VM.sysWrite("Bulk compiling for counters ");
                            VM.sysWriteln(value.toString());
                        }
                        RuntimeCompiler.recompileWithOpt(compPlan);
                        AOSLogging.logger.recompilationCompleted(compPlan);
                    } else if (Controller.options.sampling()) {
                        // Create our set of standard optimization plans.
                        compPlan = Controller.recompilationStrategy.createCompilationPlan((NormalMethod) method, value.getOptLevel(), null);
                        if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                            VM.sysWrite("Bulk compiling for sampling ");
                            VM.sysWriteln(value.toString());
                        }
                        if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                            VM.sysWrite(value.getOptLevel());
                        }
                        AOSLogging.logger.recompilationStarted(compPlan);
                        RuntimeCompiler.recompileWithOpt(compPlan);
                        AOSLogging.logger.recompilationCompleted(compPlan);
                    } else {
                        if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                            VM.sysWrite("Compiler advice file overridden ");
                            VM.sysWriteln(value.toString());
                        }
                        method.compile();
                    }
                }
            } else {
                if (Controller.options.BULK_COMPILATION_VERBOSITY > 1) {
                    VM.sysWrite("Replay failed for ");
                    VM.sysWrite(value.toString());
                    VM.sysWrite(" ");
                    VM.sysWriteln(cl.toString());
                } else if (Controller.options.BULK_COMPILATION_VERBOSITY == 1) {
                    VM.sysWrite("*");
                }
            }
        }
    }
    AOSLogging.logger.compileAllMethodsCompleted();
    if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
        VM.sysWriteln();
    if (Controller.options.BULK_COMPILATION_VERBOSITY >= 1)
        VM.sysWriteln("Recompilation complete");
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) NormalMethod(org.jikesrvm.classloader.NormalMethod) RVMClassLoader(org.jikesrvm.classloader.RVMClassLoader) CompilationPlan(org.jikesrvm.compilers.opt.driver.CompilationPlan) TypeReference(org.jikesrvm.classloader.TypeReference) CompilerAdviceAttribute(org.jikesrvm.adaptive.util.CompilerAdviceAttribute) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 5 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BootImageWriter method writeAddressMap.

/**
 * Write method address map for use with dbx debugger.
 *
 * @param fileName name of file to write the map to
 */
private static void writeAddressMap(String mapFileName) throws IOException {
    if (verbosity.isAtLeast(SUMMARY))
        say("writing ", mapFileName);
    // Restore previously unnecessary Statics data structures
    Statics.bootImageReportGeneration(staticsJunk);
    FileOutputStream fos = new FileOutputStream(mapFileName);
    BufferedOutputStream bos = new BufferedOutputStream(fos, 128);
    PrintStream out = new PrintStream(bos, false);
    out.println("#! /bin/bash");
    out.println("# This is a method address map, for use with the ``dbx'' debugger.");
    out.println("# To sort by \"code\" address, type \"bash <name-of-this-file>\".");
    out.println("# Bootimage data: " + Integer.toHexString(BOOT_IMAGE_DATA_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_DATA_START.toInt() + bootImage.getDataSize()));
    out.println("# Bootimage code: " + Integer.toHexString(BOOT_IMAGE_CODE_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_CODE_START.toInt() + bootImage.getCodeSize()));
    out.println("# Bootimage refs: " + Integer.toHexString(BOOT_IMAGE_RMAP_START.toInt()) + "..." + Integer.toHexString(BOOT_IMAGE_RMAP_START.toInt() + bootImage.getRMapSize()));
    out.println();
    out.println("(/bin/grep 'code     0x' | /bin/sort -k 4.3,4) << EOF-EOF-EOF");
    out.println();
    out.println("JTOC Map");
    out.println("--------");
    out.println("slot  offset     category contents            details");
    out.println("----  ------     -------- --------            -------");
    String pad = "        ";
    // Numeric JTOC fields
    for (int jtocSlot = Statics.getLowestInUseSlot(); jtocSlot < Statics.middleOfTable; jtocSlot++) {
        Offset jtocOff = Statics.slotAsOffset(jtocSlot);
        String category;
        String contents;
        String details;
        RVMField field = getRvmStaticField(jtocOff);
        RVMField field2 = getRvmStaticField(jtocOff.plus(4));
        boolean couldBeLongLiteral = Statics.isLongSizeLiteral(jtocSlot);
        boolean couldBeIntLiteral = Statics.isIntSizeLiteral(jtocSlot);
        if (couldBeLongLiteral && ((field == null) || (field2 == null))) {
            if ((field == null) && (field2 == null)) {
                category = "literal      ";
                long lval = Statics.getSlotContentsAsLong(jtocOff);
                contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
                details = lval + "L";
            } else if ((field == null) && (field2 != null)) {
                category = "literal/field";
                long lval = Statics.getSlotContentsAsLong(jtocOff);
                contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
                details = lval + "L / " + field2.toString();
            } else if ((field != null) && (field2 == null)) {
                category = "literal/field";
                long lval = Statics.getSlotContentsAsLong(jtocOff);
                contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
                details = lval + "L / " + field.toString();
            } else {
                throw new Error("Unreachable");
            }
            jtocSlot++;
        } else if (couldBeIntLiteral) {
            if (field != null) {
                category = "literal/field";
                int ival = Statics.getSlotContentsAsInt(jtocOff);
                contents = Services.intAsHexString(ival) + pad;
                details = Integer.toString(ival) + " / " + field.toString();
            } else {
                category = "literal      ";
                int ival = Statics.getSlotContentsAsInt(jtocOff);
                contents = Services.intAsHexString(ival) + pad;
                details = Integer.toString(ival);
            }
        } else {
            if (field != null) {
                category = "field        ";
                details = field.toString();
                TypeReference type = field.getType();
                if (type.isIntLikeType()) {
                    int ival = Statics.getSlotContentsAsInt(jtocOff);
                    contents = Services.intAsHexString(ival) + pad;
                } else if (type.isLongType()) {
                    long lval = Statics.getSlotContentsAsLong(jtocOff);
                    contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
                    jtocSlot++;
                } else if (type.isFloatType()) {
                    int ival = Statics.getSlotContentsAsInt(jtocOff);
                    contents = Float.toString(Float.intBitsToFloat(ival)) + pad;
                } else if (type.isDoubleType()) {
                    long lval = Statics.getSlotContentsAsLong(jtocOff);
                    contents = Double.toString(Double.longBitsToDouble(lval)) + pad;
                    jtocSlot++;
                } else if (type.isWordLikeType()) {
                    if (VM.BuildFor32Addr) {
                        int ival = Statics.getSlotContentsAsInt(jtocOff);
                        contents = Services.intAsHexString(ival) + pad;
                    } else {
                        long lval = Statics.getSlotContentsAsLong(jtocOff);
                        contents = Services.intAsHexString((int) (lval >> 32)) + Services.intAsHexString((int) (lval & 0xffffffffL)).substring(2);
                        jtocSlot++;
                    }
                } else {
                    // Unknown?
                    int ival = Statics.getSlotContentsAsInt(jtocOff);
                    category = "<? - field>  ";
                    details = "<? - " + field.toString() + ">";
                    contents = Services.intAsHexString(ival) + pad;
                }
            } else {
                // Unknown?
                int ival = Statics.getSlotContentsAsInt(jtocOff);
                category = "<?>        ";
                details = "<?>";
                contents = Services.intAsHexString(ival) + pad;
            }
        }
        out.println((jtocSlot + "        ").substring(0, 8) + Services.addressAsHexString(jtocOff.toWord().toAddress()) + " " + category + "  " + contents + "  " + details);
    }
    // Reference JTOC fields
    for (int jtocSlot = Statics.middleOfTable, n = Statics.getHighestInUseSlot(); jtocSlot <= n; jtocSlot += Statics.getReferenceSlotSize()) {
        Offset jtocOff = Statics.slotAsOffset(jtocSlot);
        Object obj = BootImageMap.getObject(getIVal(jtocOff));
        String category;
        String details;
        String contents = Services.addressAsHexString(getReferenceAddr(jtocOff, false)) + pad;
        RVMField field = getRvmStaticField(jtocOff);
        if (Statics.isReferenceLiteral(jtocSlot)) {
            if (field != null) {
                category = "literal/field";
            } else {
                category = "literal      ";
            }
            if (obj == null) {
                details = "(null)";
            } else if (obj instanceof String) {
                details = "\"" + obj + "\"";
            } else if (obj instanceof Class) {
                details = obj.toString();
                ;
            } else if (obj instanceof TIB) {
                category = "literal tib  ";
                RVMType type = ((TIB) obj).getType();
                details = (type == null) ? "?" : type.toString();
            } else {
                details = "object " + obj.getClass();
            }
            if (field != null) {
                details += " / " + field.toString();
            }
        } else if (field != null) {
            category = "field        ";
            details = field.toString();
        } else if (obj instanceof TIB) {
            // TIBs confuse the statics as their backing is written into the boot image
            category = "tib          ";
            RVMType type = ((TIB) obj).getType();
            details = (type == null) ? "?" : type.toString();
        } else {
            category = "unknown      ";
            if (obj instanceof String) {
                details = "\"" + obj + "\"";
            } else if (obj instanceof Class) {
                details = obj.toString();
            } else {
                CompiledMethod m = findMethodOfCode(obj);
                if (m != null) {
                    category = "code         ";
                    details = m.getMethod().toString();
                } else if (obj != null) {
                    details = "<?> - unrecognized field or literal of type " + obj.getClass();
                } else {
                    details = "<?>";
                }
            }
        }
        out.println((jtocSlot + "        ").substring(0, 8) + Services.addressAsHexString(jtocOff.toWord().toAddress()) + " " + category + "  " + contents + "  " + details);
    }
    out.println();
    out.println("Method Map");
    out.println("----------");
    out.println("                          address             method");
    out.println("                          -------             ------");
    out.println();
    for (int i = 0; i < CompiledMethods.numCompiledMethods(); ++i) {
        CompiledMethod compiledMethod = CompiledMethods.getCompiledMethodUnchecked(i);
        if (compiledMethod != null) {
            RVMMethod m = compiledMethod.getMethod();
            if (m != null && compiledMethod.isCompiled()) {
                CodeArray instructions = compiledMethod.getEntryCodeArray();
                Address code = BootImageMap.getImageAddress(instructions.getBacking(), true);
                out.println(".     .          code     " + Services.addressAsHexString(code) + "          " + compiledMethod.getMethod());
            }
        }
    }
    // Extra information on the layout of objects in the boot image
    if (false) {
        out.println();
        out.println("Object Map");
        out.println("----------");
        out.println("                          address             type");
        out.println("                          -------             ------");
        out.println();
        SortedSet<BootImageMap.Entry> set = new TreeSet<BootImageMap.Entry>(new Comparator<BootImageMap.Entry>() {

            @Override
            public int compare(BootImageMap.Entry a, BootImageMap.Entry b) {
                return Integer.valueOf(a.imageAddress.toInt()).compareTo(b.imageAddress.toInt());
            }
        });
        for (Enumeration<BootImageMap.Entry> e = BootImageMap.elements(); e.hasMoreElements(); ) {
            BootImageMap.Entry entry = e.nextElement();
            set.add(entry);
        }
        for (Iterator<BootImageMap.Entry> i = set.iterator(); i.hasNext(); ) {
            BootImageMap.Entry entry = i.next();
            Address data = entry.imageAddress;
            out.println(".     .          data     " + Services.addressAsHexString(data) + "          " + entry.jdkObject.getClass());
        }
    }
    out.println();
    out.println("EOF-EOF-EOF");
    out.flush();
    out.close();
}
Also used : Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) CodeArray(org.jikesrvm.compilers.common.CodeArray) TreeSet(java.util.TreeSet) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) BufferedOutputStream(java.io.BufferedOutputStream) PrintStream(java.io.PrintStream) TIB(org.jikesrvm.objectmodel.TIB) Offset(org.vmmagic.unboxed.Offset) RVMMethod(org.jikesrvm.classloader.RVMMethod) FileOutputStream(java.io.FileOutputStream) RVMClass(org.jikesrvm.classloader.RVMClass)

Aggregations

TypeReference (org.jikesrvm.classloader.TypeReference)164 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)58 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)43 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)38 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)30 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)28 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)27 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)25 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)24 RVMClass (org.jikesrvm.classloader.RVMClass)23 RVMField (org.jikesrvm.classloader.RVMField)21 Register (org.jikesrvm.compilers.opt.ir.Register)21 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)21 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)21 Address (org.vmmagic.unboxed.Address)21 RVMType (org.jikesrvm.classloader.RVMType)18 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)18 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)18 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)18 RVMMethod (org.jikesrvm.classloader.RVMMethod)17