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 }