import java.io.*; import java.util.*; public class Prof { // cat /tmp/profile.log | arm-elf-addr2line -e main.out -fi > /tmp/profile.dat static class Line implements Comparable { int lineNumber; int samples; public Line(int lineNumber) { this.lineNumber = lineNumber; } // sort by line number public int compareTo(Line l) { return lineNumber - l.lineNumber; } } static class Function implements Comparable { String file; String name; int samples; HashMap lines = new HashMap(); public Function(String file, String name) { this.file = file; this.name = name; } public int compareTo(Function f) { return f.samples - samples; } public void sampleLine(int lineNumber) { Line line = lines.get(lineNumber); if (line == null) { line = new Line(lineNumber); lines.put(lineNumber, line); } line.samples++; samples++; } public void output(int totalSamples) { ArrayList ls = new ArrayList(lines.values()); Collections.sort(ls); int context = 5; int low = ls.get(0).lineNumber - context; if (low < 0) low = 0; int high = ls.get(ls.size()-1).lineNumber + context; int next = 0; for (int i = low; i <= high; i++) { Line line = null; if (next < lines.size()) line = ls.get(next); double percent = 0; if (line != null && line.lineNumber == i) { percent = 100.0*line.samples/totalSamples; next++; } System.out.printf(" %6.5f %5d: %s\n", percent, i, db.getLine(file, i)); } System.out.printf("\n"); } } static class LineDatabase { HashMap> files = new HashMap>(); ArrayList searchPath = new ArrayList(); public LineDatabase() { addPath("."); addPath("/"); } public void addPath(String path) { searchPath.add(path); } void loadFile(String file) { ArrayList lines = new ArrayList(); String path = null; for (int i = 0; i < searchPath.size(); i++) { path = searchPath.get(i) + "/" + file; File f = new File(path); if (f.exists()) break; } try { BufferedReader ins = new BufferedReader(new FileReader(path)); String line; while ((line = ins.readLine())!=null) { lines.add(line); } ins.close(); files.put(file, lines); } catch (IOException ex) { // System.out.println("ex: "+ex); } } public String getLine(String file, int line) { line--; // adjust for zero-indexing ArrayList lines = files.get(file); if (lines == null) { loadFile(file); lines = files.get(file); } if (lines == null || line >= lines.size()) return ""; return lines.get(line); } } static LineDatabase db = new LineDatabase(); public static void main(String args[]) { for (int i = 1; i < args.length; i++) db.addPath(args[i]); HashMap functions = new HashMap(); try { BufferedReader ins = new BufferedReader(new FileReader(args[0])); int totalSamples = 0; while (true) { String functionName = ins.readLine(); String fileline = ins.readLine(); if (functionName == null || fileline==null) break; int idx = fileline.indexOf(':'); String file = fileline.substring(0, idx); int lineNumber = Integer.parseInt(fileline.substring(idx+1)); Function f = functions.get(functionName); if (f == null) { f = new Function(file, functionName); functions.put(functionName, f); } f.sampleLine(lineNumber); totalSamples++; } System.out.printf("%d samples, each samples is %6.5f%%\n\n", totalSamples, 100.0/totalSamples); ArrayList fs = new ArrayList(functions.values()); Collections.sort(fs); for (int i = 0; i < fs.size(); i++) { Function f = fs.get(i); System.out.printf("%6.3f %s\n", f.samples*100.0/totalSamples, f.name); f.output(totalSamples); } System.out.printf("Total hits: %d\n", totalSamples); } catch (IOException ex) { System.out.println("ioex: "+ex); } } }