/******************************************************************************* * Copyright (c) 2004, 2006 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.*; import java.lang.reflect.*; import java.util.*; /** * 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<String, NativeFunction[]> snapshot; final static String[] classes = new String[]{"OS", "ATK", "CDE", "GNOME", "GTK", "XPCOM", "COM", "AGL", "Gdip", "GLX", "Cairo", "WGL"}; public static class NativeFunction implements Comparable<Object> { 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<String, NativeFunction[]> diff() { Hashtable<String, NativeFunction[]> newSnapshot = snapshot(); Enumeration<String> keys = newSnapshot.keys(); while (keys.hasMoreElements()) { String className = keys.nextElement(); NativeFunction[] newFuncs = newSnapshot.get(className); NativeFunction[] funcs = 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<String, NativeFunction[]> snapshot = new Hashtable<String, NativeFunction[]>(); snapshot(className, snapshot); dump(className, snapshot.get(className), ps); } public void dump(Hashtable<String, NativeFunction[]> snapshot, PrintStream ps) { Enumeration<String> keys = snapshot.keys(); while (keys.hasMoreElements()) { String className = keys.nextElement(); dump(className, 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<String, NativeFunction[]> snapshot() { Hashtable<String, NativeFunction[]> snapshot = new Hashtable<String, NativeFunction[]>(); for (int i = 0; i < classes.length; i++) { String className = classes[i]; snapshot(className, snapshot); } return snapshot; } public Hashtable<String, NativeFunction[]> snapshot(String className, Hashtable<String, NativeFunction[]> snapshot) { try { Class<? extends NativeStats> 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 AGL_GetFunctionCount(); public static final native String AGL_GetFunctionName(int index); public static final native int AGL_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 Gdip_GetFunctionCount(); public static final native String Gdip_GetFunctionName(int index); public static final native int Gdip_GetFunctionCallCount(int index); public static final native int GLX_GetFunctionCount(); public static final native String GLX_GetFunctionName(int index); public static final native int GLX_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); public static final native int WGL_GetFunctionCount(); public static final native String WGL_GetFunctionName(int index); public static final native int WGL_GetFunctionCallCount(int index); public static final native int Cairo_GetFunctionCount(); public static final native String Cairo_GetFunctionName(int index); public static final native int Cairo_GetFunctionCallCount(int index); }