public void determineTheBasicBlocks(VM_NormalMethod method) {
void determineTheBasicBlocks(VM_NormalMethod method) {
  public void determineTheBasicBlocks(VM_NormalMethod method) {    VM_ExceptionHandlerMap    exceptions;   // Used to get a hold of the try Start, End and Handler lists    int                       retList[];    // List of basic block numbers that end with a "ret" instruction.    VM_BytecodeStream         bcodes;       // The bytecodes being analyzed.    VM_BasicBlock             currentBB;    // current basic block being processed    byte                      lastInstrType;// type of the last instruction    int                       lastInstrStart;// byte index where last instruction started    //    //  Initialization    //    int nextRetList = 0;    numJsrs        = 0;    gcPointCount   = 1;  // All methods have the possible thread switch in prologue    bcodes         = method.getBytecodes();    bytelength     = bcodes.length();    maxStackHeight = method.getOperandWords();    byteToBlockMap = new short[bytelength];    java.util.Arrays.fill(byteToBlockMap, (short)VM_BasicBlock.NOTBLOCK);    basicBlocks    = new VM_BasicBlock[2];  // many methods only have one block (+1 for EXIT)    bbf = new VM_BasicBlockFactory();    exceptions = method.getExceptionHandlerMap();    retList = null;    if (nextInstructionStart == null ||        nextInstructionStart.length < bytelength) {      nextInstructionStart = new int[bytelength];    }        //     //  Set up the EXIT basic block    //     basicBlocks[VM_BasicBlock.EXITBLOCK] =       new VM_BasicBlock(bytelength,bytelength,VM_BasicBlock.EXITBLOCK);    //    // Get the first basic block    //    currentBB = bbf.newBlock(0);    addBasicBlock(currentBB);    currentBB.setState(VM_BasicBlock.METHODENTRY);    lastInstrType = NONBRANCH;    lastInstrStart = 0;    if (exceptions != null) {      // Get blocks for any handlers, which tend to not be a clear block boundaries      //      setupHandlerBBs(exceptions);      // Set up blocks for start of try block, which tend not be to at clear       // block boundaries      //      setupTryStartBBs(exceptions);    }    //    // Scan the bytecodes for this method    //    while(bcodes.hasMoreBytecodes()) {      // Determine if we are at a block boundary      // We are at a block boundary if:      //   1) non-branch instruction followed by a known block       //   2) last instruction was a conditional branch      //   3) last instruction was a branch      // Note that forward branches mean that the byteToBlockMap will have      // a basic block value prior to us examining that destination byte code      //      if (lastInstrType == NONBRANCH) {        if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {          // Not a new block          // Make note of current block           byteToBlockMap[bcodes.index()] = (short)currentBB.getBlockNumber();        } else {          // Earlier forward branch must have started this block          currentBB.setEnd(lastInstrStart);          basicBlocks[byteToBlockMap[bcodes.index()]].addPredecessor(currentBB);          currentBB = basicBlocks[byteToBlockMap[bcodes.index()]];        }      } else { // we are at a block boundary, last instr was some type of branch        if (lastInstrType == CONDITIONAL_BRANCH) {          currentBB.setEnd(lastInstrStart);          // See if we need a new block          if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {            VM_BasicBlock newBB = bbf.newBlock(bcodes.index());            addBasicBlock(newBB);            newBB.addPredecessor(currentBB);            currentBB = newBB;            // Make note of current block             byteToBlockMap[bcodes.index()] = (short)currentBB.getBlockNumber();          } else {            // From an earlier forward branch             basicBlocks[byteToBlockMap[bcodes.index()]].addPredecessor(currentBB);                      currentBB = basicBlocks[byteToBlockMap[bcodes.index()]];          }        } else {          if (lastInstrType == BRANCH) {            currentBB.setEnd(lastInstrStart);            // See if we need a new block            if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {              VM_BasicBlock newBB = bbf.newBlock(bcodes.index());              addBasicBlock(newBB);              currentBB = newBB;              // Make note of current block               byteToBlockMap[bcodes.index()] = (short)currentBB.getBlockNumber();            } else {              // From an earlier forward branch               currentBB = basicBlocks[byteToBlockMap[bcodes.index()]];            }          }        }      }      // end of determining if at block boundary      // Now examine this instruction      int savedStart = lastInstrStart;      lastInstrStart = bcodes.index();  // Instruction starts here      nextInstructionStart[savedStart] = lastInstrStart;      lastInstrType = NONBRANCH;        // assume it will be a non-branch      switch(bcodes.nextInstruction()) {      case JBC_ifeq:      case JBC_ifne:      case JBC_iflt:      case JBC_ifge:      case JBC_ifgt:      case JBC_ifle:      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:      case JBC_ifnull:      case JBC_ifnonnull:        {          lastInstrType = CONDITIONAL_BRANCH;          int offset = bcodes.getBranchOffset();          if(offset < 0) gcPointCount++; // gc map required if backward edge          int branchtarget = lastInstrStart + offset;          processBranchTarget(lastInstrStart, branchtarget);          break;        }                     case JBC_jsr:        {          lastInstrType = BRANCH;          int offset = bcodes.getBranchOffset();          int branchtarget = lastInstrStart + offset;          processBranchTarget(lastInstrStart, branchtarget);          int jsrentryBBNum = byteToBlockMap[branchtarget];          VM_BasicBlock bb = basicBlocks[jsrentryBBNum];          if ((bb.getState() & VM_BasicBlock.JSRENTRY) == 0) numJsrs++;          bb.setState(VM_BasicBlock.JSRENTRY);            gcPointCount = gcPointCount+1;          break;        }      case JBC_jsr_w:        {          lastInstrType = BRANCH;          int offset = bcodes.getWideBranchOffset();          int branchtarget = lastInstrStart + offset;          processBranchTarget(lastInstrStart, branchtarget);          int jsrentryBBNum = byteToBlockMap[branchtarget];          VM_BasicBlock bb = basicBlocks[jsrentryBBNum];          if ((bb.getState() & VM_BasicBlock.JSRENTRY) == 0) numJsrs++;          bb.setState(VM_BasicBlock.JSRENTRY);            gcPointCount = gcPointCount+1;          break;        }      case JBC_goto:        {          lastInstrType = BRANCH;          int offset = bcodes.getBranchOffset();          if(offset < 0) gcPointCount++; // gc map required if backward edge          int branchtarget = lastInstrStart + offset;          processBranchTarget(lastInstrStart, branchtarget);          break;        }      case JBC_goto_w:        {          int offset = bcodes.getWideBranchOffset();          if(offset < 0) gcPointCount++; // gc map required if backward edge          int branchtarget = lastInstrStart + offset;          processBranchTarget(lastInstrStart, branchtarget);          break;        }      case JBC_tableswitch:        {          bcodes.alignSwitch();          int def = bcodes.getDefaultSwitchOffset();          processBranchTarget(lastInstrStart, lastInstrStart+def);          int low = bcodes.getLowSwitchValue();          int high = bcodes.getHighSwitchValue();          int n = high-low+1;                        // n = number of normal cases (0..n-1)          // generate labels for offsets          for (int i=0; i<n; i++) {            int offset = bcodes.getTableSwitchOffset(i);            processBranchTarget(lastInstrStart, lastInstrStart+offset);          }          bcodes.skipTableSwitchOffsets(n);          break;        }                case JBC_lookupswitch:        {          bcodes.alignSwitch();          int def = bcodes.getDefaultSwitchOffset();          int npairs = bcodes.getSwitchLength();          processBranchTarget(lastInstrStart, lastInstrStart+def);          // generate label for each offset in table          for (int i=0; i<npairs; i++) {            int offset  = bcodes.getLookupSwitchOffset(i);            processBranchTarget(lastInstrStart, lastInstrStart+offset);          }                  bcodes.skipLookupSwitchPairs(npairs);          break;        }      case JBC_ireturn:      case JBC_lreturn:      case JBC_freturn:      case JBC_dreturn:      case JBC_areturn:      case JBC_return:        {          lastInstrType = BRANCH;          basicBlocks[VM_BasicBlock.EXITBLOCK].addPredecessor(currentBB);           if (method.isSynchronized() || VM.UseEpilogueYieldPoints)            gcPointCount++;          break;        }      case JBC_ret:        {          lastInstrType = BRANCH;          int index = bcodes.getLocalNumber();          int blocknum = currentBB.getBlockNumber();          basicBlocks[blocknum].setState(VM_BasicBlock.JSREXIT);          // Worry about growing retListarray          if (retList == null) retList = new int[10];          if (nextRetList >= retList.length) {            int[] biggerRetList = new int[nextRetList + 10];            for (int i=0; i<nextRetList; i++)               biggerRetList[i] = retList[i];            retList = biggerRetList;            biggerRetList = null;          }          retList[nextRetList++] = blocknum;                break;        }      case JBC_wide: {        int widecode = bcodes.getWideOpcode();        int index = bcodes.getWideLocalNumber();        if (widecode == JBC_ret) {          lastInstrType = BRANCH;          int blocknum = currentBB.getBlockNumber();          basicBlocks[blocknum].setState(VM_BasicBlock.JSREXIT);                    // Worry about growing retListarray          if (retList == null) retList = new int[10];          if (nextRetList >= retList.length) {            int[] biggerRetList = new int[nextRetList + 10];            for (int i=0; i<nextRetList; i++)               biggerRetList[i] = retList[i];            retList = biggerRetList;            biggerRetList = null;          }          retList[nextRetList++] = blocknum;              } else if (widecode == JBC_iinc) {          int val = bcodes.getWideIncrement();        } else {          // nothing more to do        }      }             case JBC_athrow:        {          lastInstrType = BRANCH;          processAthrow(exceptions, lastInstrStart);          gcPointCount++;          break;        }      case JBC_aaload:      case JBC_iaload:      case JBC_faload:      case JBC_baload:      case JBC_caload:      case JBC_saload:      case JBC_laload:      case JBC_daload:      case JBC_lastore:      case JBC_dastore:      case JBC_iastore:      case JBC_fastore:      case JBC_aastore:      case JBC_bastore:      case JBC_castore:      case JBC_sastore:      case JBC_putfield:      case JBC_getfield:      case JBC_getstatic:      case JBC_putstatic:      case JBC_irem:      case JBC_idiv:      case JBC_lrem:      case JBC_ldiv:      case JBC_invokevirtual:      case JBC_invokespecial:      case JBC_invokestatic:      case JBC_invokeinterface:      case JBC_instanceof:      case JBC_checkcast:      case JBC_monitorenter:      case JBC_monitorexit:      case JBC_new:      case JBC_newarray:      case JBC_anewarray:      case JBC_multianewarray:        {          bcodes.skipInstruction();          byteToBlockMap[lastInstrStart] = (short)currentBB.getBlockNumber();           gcPointCount = gcPointCount+1;          break;        }      default:        {          bcodes.skipInstruction();          byteToBlockMap[lastInstrStart] = (short)currentBB.getBlockNumber();          break;        }      } // switch (opcode)     } // while (bcodes.hasMoreBytecodes)    currentBB.setEnd(lastInstrStart);   // close off last block    // process try and catch blocks    if (exceptions != null) {      // process catch blocks      processExceptionHandlers(exceptions);      // mark all blocks in try sections as being part of a try      markTryBlocks(exceptions);    }    // process ret instructions as last step    if (retList != null) {      processRetList(retList, nextRetList);    }  } 