1 cananian 1.1.2.1 // MZFWidenType.java, created Tue Nov 13 00:23:59 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.Analysis.SizeOpt; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.Analysis.Transformation.MethodMutator; 7 cananian 1.1.2.1 import harpoon.ClassFile.HClass; 8 cananian 1.1.2.1 import harpoon.ClassFile.HCode; 9 cananian 1.1.2.1 import harpoon.ClassFile.HCodeAndMaps; 10 cananian 1.1.2.1 import harpoon.ClassFile.HCodeFactory; 11 cananian 1.1.2.1 import harpoon.ClassFile.HField; 12 cananian 1.1.2.2 import harpoon.ClassFile.HFieldMutator; 13 cananian 1.1.2.2 import harpoon.ClassFile.HMethod; 14 cananian 1.1.2.2 import harpoon.ClassFile.HMethodMutator; 15 cananian 1.1.2.1 import harpoon.ClassFile.Linker; 16 cananian 1.1.2.1 import harpoon.IR.Quads.ANEW; 17 cananian 1.1.2.1 import harpoon.IR.Quads.INSTANCEOF; 18 cananian 1.1.2.1 import harpoon.IR.Quads.Quad; 19 cananian 1.1.2.1 import harpoon.IR.Quads.QuadVisitor; 20 cananian 1.1.2.1 import harpoon.IR.Quads.TYPESWITCH; 21 cananian 1.8 import net.cscott.jutil.Default.PairList; 22 cananian 1.1.2.1 import harpoon.Util.HClassUtil; 23 cananian 1.8 import net.cscott.jutil.SnapshotIterator; 24 cananian 1.1.2.1 import harpoon.Util.Util; 25 cananian 1.1.2.1 26 cananian 1.1.2.2 import java.util.Arrays; 27 cananian 1.6 import java.util.HashSet; 28 cananian 1.1.2.2 import java.util.Iterator; 29 cananian 1.1.2.1 import java.util.List; 30 cananian 1.1.2.1 import java.util.Map; 31 cananian 1.1.2.2 import java.util.Set; 32 cananian 1.1.2.1 /** 33 cananian 1.1.2.1 * <code>MZFWidenType</code> widens the types mentioned in 34 cananian 1.1.2.1 * <code>ANEW</code>, <code>INSTANCEOF</code>, and <code>TYPESWITCH</code> 35 cananian 1.1.2.1 * quads so that they play nicely with the split types generated by 36 cananian 1.1.2.2 * <code>MZFCompressor</code>. It also widens types mentioned in 37 cananian 1.1.2.2 * field and method signatures. 38 cananian 1.1.2.1 * 39 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 40 cananian 1.9 * @version $Id: MZFWidenType.java,v 1.9 2004/02/08 03:20:22 cananian Exp $ 41 cananian 1.1.2.1 */ 42 cananian 1.5 class MZFWidenType extends MethodMutator<Quad> { 43 cananian 1.1.2.1 /** the linker to use */ 44 cananian 1.1.2.1 final Linker linker; 45 cananian 1.1.2.1 /** a map from HClasses to a list of sorted fields; the splitting has 46 cananian 1.1.2.1 * been done in the order of the list. */ 47 cananian 1.7 final Map<HClass,List<PairList<HField,Number>>> listmap; 48 cananian 1.1.2.1 /** a map from <code>HField</code>s to the <code>HClass</code> which 49 cananian 1.1.2.1 * eliminates that field. */ 50 cananian 1.5 final Map<HField,HClass> field2class; 51 cananian 1.1.2.1 /** Creates a <code>MZFWidenType</code>. */ 52 cananian 1.1.2.1 public MZFWidenType(HCodeFactory hcf, 53 cananian 1.5 Linker linker, 54 cananian 1.7 Map<HClass,List<PairList<HField,Number>>> listmap, 55 cananian 1.5 Map<HField,HClass> field2class, 56 cananian 1.5 Set<HMethod> callableMethods, Set<HClass> allClasses) { 57 cananian 1.1.2.1 super(hcf); 58 cananian 1.1.2.1 this.linker = linker; 59 cananian 1.1.2.1 this.listmap = listmap; 60 cananian 1.1.2.1 this.field2class = field2class; 61 cananian 1.1.2.2 // widen parameter and return types of all callable methods. 62 cananian 1.3.2.2 // (also, of all interfaces which these callable methods implement, 63 cananian 1.3.2.2 // and all superclass methods which these callable methods override) 64 cananian 1.9 for (HMethod hm : allMethods(allClasses)) { 65 cananian 1.1.2.2 hm.getMutator().setReturnType(widen(hm.getReturnType())); 66 cananian 1.1.2.2 HClass[] paramTypes = hm.getParameterTypes(); 67 cananian 1.1.2.2 for (int i=0; i<paramTypes.length; i++) 68 cananian 1.1.2.2 if (widen(paramTypes[i])!=paramTypes[i]) 69 cananian 1.1.2.2 hm.getMutator().setParameterType(i, widen(paramTypes[i])); 70 cananian 1.1.2.2 } 71 cananian 1.1.2.2 // widen types of all fields 72 cananian 1.9 for (HClass hc : allClasses) { 73 cananian 1.1.2.2 HField[] hfa = hc.getDeclaredFields(); 74 cananian 1.1.2.2 for (int i=0; i<hfa.length; i++) 75 cananian 1.1.2.2 if (widen(hfa[i].getType())!=hfa[i].getType()) 76 cananian 1.1.2.2 hfa[i].getMutator().setType(widen(hfa[i].getType())); 77 cananian 1.1.2.2 } 78 cananian 1.1.2.1 } 79 cananian 1.5 private Set<HMethod> allMethods(Set<HClass> allClasses) { 80 cananian 1.5 Set<HMethod> result = new HashSet<HMethod>(); 81 cananian 1.9 for (HClass hc : allClasses) { 82 cananian 1.3.2.2 result.addAll(Arrays.asList(hc.getMethods())); 83 cananian 1.3.2.2 } 84 cananian 1.3.2.2 return result; 85 cananian 1.1.2.1 } 86 cananian 1.5 protected HCode<Quad> mutateHCode(HCodeAndMaps<Quad> input) { 87 cananian 1.5 HCode<Quad> hc = input.hcode(); 88 cananian 1.1.2.1 QuadVisitor qv = new QuadVisitor() { 89 cananian 1.1.2.1 public void visit(Quad q) { /* booring. */ } 90 cananian 1.1.2.1 public void visit(ANEW q) { 91 cananian 1.1.2.1 Quad.replace 92 cananian 1.1.2.1 (q, new ANEW(q.getFactory(), q, q.dst(), 93 cananian 1.1.2.1 widen(q.hclass()), q.dims())); 94 cananian 1.1.2.1 } 95 cananian 1.1.2.1 public void visit(INSTANCEOF q) { 96 cananian 1.1.2.1 Quad.replace 97 cananian 1.1.2.1 (q, new INSTANCEOF(q.getFactory(), q, q.dst(), 98 cananian 1.1.2.1 q.src(), widen(q.hclass()))); 99 cananian 1.1.2.1 } 100 cananian 1.1.2.1 public void visit(TYPESWITCH q) { 101 cananian 1.1.2.1 HClass[] keys = (HClass[]) q.keys().clone(); 102 cananian 1.1.2.1 for (int i=0; i<keys.length; i++) 103 cananian 1.1.2.1 keys[i] = widen(keys[i]); 104 cananian 1.1.2.1 Quad.replace 105 cananian 1.1.2.1 (q, new TYPESWITCH(q.getFactory(), q, q.index(), 106 cananian 1.1.2.1 keys, q.dst(), q.src(), 107 cananian 1.1.2.1 q.hasDefault())); 108 cananian 1.1.2.1 } 109 cananian 1.1.2.1 }; 110 cananian 1.6 for (Iterator<Quad> it=new SnapshotIterator<Quad> 111 cananian 1.6 (hc.getElementsI()); it.hasNext(); ) 112 cananian 1.6 it.next().accept(qv); 113 cananian 1.1.2.1 // done. 114 cananian 1.1.2.1 return hc; 115 cananian 1.1.2.1 } 116 cananian 1.1.2.1 HClass widen(HClass hc) { 117 cananian 1.1.2.1 if (hc.isPrimitive() || hc.isInterface()) 118 cananian 1.1.2.1 return hc; 119 cananian 1.1.2.1 if (hc.isArray()) 120 cananian 1.1.2.1 return HClassUtil.arrayClass 121 cananian 1.1.2.1 (linker, widen(HClassUtil.baseClass(hc)), HClassUtil.dims(hc)); 122 cananian 1.7 List<PairList<HField,Number>> sortedFields = listmap.get(hc); 123 cananian 1.1.2.1 if (sortedFields==null) return hc; // not a split class. 124 cananian 1.7 PairList<HField,Number> lastpair = 125 cananian 1.5 sortedFields.get(sortedFields.size()-1); 126 cananian 1.1.2.1 HField lastF = (HField) lastpair.get(0); 127 cananian 1.5 HClass broadest = field2class.get(lastF); 128 cananian 1.3.2.1 assert broadest!=null; 129 cananian 1.1.2.1 return broadest; 130 cananian 1.1.2.1 } 131 cananian 1.2 }