pascal.taie.analysis.pta.toolkit.zipper.ObjectAllocationGraph Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tai-e Show documentation
Show all versions of tai-e Show documentation
An easy-to-learn/use static analysis framework for Java
The newest version!
/*
* Tai-e: A Static Analysis Framework for Java
*
* Copyright (C) 2022 Tian Tan
* Copyright (C) 2022 Yue Li
*
* This file is part of Tai-e.
*
* Tai-e is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Tai-e. If not, see .
*/
package pascal.taie.analysis.pta.toolkit.zipper;
import pascal.taie.analysis.pta.core.heap.Obj;
import pascal.taie.analysis.pta.toolkit.PointerAnalysisResultEx;
import pascal.taie.analysis.pta.toolkit.util.OAGs;
import pascal.taie.language.type.ArrayType;
import pascal.taie.language.type.Type;
import pascal.taie.util.Canonicalizer;
import pascal.taie.util.Indexer;
import pascal.taie.util.collection.IndexerBitSet;
import pascal.taie.util.collection.Maps;
import pascal.taie.util.graph.MergedNode;
import pascal.taie.util.graph.MergedSCCGraph;
import pascal.taie.util.graph.SimpleGraph;
import pascal.taie.util.graph.TopologicalSorter;
import java.util.Map;
import java.util.Set;
/**
* Object allocation graph tailored for Zipper.
*/
class ObjectAllocationGraph extends SimpleGraph {
private final Map> obj2Allocatees = Maps.newMap();
private final Map> type2Allocatees = Maps.newConcurrentMap();
private Indexer objIndexer;
ObjectAllocationGraph(PointerAnalysisResultEx pta) {
OAGs.computeInvokedMethods(pta).forEach((obj, methods) -> {
addNode(obj);
methods.stream()
.map(pta::getObjectsAllocatedIn)
.flatMap(Set::stream)
.forEach(succ -> {
if (!(obj.getType() instanceof ArrayType)) {
addEdge(obj, succ);
}
});
});
objIndexer = pta.getBase().getObjectIndexer();
computeAllocatees(pta);
objIndexer = null;
assert getNumberOfNodes() == pta.getBase().getObjects().size();
}
Set getAllocateesOf(Type type) {
return type2Allocatees.get(type);
}
private Set getAllocateesOf(Obj obj) {
return obj2Allocatees.get(obj);
}
private void computeAllocatees(PointerAnalysisResultEx pta) {
// compute allocatees of objects
MergedSCCGraph mg = new MergedSCCGraph<>(this);
TopologicalSorter> sorter = new TopologicalSorter<>(mg, true);
Canonicalizer> canonicalizer = new Canonicalizer<>();
sorter.get().forEach(node -> {
Set allocatees = canonicalizer.get(getAllocatees(node, mg));
node.getNodes().forEach(obj -> obj2Allocatees.put(obj, allocatees));
});
// compute allocatees of types
pta.getObjectTypes().parallelStream().forEach(type -> {
Set allocatees = new IndexerBitSet<>(objIndexer, true);
pta.getObjectsOf(type)
.forEach(o -> allocatees.addAll(getAllocateesOf(o)));
type2Allocatees.put(type, canonicalizer.get(allocatees));
});
}
private Set getAllocatees(
MergedNode node, MergedSCCGraph mg) {
Set allocatees = new IndexerBitSet<>(objIndexer, true);
mg.getSuccsOf(node).forEach(n -> {
// direct allocatees
allocatees.addAll(n.getNodes());
// indirect allocatees
Obj o = n.getNodes().get(0);
allocatees.addAll(getAllocateesOf(o));
});
Obj obj = node.getNodes().get(0);
if (node.getNodes().size() > 1 ||
getSuccsOf(obj).contains(obj)) { // self-loop
// The merged node is a true SCC
allocatees.addAll(node.getNodes());
}
return allocatees;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy