if (!result.isValid()) return;  final int numSlots = result.getNumSlots();         BasicBlock dest = edge.getDest(); if (dest.getNumIncomingEdges() == 1) { BasicBlock source = edge.getSource();  int edgeType = edge.getType(); if (edgeType == IFCMP_EDGE || edgeType == FALL_THROUGH_EDGE) {    InstructionHandle lastInSourceHandle = source.getLastInstruction(); if (lastInSourceHandle == null) return;  Instruction lastInSource = lastInSourceHandle.getInstruction(); short opcode = lastInSource.getOpcode();     IsNullValue newTOS = null; if (opcode == Constants.IFNULL) { newTOS = (edgeType == IFCMP_EDGE) ? IsNullValue.nullValue() : IsNullValue.notNullValue(); } else if (opcode == Constants.IFNONNULL) { newTOS = (edgeType == IFCMP_EDGE) ? IsNullValue.notNullValue() : IsNullValue.nullValue(); }  if (newTOS != null) {  ValueNumberFrame vnaFrame = getVnaFrameAtEntry(dest); if (vnaFrame == null) return; assert vnaFrame.getNumSlots() == numSlots;      ValueNumber oldTOS = vnaFrame.getTopValue();  for (int i = 0; i < numSlots; ++i) { if (vnaFrame.getValue(i).equals(oldTOS)) result.setValue(i, newTOS); } } } else {       InstructionHandle firstInDestHandle = dest.getFirstInstruction(); if (firstInDestHandle == null) return; Instruction firstInDest = firstInDestHandle.getInstruction(); short opcode = firstInDest.getOpcode(); if (!nullCheckInstructionSet.get(opcode)) return;  ValueNumberFrame vnaFrame = getVnaFrameAtEntry(dest); if (vnaFrame == null) return; assert vnaFrame.getNumSlots() == numSlots;        int numSlotsConsumed = firstInDest.consumeStack(methodGen.getConstantPool()); if (numSlotsConsumed == Constants.UNPREDICTABLE) throw new DataflowAnalysisException("Unpredictable stack consumption for " + firstInDest); ValueNumber checkedValue = vnaFrame.getValue(numSlots - numSlotsConsumed);    for (int i = 0; i < numSlots; ++i) { if (vnaFrame.getValue(i).equals(checkedValue)) result.setValue(i, IsNullValue.notNullValue()); } } }
	public void meetInto(IsNullValueFrame fact, Edge edge, IsNullValueFrame result) throws DataflowAnalysisException {		// Normal dataflow merge		result.mergeWith(fact);		// If we're at TOP or BOTTOM after merge, nothing more to do		if (!result.isValid())			return;		final int numSlots = result.getNumSlots();		// If we have a single predecessor then we can use the following		// information to make the result frame more precise:		//   - the type of edge		//   - the last instruction in the predecessor block		//   - the first instruction in the successor block (i.e., if the		//     predecessor is the exception throwing block (ETB) for		//     the instruction; for example, the null check for a field access)		BasicBlock dest = edge.getDest();		if (dest.getNumIncomingEdges() == 1) {			BasicBlock source = edge.getSource();			int edgeType = edge.getType();			if (edgeType == IFCMP_EDGE || edgeType == FALL_THROUGH_EDGE) {				// Check for IFNULL and IFNONNULL branches.				// This will tell us something about the value on the				// top of the Java operand stack.				InstructionHandle lastInSourceHandle = source.getLastInstruction();				if (lastInSourceHandle == null)					return;				Instruction lastInSource = lastInSourceHandle.getInstruction();				short opcode = lastInSource.getOpcode();				// If the last instruction was IFNULL or IFNONNULL				// then we have more precise information about the value				// on the top of the stack.				IsNullValue newTOS = null;				if (opcode == Constants.IFNULL) {					newTOS = (edgeType == IFCMP_EDGE) ? IsNullValue.nullValue() : IsNullValue.notNullValue();				} else if (opcode == Constants.IFNONNULL) {					newTOS = (edgeType == IFCMP_EDGE) ? IsNullValue.notNullValue() : IsNullValue.nullValue();				}				if (newTOS != null) {					// Get value number frame at start of dest block.					ValueNumberFrame vnaFrame = getVnaFrameAtEntry(dest);					if (vnaFrame == null)						return;					assert vnaFrame.getNumSlots() == numSlots;					// Get the value number of the value on top of the stack.					// All occurrences of that value in the frame can					// be updated to reflect the more precise null/non-null					// information.					ValueNumber oldTOS = vnaFrame.getTopValue();					for (int i = 0; i < numSlots; ++i) {						if (vnaFrame.getValue(i).equals(oldTOS))							result.setValue(i, newTOS);					}				}			} else {				// Check to see if the first instruction in the destination				// block is one that has a null check exception associated with it.				// If so, then at entry to the destination block, we know that				// the null check has occurred and the value on top of				// the stack is not null.				InstructionHandle firstInDestHandle = dest.getFirstInstruction();				if (firstInDestHandle == null)					return;				Instruction firstInDest = firstInDestHandle.getInstruction();				short opcode = firstInDest.getOpcode();				if (!nullCheckInstructionSet.get(opcode))					return;				ValueNumberFrame vnaFrame = getVnaFrameAtEntry(dest);				if (vnaFrame == null)					return;				assert vnaFrame.getNumSlots() == numSlots;				// The block starts with an instruction whose implicit null check				// has succeeded.  Now we need to figure out the stack slot which				// contains the reference that was checked for null.				// This is extremely easy.  We just find out how many				// slots the instruction consumes, and subtract that value from				// the number of slots in the frame.				int numSlotsConsumed = firstInDest.consumeStack(methodGen.getConstantPool());				if (numSlotsConsumed == Constants.UNPREDICTABLE)					throw new DataflowAnalysisException("Unpredictable stack consumption for " + firstInDest);				ValueNumber checkedValue = vnaFrame.getValue(numSlots - numSlotsConsumed);				// Now we know that all occurrences of the checked value				// are not null.				for (int i = 0; i < numSlots; ++i) {					if (vnaFrame.getValue(i).equals(checkedValue))						result.setValue(i, IsNullValue.notNullValue());				}			}		}	}