package fr.lifl.stc.stan.analyser; import java.io.FileWriter; import java.io.PrintWriter; import java.io.IOException; import java.util.Arrays; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import org.apache.bcel.classfile.Method; import org.apache.bcel.classfile.JavaClass; /** * Class used to compute different statistics * * @author dorina * */ public class Stats { public static PrintWriter printerStats; //current iteration on a set of classes static int currIteration = -1; /** * number of times global signatures are used for invoke bytecodes * insted of exact signatures */ public static long noGlobalInvoke; /** * number of times exact signatures are used for invoke bytecodes */ public static long noExactInvoke; /** * statistics variables */ static int maxPass = 0, minPass = 1000, noLabels = 0, noMethods = 0; static long noPass = 0; static float moyenne = 2.43f; static float noPassDiff; static Hashtable noMethodsPerPass; static Hashtable noLabelsPerMethod; ////////////////////////////////////////////////// //// Stats for each iteration on a set of classes ////////////////////////////////////////////////// static final int MAX_ITERATIONS = 15; // int (iteration id) => int (number of analyzed methods) //static int methPerIteration[] = new int[MAX_ITERATIONS]; static Vector methPerIteration = new Vector(); // long (time) for each iteration //static long timePerIteration[] = new long[MAX_ITERATIONS]; static Vector timePerIteration = new Vector(); /** * the total size of the proof loaded with the code */ static int sizeOfProof; static long startTime; public static void initIteration() { noGlobalInvoke = 0; noExactInvoke = 0; maxPass = 0; minPass = 10000; noLabels = 0; noMethods = 0; noPass = 0; noPassDiff = 0.0f; noMethodsPerPass = new Hashtable(); noLabelsPerMethod = new Hashtable(); currIteration ++; //methPerIteration[currIteration] = 0; //methPerIteration.setElementAt(new Integer(0), currIteration); methPerIteration.add(new Integer(0)); sizeOfProof = 0; startTime = System.currentTimeMillis(); } public static void endIteration(){ //timePerIteration[currIteration] = System.currentTimeMillis() - startTime; timePerIteration.add(new Long(System.currentTimeMillis() - startTime)); } static void incAnalyzedMethod(){ int i = methPerIteration.elementAt(currIteration).intValue(); methPerIteration.setElementAt(new Integer(i+1), currIteration); //methPerIteration[currIteration]++; } static void registerLargeMethod(JavaClass cls, Method method, long time) { if(Config.statisticsEnabled()) { try { printerStats = new PrintWriter(new FileWriter(Config.statisticsFile()+".tmp", true)); printerStats.println("iteration "+currIteration+": "+cls.getClassName()+"."+method.getName()+method.getSignature()+" : time : "+time); printerStats.close(); } catch(IOException e) { System.out.println("Exception: "+ e); } } } public static void stats(MethodAnalyzer m) { Hashtable h = m.statsLabels; noLabels += h.size(); noMethods++; Integer tmpSize = new Integer(h.size()); if (noLabelsPerMethod.containsKey(tmpSize)) { int i = noLabelsPerMethod.get(tmpSize).intValue(); noLabelsPerMethod.put(tmpSize, new Integer(i + 1)); } else noLabelsPerMethod.put(tmpSize, new Integer(1)); Iterator it = h.keySet().iterator(); int maxLocal = 0; while (it.hasNext()) { int x = h.get(it.next()).intValue(); if (x > 0) { noPassDiff += Math.abs(moyenne - (float) x); } noPass += x; // if (x == 49) // System.out.println("methode name = " + m.getJavaClass().getClassName() // + "." + m.getMethod().getName() + m.getMethod().getSignature()); if (x > maxPass) maxPass = x; if (x > maxLocal) maxLocal = x; if (x < minPass) minPass = x; } Integer maxi = new Integer(maxLocal); if (noMethodsPerPass.containsKey(maxi)) { int i = noMethodsPerPass.get(maxi).intValue(); noMethodsPerPass.put(maxi, new Integer(i + 1)); } else noMethodsPerPass.put(maxi, new Integer(1)); } public static void printStats() { String s = ""; s += "\r\n no methods:\t " + noMethods; s += "\r\n no labels:\t " + noLabels; s += "\r\n no pass:\t " + noPass; s += "\r\n no pass/label:\t " + ((double) noPass) / (double) noLabels; s += "\r\n no pass diff:\t " + noPassDiff; s += "\r\n no pass diff/label:\t " + (noPassDiff) / (float) noLabels; s += "\r\n pass max:\t " + maxPass; s += "\r\n pass min:\t " + minPass; s += "\r\n\r\nNo methods per pass (no pass: no methods):\r\n"; Object[] arr = noMethodsPerPass.keySet().toArray(); Arrays.sort(arr); for (int i = 0; i < arr.length; i++) { Integer key = (Integer) arr[i]; int val = noMethodsPerPass.get(key).intValue(); s += "\r\n "+key.intValue() + ":\t" + val; } s+="\r\n\r\nNo Labels per method (no labels: no methods):\r\n"; arr = noLabelsPerMethod.keySet().toArray(); Arrays.sort(arr); for (int i = 0; i < arr.length; i++) { Integer key = (Integer) arr[i]; int val = noLabelsPerMethod.get(key).intValue(); s += "\r\n "+key.intValue() + ":\t" + val; } s += "\r\nNo global signature used : " + noGlobalInvoke; s += "\r\nNo exact signature used : " + noExactInvoke; //////////////////////////////////////// //stats regarding no of analyzed methods //////////////////////////////////////// s += "\r\n\r\n For each iteration, number of analyzed methods (methods not final):"; for(int i = 0; i <= currIteration; i++) s += "\r\n Iteration "+i+" = "+methPerIteration.elementAt(i)+" methods"; s += "\r\n\r\n For each iteration, time (miliseconds):"; for(int i = 0; i <= currIteration; i++) s += "\r\n Iteration "+i+" = "+timePerIteration.elementAt(i)+" ms"; println(s); } public static void print(String s){ if(Config.statisticsEnabled()) { try { printerStats = new PrintWriter(new FileWriter(Config.statisticsFile(), true)); printerStats.print(s); printerStats.close(); } catch(IOException e) { System.out.println("Exception: "+ e); } } } public static void println(String s){ if(Config.statisticsEnabled()) { try { printerStats = new PrintWriter(new FileWriter(Config.statisticsFile(), true)); printerStats.println(s); printerStats.close(); } catch(IOException e) { System.out.println("Exception: "+ e); } } } public static String statsToString(MethodAnalyzer m) { Hashtable h = m.statsLabels; String s = "" + h.size() + " : "; Iterator it = h.keySet().iterator(); while (it.hasNext()) { int x = h.get(it.next()).intValue(); s += x + ";"; } return s;//+"\n"; } //stats memory static long min = 100000000; static long max = 0; static int noMeth = 0; static long totalMem = 0; public static void addMemory(long m){ if(mmax) max = m; totalMem += m; noMeth++; } public static void printMemory(){ // System.out.println("min memory = "+min); // System.out.println("max memory = "+max); // System.out.println("total memory = "+totalMem); // System.out.println("average memory = "+totalMem/noMeth); System.out.println("max aprox memory online = "+maxOnLine/1024f); System.out.println("max aprox memory offline = "+maxOffLine/1024f); System.out.println("avg aprox memory online = "+totalOnLine/countMem/1024f); System.out.println("avg aprox memory offline = "+totalOffLine/countMem/1024f); } //stats memory; aproximation static long maxOnLine = 0; static long maxOffLine = 0; static int countMem = 0; static long totalOnLine =0; static long totalOffLine =0; public static void aproxMemory(int noLabels, int sizeTableLink){ long online = 2*sizeTableLink*sizeTableLink+sizeTableLink*10; maxOnLine = Math.max(maxOnLine, online); totalOnLine += online; long offline = 4*noLabels*sizeTableLink*sizeTableLink+sizeTableLink*22; maxOffLine = Math.max(maxOffLine, offline); totalOffLine += offline; countMem++; } }