1 salcianu 1.1 // InstrumentAllocs2.java, created Fri Feb  7 21:40:28 2003 by salcianu
  2 salcianu 1.1 // Copyright (C) 2000  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.Analysis.Transformation.MethodMutator;
  7 salcianu 1.4 import harpoon.Analysis.ClassHierarchy;
  8 salcianu 1.1 import harpoon.ClassFile.HClass;
  9 salcianu 1.1 import harpoon.ClassFile.HCode;
 10 salcianu 1.1 import harpoon.ClassFile.HCodeAndMaps;
 11 salcianu 1.1 import harpoon.ClassFile.HCodeFactory;
 12 salcianu 1.1 import harpoon.ClassFile.HCodeElement;
 13 salcianu 1.1 import harpoon.ClassFile.HMethod;
 14 salcianu 1.1 import harpoon.ClassFile.Linker;
 15 salcianu 1.1 import harpoon.Temp.TempFactory;
 16 salcianu 1.1 import harpoon.Temp.Temp;
 17 salcianu 1.1 import harpoon.IR.Quads.Code;
 18 salcianu 1.1 import harpoon.IR.Quads.Quad;
 19 salcianu 1.1 import harpoon.IR.Quads.QuadVisitor;
 20 salcianu 1.1 import harpoon.IR.Quads.QuadFactory;
 21 salcianu 1.1 import harpoon.IR.Quads.QuadNoSSA;
 22 salcianu 1.1 import harpoon.IR.Quads.MONITORENTER;
 23 salcianu 1.1 import harpoon.IR.Quads.NEW;
 24 salcianu 1.1 import harpoon.IR.Quads.ALENGTH;
 25 salcianu 1.1 import harpoon.IR.Quads.ANEW;
 26 salcianu 1.1 import harpoon.IR.Quads.CALL;
 27 salcianu 1.1 import harpoon.IR.Quads.CONST;
 28 salcianu 1.1 import harpoon.IR.Quads.PHI;
 29 salcianu 1.1 import harpoon.IR.Quads.RETURN;
 30 salcianu 1.1 import harpoon.IR.Quads.THROW;
 31 cananian 1.5 import net.cscott.jutil.WorkSet;
 32 salcianu 1.1 
 33 salcianu 1.1 import harpoon.Analysis.AllocationInformationMap;
 34 salcianu 1.1 import harpoon.Analysis.DefaultAllocationInformationMap;
 35 salcianu 1.1 import harpoon.Analysis.ChainedAllocationProperties;
 36 salcianu 1.1 import harpoon.Analysis.Maps.AllocationInformation.AllocationProperties;
 37 salcianu 1.1 
 38 salcianu 1.1 import java.util.HashMap;
 39 salcianu 1.1 import java.util.Iterator;
 40 salcianu 1.1 import java.util.Map;
 41 salcianu 1.1 
 42 salcianu 1.1 
 43 salcianu 1.2 /** <code>InstrumentAllocs2</code> can be used together with
 44 salcianu 1.2     <code>InstrumentedAllocationStrategy</code> to instrument the
 45 salcianu 1.2     allocation sites from a program to record how many times each of
 46 salcianu 1.2     them is executed, and the total amount of memory allocated at each
 47 salcianu 1.2     site.  
 48 salcianu 1.2 
 49 salcianu 1.2     <p>
 50 salcianu 1.2     Unlike <code>InstrumentAllocs</code> (which takes place at Quad
 51 salcianu 1.2     level), <code>InstrumentAllocs2</code> operates at the Tree form
 52 salcianu 1.2     level.  It changes the allocation properties of each allocation
 53 salcianu 1.2     site such that the code generated for it in Tree form will contain
 54 salcianu 1.2     a call to an instrumentation method, passing it both an unique
 55 salcianu 1.2     identifier and the length of the memory allocated there.
 56 salcianu 1.2 
 57 salcianu 1.2     @author Alexandru Salcianu <salcianu@MIT.EDU>
 58 cananian 1.6     @version $Id: InstrumentAllocs2.java,v 1.6 2004/02/08 03:21:32 cananian Exp $ */
 59 salcianu 1.1 public class InstrumentAllocs2 extends MethodMutator
 60 salcianu 1.1     implements java.io.Serializable {
 61 salcianu 1.1     
 62 salcianu 1.2     /** Creates a <code>InstrumentAllocs2</code> object.
 63 salcianu 1.2 
 64 salcianu 1.2         @param parent code factory providing the original,
 65 salcianu 1.2         uninstrumented code
 66 salcianu 1.2 
 67 salcianu 1.2         @param main main method of the program
 68 salcianu 1.2 
 69 salcianu 1.2         @param linker linker for the analyzed program
 70 salcianu 1.2 
 71 salcianu 1.2         @param an provides a globally unique integer ID for each
 72 salcianu 1.2         allocation site from the program */
 73 salcianu 1.1     public InstrumentAllocs2(HCodeFactory parent, HMethod main,
 74 salcianu 1.1                              Linker linker, AllocationNumbering an) {
 75 salcianu 1.1         super(parent);
 76 salcianu 1.1 
 77 salcianu 1.4         assert
 78 salcianu 1.4             parent.getCodeName().equals(QuadNoSSA.codename) :
 79 salcianu 1.4             "InstrumentAllocs works only with QuadNoSSA";
 80 salcianu 1.4 
 81 salcianu 1.1         this.main   = main;
 82 salcianu 1.1         this.an     = an;
 83 salcianu 1.1 
 84 salcianu 1.1         hm_instr_exit = InstrumentAllocs.getMethod
 85 salcianu 1.1             (linker, "harpoon.Runtime.CounterSupport",
 86 salcianu 1.1              "exit", new HClass[0]);
 87 salcianu 1.1         hm_orig_exit = InstrumentAllocs.getMethod
 88 salcianu 1.1             (linker, "java.lang.System", "exit", "(I)V");
 89 salcianu 1.1     }
 90 salcianu 1.1 
 91 salcianu 1.1     private HMethod main;
 92 salcianu 1.1     private AllocationNumbering an;
 93 salcianu 1.1 
 94 salcianu 1.1     private HMethod hm_instr_exit;
 95 salcianu 1.1     private HMethod hm_orig_exit;
 96 salcianu 1.1 
 97 salcianu 1.1     protected HCode mutateHCode(HCodeAndMaps input) {
 98 salcianu 1.1         HCode hc = input.hcode();
 99 salcianu 1.1        
100 salcianu 1.1         // we avoid instrumenting the instrumentation itself !
101 salcianu 1.1         if (hc.getMethod().getDeclaringClass().getName().
102 salcianu 1.1             equals("harpoon.Runtime.CounterSupport"))
103 salcianu 1.1             return hc;
104 salcianu 1.1 
105 salcianu 1.1         InstrumentAllocs.instrumentProgramTermination
106 salcianu 1.1             (hc, hm_orig_exit, hm_instr_exit);
107 salcianu 1.1 
108 salcianu 1.4         try {
109 salcianu 1.4             updateAllocationProperties((Code) hc, input.ancestorElementMap());
110 salcianu 1.4         } catch(UnknownAllocationSiteError e) {
111 salcianu 1.4             // ignore: code called only by the instrumentation
112 salcianu 1.4         }
113 salcianu 1.1  
114 salcianu 1.1         if (hc.getMethod().equals(main))
115 salcianu 1.1             InstrumentAllocs.treatMainMethod(hc, hm_instr_exit);
116 salcianu 1.1 
117 salcianu 1.1         return hc;
118 salcianu 1.1     }
119 salcianu 1.1 
120 salcianu 1.1 
121 salcianu 1.1     private void updateAllocationProperties(Code hc, Map ancestor) {
122 salcianu 1.1         AllocationInformationMap aim = 
123 salcianu 1.1             (AllocationInformationMap) hc.getAllocationInformation();
124 salcianu 1.1         // Make sure there is an AllocationInfomationMap for "code"
125 salcianu 1.1         if(aim == null) {
126 salcianu 1.1             aim = new DefaultAllocationInformationMap();
127 salcianu 1.1             hc.setAllocationInformation(aim);
128 salcianu 1.1         }
129 salcianu 1.1 
130 cananian 1.6         for(Object allocO : hc.selectAllocations()) {
131 cananian 1.6             Quad alloc = (Quad) allocO;
132 salcianu 1.1             final int allocID = an.allocID((Quad) ancestor.get(alloc));
133 salcianu 1.1             AllocationProperties formerAP = aim.query(alloc);
134 salcianu 1.1             aim.associate(alloc,
135 salcianu 1.1                           new ChainedAllocationProperties(formerAP) {
136 salcianu 1.1                 private final int index = allocID;
137 salcianu 1.1                 public int getUniqueID() { return index; }
138 salcianu 1.1             });
139 salcianu 1.1         }
140 salcianu 1.1     }
141 salcianu 1.1 }