if (VM.VerifyAssertions) VM.assert(!et.isInterface());
if (VM.VerifyAssertions) VM._assert(!et.isInterface());
  static OPT_Instruction arrayStoreCheck(OPT_Instruction s, OPT_IR ir, boolean couldBeNull) {    if (VM.BuildForFastDynamicTypeCheck) {      OPT_RegisterOperand guardResult = StoreCheck.getClearGuardResult(s);      OPT_RegisterOperand arrayRef = StoreCheck.getClearRef(s).asRegister();      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();      // Set up a block with a trap instruction that we can jump to if the       // store check fails      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) {	// if rhs is null, then the checkcast succeeds	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);      }	        // Find out what we think the compile time type of the lhs is.      // Based on this, we can do one of several things:      //  (1) If the compile time element type is a final proper class, then a       //      TIB comparision of the runtime elemRef type and the       //      compile time element type is definitive.      //  (2) If the compile time type is known to be the declared type,      //      then inject a short-circuit test to see if the       //      runtime lhs type is the same as the compile-time lhs type.      //  (3) If the compile time element type is a proper class other than       //      java.lang.Object, then a subclass test of the runtime LHS elem type       //      and the runtime elemRef type is definitive.  Note: we must exclude      //      java.lang.Object because if the compile time element type is       //      java.lang.Object, then the runtime-element type might actually be       //      an interface (ie not a proper class), and we won't be testing the right thing!      // If we think the compile time type is JavaLangObjectType then      // we lost type information due to unloaded classes causing      // imprecise meets.  This should only happen once in a blue moon,      // so don't bother trying anything clever when it does.      VM_Type compType = arrayRef.type;      if (compType != VM_Type.JavaLangObjectType) {	// optionally (1) from above	if (compType.getDimensionality() == 1) {	  VM_Class et = compType.asArray().getElementType().asClass();	  if (et.isResolved() && et.isFinal()) {	    if (VM.VerifyAssertions) VM.assert(!et.isInterface());	    OPT_RegisterOperand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());	    OPT_RegisterOperand etTIB = getTIB(curBlock.lastInstruction(), ir, et);	    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();	  }	}	// optionally (2) from above	OPT_RegisterOperand lhsTIB = getTIB(curBlock.lastInstruction(), ir, arrayRef, guard);	if (arrayRef.isDeclaredType() || compType == VM_Type.JavaLangObjectArrayType) {	  OPT_RegisterOperand 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);	}	// On our way to doing (3) from above attempt another short-circuit.	// If lhsElemTIB == rhsTIB, then we are done.	OPT_RegisterOperand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());	OPT_RegisterOperand lhsElemTIB = 	  InsertUnary(curBlock.lastInstruction(), ir, GET_ARRAY_ELEMENT_TIB_FROM_TIB, 		      OPT_ClassLoaderProxy.JavaLangObjectArrayType, 		      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);	// Optionally (3) from above 	if (compType.getDimensionality() == 1) {	  VM_Class et = compType.asArray().getElementType().asClass();	  if (et.isResolved() && !et.isInterface() && !et.isJavaLangObjectType()) {	    OPT_RegisterOperand lhsElemType = 	      InsertUnary(curBlock.lastInstruction(), ir, 			  GET_TYPE_FROM_TIB, OPT_ClassLoaderProxy.VM_Type_type, 			  lhsElemTIB.copyU2U());	    OPT_RegisterOperand rhsSuperclassIds = 	      InsertUnary(curBlock.lastInstruction(), ir, GET_SUPERCLASS_IDS_FROM_TIB, 			  OPT_ClassLoaderProxy.ShortArrayType, rhsTIB.copyD2U());	    OPT_RegisterOperand lhsElemDepth = 	      getField(curBlock.lastInstruction(), ir, lhsElemType, VM_Entrypoints.depthField, TG());	    OPT_RegisterOperand rhsSuperclassIdsLength = 	      InsertGuardedUnary(curBlock.lastInstruction(), ir, 				 ARRAYLENGTH, VM_Type.IntType,				 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_Type.ShortType);	    OPT_LocationOperand loc = new OPT_LocationOperand(VM_Type.ShortType);	    if (LOWER_ARRAY_ACCESS) {	      OPT_RegisterOperand lhsDepthOffset = 		InsertBinary(curBlock.lastInstruction(), ir, INT_SHL, VM_Type.IntType, 			     lhsElemDepth.copyD2U(), I(1));	      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();	  }	}      }      // Call VM_Runtime.checkstore.      OPT_Instruction call = Call.create2(CALL, null, null,					  OPT_MethodOperand.STATIC(VM_Entrypoints.checkstoreMethod), 					  rhsGuard.copy(), arrayRef.copy(), elemRef.copy());      call.copyPosition(s);      curBlock.appendInstruction(call);      curBlock.insertOut(contBlock);      ir.cfg.linkInCodeOrder(curBlock, contBlock);      return _callHelper(call, ir);    } else {      Call.mutate2(s, CALL, null, null, 		   OPT_MethodOperand.STATIC(VM_Entrypoints.checkstoreMethod), 		   StoreCheck.getGuard(s).copy(), StoreCheck.getClearRef(s), 		   StoreCheck.getClearVal(s));      call(s, ir);      return s;    }  }