⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 valuenumberframemodelingvisitor.java

📁 一个查找java程序里bug的程序的源代码,该程序本身也是java写的,对提高java编程水平很有用
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Bytecode Analysis Framework * Copyright (C) 2003,2004 University of Maryland *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package edu.umd.cs.findbugs.ba;import java.util.*;import org.apache.bcel.Constants;import org.apache.bcel.generic.*;/** * Visitor which models the effects of bytecode instructions * on value numbers of values in the operand stack frames. * * @see ValueNumber * @see ValueNumberFrame * @see ValueNumberAnalysis * @author David Hovemeyer */public class ValueNumberFrameModelingVisitor        extends AbstractFrameModelingVisitor<ValueNumber, ValueNumberFrame>        implements Debug, ValueNumberAnalysisFeatures {	/* ----------------------------------------------------------------------	 * Fields	 * ---------------------------------------------------------------------- */	private MethodGen methodGen;	private ValueNumberFactory factory;	private ValueNumberCache cache;	private LoadedFieldSet loadedFieldSet;	private HashMap<String, ValueNumber> classObjectValueMap;	private IdentityHashMap<InstructionHandle, ValueNumber> constantValueMap;	private HashMap<ValueNumber, String> stringConstantMap;	private RepositoryLookupFailureCallback lookupFailureCallback;	private InstructionHandle handle;	/* ----------------------------------------------------------------------	 * Public interface	 * ---------------------------------------------------------------------- */	/**	 * Constructor.	 *	 * @param methodGen             the method being analyzed	 * @param factory               factory for ValueNumbers for the method	 * @param cache                 cache of input/output transformations for each instruction	 * @param loadedFieldSet        fields loaded/stored by each instruction and entire method	 * @param lookupFailureCallback callback to use to report class lookup failures	 */	public ValueNumberFrameModelingVisitor(MethodGen methodGen, ValueNumberFactory factory,	                                       ValueNumberCache cache,	                                       LoadedFieldSet loadedFieldSet,	                                       RepositoryLookupFailureCallback lookupFailureCallback) {		super(methodGen.getConstantPool());		this.methodGen = methodGen;		this.factory = factory;		this.cache = cache;		this.loadedFieldSet = loadedFieldSet;		this.classObjectValueMap = new HashMap<String, ValueNumber>();		this.constantValueMap = new IdentityHashMap<InstructionHandle, ValueNumber>();		this.stringConstantMap = new HashMap<ValueNumber, String>();		this.lookupFailureCallback = lookupFailureCallback;	}	public ValueNumber getDefaultValue() {		return factory.createFreshValue();	}	/**	 * Set the instruction handle of the instruction currently being visited.	 * This must be called before the instruction accepts this visitor!	 */	public void setHandle(InstructionHandle handle) {		this.handle = handle;	}	/* ----------------------------------------------------------------------	 * Instruction modeling	 * ---------------------------------------------------------------------- */	/**	 * Determine whether redundant load elimination	 * should be performed for the heap location referenced by	 * the current instruction.	 *	 * @return true if we should do redundant load elimination	 *         for the current instruction, false if not	 */	private boolean doRedundantLoadElimination() {		if (!REDUNDANT_LOAD_ELIMINATION)			return false;		XField xfield = loadedFieldSet.getField(handle);		if (xfield == null)			return false;		if (!xfield.isReferenceType())			return false;		// Don't do redundant load elimination for fields that		// are loaded in only one place.		if (loadedFieldSet.getLoadStoreCount(xfield).getLoadCount() <= 1)			return false;		return true;	}	/**	 * Determine whether forward substitution	 * should be performed for the heap location referenced by	 * the current instruction.	 *	 * @return true if we should do forward substitution	 *         for the current instruction, false if not	 */	private boolean doForwardSubstitution() {		if (!REDUNDANT_LOAD_ELIMINATION)			return false;		XField xfield = loadedFieldSet.getField(handle);		if (xfield == null)			return false;		if (!xfield.isReferenceType())			return false;		// Don't do forward substitution for fields that		// are never read.		if (!loadedFieldSet.isLoaded(xfield))			return false;		return true;	}	private void checkConsumedAndProducedValues(Instruction ins, ValueNumber[] consumedValueList,			ValueNumber[] producedValueList) {		int numConsumed = ins.consumeStack(getCPG());		int numProduced = ins.produceStack(getCPG());		if (numConsumed == Constants.UNPREDICTABLE)			throw new IllegalStateException("Unpredictable stack consumption for " + ins);		if (numProduced == Constants.UNPREDICTABLE)			throw new IllegalStateException("Unpredictable stack production for " + ins);		if (consumedValueList.length != numConsumed) {			throw new IllegalStateException("Wrong number of values consumed for " + ins +				": expected " + numConsumed + ", got " + consumedValueList.length);		}		if (producedValueList.length != numProduced) {			throw new IllegalStateException("Wrong number of values produced for " + ins +				": expected " + numProduced + ", got " + producedValueList.length);		}	}	/**	 * This is the default instruction modeling method.	 */	public void modelNormalInstruction(Instruction ins, int numWordsConsumed, int numWordsProduced) {		int flags = (ins instanceof InvokeInstruction) ? ValueNumber.RETURN_VALUE : 0;		// Get the input operands to this instruction.		ValueNumber[] inputValueList = popInputValues(numWordsConsumed);		// See if we have the output operands in the cache.		// If not, push default (fresh) values for the output,		// and add them to the cache.		ValueNumber[] outputValueList = getOutputValues(inputValueList, numWordsProduced, flags);		if (VERIFY_INTEGRITY) {			checkConsumedAndProducedValues(ins, inputValueList, outputValueList);		}		// Push output operands on stack.		pushOutputValues(outputValueList);	}	public void visitGETFIELD(GETFIELD obj) {		if (doRedundantLoadElimination()) {			try {				XField xfield = Hierarchy.findXField(obj, getCPG());				if (xfield != null) {					loadInstanceField((InstanceField) xfield, obj);					return;				}			} catch (ClassNotFoundException e) {				lookupFailureCallback.reportMissingClass(e);			}		}		handleNormalInstruction(obj);	}	public void visitPUTFIELD(PUTFIELD obj) {		if (doForwardSubstitution()) {			try {				XField xfield = Hierarchy.findXField(obj, getCPG());				if (xfield != null) {					storeInstanceField((InstanceField) xfield, obj, false);					return;				}			} catch (ClassNotFoundException e) {				lookupFailureCallback.reportMissingClass(e);			}		}		handleNormalInstruction(obj);	}	private static final ValueNumber[] EMPTY_INPUT_VALUE_LIST = new ValueNumber[0];	public void visitGETSTATIC(GETSTATIC obj) {		if (doRedundantLoadElimination()) {			ValueNumberFrame frame = getFrame();			ConstantPoolGen cpg = getCPG();			String fieldName = obj.getName(cpg);			String fieldSig = obj.getSignature(cpg);			// Is this an access of a Class object?			if (fieldName.startsWith("class$") && fieldSig.equals("Ljava/lang/Class;")) {				String className = fieldName.substring("class$".length()).replace('$', '.');				if (RLE_DEBUG) System.out.println("[found load of class object " + className + "]");				ValueNumber value = getClassObjectValue(className);				frame.pushValue(value);				return;			}			try {				XField xfield = Hierarchy.findXField(obj, getCPG());				if (xfield != null) {					loadStaticField((StaticField) xfield, obj);					return;				}			} catch (ClassNotFoundException e) {				lookupFailureCallback.reportMissingClass(e);			}		}		handleNormalInstruction(obj);	}	public void visitPUTSTATIC(PUTSTATIC obj) {		if (doForwardSubstitution()) {			try {				XField xfield = Hierarchy.findXField(obj, getCPG());				if (xfield != null) {					storeStaticField((StaticField) xfield, obj, false);					return;				}			} catch (ClassNotFoundException e) {				lookupFailureCallback.reportMissingClass(e);			}		}		handleNormalInstruction(obj);	}	public void visitINVOKESTATIC(INVOKESTATIC obj) {		if (REDUNDANT_LOAD_ELIMINATION) {			ConstantPoolGen cpg = getCPG();			String methodName = obj.getName(cpg);			String methodSig = obj.getSignature(cpg);			if (methodName.equals("class$") && methodSig.equals("(Ljava/lang/String;)Ljava/lang/Class;")) {				// Access of a Class object				ValueNumberFrame frame = getFrame();				try {					ValueNumber arg = frame.getTopValue();					String className = stringConstantMap.get(arg);					if (className != null) {						frame.popValue();						if (RLE_DEBUG) System.out.println("[found access of class object " + className + "]");						frame.pushValue(getClassObjectValue(className));						return;					}				} catch (DataflowAnalysisException e) {					throw new AnalysisException("stack underflow", methodGen, handle, e);				}			} else if (Hierarchy.isInnerClassAccess(obj, cpg)) {				// Possible access of field via an inner-class access method				XField xfield = loadedFieldSet.getField(handle);				if (xfield != null) {					if (loadedFieldSet.instructionIsLoad(handle)) {						// Load via inner-class accessor						if (doRedundantLoadElimination()) {							if (xfield.isStatic())								loadStaticField((StaticField) xfield, obj);							else								loadInstanceField((InstanceField) xfield, obj);							return;						}					} else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -