Skip to content

Commit

Permalink
Merge pull request #1090 from soot-oss/speedup/icfg
Browse files Browse the repository at this point in the history
make use of IdentityHashMap in JimpleICFG
  • Loading branch information
swissiety authored Oct 24, 2024
2 parents 727be92 + fc4b606 commit 778778e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import heros.SynchronizedBy;
import heros.solver.IDESolver;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import sootup.core.graph.StmtGraph;
import sootup.core.jimple.basic.Value;
Expand Down Expand Up @@ -83,22 +84,26 @@ protected AbstractJimpleBasedICFG() {
}

protected Map<Stmt, Body> createStmtToOwnerMap() {
return new LinkedHashMap<>();
return new IdentityHashMap<>();
}

protected AbstractJimpleBasedICFG(boolean enableExceptions) {
this.enableExceptions = enableExceptions;
}

public Body getBodyOf(Stmt stmt) {
assert stmtToOwner.containsKey(stmt) : "Statement " + stmt + " not in Stmt-to-owner mapping";
return stmtToOwner.get(stmt);
Body body = stmtToOwner.get(stmt);
assert body != null : "Statement " + stmt + " not in Stmt-to-owner mapping";
return body;
}

@Override
public SootMethod getMethodOf(Stmt stmt) {
Body b = getBodyOf(stmt);
return b == null ? null : view.getMethod(b.getMethodSignature()).orElse(null);
if (b == null) {
return null;
}
return view.getMethod(b.getMethodSignature()).orElse(null);
}

@Override
Expand All @@ -107,8 +112,8 @@ public List<Stmt> getSuccsOf(Stmt stmt) {
if (body == null) {
return Collections.emptyList();
}
StmtGraph<?> unitGraph = getOrCreateStmtGraph(body);
return unitGraph.successors(stmt);
StmtGraph<?> stmtGraph = getOrCreateStmtGraph(body);
return stmtGraph.successors(stmt);
}

@Override
Expand All @@ -125,30 +130,23 @@ protected StmtGraph<?> makeGraph(Body body) {
}

protected Set<Stmt> getCallsFromWithinMethod(SootMethod method) {
Set<Stmt> res = null;
for (Stmt u : method.getBody().getStmts()) {
if (isCallStmt(u)) {
if (res == null) {
res = new LinkedHashSet<>();
}
res.add(u);
}
}
return res == null ? Collections.emptySet() : res;
return method.getBody().getStmts().stream()
.filter(this::isCallStmt)
.collect(Collectors.toSet());
}

@Override
public boolean isExitStmt(Stmt stmt) {
Body body = getBodyOf(stmt);
StmtGraph<?> unitGraph = getOrCreateStmtGraph(body);
return unitGraph.getTails().contains(stmt);
StmtGraph<?> stmtGraph = getOrCreateStmtGraph(body);
return stmtGraph.getTails().contains(stmt);
}

@Override
public boolean isStartPoint(Stmt stmt) {
Body body = getBodyOf(stmt);
StmtGraph<?> unitGraph = getOrCreateStmtGraph(body);
return unitGraph.getEntrypoints().contains(stmt);
StmtGraph<?> stmtGraph = getOrCreateStmtGraph(body);
return stmtGraph.getEntrypoints().contains(stmt);
}

@Override
Expand All @@ -174,12 +172,12 @@ public List<Value> getParameterRefs(SootMethod m) {

@Override
public Collection<Stmt> getStartPointsOf(SootMethod m) {
if (m.hasBody()) {
Body body = m.getBody();
StmtGraph<?> unitGraph = getOrCreateStmtGraph(body);
return unitGraph.getEntrypoints();
if (!m.hasBody()) {
return Collections.emptySet();
}
return Collections.emptySet();
Body body = m.getBody();
StmtGraph<?> stmtGraph = getOrCreateStmtGraph(body);
return stmtGraph.getEntrypoints();
}

public boolean setOwnerStatement(Stmt u, Body b) {
Expand All @@ -193,16 +191,16 @@ public boolean isCallStmt(Stmt stmt) {

@Override
public Set<Stmt> allNonCallStartNodes() {
Set<Stmt> res = new LinkedHashSet<>(stmtToOwner.keySet());
res.removeIf(u -> isStartPoint(u) || isCallStmt(u));
return res;
return stmtToOwner.keySet().stream()
.filter(u -> !(isStartPoint(u) || isCallStmt(u)))
.collect(Collectors.toSet());
}

@Override
public Set<Stmt> allNonCallEndNodes() {
Set<Stmt> res = new LinkedHashSet<>(stmtToOwner.keySet());
res.removeIf(u -> isExitStmt(u) || isCallStmt(u));
return res;
return stmtToOwner.keySet().stream()
.filter(u -> !(isExitStmt(u) || isCallStmt(u)))
.collect(Collectors.toSet());
}

@Override
Expand All @@ -216,12 +214,11 @@ public Set<Stmt> getCallsFromWithin(SootMethod m) {
}

public void initializeStmtToOwner(SootMethod m) {
if (m.hasBody()) {
Body b = m.getBody();
for (Stmt node : b.getStmtGraph().getNodes()) {
stmtToOwner.put(node, b);
}
if (!m.hasBody()) {
return;
}
Body b = m.getBody();
b.getStmtGraph().getNodes().forEach(node -> stmtToOwner.put(node, b));
}

@Override
Expand All @@ -231,18 +228,18 @@ public List<Stmt> getPredsOf(Stmt u) {
if (body == null) {
return Collections.emptyList();
}
StmtGraph<?> unitGraph = getOrCreateStmtGraph(body);
return unitGraph.predecessors(u);
StmtGraph<?> stmtGraph = getOrCreateStmtGraph(body);
return stmtGraph.predecessors(u);
}

@Override
public Collection<Stmt> getEndPointsOf(SootMethod m) {
if (m.hasBody()) {
Body body = m.getBody();
StmtGraph<?> unitGraph = getOrCreateStmtGraph(body);
return unitGraph.getTails();
if (!m.hasBody()) {
return Collections.emptySet();
}
return Collections.emptySet();
Body body = m.getBody();
StmtGraph<?> stmtGraph = getOrCreateStmtGraph(body);
return stmtGraph.getTails();
}

@Override
Expand All @@ -252,12 +249,7 @@ public List<Stmt> getPredsOfCallAt(Stmt u) {

@Override
public boolean isReturnSite(Stmt n) {
for (Stmt pred : getPredsOf(n)) {
if (isCallStmt(pred)) {
return true;
}
}
return false;
return getPredsOf(n).stream().anyMatch(this::isCallStmt);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public Optional<? extends SootClassSource> getClassSource(
@Nonnull
@Override
public Collection<? extends SootClassSource> getClassSources(@Nonnull View view) {
// possibility to streamify this method to apply the filter at earlier stage i.e. before
// creating the ClassSources would be a faster approach..
return inputLocation.getClassSources(view).stream()
.filter(type -> filter(type.getClassType()))
.collect(Collectors.toList());
Expand Down

0 comments on commit 778778e

Please sign in to comment.