| /******************************************************************************* |
| * Copyright (c) 2004 IBM Corporation and others. |
| * 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 org.eclipse.swt.tools.internal; |
| |
| import java.io.PrintStream; |
| import java.lang.reflect.Method; |
| import java.util.Arrays; |
| import java.util.Enumeration; |
| import java.util.Hashtable; |
| |
| /** |
| * Instructions on how to use the NativeStats tool with a standlaone SWT example: |
| * |
| * 1) Compile the SWT native libraries defining the NATIVE_STATS flag (i.e. uncomment line in makefile). |
| * 2) Add the following code around the sections of interest to dump the |
| * native calls done in that section. |
| * |
| * NativeStats stats = new NativeStats(); |
| * ... |
| * <code section> |
| * ... |
| * stats.dumpDiff(System.out); |
| * |
| * 3) Or add the following code at a given point to dump a snapshot of |
| * the native calls done until that point. |
| * |
| * new NativeStats().dumpSnapshot(System.out); |
| */ |
| public class NativeStats { |
| |
| Hashtable snapshot; |
| |
| final static String[] classes = new String[]{"OS", "ATK", "CDE", "GNOME", "GTK", "XPCOM", "COM"}; |
| |
| |
| public static class NativeFunction implements Comparable { |
| String name; |
| int callCount; |
| |
| public NativeFunction(String name, int callCount) { |
| this.name = name; |
| this.callCount = callCount; |
| } |
| |
| void subtract(NativeFunction func) { |
| this.callCount -= func.callCount; |
| } |
| |
| public int getCallCount() { |
| return callCount; |
| } |
| |
| public String getName() { |
| return name; |
| } |
| public int compareTo(Object func) { |
| return ((NativeFunction)func).callCount - callCount; |
| } |
| } |
| |
| public NativeStats() { |
| snapshot = snapshot(); |
| } |
| |
| public Hashtable diff() { |
| Hashtable newSnapshot = snapshot(); |
| Enumeration keys = newSnapshot.keys(); |
| while (keys.hasMoreElements()) { |
| String className = (String)keys.nextElement(); |
| NativeFunction[] newFuncs = (NativeFunction[])newSnapshot.get(className); |
| NativeFunction[] funcs = (NativeFunction[])snapshot.get(className); |
| if (funcs != null) { |
| for (int i = 0; i < newFuncs.length; i++) { |
| newFuncs[i].subtract(funcs[i]); |
| } |
| } |
| } |
| return newSnapshot; |
| } |
| |
| public void dumpDiff(PrintStream ps) { |
| dump(diff(), ps); |
| } |
| |
| public void dumpSnapshot(PrintStream ps) { |
| dump(snapshot(), ps); |
| } |
| |
| public void dumpSnapshot(String className, PrintStream ps) { |
| Hashtable snapshot = new Hashtable(); |
| snapshot(className, snapshot); |
| dump(className, (NativeFunction[])snapshot.get(className), ps); |
| } |
| |
| public void dump(Hashtable snapshot, PrintStream ps) { |
| Enumeration keys = snapshot.keys(); |
| while (keys.hasMoreElements()) { |
| String className = (String)keys.nextElement(); |
| dump(className, (NativeFunction[])snapshot.get(className), ps); |
| } |
| } |
| |
| void dump(String className, NativeFunction[] funcs, PrintStream ps) { |
| if (funcs == null) return; |
| Arrays.sort(funcs); |
| int total = 0; |
| for (int i = 0; i < funcs.length; i++) { |
| NativeFunction func = funcs[i]; |
| total += func.getCallCount(); |
| } |
| ps.print(className); |
| ps.print("="); |
| ps.print(total); |
| ps.println(); |
| for (int i = 0; i < funcs.length; i++) { |
| NativeFunction func = funcs[i]; |
| if (func.getCallCount() > 0) { |
| ps.print("\t"); |
| ps.print(func.getName()); |
| ps.print("="); |
| ps.print(func.getCallCount()); |
| ps.println(); |
| } |
| } |
| } |
| |
| public void reset() { |
| snapshot = snapshot(); |
| } |
| |
| public Hashtable snapshot() { |
| Hashtable snapshot = new Hashtable(); |
| for (int i = 0; i < classes.length; i++) { |
| String className = classes[i]; |
| snapshot(className, snapshot); |
| } |
| return snapshot; |
| } |
| |
| public Hashtable snapshot(String className, Hashtable snapshot) { |
| try { |
| Class clazz = getClass(); |
| Method functionCount = clazz.getMethod(className + "_GetFunctionCount", new Class[0]); |
| Method functionCallCount = clazz.getMethod(className + "_GetFunctionCallCount", new Class[]{int.class}); |
| Method functionName = clazz.getMethod(className + "_GetFunctionName", new Class[]{int.class}); |
| int count = ((Integer)functionCount.invoke(clazz, new Object[0])).intValue(); |
| NativeFunction[] funcs = new NativeFunction[count]; |
| Object[] index = new Object[1]; |
| for (int i = 0; i < count; i++) { |
| index[0] = new Integer(i); |
| int callCount = ((Integer)functionCallCount.invoke(clazz, index)).intValue(); |
| String name = (String)functionName.invoke(clazz, index); |
| funcs[i] = new NativeFunction(name, callCount); |
| } |
| snapshot.put(className, funcs); |
| } catch (Throwable e) { |
| // e.printStackTrace(System.out); |
| } |
| return snapshot; |
| } |
| |
| public static final native int OS_GetFunctionCount(); |
| public static final native String OS_GetFunctionName(int index); |
| public static final native int OS_GetFunctionCallCount(int index); |
| |
| public static final native int ATK_GetFunctionCount(); |
| public static final native String ATK_GetFunctionName(int index); |
| public static final native int ATK_GetFunctionCallCount(int index); |
| |
| public static final native int CDE_GetFunctionCount(); |
| public static final native String CDE_GetFunctionName(int index); |
| public static final native int CDE_GetFunctionCallCount(int index); |
| |
| public static final native int GNOME_GetFunctionCount(); |
| public static final native String GNOME_GetFunctionName(int index); |
| public static final native int GNOME_GetFunctionCallCount(int index); |
| |
| public static final native int GTK_GetFunctionCount(); |
| public static final native String GTK_GetFunctionName(int index); |
| public static final native int GTK_GetFunctionCallCount(int index); |
| |
| public static final native int XPCOM_GetFunctionCount(); |
| public static final native String XPCOM_GetFunctionName(int index); |
| public static final native int XPCOM_GetFunctionCallCount(int index); |
| |
| public static final native int COM_GetFunctionCount(); |
| public static final native String COM_GetFunctionName(int index); |
| public static final native int COM_GetFunctionCallCount(int index); |
| |
| } |