Program: 150077
Project: 150077
Buggy source:
/** 
 * Expand an object array store check into the LIR sequence that  implements it.
 * @param s an OBJARRAY_STORE_CHECK instruction to expand 
 * @param ir the enclosing OPT_IR
 * @param couldBeNull is it possible that the element being stored is null?
 * @return the last OPT_Instruction in the generated LIR sequence.
 */
static OPT_Instruction arrayStoreCheck(OPT_Instruction s,OPT_IR ir,boolean couldBeNull){
  OPT_RegisterOperand guardResult=StoreCheck.getClearGuardResult(s);
  OPT_Operand arrayRef=StoreCheck.getClearRef(s);
  OPT_Operand elemRef=StoreCheck.getClearVal(s);
  OPT_Operand guard=StoreCheck.getClearGuard(s);
  if (elemRef instanceof OPT_NullConstantOperand) {
    OPT_Instruction continueAt=s.prevInstructionInCodeOrder();
    s.remove();
    return continueAt;
  }
  OPT_BasicBlock myBlock=s.getBasicBlock();
  OPT_BasicBlock contBlock=myBlock.splitNodeAt(s,ir);
  OPT_BasicBlock trapBlock=myBlock.createSubBlock(s.bcIndex,ir,.0001f);
  OPT_BasicBlock curBlock=myBlock;
  s.remove();
  OPT_Instruction trap=Trap.create(TRAP,null,OPT_TrapCodeOperand.StoreCheck());
  trap.copyPosition(s);
  trapBlock.appendInstruction(trap);
  ir.cfg.addLastInCodeOrder(trapBlock);
  OPT_Operand rhsGuard=guard;
  if (couldBeNull) {
    rhsGuard=ir.regpool.makeTempValidation();
    contBlock.prependInstruction(Binary.create(GUARD_COMBINE,guardResult,guardResult.copyRO(),rhsGuard.copy()));
    curBlock.appendInstruction(IfCmp.create(REF_IFCMP,rhsGuard.asRegister(),elemRef,new OPT_NullConstantOperand(),OPT_ConditionOperand.EQUAL(),contBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
    curBlock.insertOut(contBlock);
    curBlock=advanceBlock(s.bcIndex,curBlock,ir);
  }
  VM_Type compType=arrayRef.getType().peekResolvedType();
  if (compType != null && !compType.isJavaLangObjectType()) {
    if (compType.getDimensionality() == 1) {
      VM_Class etc=(VM_Class)compType.asArray().getElementType();
      if (etc.isResolved() && etc.isFinal()) {
        if (VM.VerifyAssertions)         VM._assert(!etc.isInterface());
        OPT_RegisterOperand rhsTIB=getTIB(curBlock.lastInstruction(),ir,elemRef.copy(),rhsGuard.copy());
        OPT_Operand etTIB=getTIB(curBlock.lastInstruction(),ir,etc);
        curBlock.appendInstruction(IfCmp.create(REF_IFCMP,guardResult.copyRO(),rhsTIB,etTIB,OPT_ConditionOperand.NOT_EQUAL(),trapBlock.makeJumpTarget(),OPT_BranchProfileOperand.never()));
        curBlock.insertOut(trapBlock);
        curBlock.insertOut(contBlock);
        ir.cfg.linkInCodeOrder(curBlock,contBlock);
        return curBlock.lastInstruction();
      }
    }
    OPT_RegisterOperand lhsTIB=getTIB(curBlock.lastInstruction(),ir,arrayRef,guard);
    if (((arrayRef instanceof OPT_RegisterOperand) && ((OPT_RegisterOperand)arrayRef).isDeclaredType()) || compType == VM_Type.JavaLangObjectArrayType) {
      OPT_Operand declTIB=getTIB(curBlock.lastInstruction(),ir,compType);
      curBlock.appendInstruction(IfCmp.create(REF_IFCMP,guardResult.copyRO(),declTIB,lhsTIB,OPT_ConditionOperand.EQUAL(),contBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
      curBlock.insertOut(contBlock);
      curBlock=advanceBlock(s.bcIndex,curBlock,ir);
    }
    OPT_RegisterOperand rhsTIB=getTIB(curBlock.lastInstruction(),ir,elemRef.copy(),rhsGuard.copy());
    OPT_RegisterOperand lhsElemTIB=InsertUnary(curBlock.lastInstruction(),ir,GET_ARRAY_ELEMENT_TIB_FROM_TIB,VM_TypeReference.JavaLangObjectArray,lhsTIB.copyRO());
    curBlock.appendInstruction(IfCmp.create(REF_IFCMP,guardResult.copyRO(),rhsTIB,lhsElemTIB,OPT_ConditionOperand.EQUAL(),contBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
    curBlock.insertOut(contBlock);
    curBlock=advanceBlock(s.bcIndex,curBlock,ir);
    if (compType.getDimensionality() == 1) {
      VM_Class etc=(VM_Class)compType.asArray().getElementType();
      if (etc.isResolved() && !etc.isInterface() && !etc.isJavaLangObjectType()) {
        OPT_RegisterOperand lhsElemType=InsertUnary(curBlock.lastInstruction(),ir,GET_TYPE_FROM_TIB,VM_TypeReference.VM_Type,lhsElemTIB.copyU2U());
        OPT_RegisterOperand rhsSuperclassIds=InsertUnary(curBlock.lastInstruction(),ir,GET_SUPERCLASS_IDS_FROM_TIB,VM_TypeReference.ShortArray,rhsTIB.copyD2U());
        OPT_RegisterOperand lhsElemDepth=getField(curBlock.lastInstruction(),ir,lhsElemType,VM_Entrypoints.depthField,TG());
        OPT_RegisterOperand rhsSuperclassIdsLength=InsertGuardedUnary(curBlock.lastInstruction(),ir,ARRAYLENGTH,VM_TypeReference.Int,rhsSuperclassIds.copyD2U(),TG());
        curBlock.appendInstruction(IfCmp.create(INT_IFCMP,guardResult.copyRO(),lhsElemDepth,rhsSuperclassIdsLength,OPT_ConditionOperand.GREATER_EQUAL(),trapBlock.makeJumpTarget(),OPT_BranchProfileOperand.never()));
        curBlock.insertOut(trapBlock);
        curBlock=advanceBlock(s.bcIndex,curBlock,ir);
        OPT_RegisterOperand lhsElemId=getField(curBlock.lastInstruction(),ir,lhsElemType.copyD2U(),VM_Entrypoints.idField,TG());
        OPT_RegisterOperand refCandidate=ir.regpool.makeTemp(VM_TypeReference.Short);
        OPT_LocationOperand loc=new OPT_LocationOperand(VM_TypeReference.Short);
        if (LOWER_ARRAY_ACCESS) {
          OPT_RegisterOperand lhsDepthOffset=InsertBinary(curBlock.lastInstruction(),ir,INT_SHL,VM_TypeReference.Int,lhsElemDepth.copyD2U(),IC(1));
          lhsDepthOffset=InsertUnary(curBlock.lastInstruction(),ir,INT_2ADDRZerExt,VM_TypeReference.Offset,lhsDepthOffset.copy());
          curBlock.appendInstruction(Load.create(USHORT_LOAD,refCandidate,rhsSuperclassIds,lhsDepthOffset,loc,TG()));
        }
 else {
          curBlock.appendInstruction(ALoad.create(USHORT_ALOAD,refCandidate,rhsSuperclassIds,lhsElemDepth,loc,TG()));
        }
        curBlock.appendInstruction(IfCmp.create(INT_IFCMP,guardResult.copyRO(),refCandidate.copyD2U(),lhsElemId,OPT_ConditionOperand.NOT_EQUAL(),trapBlock.makeJumpTarget(),OPT_BranchProfileOperand.never()));
        curBlock.insertOut(trapBlock);
        curBlock.insertOut(contBlock);
        ir.cfg.linkInCodeOrder(curBlock,contBlock);
        return curBlock.lastInstruction();
      }
    }
  }
  VM_Method target=VM_Entrypoints.checkstoreMethod;
  OPT_Instruction call=Call.create2(CALL,null,AC(target.getOffset()),OPT_MethodOperand.STATIC(target),rhsGuard.copy(),arrayRef.copy(),elemRef.copy());
  call.copyPosition(s);
  curBlock.appendInstruction(call);
  curBlock.insertOut(contBlock);
  ir.cfg.linkInCodeOrder(curBlock,contBlock);
  return callHelper(call,ir);
}

Fixed version (ground truth):
/** 
 * Expand an object array store check into the LIR sequence that  implements it.
 * @param s an OBJARRAY_STORE_CHECK instruction to expand 
 * @param ir the enclosing OPT_IR
 * @param couldBeNull is it possible that the element being stored is null?
 * @return the last OPT_Instruction in the generated LIR sequence.
 */
static OPT_Instruction arrayStoreCheck(OPT_Instruction s,OPT_IR ir,boolean couldBeNull){
  OPT_RegisterOperand guardResult=StoreCheck.getClearGuardResult(s);
  OPT_Operand arrayRef=StoreCheck.getClearRef(s);
  OPT_Operand elemRef=StoreCheck.getClearVal(s);
  OPT_Operand guard=StoreCheck.getClearGuard(s);
  if (elemRef instanceof OPT_NullConstantOperand) {
    OPT_Instruction continueAt=s.prevInstructionInCodeOrder();
    s.remove();
    return continueAt;
  }
  OPT_BasicBlock myBlock=s.getBasicBlock();
  OPT_BasicBlock contBlock=myBlock.splitNodeAt(s,ir);
  OPT_BasicBlock trapBlock=myBlock.createSubBlock(s.bcIndex,ir,.0001f);
  OPT_BasicBlock curBlock=myBlock;
  s.remove();
  OPT_Instruction trap=Trap.create(TRAP,null,OPT_TrapCodeOperand.StoreCheck());
  trap.copyPosition(s);
  trapBlock.appendInstruction(trap);
  ir.cfg.addLastInCodeOrder(trapBlock);
  OPT_Operand rhsGuard=guard;
  if (couldBeNull) {
    rhsGuard=ir.regpool.makeTempValidation();
    contBlock.prependInstruction(Binary.create(GUARD_COMBINE,guardResult,guardResult.copyRO(),rhsGuard.copy()));
    curBlock.appendInstruction(IfCmp.create(REF_IFCMP,rhsGuard.asRegister(),elemRef,new OPT_NullConstantOperand(),OPT_ConditionOperand.EQUAL(),contBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
    curBlock.insertOut(contBlock);
    curBlock=advanceBlock(s.bcIndex,curBlock,ir);
  }
  VM_Type compType=arrayRef.getType().peekResolvedType();
  if (compType != null && !compType.isJavaLangObjectType()) {
    if (compType.getDimensionality() == 1) {
      VM_Class etc=(VM_Class)compType.asArray().getElementType();
      if (etc.isResolved() && etc.isFinal()) {
        if (VM.VerifyAssertions)         VM._assert(!etc.isInterface());
        OPT_RegisterOperand rhsTIB=getTIB(curBlock.lastInstruction(),ir,elemRef.copy(),rhsGuard.copy());
        OPT_Operand etTIB=getTIB(curBlock.lastInstruction(),ir,etc);
        curBlock.appendInstruction(IfCmp.create(REF_IFCMP,guardResult.copyRO(),rhsTIB,etTIB,OPT_ConditionOperand.NOT_EQUAL(),trapBlock.makeJumpTarget(),OPT_BranchProfileOperand.never()));
        curBlock.insertOut(trapBlock);
        curBlock.insertOut(contBlock);
        ir.cfg.linkInCodeOrder(curBlock,contBlock);
        return curBlock.lastInstruction();
      }
    }
    OPT_RegisterOperand lhsTIB=getTIB(curBlock.lastInstruction(),ir,arrayRef,guard);
    if (((arrayRef instanceof OPT_RegisterOperand) && ((OPT_RegisterOperand)arrayRef).isDeclaredType()) || compType == VM_Type.JavaLangObjectArrayType) {
      OPT_Operand declTIB=getTIB(curBlock.lastInstruction(),ir,compType);
      curBlock.appendInstruction(IfCmp.create(REF_IFCMP,guardResult.copyRO(),declTIB,lhsTIB,OPT_ConditionOperand.EQUAL(),contBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
      curBlock.insertOut(contBlock);
      curBlock=advanceBlock(s.bcIndex,curBlock,ir);
    }
    OPT_RegisterOperand rhsTIB=getTIB(curBlock.lastInstruction(),ir,elemRef.copy(),rhsGuard.copy());
    OPT_RegisterOperand lhsElemTIB=InsertUnary(curBlock.lastInstruction(),ir,GET_ARRAY_ELEMENT_TIB_FROM_TIB,VM_TypeReference.JavaLangObjectArray,lhsTIB.copyRO());
    curBlock.appendInstruction(IfCmp.create(REF_IFCMP,guardResult.copyRO(),rhsTIB,lhsElemTIB,OPT_ConditionOperand.EQUAL(),contBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
    curBlock.insertOut(contBlock);
    curBlock=advanceBlock(s.bcIndex,curBlock,ir);
    if (compType.getDimensionality() == 1) {
      VM_Class etc=(VM_Class)compType.asArray().getElementType();
      if (etc.isResolved() && !etc.isInterface() && !etc.isJavaLangObjectType()) {
        OPT_RegisterOperand lhsElemType=InsertUnary(curBlock.lastInstruction(),ir,GET_TYPE_FROM_TIB,VM_TypeReference.VM_Type,lhsElemTIB.copyU2U());
        OPT_RegisterOperand rhsSuperclassIds=InsertUnary(curBlock.lastInstruction(),ir,GET_SUPERCLASS_IDS_FROM_TIB,VM_TypeReference.ShortArray,rhsTIB.copyD2U());
        OPT_RegisterOperand lhsElemDepth=getField(curBlock.lastInstruction(),ir,lhsElemType,VM_Entrypoints.depthField,TG());
        OPT_RegisterOperand rhsSuperclassIdsLength=InsertGuardedUnary(curBlock.lastInstruction(),ir,ARRAYLENGTH,VM_TypeReference.Int,rhsSuperclassIds.copyD2U(),TG());
        curBlock.appendInstruction(IfCmp.create(INT_IFCMP,guardResult.copyRO(),lhsElemDepth,rhsSuperclassIdsLength,OPT_ConditionOperand.GREATER_EQUAL(),trapBlock.makeJumpTarget(),OPT_BranchProfileOperand.never()));
        curBlock.insertOut(trapBlock);
        curBlock=advanceBlock(s.bcIndex,curBlock,ir);
        OPT_RegisterOperand lhsElemId=getField(curBlock.lastInstruction(),ir,lhsElemType.copyD2U(),VM_Entrypoints.idField,TG());
        OPT_RegisterOperand refCandidate=ir.regpool.makeTemp(VM_TypeReference.Short);
        OPT_LocationOperand loc=new OPT_LocationOperand(VM_TypeReference.Short);
        if (LOWER_ARRAY_ACCESS) {
          OPT_RegisterOperand lhsDepthOffset=InsertBinary(curBlock.lastInstruction(),ir,INT_SHL,VM_TypeReference.Int,lhsElemDepth.copyD2U(),IC(1));
          lhsDepthOffset=InsertUnary(curBlock.lastInstruction(),ir,INT_2ADDRZerExt,VM_TypeReference.Offset,lhsDepthOffset.copy());
          curBlock.appendInstruction(Load.create(USHORT_LOAD,refCandidate,rhsSuperclassIds,lhsDepthOffset,loc,TG()));
        }
 else {
          curBlock.appendInstruction(ALoad.create(USHORT_ALOAD,refCandidate,rhsSuperclassIds,lhsElemDepth.copyRO(),loc,TG()));
        }
        curBlock.appendInstruction(IfCmp.create(INT_IFCMP,guardResult.copyRO(),refCandidate.copyD2U(),lhsElemId,OPT_ConditionOperand.NOT_EQUAL(),trapBlock.makeJumpTarget(),OPT_BranchProfileOperand.never()));
        curBlock.insertOut(trapBlock);
        curBlock.insertOut(contBlock);
        ir.cfg.linkInCodeOrder(curBlock,contBlock);
        return curBlock.lastInstruction();
      }
    }
  }
  VM_Method target=VM_Entrypoints.checkstoreMethod;
  OPT_Instruction call=Call.create2(CALL,null,AC(target.getOffset()),OPT_MethodOperand.STATIC(target),rhsGuard.copy(),arrayRef.copy(),elemRef.copy());
  call.copyPosition(s);
  curBlock.appendInstruction(call);
  curBlock.insertOut(contBlock);
  ir.cfg.linkInCodeOrder(curBlock,contBlock);
  return callHelper(call,ir);
}