1 cananian 1.1.2.1 // Counters.java, created Thu Feb 22 21:48:58 2001 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.Runtime; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import java.lang.reflect.Field; 7 cananian 1.1.2.1 /** 8 cananian 1.1.2.1 * <code>Counters</code> uses reflection to provide a very light-weight 9 cananian 1.1.2.1 * counter package -- light-weight in terms of FLEX code required to 10 cananian 1.1.2.1 * add/enable counters, not necessarily light-weight in terms of 11 cananian 1.1.2.1 * execution time. All counters are thread-safe. We use reflection 12 cananian 1.1.2.1 * at initialization time and at program termination to initialize 13 cananian 1.1.2.1 * and report counter values, which minimizes the amount of 14 cananian 1.1.2.1 * counter-specific code generation required by the FLEX side of 15 cananian 1.1.2.1 * this. No special runtime support is required. 16 cananian 1.1.2.1 * <p> 17 cananian 1.1.2.1 * The dynamic generation of counter fields in this class is 18 cananian 1.1.2.1 * handled by <code>harpoon.Analysis.Counters.CounterFactory</code>. 19 cananian 1.1.2.3 * There is a <code>HCodeFactory</code> in this class which must be 20 cananian 1.1.2.3 * included as a compilation pass to generate the proper calls to 21 cananian 1.1.2.3 * the <code>report()</code> method at program's end. 22 cananian 1.1.2.1 * 23 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 24 cananian 1.2 * @version $Id: Counters.java,v 1.2 2002/02/25 21:06:26 cananian Exp $ 25 cananian 1.1.2.1 */ 26 cananian 1.1.2.1 public class Counters { 27 cananian 1.1.2.2 // hide constructor. all fields/methods are static. 28 cananian 1.1.2.2 private Counters() { } 29 cananian 1.1.2.1 /** Initialize by using reflection to store new <code>Object</code>s in 30 cananian 1.1.2.1 * all (FLEX-generated) fields of this class with names starting 31 cananian 1.1.2.1 * with "LOCK_". 32 cananian 1.1.2.1 */ 33 cananian 1.1.2.1 static { 34 cananian 1.1.2.1 Field[] field = Counters.class.getDeclaredFields(); 35 cananian 1.1.2.1 for (int i=0; i<field.length; i++) 36 cananian 1.1.2.1 if (field[i].getName().startsWith("LOCK_")) 37 cananian 1.1.2.1 try { 38 cananian 1.1.2.1 field[i].set(null, new Object()); 39 cananian 1.1.2.1 } catch (IllegalAccessException e) { 40 cananian 1.1.2.4 System.err.println("SKIPPING INIT OF "+field[i].toString()); 41 cananian 1.1.2.1 } 42 cananian 1.1.2.1 } 43 cananian 1.1.2.1 44 cananian 1.1.2.1 /** Report counter values to <code>System.err</code>, using reflection 45 cananian 1.1.2.1 * to discover all fields starting with "COUNTER_". */ 46 cananian 1.1.2.1 public static void report() { 47 cananian 1.1.2.1 Field[] field = Counters.class.getDeclaredFields(); 48 cananian 1.1.2.1 for (int i=0; i<field.length; i++) 49 cananian 1.1.2.1 if (field[i].getName().startsWith("COUNTER_")) 50 cananian 1.1.2.1 try { 51 cananian 1.1.2.1 String name = field[i].getName().substring(8); 52 cananian 1.1.2.1 Field Flck = Counters.class.getDeclaredField("LOCK_"+name); 53 cananian 1.1.2.1 synchronized(Flck.get(null)) { 54 cananian 1.1.2.4 System.err.println(name+": "+ 55 cananian 1.1.2.4 ((Number)field[i].get(null)) 56 cananian 1.1.2.4 .longValue()); 57 cananian 1.1.2.1 } 58 cananian 1.1.2.1 } catch (NoSuchFieldException e) { 59 cananian 1.1.2.4 System.err.println("CAN'T FIND FIELD: "+e.toString()); 60 cananian 1.1.2.1 } catch (IllegalAccessException e) { 61 cananian 1.1.2.4 System.err.println("CAN'T READ FIELD: "+e.toString()); 62 cananian 1.1.2.1 } 63 cananian 1.1.2.1 } 64 cananian 1.2 }