📄 valuenumberframemodelingvisitor.java
字号:
// Store via inner-class accessor if (doForwardSubstitution()) { // Some inner class access store methods // return the value stored. boolean pushValue = !methodSig.endsWith(")V"); if (xfield.isStatic()) storeStaticField((StaticField) xfield, obj, pushValue); else storeInstanceField((InstanceField) xfield, obj, pushValue); return; } } } } } handleNormalInstruction(obj); }/* public void visitINVOKESPECIAL(INVOKESPECIAL obj) { handleNormalInstruction(obj); } public void visitINVOKEINTERFACE(INVOKEINTERFACE obj) { handleNormalInstruction(obj); } public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) { handleNormalInstruction(obj); }*/ public void visitLDC(LDC obj) { ValueNumber value = constantValueMap.get(handle); if (value == null) { ConstantPoolGen cpg = getCPG(); value = factory.createFreshValue(); constantValueMap.put(handle, value); // Keep track of String constants Object constantValue = obj.getValue(cpg); if (constantValue instanceof String) { stringConstantMap.put(value, (String) constantValue); } } getFrame().pushValue(value); } /* ---------------------------------------------------------------------- * 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 AnalysisException("ValueNumberFrameModelingVisitor caught exception: " + e.toString(), e); } return inputValueList; } /** * Push given output values onto the current frame. */ private void pushOutputValues(ValueNumber[] outputValueList) { ValueNumberFrame frame = getFrame(); for (int i = 0; i < outputValueList.length; ++i) frame.pushValue(outputValueList[i]); } /** * 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 (RLE_DEBUG) { System.out.println("<<cache fill for " + handle.getPosition() + ": " + vlts(inputValueList) + " ==> " + vlts(outputValueList) + ">>"); } cache.addOutputValues(entry, outputValueList); } else if (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 (int i = 0; i < vl.length; ++i) { if (buf.length() > 0) buf.append(','); buf.append(vl[i].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 AnalysisException("ValueNumberFrameModelingVisitor caught exception: " + e.toString(), 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 */ private ValueNumber getClassObjectValue(String className) { ValueNumber value = classObjectValueMap.get(className); if (value == null) { value = factory.createFreshValue(); classObjectValueMap.put(className, value); } return value; }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -