Program: 150059
Project: 150059
Buggy source:
/** 
 * Analyze the bytecodes and build the basic blocks with their predecessors. The results will be used by VM_BuildReferenceMaps
 */
public void determineTheBasicBlocks(VM_NormalMethod method){
  VM_ExceptionHandlerMap exceptions;
  int retList[];
  VM_BytecodeStream bcodes;
  VM_BasicBlock currentBB;
  byte lastInstrType;
  int lastInstrStart;
  int nextRetList=0;
  numJsrs=0;
  gcPointCount=1;
  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];
  bbf=new VM_BasicBlockFactory();
  exceptions=method.getExceptionHandlerMap();
  retList=null;
  if (nextInstructionStart == null || nextInstructionStart.length < bytelength) {
    nextInstructionStart=new int[bytelength];
  }
  basicBlocks[VM_BasicBlock.EXITBLOCK]=new VM_BasicBlock(bytelength,bytelength,VM_BasicBlock.EXITBLOCK);
  currentBB=bbf.newBlock(0);
  addBasicBlock(currentBB);
  currentBB.setState(VM_BasicBlock.METHODENTRY);
  lastInstrType=NONBRANCH;
  lastInstrStart=0;
  if (exceptions != null) {
    setupHandlerBBs(exceptions);
    setupTryStartBBs(exceptions);
  }
  while (bcodes.hasMoreBytecodes()) {
    if (lastInstrType == NONBRANCH) {
      if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {
        byteToBlockMap[bcodes.index()]=(short)currentBB.getBlockNumber();
      }
 else {
        currentBB.setEnd(lastInstrStart);
        basicBlocks[byteToBlockMap[bcodes.index()]].addPredecessor(currentBB);
        currentBB=basicBlocks[byteToBlockMap[bcodes.index()]];
      }
    }
 else {
      if (lastInstrType == CONDITIONAL_BRANCH) {
        currentBB.setEnd(lastInstrStart);
        if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {
          VM_BasicBlock newBB=bbf.newBlock(bcodes.index());
          addBasicBlock(newBB);
          newBB.addPredecessor(currentBB);
          currentBB=newBB;
          byteToBlockMap[bcodes.index()]=(short)currentBB.getBlockNumber();
        }
 else {
          basicBlocks[byteToBlockMap[bcodes.index()]].addPredecessor(currentBB);
          currentBB=basicBlocks[byteToBlockMap[bcodes.index()]];
        }
      }
 else {
        if (lastInstrType == BRANCH) {
          currentBB.setEnd(lastInstrStart);
          if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {
            VM_BasicBlock newBB=bbf.newBlock(bcodes.index());
            addBasicBlock(newBB);
            currentBB=newBB;
            byteToBlockMap[bcodes.index()]=(short)currentBB.getBlockNumber();
          }
 else {
            currentBB=basicBlocks[byteToBlockMap[bcodes.index()]];
          }
        }
      }
    }
    int savedStart=lastInstrStart;
    lastInstrStart=bcodes.index();
    nextInstructionStart[savedStart]=lastInstrStart;
    lastInstrType=NONBRANCH;
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++;
        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++;
  int branchtarget=lastInstrStart + offset;
  processBranchTarget(lastInstrStart,branchtarget);
  break;
}
case JBC_goto_w:
{
int offset=bcodes.getWideBranchOffset();
if (offset < 0) gcPointCount++;
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;
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);
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);
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);
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 {
}
}
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;
}
}
}
currentBB.setEnd(lastInstrStart);
if (exceptions != null) {
processExceptionHandlers(exceptions);
markTryBlocks(exceptions);
}
if (retList != null) {
processRetList(retList,nextRetList);
}
}

Fixed version (ground truth):
/** 
 * Analyze the bytecodes and build the basic blocks with their predecessors. The results will be used by VM_BuildReferenceMaps
 */
public void determineTheBasicBlocks(VM_NormalMethod method){
  VM_ExceptionHandlerMap exceptions;
  int retList[];
  VM_BytecodeStream bcodes;
  VM_BasicBlock currentBB;
  byte lastInstrType;
  int lastInstrStart;
  int nextRetList=0;
  numJsrs=0;
  gcPointCount=1;
  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];
  bbf=new VM_BasicBlockFactory();
  exceptions=method.getExceptionHandlerMap();
  retList=null;
  if (nextInstructionStart == null || nextInstructionStart.length < bytelength) {
    nextInstructionStart=new int[bytelength];
  }
  basicBlocks[VM_BasicBlock.EXITBLOCK]=new VM_BasicBlock(bytelength,bytelength,VM_BasicBlock.EXITBLOCK);
  currentBB=bbf.newBlock(0);
  addBasicBlock(currentBB);
  currentBB.setState(VM_BasicBlock.METHODENTRY);
  lastInstrType=NONBRANCH;
  lastInstrStart=0;
  if (exceptions != null) {
    setupHandlerBBs(exceptions);
    setupTryStartBBs(exceptions);
  }
  while (bcodes.hasMoreBytecodes()) {
    if (lastInstrType == NONBRANCH) {
      if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {
        byteToBlockMap[bcodes.index()]=(short)currentBB.getBlockNumber();
      }
 else {
        currentBB.setEnd(lastInstrStart);
        basicBlocks[byteToBlockMap[bcodes.index()]].addPredecessor(currentBB);
        currentBB=basicBlocks[byteToBlockMap[bcodes.index()]];
      }
    }
 else {
      if (lastInstrType == CONDITIONAL_BRANCH) {
        currentBB.setEnd(lastInstrStart);
        if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {
          VM_BasicBlock newBB=bbf.newBlock(bcodes.index());
          addBasicBlock(newBB);
          newBB.addPredecessor(currentBB);
          currentBB=newBB;
          byteToBlockMap[bcodes.index()]=(short)currentBB.getBlockNumber();
        }
 else {
          basicBlocks[byteToBlockMap[bcodes.index()]].addPredecessor(currentBB);
          currentBB=basicBlocks[byteToBlockMap[bcodes.index()]];
        }
      }
 else {
        if (lastInstrType == BRANCH) {
          currentBB.setEnd(lastInstrStart);
          if (byteToBlockMap[bcodes.index()] == VM_BasicBlock.NOTBLOCK) {
            VM_BasicBlock newBB=bbf.newBlock(bcodes.index());
            addBasicBlock(newBB);
            currentBB=newBB;
            byteToBlockMap[bcodes.index()]=(short)currentBB.getBlockNumber();
          }
 else {
            currentBB=basicBlocks[byteToBlockMap[bcodes.index()]];
          }
        }
      }
    }
    int savedStart=lastInstrStart;
    lastInstrStart=bcodes.index();
    nextInstructionStart[savedStart]=lastInstrStart;
    lastInstrType=NONBRANCH;
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++;
        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++;
  int branchtarget=lastInstrStart + offset;
  processBranchTarget(lastInstrStart,branchtarget);
  break;
}
case JBC_goto_w:
{
int offset=bcodes.getWideBranchOffset();
if (offset < 0) gcPointCount++;
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;
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);
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);
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);
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 {
}
break;
}
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;
}
}
}
currentBB.setEnd(lastInstrStart);
if (exceptions != null) {
processExceptionHandlers(exceptions);
markTryBlocks(exceptions);
}
if (retList != null) {
processRetList(retList,nextRetList);
}
}