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     }