[Joeq-checkins] /joeq_core/joeq/Compiler/Analysis/Primitive PrimitiveSubtypeHelper.java,NONE,1.1 Pri
Status: Alpha
Brought to you by:
joewhaley
From: V.Benjamin L. <liv...@us...> - 2005-09-27 01:05:40
|
Update of /cvsroot/joeq//joeq_core/joeq/Compiler/Analysis/Primitive In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16620/joeq/Compiler/Analysis/Primitive Modified Files: PrimitivePA.java PrimitivePAMethodSummary.java Added Files: PrimitiveSubtypeHelper.java Log Message: Added the subtype helper. Index: PrimitivePA.java =================================================================== RCS file: /cvsroot/joeq//joeq_core/joeq/Compiler/Analysis/Primitive/PrimitivePA.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** PrimitivePA.java 26 Sep 2005 07:45:22 -0000 1.6 --- PrimitivePA.java 27 Sep 2005 01:05:21 -0000 1.7 *************** *** 53,57 **** import joeq.Compiler.Analysis.IPA.PA; import joeq.Compiler.Analysis.IPA.ProgramLocation; - import joeq.Compiler.Analysis.IPA.SubtypeHelper; import joeq.Compiler.Analysis.Primitive.PrimitiveMethodSummary.ConcreteObjectNode; import joeq.Compiler.Analysis.Primitive.PrimitiveMethodSummary.ConcreteTypeNode; --- 53,56 ---- *************** *** 2041,2045 **** private static int printed = 0; ! private SubtypeHelper _subtypeHelper; private static void fdd_printset_rec(BDDFactory bdd, StringBuffer sb, BDD r, int[] set) { int fdvarnum = bdd.numberOfDomains(); --- 2040,2044 ---- private static int printed = 0; ! private PrimitiveSubtypeHelper _subtypeHelper; private static void fdd_printset_rec(BDDFactory bdd, StringBuffer sb, BDD r, int[] set) { int fdvarnum = bdd.numberOfDomains(); *************** *** 2338,2345 **** } ! SubtypeHelper retrieveSubtypeHelper(){ if(this._subtypeHelper == null){ ! // this._subtypeHelper = SubtypeHelper.newSubtypeHelper( ! // this, System.getProperty("pa.subtypehelpertype")); } --- 2337,2344 ---- } ! PrimitiveSubtypeHelper retrieveSubtypeHelper(){ if(this._subtypeHelper == null){ ! this._subtypeHelper = PrimitiveSubtypeHelper.newSubtypeHelper( ! this, System.getProperty("pa.subtypehelpertype")); } *************** *** 2394,2398 **** } ! SubtypeHelper subtypeHelper = retrieveSubtypeHelper(); Collection subtypes = subtypeHelper.getSubtypes((jq_Class) t); if(subtypes == null){ --- 2393,2397 ---- } ! PrimitiveSubtypeHelper subtypeHelper = retrieveSubtypeHelper(); Collection subtypes = subtypeHelper.getSubtypes((jq_Class) t); if(subtypes == null){ --- NEW FILE: PrimitiveSubtypeHelper.java --- package joeq.Compiler.Analysis.Primitive; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import joeq.Class.PrimordialClassLoader; import joeq.Class.jq_Class; import joeq.Class.jq_Reference; import joeq.Class.jq_Reference.jq_NullType; import jwutil.util.Assert; import net.sf.javabdd.BDD; public abstract class PrimitiveSubtypeHelper { protected PrimitivePA pa; protected static boolean TRACE = true; protected static final String OFFLINE = "offline"; protected static final String ONLINE = "online"; protected static final String KNOWN = "known"; public PrimitiveSubtypeHelper(PrimitivePA pa){ this.pa = pa; } static String canonicalizeClassName(String s) { if (s.endsWith(".class")) s = s.substring(0, s.length() - 6); s = s.replace('.', '/'); String desc = "L" + s + ";"; return desc; } public abstract Collection getSubtypes(jq_Class clazz); public static class KnownClassesSubtypeHelper extends PrimitiveSubtypeHelper { static final String kind = KNOWN; public KnownClassesSubtypeHelper(PrimitivePA pa) { super(pa); if(TRACE) System.out.println("Instantiating a subtype helper of type " + kind); } public Collection getSubtypes(jq_Class t) { if(TRACE) System.out.println("Requesting subtypes of class " + t); Collection result = new LinkedList(); int T1_i = pa.Tmap.get(t); BDD subtypes = pa.aT.relprod(pa.T1.ithVar(T1_i), pa.T1set); // T2 for(Iterator typeIter = subtypes.iterator(pa.T2set); typeIter.hasNext();){ jq_Reference subtype = (jq_Reference) pa.Tmap.get(((BDD)typeIter.next()).scanVar(pa.T2).intValue()); if (subtype == null || subtype == jq_NullType.NULL_TYPE) continue; if(!(subtype instanceof jq_Class)){ System.err.println("Skipping a non-class type: " + t); continue; } jq_Class c = (jq_Class) subtype; result.add(c); } if(TRACE) System.out.println("Returning " + result.size() + " subtypes."); return result; } } public static class OnlineSubtypeHelper extends PrimitiveSubtypeHelper { private Map/*<jq_Class, Collection<jq_Class>>*/ type2subtypeCache = new HashMap(); static final String kind = ONLINE; public OnlineSubtypeHelper(PrimitivePA pa) { super(pa); if(TRACE) System.out.println("Instantiating a subtype helper of type " + kind); } public Collection getSubtypes(jq_Class clazz) { if(TRACE) System.out.println("Requesting subtypes of class " + clazz); Collection result = (Collection) type2subtypeCache.get(clazz); if(result != null) { return result; } result = new LinkedList(); for(Iterator iter = PrimordialClassLoader.loader.listPackages(); iter.hasNext();){ //System.out.println("\t" + iter.next()); String packageName = (String) iter.next(); HashSet loaded = new HashSet(); if(TRACE) System.out.println("Processing package " + packageName); for(Iterator classIter = PrimordialClassLoader.loader.listPackage(packageName, true); classIter.hasNext();){ String className = (String) classIter.next(); String canonicalClassName = canonicalizeClassName(className); if (loaded.contains(canonicalClassName)) continue; loaded.add(canonicalClassName); try { jq_Class c = (jq_Class) PrimordialClassLoader.loader.getOrCreateBSType(canonicalClassName); c.load(); c.prepare(); if(c.isSubtypeOf(clazz)){ System.out.println("Initialized a subclass of " + clazz + ", class: " + c); result.add(c); } } catch (NoClassDefFoundError x) { if(TRACE) System.err.println("Package " + packageName + ": Class not found (canonical name " + canonicalClassName + ")."); } catch (LinkageError le) { if(TRACE) System.err.println("Linkage error occurred while loading class (" + canonicalClassName + "):" + le.getMessage()); //le.printStackTrace(System.err); } catch (RuntimeException e){ if(TRACE) System.err.println("Security error occured: " + e.getMessage()); } } } type2subtypeCache.put(clazz, result); if(TRACE) System.out.println("Returning " + result.size() + " subtypes."); return result; } } public static class OfflineSubtypeHelper extends PrimitiveSubtypeHelper { static final String subtypeFileName = "reversed_subclasses.txt"; Map classes2subclasses = new HashMap(); private boolean initialized = false; final static String kind = OFFLINE; public OfflineSubtypeHelper(PrimitivePA pa) { super(pa); if(TRACE) System.out.println("Instantiating a subtype helper of type " + kind); } void initializeSubclasses() throws IOException { if(initialized) return; BufferedReader r = new BufferedReader(new FileReader(subtypeFileName)); String s = null; String className = null; Collection subclassList = null; while ((s = r.readLine()) != null) { if(s.startsWith("CLASS ")){ className = s.substring("CLASS ".length(), s.indexOf(" ", "CLASS ".length() + 1)); subclassList = new LinkedList(); // add the class itself to the list of subclasses subclassList.add(className); classes2subclasses.put(className, subclassList); }else{ int index = s.indexOf("SUBCLASS "); if(index != -1){ String subclass = s.substring(index + "SUBCLASS ".length(), s.length()); subclassList.add(subclass); } } } initialized = true; } /* (non-Javadoc) * @see joeq.Compiler.Analysis.IPA.SubtypeHelper#getSubtypes(joeq.Class.jq_Class) */ public Collection getSubtypes(jq_Class clazz) { if(TRACE) System.out.println("Requesting subtypes of class " + clazz); String className = clazz.getName(); try { initializeSubclasses(); // lazily initialize the subclasses } catch (IOException e) { Assert._assert(false, e.toString()); return null; } Collection subtypeNames = (Collection) classes2subclasses.get(className); if(subtypeNames == null){ System.err.println("No match for class \"" + className + "\" in " + subtypeFileName); return null; } Collection result = new LinkedList(); for(Iterator iter = subtypeNames.iterator(); iter.hasNext();){ String subtypeName = (String) iter.next(); String canonicalName = canonicalizeClassName(subtypeName.trim()); try { jq_Class subtypeClass = (jq_Class) jq_Class.parseType(canonicalName); if(!subtypeClass.isPrepared()){ // if(TRACE){ // System.out.println("Preparing class " + subtypeClass + " by name " + canonicalName); // } subtypeClass.prepare(); } result.add(subtypeClass); } catch (java.lang.NoClassDefFoundError e){ if(TRACE) System.err.println("Can't load " + subtypeName + ": " + e); continue; } } Assert._assert(result.size() <= subtypeNames.size()); if(TRACE) System.out.println("Returning " + result.size() + " subtypes."); return result; } } public static PrimitiveSubtypeHelper newSubtypeHelper(PrimitivePA pa, String kind) { if(kind.equals(OFFLINE)) { return new OfflineSubtypeHelper(pa); } if(kind.equals(ONLINE)) { return new OnlineSubtypeHelper(pa); } if(kind.equals(KNOWN)) { return new KnownClassesSubtypeHelper(pa); } Assert._assert(false, "Unknown kind: " + kind); return null; } } Index: PrimitivePAMethodSummary.java =================================================================== RCS file: /cvsroot/joeq//joeq_core/joeq/Compiler/Analysis/Primitive/PrimitivePAMethodSummary.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** PrimitivePAMethodSummary.java 27 Sep 2005 00:52:51 -0000 1.6 --- PrimitivePAMethodSummary.java 27 Sep 2005 01:05:21 -0000 1.7 *************** *** 12,16 **** import java.util.Map; import java.util.Set; - import joeq.Class.PrimordialClassLoader; import joeq.Class.jq_Class; import joeq.Class.jq_Field; --- 12,15 ---- *************** *** 20,24 **** import joeq.Class.jq_Reference; import joeq.Class.jq_Type; - import joeq.Compiler.Analysis.FlowInsensitive.MethodSummary; import joeq.Compiler.Analysis.FlowInsensitive.ReflectionInformationProvider; import joeq.Compiler.Analysis.IPA.PA; --- 19,22 ---- |