1 cananian 1.1.2.1 // SortedClassFieldMap.java, created Wed Jul 11 12:22:16 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.Backend.Analysis; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.ClassFile.HClass; 7 cananian 1.1.2.1 import harpoon.ClassFile.HField; 8 cananian 1.1.2.1 import java.util.ArrayList; 9 cananian 1.1.2.1 import java.util.Arrays; 10 cananian 1.1.2.1 import java.util.Collections; 11 cananian 1.1.2.1 import java.util.Comparator; 12 cananian 1.1.2.1 import java.util.HashMap; 13 cananian 1.1.2.1 import java.util.Iterator; 14 cananian 1.1.2.1 import java.util.List; 15 cananian 1.1.2.1 import java.util.Map; 16 cananian 1.1.2.1 /** 17 cananian 1.1.2.1 * A <code>SortedClassFieldMap</code> is an extension of 18 cananian 1.1.2.1 * <code>ClassFieldMap</code> which sorts object fields to 19 cananian 1.1.2.1 * minimize "holes" between fields. 20 cananian 1.1.2.1 * 21 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 22 cananian 1.3 * @version $Id: SortedClassFieldMap.java,v 1.3 2002/04/10 03:02:22 cananian Exp $ 23 cananian 1.1.2.1 */ 24 cananian 1.1.2.1 public abstract class SortedClassFieldMap extends ClassFieldMap { 25 cananian 1.1.2.1 26 cananian 1.1.2.1 /** Creates a <code>SortedClassFieldMap</code>. */ 27 cananian 1.1.2.1 public SortedClassFieldMap() { } 28 cananian 1.1.2.1 29 cananian 1.2.2.1 private final Map<HClass,HField[]> cache = new HashMap<HClass,HField[]>(); 30 cananian 1.1.2.1 protected HField[] declaredFields(HClass hc) { 31 cananian 1.1.2.1 if (!cache.containsKey(hc)) { 32 cananian 1.1.2.1 // determine the alignment of the last field of the superclass. 33 cananian 1.1.2.1 int alignment=0; 34 cananian 1.1.2.1 HClass sc = hc.getSuperclass(); 35 cananian 1.1.2.1 if (sc!=null) { 36 cananian 1.2.2.1 List<HField> l = fieldList(sc); 37 cananian 1.1.2.1 if (l.size()>0) { 38 cananian 1.2.2.1 HField lastfield = l.get(l.size()-1); 39 cananian 1.1.2.1 alignment = fieldOffset(lastfield)+fieldSize(lastfield); 40 cananian 1.1.2.1 } 41 cananian 1.1.2.1 } 42 cananian 1.1.2.1 // make list of non-static fields. 43 cananian 1.2.2.1 List<HField> l = 44 cananian 1.2.2.1 new ArrayList<HField>(Arrays.asList(hc.getDeclaredFields())); 45 cananian 1.2.2.1 for (Iterator<HField> it=l.iterator(); it.hasNext(); ) 46 cananian 1.2.2.1 if (it.next().isStatic()) 47 cananian 1.1.2.1 it.remove(); 48 cananian 1.1.2.1 // sort declared fields by max(alignment,size) 49 cananian 1.2.2.2 // (smallest first) 50 cananian 1.2.2.1 Collections.sort(l, new Comparator<HField>() { 51 cananian 1.2.2.1 public int compare(HField hf1, HField hf2) { 52 cananian 1.1.2.1 return Math.max(fieldSize(hf1),fieldAlignment(hf1)) 53 cananian 1.1.2.1 - Math.max(fieldSize(hf2),fieldAlignment(hf2)); 54 cananian 1.1.2.1 } 55 cananian 1.1.2.1 }); 56 cananian 1.1.2.1 // if parent is unaligned, start at small end; else start at big 57 cananian 1.1.2.1 // end. 58 cananian 1.1.2.1 if (l.size()>0) { 59 cananian 1.2.2.1 HField big = l.get(l.size()-1); 60 cananian 1.1.2.1 if ((alignment % Math.max(fieldSize(big),fieldAlignment(big))) 61 cananian 1.1.2.1 ==0) 62 cananian 1.1.2.1 Collections.reverse(l); 63 cananian 1.1.2.1 } 64 cananian 1.1.2.1 // done. 65 cananian 1.1.2.1 cache.put(hc, l.toArray(new HField[l.size()])); 66 cananian 1.1.2.1 } 67 cananian 1.2.2.1 return cache.get(hc); 68 cananian 1.1.2.1 } 69 cananian 1.2 }