1 cananian 1.1 // Virtualize.java, created Mon Sep  9 18:16:57 2002 by cananian
 2 cananian 1.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu>
 3 cananian 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details.
 4 cananian 1.1 package harpoon.Analysis.Quads;
 5 cananian 1.1 
 6 cananian 1.1 import harpoon.Analysis.ClassHierarchy;
 7 cananian 1.1 import harpoon.ClassFile.HCode;
 8 cananian 1.1 import harpoon.ClassFile.HCodeAndMaps;
 9 cananian 1.1 import harpoon.ClassFile.HCodeFactory;
10 cananian 1.1 import harpoon.ClassFile.HMethod;
11 cananian 1.1 import harpoon.IR.Quads.CALL;
12 cananian 1.1 import harpoon.IR.Quads.Quad;
13 cananian 1.2 import net.cscott.jutil.SnapshotIterator;
14 cananian 1.1 
15 cananian 1.1 import java.util.Iterator;
16 cananian 1.1 import java.util.Set;
17 cananian 1.1 /**
18 cananian 1.1  * <code>Virtualize</code> makes any non-virtual invocations of
19 cananian 1.1  * uncallable methods non-virtual, so that they don't lead to
20 cananian 1.1  * link errors later. It works on any sort of quad form.
21 cananian 1.1  * 
22 cananian 1.1  * @author  C. Scott Ananian <cananian@alumni.princeton.edu>
23 cananian 1.2  * @version $Id: Virtualize.java,v 1.2 2004/02/08 01:53:14 cananian Exp $
24 cananian 1.1  * @see harpoon.Analysis.Quads.Nonvirtualize
25 cananian 1.1  * @see harpoon.Analysis.Quads.QuadClassHierarchy
26 cananian 1.1  */
27 cananian 1.1 public class Virtualize
28 cananian 1.1     extends harpoon.Analysis.Transformation.MethodMutator<Quad> {
29 cananian 1.1     /** The set of callable methods we will use to guide our virtualization. */
30 cananian 1.1     private final Set<HMethod> callable;
31 cananian 1.1 
32 cananian 1.1     /** Creates a <code>Virtualize</code> code factory using the given
33 cananian 1.1      *  <code>ClassHierarchy</code>. */
34 cananian 1.1     public Virtualize(HCodeFactory hcf, ClassHierarchy ch) {
35 cananian 1.1         super(hcf);
36 cananian 1.1         this.callable = ch.callableMethods();
37 cananian 1.1     }
38 cananian 1.1 
39 cananian 1.1     protected HCode<Quad> mutateHCode(HCodeAndMaps<Quad> input) {
40 cananian 1.1         HCode<Quad> hc = input.hcode();
41 cananian 1.1         for (Iterator<Quad> it = new SnapshotIterator<Quad>(hc.getElementsI());
42 cananian 1.1              it.hasNext(); ) {
43 cananian 1.1             Quad aquad = it.next();
44 cananian 1.1             if (!(aquad instanceof CALL)) continue;
45 cananian 1.1             CALL q = (CALL) aquad;
46 cananian 1.1             if (q.isVirtual()) continue;
47 cananian 1.1             if (callable.contains(q.method())) continue;
48 cananian 1.1             assert !q.method().isStatic() : "non-callable static?  how?";
49 cananian 1.1             // okay, CALL to a non-callable method.  make it virtual!
50 cananian 1.1             CALL nq = new CALL(q.getFactory(), q, q.method(), q.params(),
51 cananian 1.1                                q.retval(), q.retex(), true/*isVirtual*/,
52 cananian 1.1                                q.isTailCall(), q.dst(), q.src());
53 cananian 1.1             Quad.replace(q, nq);
54 cananian 1.1             Quad.transferHandlers(q, nq);
55 cananian 1.1             // ta-da!
56 cananian 1.1         }
57 cananian 1.1         return hc;
58 cananian 1.1     }
59 cananian 1.1 }