use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class TypeGraph method computeInterfaceBuckets.
/**
* Bucket assignment for interfaces.
* Two interfaces may not share a bucket if they have a common subtype.
* Uses a simple highest-degree first graph coloring heuristic
* @param maxBucketEntries
* @return
*/
public Map<ClassInfo, Integer> computeInterfaceBuckets(int maxBucketEntries) {
Map<ClassInfo, Integer> bucketMap = new HashMap<ClassInfo, Integer>();
SimpleGraph<ClassInfo, DefaultEdge> conflictGraph = getInterfaceConflictGraph();
List<ClassInfo> ifaces = new LinkedList<ClassInfo>();
for (ClassInfo v : vertexSet()) {
if (!v.isInterface())
continue;
ifaces.add(v);
}
Collections.sort(ifaces, new ReverseSubtypeCountComparator(getSubtypeSets()));
BitSet fullBuckets = new BitSet();
int[] count = new int[ifaces.size()];
for (ClassInfo iface : ifaces) {
BitSet used = (BitSet) fullBuckets.clone();
for (DefaultEdge conflictEdge : conflictGraph.edgesOf(iface)) {
ClassInfo conflictNode = conflictGraph.getEdgeSource(conflictEdge);
// FIXME: ugly JGraphT idiom ?
if (conflictNode == iface)
conflictNode = conflictGraph.getEdgeTarget(conflictEdge);
if (bucketMap.containsKey(conflictNode)) {
used.set(bucketMap.get(conflictNode));
}
}
int color = used.nextClearBit(0);
count[color]++;
if (count[color] == maxBucketEntries) {
fullBuckets.set(color);
}
bucketMap.put(iface, color);
}
return bucketMap;
}
use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class TypeGraph method getLevels.
/**
* Compute a the maximum level of each class
* If the longest subtype chain
* {@code Object <: T1 <: T2 <: ... <: T @} has length l+1,
* T has a maximum level of l.
* @return
*/
public Map<ClassInfo, Integer> getLevels() {
Map<ClassInfo, Integer> levels = new HashMap<ClassInfo, Integer>();
for (ClassInfo v : topDownTraversal()) {
int level = 0;
for (DefaultEdge parentEdge : incomingEdgesOf(v)) {
level = Math.max(level, 1 + levels.get(getEdgeSource(parentEdge)));
}
levels.put(v, level);
}
return levels;
}
use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class ConstantPoolReferenceFinder method findPoolReferences.
private static Set<Integer> findPoolReferences(MethodInfo methodInfo, Method method) {
ClassInfo classInfo = methodInfo.getClassInfo();
IdFinderVisitor visitor = new IdFinderVisitor(classInfo);
visitor.visitConstantUtf8(method.getNameIndex());
visitor.visitConstantUtf8(method.getSignatureIndex());
DescendingClassTraverser traverser = new DescendingClassTraverser(visitor);
// Code is an attribute, since we visit Method, not MethodGen
traverser.visitAttributes(methodInfo, method.getAttributes());
return visitor.getIds();
}
use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class TypeGraph method getSubtypeSets.
/**
* Compute, for each type, the set of subtypes, using a single
* bottom-up traversal.
* @return
*/
public Map<ClassInfo, Set<ClassInfo>> getSubtypeSets() {
Map<ClassInfo, Set<ClassInfo>> subtypeMap = new HashMap<ClassInfo, Set<ClassInfo>>();
for (ClassInfo v : bottomUpTraversal()) {
Set<ClassInfo> subtypes = new HashSet<ClassInfo>();
for (DefaultEdge kidEdge : outgoingEdgesOf(v)) {
ClassInfo subtype = getEdgeTarget(kidEdge);
subtypes.addAll(subtypeMap.get(subtype));
subtypes.add(subtype);
}
subtypeMap.put(v, subtypes);
}
return subtypeMap;
}
use of com.jopdesign.common.ClassInfo in project jop by jop-devel.
the class TypeGraph method getInterfaceConflictGraph.
/** Compute the interface conflict graph.<br/>
* Two distinct types A and B conflict if either {@code A <: B} or
* {@code B <: A}, or if A and B share a common descendant.
* Algorithmically, assume A conflicts with B.
* Then either<ul>
* <li/>A is in the <emph>subtype set</emph> of B or vice versa
* <li/>A and B are ancestors of some join node T.
* </ul>
* A join node is a type which is the root of a single inheritance hierarchy,
* but has more than one parent (think: the leaves of the multiple inheritance
* hierarchy).
* <p>
* For detailed information see
* <quote>Vitek, J., Horspool, R. N., and Krall, A. 1997. Efficient type inclusion tests.
* SIGPLAN Not. 32, 10 (Oct. 1997), 142-157.</quote>
* </p>
*
* @return
*/
public SimpleGraph<ClassInfo, DefaultEdge> getInterfaceConflictGraph() {
SimpleGraph<ClassInfo, DefaultEdge> conflicts = new SimpleGraph<ClassInfo, DefaultEdge>(DefaultEdge.class);
Map<ClassInfo, Set<ClassInfo>> ancestors = getSupertypeSets();
Map<ClassInfo, Set<ClassInfo>> subtypes = getSubtypeSets();
for (ClassInfo v : topDownTraversal()) {
if (v.isInterface())
conflicts.addVertex(v);
}
for (ClassInfo a : conflicts.vertexSet()) {
for (ClassInfo b : subtypes.get(a)) {
if (b.isInterface())
conflicts.addEdge(a, b);
}
}
for (ClassInfo joinNode : getJoinNodes()) {
for (ClassInfo a : ancestors.get(joinNode)) {
if (!a.isInterface())
continue;
if (joinNode.isInterface())
conflicts.addEdge(joinNode, a);
for (ClassInfo b : ancestors.get(joinNode)) {
if (b.isInterface() && !a.equals(b))
conflicts.addEdge(a, b);
}
}
}
return conflicts;
}
Aggregations