📄 valuenumberframemodelingvisitor.java
字号:
// Don't know what this method invocation is doing. // Kill all loads. killLoadsOfObjectsPassed(obj); getFrame().killAllLoadsOf(null); } } handleNormalInstruction(obj); } private void killLoadsOfObjectsPassed(InvokeInstruction ins) { try { int passed = getNumWordsConsumed(ins); ValueNumber [] arguments = new ValueNumber[passed]; getFrame().killLoadsWithSimilarName(ins.getClassName(cpg), ins.getMethodName(cpg)); getFrame().getTopStackWords(arguments); for(ValueNumber v : arguments) getFrame().killAllLoadsOf(v); } catch (DataflowAnalysisException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void visitMONITORENTER(MONITORENTER obj) { // Don't know what this sync invocation is doing. // Kill all loads. getFrame().killAllLoads(); handleNormalInstruction(obj); } @Override public void visitINVOKESPECIAL(INVOKESPECIAL obj) { // Don't know what this method invocation is doing. // Kill all loads. killLoadsOfObjectsPassed(obj); handleNormalInstruction(obj); } @Override public void visitINVOKEINTERFACE(INVOKEINTERFACE obj) { // Don't know what this method invocation is doing. // Kill all loads. if (obj.getMethodName(cpg).equals("lock")) getFrame().killAllLoads(); else killLoadsOfObjectsPassed(obj); handleNormalInstruction(obj); } @Override public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { // Don't know what this method invocation is doing. // Kill all loads. if (obj.getMethodName(cpg).equals("lock")) getFrame().killAllLoads(); else killLoadsOfObjectsPassed(obj); handleNormalInstruction(obj); } @Override public void visitLDC(LDC obj) { Object constantValue = obj.getValue(cpg); ValueNumber value; if (constantValue instanceof ConstantClass) { ConstantClass constantClass = (ConstantClass) constantValue; String className = constantClass.getBytes(cpg.getConstantPool()); value = getClassObjectValue(className); } else { value = constantValueMap.get(constantValue); if (value == null) { value = factory.createFreshValue(); constantValueMap.put(constantValue, value); // Keep track of String constants if (constantValue instanceof String) { stringConstantMap.put(value, (String) constantValue); } } } getFrame().pushValue(value); } @Override public void visitIINC(IINC obj) { if (obj.getIncrement() == 0) { // A no-op. return; } // IINC is a special case because its input and output are not on the stack. // However, we still want to use the value number cache to ensure that // this operation is modeled consistently. (If we do nothing, we miss // the fact that the referenced local is modified.) int local = obj.getIndex(); ValueNumber[] input = new ValueNumber[]{ getFrame().getValue(local) }; ValueNumberCache.Entry entry = new ValueNumberCache.Entry(handle, input); ValueNumber[] output = cache.lookupOutputValues(entry); if (output == null) { output = new ValueNumber[]{ factory.createFreshValue() }; cache.addOutputValues(entry, output); } getFrame().setValue(local, output[0]); } @Override public void visitCHECKCAST(CHECKCAST obj) { // Do nothing } /* ---------------------------------------------------------------------- * Implementation * ---------------------------------------------------------------------- */ /** * Pop the input values for the given instruction from the * current frame. */ private ValueNumber[] popInputValues(int numWordsConsumed) { ValueNumberFrame frame = getFrame(); ValueNumber[] inputValueList = new ValueNumber[numWordsConsumed]; // Pop off the input operands. try { frame.getTopStackWords(inputValueList); while (numWordsConsumed-- > 0) { frame.popValue(); } } catch (DataflowAnalysisException e) { throw new InvalidBytecodeException("Error getting input operands", e); } return inputValueList; } /** * Push given output values onto the current frame. */ private void pushOutputValues(ValueNumber[] outputValueList) { ValueNumberFrame frame = getFrame(); for (ValueNumber aOutputValueList : outputValueList) frame.pushValue(aOutputValueList); } /** * Get output values for current instruction from the ValueNumberCache. */ private ValueNumber[] getOutputValues(ValueNumber[] inputValueList, int numWordsProduced) { return getOutputValues(inputValueList, numWordsProduced, 0); } private ValueNumber[] getOutputValues(ValueNumber[] inputValueList, int numWordsProduced, int flags) { ValueNumberCache.Entry entry = new ValueNumberCache.Entry(handle, inputValueList); ValueNumber[] outputValueList = cache.lookupOutputValues(entry); if (outputValueList == null) { outputValueList = new ValueNumber[numWordsProduced]; for (int i = 0; i < numWordsProduced; ++i) { ValueNumber freshValue = factory.createFreshValue(); freshValue.setFlags(flags); outputValueList[i] = freshValue; } if (false && RLE_DEBUG) { System.out.println("<<cache fill for " + handle.getPosition() + ": " + vlts(inputValueList) + " ==> " + vlts(outputValueList) + ">>"); } cache.addOutputValues(entry, outputValueList); } else if (false && RLE_DEBUG) { System.out.println("<<cache hit for " + handle.getPosition() + ": " + vlts(inputValueList) + " ==> " + vlts(outputValueList) + ">>"); } return outputValueList; } private static String vlts(ValueNumber[] vl) { StringBuffer buf = new StringBuffer(); for (ValueNumber aVl : vl) { if (buf.length() > 0) buf.append(','); buf.append(aVl.getNumber()); } return buf.toString(); } /** * Load an instance field. * * @param instanceField the field * @param obj the Instruction loading the field */ private void loadInstanceField(InstanceField instanceField, Instruction obj) { if (RLE_DEBUG) { System.out.println("[loadInstanceField for field " + instanceField + " in instruction " + handle); } ValueNumberFrame frame = getFrame(); try { ValueNumber reference = frame.popValue(); AvailableLoad availableLoad = new AvailableLoad(reference, instanceField); if (RLE_DEBUG) System.out.println("[getfield of " + availableLoad + "]"); ValueNumber[] loadedValue = frame.getAvailableLoad(availableLoad); if (loadedValue == null) { // Get (or create) the cached result for this instruction ValueNumber[] inputValueList = new ValueNumber[]{reference}; loadedValue = getOutputValues(inputValueList, getNumWordsProduced(obj)); // Make the load available frame.addAvailableLoad(availableLoad, loadedValue); if (RLE_DEBUG) { System.out.println("[Making load available " + availableLoad + " <- " + vlts(loadedValue) + "]"); } } else { // Found an available load! if (RLE_DEBUG) { System.out.println("[Found available load " + availableLoad + " <- " + vlts(loadedValue) + "]"); } } pushOutputValues(loadedValue); if (VERIFY_INTEGRITY) { checkConsumedAndProducedValues(obj, new ValueNumber[]{reference}, loadedValue); } } catch (DataflowAnalysisException e) { throw new InvalidBytecodeException("Error loading from instance field", e); } } /** * Load a static field. * * @param staticField the field * @param obj the Instruction loading the field */ private void loadStaticField(StaticField staticField, Instruction obj) { if (RLE_DEBUG) { System.out.println("[loadStaticField for field " + staticField + " in instruction " + handle); } ValueNumberFrame frame = getFrame(); AvailableLoad availableLoad = new AvailableLoad(staticField); ValueNumber[] loadedValue = frame.getAvailableLoad(availableLoad); if (loadedValue == null) { // Make the load available int numWordsProduced = getNumWordsProduced(obj); loadedValue = getOutputValues(EMPTY_INPUT_VALUE_LIST, numWordsProduced); frame.addAvailableLoad(availableLoad, loadedValue); if (RLE_DEBUG) System.out.println("[making load of " + staticField + " available]"); } else { if (RLE_DEBUG) System.out.println("[found available load of " + staticField + "]"); } if (VERIFY_INTEGRITY) { checkConsumedAndProducedValues(obj, new ValueNumber[0], loadedValue); } pushOutputValues(loadedValue); } /** * Store an instance field. * * @param instanceField the field * @param obj the instruction which stores the field * @param pushStoredValue push the stored value onto the stack * (because we are modeling an inner-class field access method) */ private void storeInstanceField(InstanceField instanceField, Instruction obj, boolean pushStoredValue) { if (RLE_DEBUG) { System.out.println("[storeInstanceField for field " + instanceField + " in instruction " + handle); } ValueNumberFrame frame = getFrame(); int numWordsConsumed = getNumWordsConsumed(obj);/* System.out.println("Instruction is " + handle); System.out.println("numWordsConsumed="+numWordsConsumed);*/ ValueNumber[] inputValueList = popInputValues(numWordsConsumed); ValueNumber reference = inputValueList[0]; ValueNumber[] storedValue = new ValueNumber[inputValueList.length - 1]; System.arraycopy(inputValueList, 1, storedValue, 0, inputValueList.length - 1); if (pushStoredValue) pushOutputValues(storedValue); // Kill all previous loads of the same field, // in case there is aliasing we don't know about frame.killLoadsOfField(instanceField); // Forward substitution frame.addAvailableLoad(new AvailableLoad(reference, instanceField), storedValue); if (RLE_DEBUG) System.out.println("[making store of " + instanceField + " available]"); if (VERIFY_INTEGRITY) {/* System.out.println("pushStoredValue="+pushStoredValue);*/ checkConsumedAndProducedValues(obj, inputValueList, pushStoredValue ? storedValue : new ValueNumber[0]); } } /** * Store a static field. * * @param staticField the static field * @param obj the instruction which stores the field * @param pushStoredValue push the stored value onto the stack * (because we are modeling an inner-class field access method) */ private void storeStaticField(StaticField staticField, Instruction obj, boolean pushStoredValue) { if (RLE_DEBUG) { System.out.println("[storeStaticField for field " + staticField + " in instruction " + handle); } ValueNumberFrame frame = getFrame(); AvailableLoad availableLoad = new AvailableLoad(staticField); int numWordsConsumed = getNumWordsConsumed(obj); ValueNumber[] inputValueList = popInputValues(numWordsConsumed); if (pushStoredValue) pushOutputValues(inputValueList); // Kill loads of this field frame.killLoadsOfField(staticField); // Make load available frame.addAvailableLoad(availableLoad, inputValueList); if (RLE_DEBUG) System.out.println("[making store of " + staticField + " available]"); if (VERIFY_INTEGRITY) { checkConsumedAndProducedValues(obj, inputValueList, pushStoredValue ? inputValueList : new ValueNumber[0]); } } /** * Get the ValueNumber for given class's Class object. * * @param className the class */ public ValueNumber getClassObjectValue(String className) { // TODO: Check to see if we need to do this className = className.replace('/','.'); ValueNumber value = classObjectValueMap.get(className); if (value == null) { value = factory.createFreshValue(); value.setFlag(ValueNumber.CONSTANT_CLASS_OBJECT); classObjectValueMap.put(className, value); } return value; }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -