if (byteToBlockMap[index] == VM_BasicBlock.NOTBLOCK) { VM_BasicBlock newBB = new VM_BasicBlock(index); basicBlocks = addBasicBlock(newBB, basicBlocks); newBB.addPredecessor(currentBB);
if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) { VM_BasicBlock newBB = new VM_BasicBlock(bcodes.index()); addBasicBlock(newBB); newBB.addPredecessor(currentBB);
  determineTheBasicBlocks(VM_Method method) {   // Other local variables   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.   byte                      bytecodes[];  // 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   bytecodes      = method.getRawBytecodes();   bytelength     = bytecodes.length;   byteToBlockMap = new short[bytelength];   basicBlocks    = new VM_BasicBlock[2];  // many methods only have one block                                            // (+1 for EXIT)   VM_BasicBlock.resetBlockNumber();   exceptions = method.getExceptionHandlerMap();   retList = null;   //    //  Set up the EXIT basic block   //    basicBlocks[VM_BasicBlock.EXITBLOCK] =         new VM_BasicBlock(bytelength,bytelength,VM_BasicBlock.EXITBLOCK);   //   // Get the first basic block   //   currentBB = new VM_BasicBlock(0);   basicBlocks = addBasicBlock(currentBB, basicBlocks);   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     //     basicBlocks = setupHandlerBBs(exceptions, byteToBlockMap, basicBlocks);     // Set up blocks for start of try block, which tend not be to at clear      // block boundaries     //     basicBlocks = setupTryStartBBs(exceptions, byteToBlockMap, basicBlocks);   }   //   // Scan the bytecodes for this method   //   for (int index=0; index<bytelength; ) {          // 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[index] == VM_BasicBlock.NOTBLOCK) {	  // Not a new block         // Make note of current block          byteToBlockMap[index] = (short)currentBB.getBlockNumber();	}	else {	  // Earlier forward branch must have started this block	  currentBB.setEnd(lastInstrStart);	  basicBlocks[byteToBlockMap[index]].addPredecessor(currentBB);         currentBB = basicBlocks[byteToBlockMap[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[index] == VM_BasicBlock.NOTBLOCK) {	    VM_BasicBlock newBB = new VM_BasicBlock(index);	    basicBlocks = addBasicBlock(newBB, basicBlocks);           newBB.addPredecessor(currentBB);	    currentBB = newBB;           // Make note of current block            byteToBlockMap[index] = (short)currentBB.getBlockNumber();	  }         else {	    // From an earlier forward branch            basicBlocks[byteToBlockMap[index]].addPredecessor(currentBB);	    	    currentBB = basicBlocks[byteToBlockMap[index]];	  }	}	else {	  if (lastInstrType == BRANCH) {	    currentBB.setEnd(lastInstrStart);	    // See if we need a new block           if (byteToBlockMap[index] == VM_BasicBlock.NOTBLOCK) {	      VM_BasicBlock newBB = new VM_BasicBlock(index);	      basicBlocks = addBasicBlock(newBB, basicBlocks);             currentBB = newBB;            // Make note of current block             byteToBlockMap[index] = (short)currentBB.getBlockNumber();	    }           else {	      // From an earlier forward branch              currentBB = basicBlocks[byteToBlockMap[index]];	    }	  }	}     }       // end of determining if at block boundary     // Now examine this instruction         int opcode = ((int)bytecodes[index]) & 0xFF;        // get length (known constant for most)	//        int oplength = JBC_length[ opcode ];        lastInstrStart = index;      // Instruction starts here	lastInstrType = NONBRANCH;   // assume it will be a non-branch        switch (opcode) {	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;            short offset = getShortOffset(index, bytecodes);            if(offset < 0) gcPointCount++; // gc map required if backward edge	    int branchtarget = index + offset;            basicBlocks = processBranchTarget(index, branchtarget, 					      byteToBlockMap, basicBlocks);	    index = index + oplength;	    break;	  }	               case JBC_jsr :	  {	    lastInstrType = BRANCH;	    short offset = getShortOffset(index, bytecodes);	    int branchtarget = index + offset;	    basicBlocks = processBranchTarget(index, branchtarget, 					      byteToBlockMap, basicBlocks);	    int jsrentryBBNum = byteToBlockMap[branchtarget];            VM_BasicBlock bb = basicBlocks[jsrentryBBNum];            if ((bb.getState() & VM_BasicBlock.JSRENTRY) == 0) numJsrs++;	    bb.setState(VM_BasicBlock.JSRENTRY);  	    index = index + oplength;	    gcPointCount = gcPointCount+1;	    break;	  }        case JBC_jsr_w :	  {	    // As with jsr, but the offset is wide.	    lastInstrType = BRANCH;            int offset = getIntOffset(index, bytecodes);	    int branchtarget = index + offset;	    basicBlocks = processBranchTarget(index, branchtarget, 					      byteToBlockMap, basicBlocks);	    int jsrentryBBNum = byteToBlockMap[branchtarget];            VM_BasicBlock bb = basicBlocks[jsrentryBBNum];            if ((bb.getState() & VM_BasicBlock.JSRENTRY) == 0) numJsrs++;	    bb.setState(VM_BasicBlock.JSRENTRY);  	    index = index + oplength;	    gcPointCount = gcPointCount+1;	    break;	  }	case JBC_goto :	  {	    lastInstrType = BRANCH;	    short offset = getShortOffset(index, bytecodes);            if(offset < 0) gcPointCount++; // gc map required if backward edge	    int branchtarget = index + offset;	    basicBlocks = processBranchTarget(index, branchtarget, 					      byteToBlockMap, basicBlocks);	    index = index + oplength;	    break;	  }        case JBC_goto_w :	  {	    // As with goto, but the offset is wide.	    int offset = getIntOffset(index, bytecodes);            if(offset < 0) gcPointCount++; // gc map required if backward edge	    int branchtarget = index + offset;	    basicBlocks = processBranchTarget(index, branchtarget, 					      byteToBlockMap, basicBlocks);	    index = index + oplength;	    break;	  }        case JBC_tableswitch :	  {	    int j = index;           // save initial value	    index = index + 1;           // space past op code	    index = (((index + 3)/4)*4); // align to next word boundary	    // get default offset and generate basic block at default offset	    // getIntOffset expects byte before offset	    //	    int def = getIntOffset(index-1, bytecodes);  	    basicBlocks = processBranchTarget(j,j+def, byteToBlockMap, 					      basicBlocks);	    // get low offset	    index = index + 4;           // go past default br offset	    int low = getIntOffset(index-1, bytecodes);	    index = index + 4;           // space past low offset	    // get high offset	    int high = getIntOffset(index-1, bytecodes);	    index = index + 4;           // go past high offset	    // generate labels for offsets	    for (int k = 0; k < (high - low +1); k++) {	      int l = index + k*4; // point to next offset              // get next offset              int offset = getIntOffset(l-1, bytecodes);	      basicBlocks = processBranchTarget(j, j+offset, 						  byteToBlockMap, basicBlocks);	    }	    index = index + (high - low +1) * 4; // space past offsets	    break;	  }	          case JBC_lookupswitch :	  {	    int j = index;           // save initial value for labels	    index = index +1;            // space past op code	    index = (((index + 3)/4)*4); // align to next word boundary	    // get default offset and	    // process branch to default branch point	    //	    int def = getIntOffset(index-1, bytecodes);	    basicBlocks = processBranchTarget(j, j+def, byteToBlockMap, 					      basicBlocks);	    index = index + 4;           // go past default  offset	    // get number of pairs	    int npairs = getIntOffset(index-1, bytecodes);	    index = index + 4;           // space past  number of pairs	    // generate label for each offset in table	    for (int k = 0; k < npairs; k++) {	      int l = index + k*8 + 4; // point to next offset	      // get next offset              int offset = getIntOffset(l-1, bytecodes);	      basicBlocks = processBranchTarget(j, j+offset, byteToBlockMap, 						basicBlocks);	    }	    index = index + (npairs) *8; // space past match-offset pairs	    break;	  }        case JBC_wide :	  {	    int wopcode = ((int)(bytecodes[index+1])) & 0xFF;	    if (wopcode == JBC_iinc)	      index = index + 6;	    else	      index = index + 4;	    break;	  }	case JBC_ireturn : 	case JBC_lreturn :	case JBC_freturn :	case JBC_dreturn :	case JBC_areturn :	case JBC_return  :	  {	    lastInstrType = BRANCH;            index = index + oplength;            basicBlocks[VM_BasicBlock.EXITBLOCK].addPredecessor(currentBB); 	    if (method.isSynchronized() || VM.UseEpilogueYieldPoints)	      gcPointCount++;            break;	  }	case JBC_ret :	  {	    lastInstrType = BRANCH;	    int variableNum = ((int)bytecodes[index + 1]) & 0xFF; 	    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;	              index = index + oplength;            break;	  }	case JBC_athrow :	   {	     lastInstrType = BRANCH;	     processAthrow(exceptions, index, basicBlocks, byteToBlockMap);             index = index + oplength;	     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 :	  {	    index = index + oplength;	    gcPointCount = gcPointCount+1;	    break;	  }	default :          {	    if (oplength == 0) 	      throw new ClassFormatError("Unknown opcode:" + opcode);	    byteToBlockMap[index] = (short)currentBB.getBlockNumber();             index = index + oplength;            break;          }        } // switch (opcode)    } // for (index=0; ...   currentBB.setEnd(lastInstrStart);   // close off last block   if (exceptions != null) {     // process catch blocks     processExceptionHandlers(exceptions, byteToBlockMap, basicBlocks);     // mark all blocks in try sections as being part of a try     markTryBlocks(exceptions, byteToBlockMap, basicBlocks);     // process ret instructions as last step     if ( retList != null)         processRetList(basicBlocks, retList, nextRetList, byteToBlockMap);   }  } // end BuildBB(...)