/* * @(#)CVMMethodStats.java 1.5 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ package vm; import consts.Const; import consts.CVMConst; import components.*; import vm.*; import jcc.Util; import util.*; import java.util.Arrays; import java.util.Comparator; import java.util.Enumeration; import java.util.Hashtable; import java.io.OutputStream; public class CVMMethodStats implements Comparator { int tableIdx; Entry[] table; public class Entry { // Remember these three int argsSize; String invoker; int access; // Index in global table int idx; // // And count references. The top referenced guys are going to // be at the top of the table // int refcount; Entry(int argsSize, String invoker, int access) { this.argsSize = argsSize; this.invoker = invoker; this.access = access; this.refcount = 1; } public String toString() { return "["+ "argsSize = "+argsSize+ ", access = "+access+ ", invoker = "+invoker+ "]"; } public int getIdx() { return idx; } public String getInvoker() { return invoker; } } public CVMMethodStats() { super(); // This should be more than enough table = new Entry[1024]; tableIdx = 0; } public void record(int argsSize, String invoker, int access) { Entry entry = lookup(argsSize, invoker, access); if (entry == null) { entry = new Entry(argsSize, invoker, access); // Created a new one. Add to table entry.idx = tableIdx; table[tableIdx++] = entry; } else { // Just increment refcount entry.refcount++; } } public Entry lookup(int argsSize, String invoker, int access) { for (int i = 0; i < tableIdx; i++) { Entry entry = table[i]; if ((entry.argsSize == argsSize) && (entry.access == access) && invoker.equals(entry.invoker)) { return entry; } } return null; } public void sort() { Entry newTable[] = new Entry[tableIdx]; System.arraycopy(table, 0, newTable, 0, tableIdx); Arrays.sort(newTable, this); for (int i = 0; i < tableIdx; i++) { newTable[i].idx = i; } table = newTable; } public int compare(java.lang.Object o1, java.lang.Object o2) { Entry obj1 = (Entry) o1; Entry obj2 = (Entry) o2; if (obj1.refcount < obj2.refcount) { return 1; } else if (obj1.refcount == obj2.refcount) return 0; return -1; } // // Dump the first 256 elements at most // public void dump(runtime.CCodeWriter out) { int numElements = Math.min(256, tableIdx); out.println(); out.println("const CVMUint16 argsInvokerAccess[] = {"); for (int i = 0; i < numElements; i++) { out.print(" /* idx="+i+", refcount="+table[i].refcount+" */ "); out.println(table[i].argsSize + ", "+table[i].invoker+", "+ table[i].access+","); } out.println("};"); out.println(); } }