1 salcianu 1.1 // AllocationInstrCompStage.java, created Tue Apr 15 17:31:35 2003 by salcianu
  2 salcianu 1.1 // Copyright (C) 2003 Alexandru Salcianu <salcianu@MIT.EDU>
  3 salcianu 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 salcianu 1.1 package harpoon.Instrumentation.AllocationStatistics;
  5 salcianu 1.1 
  6 salcianu 1.1 import harpoon.ClassFile.HClass;
  7 salcianu 1.1 import harpoon.ClassFile.HCodeFactory;
  8 salcianu 1.1 import harpoon.ClassFile.CachingCodeFactory;
  9 salcianu 1.1 
 10 salcianu 1.1 import harpoon.IR.Quads.QuadNoSSA;
 11 salcianu 1.1 
 12 salcianu 1.1 import harpoon.Analysis.Quads.QuadClassHierarchy;
 13 salcianu 1.1 
 14 salcianu 1.1 import harpoon.Main.CompilerState;
 15 salcianu 1.1 import harpoon.Main.CompilerStage;
 16 salcianu 1.1 
 17 salcianu 1.1 import harpoon.Util.Options.Option;
 18 salcianu 1.1 
 19 salcianu 1.1 import java.util.List;
 20 salcianu 1.1 import java.util.LinkedList;
 21 salcianu 1.1 import java.io.ObjectOutputStream;
 22 salcianu 1.1 import java.io.FileOutputStream;
 23 salcianu 1.1 
 24 salcianu 1.1 /**
 25 salcianu 1.1  * <code>AllocationInstrCompStage</code>
 26 salcianu 1.1  * 
 27 salcianu 1.1  * @author  Alexandru Salcianu <salcianu@MIT.EDU>
 28 salcianu 1.3  * @version $Id: AllocationInstrCompStage.java,v 1.3 2003/06/04 18:46:09 salcianu Exp $
 29 salcianu 1.1  */
 30 salcianu 1.1 public class AllocationInstrCompStage extends CompilerStage {
 31 salcianu 1.1 
 32 salcianu 1.1     /** Creates a <code>AllocationInstrCompStage</code>. */
 33 salcianu 1.1     public AllocationInstrCompStage() { super("allocation-instrumentation"); }
 34 salcianu 1.1 
 35 salcianu 1.1     private boolean READ_ALLOC_STATS = false;
 36 salcianu 1.1     private String allocNumberingFileName;
 37 salcianu 1.1     private String instrumentationResultsFileName;
 38 salcianu 1.1     public static boolean INSTRUMENT_ALLOCS = false;
 39 salcianu 1.1     // 1 - Brian's instrumentation
 40 salcianu 1.1     // 2 - Alex's  instrumentation
 41 salcianu 1.1     public static int INSTRUMENT_ALLOCS_TYPE = 2;
 42 salcianu 1.1     // TODO: add command line options about instrumenting syncs/calls
 43 salcianu 1.1     private boolean INSTRUMENT_SYNCS = false;
 44 salcianu 1.1     private boolean INSTRUMENT_CALLS = false;
 45 salcianu 1.1     private boolean INSTRUMENT_ALLOCS_STUB = false;
 46 salcianu 1.1     private String IFILE = null;
 47 salcianu 1.1     private boolean PRINT_ALLOC_STATS = false;
 48 salcianu 1.1 
 49 salcianu 1.1     private AllocationStatistics as = null;
 50 salcianu 1.1     public AllocationStatistics getAllocationStatistics() { return as; }
 51 salcianu 1.1 
 52 salcianu 1.1     public List/*<Option>*/ getOptions() {
 53 salcianu 1.1         List/*<Option>*/ opts = new LinkedList/*<Option>*/();
 54 salcianu 1.1 
 55 salcianu 1.1         opts.add(new Option("N", "<fileName>",
 56 salcianu 1.1                             "Serialize compiler state + allocation numbering object to <fileName>") {
 57 salcianu 1.1             public void action() { 
 58 salcianu 1.1                 INSTRUMENT_ALLOCS = true;
 59 salcianu 1.1                 IFILE = getArg(0);
 60 salcianu 1.1             }
 61 salcianu 1.1         });
 62 salcianu 1.1 
 63 salcianu 1.1         opts.add(new Option("W", "<fileName>",
 64 salcianu 1.1                             "Same as -N, but writes only a small text file (an AllocationNumberingStub).  This file can be read with the -Z option.  Use if serialization makes troubles.") {
 65 salcianu 1.1             public void action() {
 66 salcianu 1.1                 INSTRUMENT_ALLOCS = true;
 67 salcianu 1.1                 INSTRUMENT_ALLOCS_STUB = true;
 68 salcianu 1.1                 IFILE = getArg(0);
 69 salcianu 1.1             }
 70 salcianu 1.1         });
 71 salcianu 1.1 
 72 salcianu 1.1         opts.add(new Option("Z",
 73 salcianu 1.1                             "<allocNumberingFileName> <instrResultFileName>",
 74 salcianu 1.1                             "Reads in allocation numbering stub and instrumentation results") {
 75 salcianu 1.1             public void action() {
 76 salcianu 1.1                 allocNumberingFileName = getArg(0);
 77 salcianu 1.1                 instrumentationResultsFileName = getArg(1);
 78 salcianu 1.1                 System.out.println("allocNumberingFileName = " + 
 79 salcianu 1.1                                    allocNumberingFileName);
 80 salcianu 1.1                 System.out.println("instrumentationResultsFileName = " +
 81 salcianu 1.1                                    instrumentationResultsFileName);
 82 salcianu 1.1             }
 83 salcianu 1.1         });
 84 salcianu 1.1 
 85 salcianu 1.1         opts.add(new Option("print-alloc-stats", "prints dynamic memory allocation statistics") {
 86 salcianu 1.1             public void action() { PRINT_ALLOC_STATS = true; }
 87 salcianu 1.1         });
 88 salcianu 1.1 
 89 salcianu 1.1         return opts;
 90 salcianu 1.1     }
 91 salcianu 1.2 
 92 salcianu 1.2     // bogus, the real selection will be done inside action
 93 salcianu 1.2     public boolean enabled() { return true; }
 94 salcianu 1.1 
 95 salcianu 1.1     public CompilerState action(CompilerState cs) {
 96 salcianu 1.1         assert !PRINT_ALLOC_STATS || READ_ALLOC_STATS :
 97 salcianu 1.1             "-print-alloc-stats requires -Z";
 98 salcianu 1.1 
 99 salcianu 1.1         if (INSTRUMENT_ALLOCS)
100 salcianu 1.1             return instrument_allocations(cs);
101 salcianu 1.1         // Try not to add anything in between instrument_allocs and
102 salcianu 1.1         // read_allocation_statistics.  When we load the allocation
103 salcianu 1.1         // stats, we want to be in the same place where we were when
104 salcianu 1.1         // we instrumented the code.
105 salcianu 1.1         if (READ_ALLOC_STATS)
106 salcianu 1.1             return read_allocation_statistics(cs);
107 salcianu 1.1 
108 salcianu 1.1         return cs;
109 salcianu 1.1     }
110 salcianu 1.1 
111 salcianu 1.1     private CompilerState instrument_allocations(CompilerState cs) {
112 salcianu 1.1         // A: make sure we have a caching NoSSA code factory
113 salcianu 1.1         cs = ensure_caching_NoSSA(cs);
114 salcianu 1.1 
115 salcianu 1.1         // create the allocation numbering
116 salcianu 1.1         AllocationNumbering an =
117 salcianu 1.1             new AllocationNumbering((CachingCodeFactory) cs.getCodeFactory(),
118 salcianu 1.1                                     cs.getClassHierarchy(), INSTRUMENT_CALLS);
119 salcianu 1.1         
120 salcianu 1.1         try {
121 salcianu 1.1             if(INSTRUMENT_ALLOCS_STUB) { // "textualize" only a stub
122 salcianu 1.1                 System.out.println
123 salcianu 1.1                     ("Writing AllocationNumbering into " + IFILE);
124 salcianu 1.1                 AllocationNumberingStub.writeToFile(an, IFILE, cs.getLinker());
125 salcianu 1.1             }
126 salcianu 1.1             else { // classic INSTRUMENT_ALLOCS: serialize serious stuff
127 salcianu 1.1                 ObjectOutputStream oos =
128 salcianu 1.1                     new ObjectOutputStream(new FileOutputStream(IFILE));
129 salcianu 1.1                 oos.writeObject(cs);
130 salcianu 1.1                 oos.writeObject(an);
131 salcianu 1.1                 oos.close();
132 salcianu 1.1             }
133 salcianu 1.1         } catch (java.io.IOException e) {
134 salcianu 1.1             System.out.println(e + " was thrown:");
135 salcianu 1.1             e.printStackTrace(System.out);
136 salcianu 1.1             System.exit(1);
137 salcianu 1.1         }
138 salcianu 1.1         
139 salcianu 1.1         switch(INSTRUMENT_ALLOCS_TYPE) {
140 salcianu 1.3         case 1: // Brian's instr.
141 salcianu 1.1             cs = cs.changeCodeFactory
142 salcianu 1.1                 ((new InstrumentAllocs(cs.getCodeFactory(), cs.getMain(),
143 salcianu 1.1                                        cs.getLinker(), an,
144 salcianu 1.1                                        INSTRUMENT_SYNCS,
145 salcianu 1.1                                        INSTRUMENT_CALLS)).codeFactory());
146 salcianu 1.1             break;
147 salcianu 1.3         case 2: // Alex's instr. (no support for counting syncs)
148 salcianu 1.1             cs = cs.changeCodeFactory
149 salcianu 1.1                 ((new InstrumentAllocs2(cs.getCodeFactory(), cs.getMain(),
150 salcianu 1.1                                         cs.getLinker(), an)).codeFactory());
151 salcianu 1.1             // TODO: this is NOT functional ...
152 salcianu 1.1             cs.getRoots().add(InstrumentAllocs.getMethod
153 salcianu 1.1                               (cs.getLinker(),
154 salcianu 1.1                                "harpoon.Runtime.CounterSupport", "count2",
155 salcianu 1.1                                new HClass[]{HClass.Int, HClass.Int}));
156 salcianu 1.1             break;
157 salcianu 1.1         default:
158 salcianu 1.1             assert false :
159 salcianu 1.1                 "Illegal INSTRUMENT_ALLOCS_TYPE" + INSTRUMENT_ALLOCS_TYPE;
160 salcianu 1.1         }
161 salcianu 1.1         
162 salcianu 1.1         cs = cs.changeCodeFactory(new CachingCodeFactory(cs.getCodeFactory()));
163 salcianu 1.1         cs = cs.changeClassHierarchy
164 salcianu 1.1             (new QuadClassHierarchy(cs.getLinker(), cs.getRoots(),
165 salcianu 1.1                                     cs.getCodeFactory()));
166 salcianu 1.1         return cs;
167 salcianu 1.1     }
168 salcianu 1.1 
169 salcianu 1.1 
170 salcianu 1.1     private CompilerState read_allocation_statistics(CompilerState cs) {
171 salcianu 1.1         // B: make sure we have the same code factory as in A above
172 salcianu 1.1         cs = ensure_caching_NoSSA(cs);
173 salcianu 1.1 
174 salcianu 1.1         as = new AllocationStatistics(cs.getLinker(),
175 salcianu 1.1                                       allocNumberingFileName,
176 salcianu 1.1                                       instrumentationResultsFileName);
177 salcianu 1.1         if(PRINT_ALLOC_STATS)
178 salcianu 1.1             as.printStatistics
179 salcianu 1.1                 (AllocationStatistics.getAllocs
180 salcianu 1.1                  (cs.getClassHierarchy().callableMethods(),
181 salcianu 1.1                   cs.getCodeFactory()));
182 salcianu 1.1         
183 salcianu 1.1         return cs;
184 salcianu 1.1     }
185 salcianu 1.1 
186 salcianu 1.1 
187 salcianu 1.1     private CompilerState ensure_caching_NoSSA(CompilerState cs) {
188 salcianu 1.1         // make sure we have a caching NoSSA code factory
189 salcianu 1.1         HCodeFactory hcf = QuadNoSSA.codeFactory(cs.getCodeFactory());
190 salcianu 1.1         hcf = new CachingCodeFactory(hcf, true);
191 salcianu 1.1         return cs.changeCodeFactory(hcf);
192 salcianu 1.1     }
193 salcianu 1.1 
194 salcianu 1.1 }