/******************************************************************************* * Copyright (c) 2002,2006 IBM Corporation. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package com.ibm.wala.shrikeBT.info; import com.ibm.wala.shrikeBT.ArrayLengthInstruction; import com.ibm.wala.shrikeBT.ConstantInstruction; import com.ibm.wala.shrikeBT.DupInstruction; import com.ibm.wala.shrikeBT.ExceptionHandler; import com.ibm.wala.shrikeBT.GotoInstruction; import com.ibm.wala.shrikeBT.IArrayLoadInstruction; import com.ibm.wala.shrikeBT.IArrayStoreInstruction; import com.ibm.wala.shrikeBT.IBinaryOpInstruction; import com.ibm.wala.shrikeBT.IComparisonInstruction; import com.ibm.wala.shrikeBT.IConditionalBranchInstruction; import com.ibm.wala.shrikeBT.IConversionInstruction; import com.ibm.wala.shrikeBT.IGetInstruction; import com.ibm.wala.shrikeBT.IInstanceofInstruction; import com.ibm.wala.shrikeBT.IInstruction; import com.ibm.wala.shrikeBT.IInvokeInstruction; import com.ibm.wala.shrikeBT.ILoadInstruction; import com.ibm.wala.shrikeBT.IPutInstruction; import com.ibm.wala.shrikeBT.IShiftInstruction; import com.ibm.wala.shrikeBT.IStoreInstruction; import com.ibm.wala.shrikeBT.ITypeTestInstruction; import com.ibm.wala.shrikeBT.IUnaryOpInstruction; import com.ibm.wala.shrikeBT.MethodData; import com.ibm.wala.shrikeBT.MonitorInstruction; import com.ibm.wala.shrikeBT.NewInstruction; import com.ibm.wala.shrikeBT.PopInstruction; import com.ibm.wala.shrikeBT.ReturnInstruction; import com.ibm.wala.shrikeBT.SwapInstruction; import com.ibm.wala.shrikeBT.SwitchInstruction; import com.ibm.wala.shrikeBT.ThrowInstruction; /** * This method annotation counts the number of instructions of each type (according to each Instruction subclass). * * The get...Count methods are the only methods needed by clients. These methods check to see if the MethodData object already has * an InstructionTypeCounter annotation before recomputing the counts and returning the desired count. */ public class InstructionTypeCounter implements MethodData.Results { private final static String key = InstructionTypeCounter.class.getName(); private int countMonitors; private int countGets; private int countPuts; private int countArrayLoads; private int countArrayStores; private int countInvokes; private int countArrayLengths; private int countBinaryOps; private int countCheckCasts; private int countComparisons; private int countConditionalBranches; private int countConstants; private int countConversions; private int countDups; private int countGotos; private int countInstanceOfs; private int countLocalLoads; private int countLocalStores; private int countNews; private int countPops; private int countReturns; private int countShifts; private int countSwaps; private int countSwitches; private int countThrows; private int countUnaryOps; InstructionTypeCounter(MethodData info) { recalculateFrom(info.getInstructions()); } private void recalculateFrom(IInstruction[] instructions) { countMonitors = 0; countGets = 0; countPuts = 0; countArrayLoads = 0; countArrayStores = 0; countInvokes = 0; countArrayLengths = 0; countBinaryOps = 0; countCheckCasts = 0; countComparisons = 0; countConditionalBranches = 0; countConstants = 0; countConversions = 0; countDups = 0; countGotos = 0; countInstanceOfs = 0; countLocalLoads = 0; countLocalStores = 0; countNews = 0; countPops = 0; countReturns = 0; countShifts = 0; countSwaps = 0; countSwitches = 0; countThrows = 0; countUnaryOps = 0; IInstruction.Visitor visitor = new IInstruction.Visitor() { @Override public void visitArrayLength(ArrayLengthInstruction instruction) { countArrayLengths++; } @Override public void visitBinaryOp(IBinaryOpInstruction instruction) { countBinaryOps++; } @Override public void visitCheckCast(ITypeTestInstruction instruction) { countCheckCasts++; } @Override public void visitComparison(IComparisonInstruction instruction) { countComparisons++; } @Override public void visitConditionalBranch(IConditionalBranchInstruction instruction) { countConditionalBranches++; } @Override public void visitConstant(ConstantInstruction instruction) { countConstants++; } @Override public void visitConversion(IConversionInstruction instruction) { countConversions++; } @Override public void visitDup(DupInstruction instruction) { countDups++; } @Override public void visitGoto(GotoInstruction instruction) { countGotos++; } @Override public void visitInstanceof(IInstanceofInstruction instruction) { countInstanceOfs++; } @Override public void visitLocalLoad(ILoadInstruction instruction) { countLocalLoads++; } @Override public void visitLocalStore(IStoreInstruction instruction) { countLocalStores++; } @Override public void visitNew(NewInstruction instruction) { countNews++; } @Override public void visitPop(PopInstruction instruction) { countPops++; } @Override public void visitReturn(ReturnInstruction instruction) { countReturns++; } @Override public void visitShift(IShiftInstruction instruction) { countShifts++; } @Override public void visitSwap(SwapInstruction instruction) { countSwaps++; } @Override public void visitSwitch(SwitchInstruction instruction) { countSwitches++; } @Override public void visitThrow(ThrowInstruction instruction) { countThrows++; } @Override public void visitUnaryOp(IUnaryOpInstruction instruction) { countUnaryOps++; } @Override public void visitArrayLoad(IArrayLoadInstruction instruction) { countArrayLoads++; } @Override public void visitArrayStore(IArrayStoreInstruction instruction) { countArrayStores++; } @Override public void visitGet(IGetInstruction instruction) { countGets++; } @Override public void visitPut(IPutInstruction instruction) { countPuts++; } @Override public void visitMonitor(MonitorInstruction instruction) { countMonitors++; } @Override public void visitInvoke(IInvokeInstruction instruction) { countInvokes++; } }; for (int i = 0; i < instructions.length; i++) { instructions[i].visit(visitor); } } /** * Whenever the underlying method is updated, we'll throw away our counts so they can be reconstructed from scratch next time. * * This is not to be called by clients. */ @Override public boolean notifyUpdate(MethodData info, IInstruction[] newInstructions, ExceptionHandler[][] newHandlers, int[] newInstructionMap) { // just throw this away and we'll recalculate from scratch if necessary return true; } public static int getArrayLoadCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countArrayLoads; } public static int getArrayStoreCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countArrayStores; } public static int getGetCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countGets; } public static int getPutCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countPuts; } public static int getMonitorCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countMonitors; } public static int getInvokeCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countInvokes; } public static int getComparisonCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countComparisons; } public static int getArrayLengthCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countArrayLengths; } public static int getConstantCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countConstants; } public static int getShiftCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countShifts; } public static int getSwitchesCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countSwitches; } public static int getSwapCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countSwaps; } public static int getBinaryOpCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countBinaryOps; } public static int getCheckCastCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countCheckCasts; } public static int getThrowCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countThrows; } public static int getConditionalBranchCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countConditionalBranches; } public static int getConversionCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countConversions; } public static int getDupCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countDups; } public static int getGotoCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countGotos; } public static int getReturnCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countReturns; } public static int getInstanceOfCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countInstanceOfs; } public static int getLocalLoadCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countLocalLoads; } public static int getLocalStoreCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countLocalStores; } public static int getNewCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countNews; } public static int getPopCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countPops; } public static int getUnaryOpCount(MethodData info) throws IllegalArgumentException { if (info == null) { throw new IllegalArgumentException(); } return getCounter(info).countUnaryOps; } private static InstructionTypeCounter getCounter(MethodData info) { InstructionTypeCounter c = (InstructionTypeCounter) info.getInfo(key); if (c == null) { c = new InstructionTypeCounter(info); info.putInfo(key, c); } return c; } }