InstructionHandle rewriteStore(MethodGen m, InstructionList il, InstructionHandle i, int maxLocals, String localClassName) { LocalVariableInstruction curr = (LocalVariableInstruction) (i .getInstruction()); Type type = mtab.getLocalType(m, curr, i.getPosition()); if (type == null) { return i; } String name = mtab.getLocalName(m, curr, i.getPosition()); String fieldName = MethodTable.generatedLocalName(type, name); i.setInstruction(new ALOAD(maxLocals)); i = i.getNext(); if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) { il.insert(i, new DUP_X2()); il.insert(i, new POP()); } else { il.insert(i, new SWAP()); } i = il.insert(i, ins_f.createFieldAccess(localClassName, fieldName, type, Constants.PUTFIELD)); return i; }
/** * @param aInstruction * @param aPoolGen */ public PUTFIELDReference( PUTFIELD aInstruction, ConstantPoolGen aPoolGen) { super(aInstruction, aPoolGen); }
boolean isPutField(InstructionHandle ins) { if (ins == null) { return false; } Instruction i = ins.getInstruction(); return i instanceof PUTFIELD; }
private int indexToCheckForAlias(InstructionHandle ih, MethodGen mg) { if (mg.isArrayStore(ih.getInstruction()) || ih.getInstruction() instanceof PUTFIELD) { ih = mg.getObjectReferenceLoadInstruction(ih); ALOAD objectLoadInstruction = (ALOAD) ih.getInstruction(); // The 'not an ALOAD' case is already dealt with. return objectLoadInstruction.getIndex(); } return -1; }
@Override public void visitPUTFIELD(PUTFIELD obj) { if (doForwardSubstitution()) { XField xfield = Hierarchy.findXField(obj, getCPG()); if (xfield != null) { storeInstanceField(xfield, obj, false); return; } } handleNormalInstruction(obj); }
@Override public void visitPUTFIELD(PUTFIELD obj) { if (getNumWordsConsumed(obj) != 2) { super.visitPUTFIELD(obj); return; } IsNullValue nullValueStored = null; try { nullValueStored = getFrame().getTopValue(); } catch (DataflowAnalysisException e1) { AnalysisContext.logError("Oops", e1); } super.visitPUTFIELD(obj); XField field = XFactory.createXField(obj, cpg); if (nullValueStored != null && ValueNumberAnalysisFeatures.REDUNDANT_LOAD_ELIMINATION) try { ValueNumberFrame vnaFrameBefore = vnaDataflow.getFactAtLocation(getLocation()); ValueNumber refValue = vnaFrameBefore.getStackValue(1); AvailableLoad load = new AvailableLoad(refValue, field); ValueNumberFrame vnaFrameAfter = vnaDataflow.getFactAfterLocation(getLocation()); ValueNumber[] newValueNumbersForField = vnaFrameAfter.getAvailableLoad(load); if (newValueNumbersForField != null && trackValueNumbers) for (ValueNumber v : newValueNumbersForField) getFrame().setKnownValue(v, nullValueStored); } catch (DataflowAnalysisException e) { AnalysisContext.logError("Oops", e); } }
/** @see org.apache.bcel.generic.Visitor */ public void visitPUTFIELD(PUTFIELD aPUTFIELD) { addFieldReference( new PUTFIELDReference(aPUTFIELD, mCurrentPoolGen)); }
void initSpawnTargets(InstructionList il) { for (int i = 0; i < idTable.size(); i++) { InstructionList storeIns = getStoreIns(i); if (storeIns == null) { continue; } if (isArrayStore(storeIns.getStart())) { continue; } Instruction store = storeIns.getStart().getInstruction(); if (store instanceof LSTORE) { il.insert(new LCONST(0)); il.append(il.getStart(), store); } else if (store instanceof ISTORE) { il.insert(new ICONST(0)); il.append(il.getStart(), store); } else if (store instanceof FSTORE) { il.insert(new FCONST((float) 0.0)); il.append(il.getStart(), store); } else if (store instanceof DSTORE) { il.insert(new DCONST(0.0)); il.append(il.getStart(), store); } else if (store instanceof ASTORE) { il.insert(new ACONST_NULL()); il.append(il.getStart(), store); } else if (store instanceof PUTFIELD) { // no need to init. } else if (store instanceof PUTSTATIC) { // no need to init. } else if (store instanceof ALOAD) { // no need to init. } else { System.err.println("WARNING: Unhandled store instruction in " + "initSpawnTargets, opcode = " + store.getOpcode() + " ins = " + store); // System.exit(1); } } }
byte[] counterAdaptClass(final InputStream is, final String name) throws Exception { JavaClass jc = new ClassParser(is, name + ".class").parse(); ClassGen cg = new ClassGen(jc); ConstantPoolGen cp = cg.getConstantPool(); if (!cg.isInterface()) { FieldGen fg = new FieldGen(ACC_PUBLIC, Type.getType("I"), "_counter", cp); cg.addField(fg.getField()); } Method[] ms = cg.getMethods(); for (int j = 0; j < ms.length; ++j) { MethodGen mg = new MethodGen(ms[j], cg.getClassName(), cp); if (!mg.getName().equals("<init>") && !mg.isStatic() && !mg.isAbstract() && !mg.isNative()) { if (mg.getInstructionList() != null) { InstructionList il = new InstructionList(); il.append(new ALOAD(0)); il.append(new ALOAD(0)); il.append(new GETFIELD(cp.addFieldref(name, "_counter", "I"))); il.append(new ICONST(1)); il.append(new IADD()); il.append(new PUTFIELD(cp.addFieldref(name, "_counter", "I"))); mg.getInstructionList().insert(il); mg.setMaxStack(Math.max(mg.getMaxStack(), 2)); boolean lv = ms[j].getLocalVariableTable() == null; boolean ln = ms[j].getLineNumberTable() == null; if (lv) { mg.removeLocalVariables(); } if (ln) { mg.removeLineNumbers(); } cg.replaceMethod(ms[j], mg.getMethod()); } } } return cg.getJavaClass().getBytes(); }
@Override public void visitPUTFIELD(PUTFIELD putfield) { handleFieldStore(putfield); }
@Override public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, UnconditionalValueDerefSet fact) throws DataflowAnalysisException { Instruction instruction = handle.getInstruction(); if (fact.isTop()) return; Location location = new Location(handle, basicBlock); // If this is a call to an assertion method, // change the dataflow value to be TOP. // We don't want to report future derefs that would // be guaranteed only if the assertion methods // returns normally. // TODO: at some point, evaluate whether we should revisit this if (isAssertion(handle) // || handle.getInstruction() instanceof ATHROW ) { if (DEBUG) System.out.println("MAKING BOTTOM0 AT: " + location); fact.clear(); return; } // Get value number frame ValueNumberFrame vnaFrame = vnaDataflow.getFactAtLocation(location); if (!vnaFrame.isValid()) { if (DEBUG) System.out.println("MAKING TOP1 AT: " + location); // Probably dead code. // Assume this location can't be reached. makeFactTop(fact); return; } if (isNullCheck(handle, methodGen.getConstantPool())) { handleNullCheck(location, vnaFrame, fact); } // Check for calls to a method that unconditionally dereferences // a parameter. Mark any such arguments as derefs. if (CHECK_CALLS && instruction instanceof InvokeInstruction) { checkUnconditionalDerefDatabase(location, vnaFrame, fact); } // If this is a method call instruction, // check to see if any of the parameters are @NonNull, // and treat them as dereferences. if (CHECK_ANNOTATIONS && instruction instanceof InvokeInstruction) { checkNonNullParams(location, vnaFrame, fact); } if (CHECK_ANNOTATIONS && instruction instanceof ARETURN) { XMethod thisMethod = XFactory.createXMethod(methodGen); checkNonNullReturnValue(thisMethod, location, vnaFrame, fact); } if (CHECK_ANNOTATIONS && (instruction instanceof PUTFIELD || instruction instanceof PUTSTATIC)) { checkNonNullPutField(location, vnaFrame, fact); } // Check to see if an instance value is dereferenced here checkInstance(location, vnaFrame, fact); if (false) fact.cleanDerefSet(location, vnaFrame); if (DEBUG && fact.isTop()) System.out.println("MAKING TOP2 At: " + location); }
/** * Is the instruction a write of a field? * * @param ins * the Instruction to check * @param cpg * ConstantPoolGen of the method containing the instruction * @return the Field if instruction is a write of a field, null otherwise */ public static FieldAnnotation isWrite(Instruction ins, ConstantPoolGen cpg) { if (ins instanceof PUTFIELD || ins instanceof PUTSTATIC) { FieldInstruction fins = (FieldInstruction) ins; String className = fins.getClassName(cpg); return new FieldAnnotation(className, fins.getName(cpg), fins.getSignature(cpg), fins instanceof PUTSTATIC); } else return null; }