Skip to content

Commit 765abd4

Browse files
committed
Refactoring for better code structure.
Change a default behavior: update Soot call graph and rechable methods after geomPTA.
1 parent bf5db26 commit 765abd4

File tree

7 files changed

+125
-64
lines changed

7 files changed

+125
-64
lines changed

src/soot/jimple/spark/geom/geomE/FullSensitiveNode.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import soot.jimple.spark.geom.geomPA.GeomPointsTo;
3838
import soot.jimple.spark.geom.geomPA.IVarAbstraction;
3939
import soot.jimple.spark.geom.geomPA.IWorklist;
40+
import soot.jimple.spark.geom.geomPA.Parameters;
4041
import soot.jimple.spark.pag.AllocNode;
4142
import soot.jimple.spark.pag.ClassConstantNode;
4243
import soot.jimple.spark.pag.Node;
@@ -700,14 +701,14 @@ private boolean addFlowsTo(int code, IVarAbstraction qv)
700701
private void do_pts_interval_merge()
701702
{
702703
for ( GeometricManager gm : new_pts.values() ) {
703-
gm.mergeFigures( Constants.max_pts_budget );
704+
gm.mergeFigures( Parameters.max_pts_budget );
704705
}
705706
}
706707

707708
private void do_flow_edge_interval_merge()
708709
{
709710
for ( GeometricManager gm : flowto.values() ) {
710-
gm.mergeFigures( Constants.max_cons_budget );
711+
gm.mergeFigures( Parameters.max_cons_budget );
711712
}
712713
}
713714

src/soot/jimple/spark/geom/geomPA/Constants.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,23 @@
2121
import soot.RefType;
2222

2323
/**
24-
* Parameters to control the behaviors of geom points-to solver.
25-
* Not all fields are really constants.
24+
* Named constants used in the geomPA.
2625
*
2726
* @author xiao
2827
*
2928
*/
30-
public class Constants {
31-
29+
public class Constants
30+
{
3231
// Available encodings
3332
public static final String geomE = "Geom";
3433
public static final String heapinsE = "HeapIns";
3534
public static final String ptinsE = "PtIns";
3635

36+
// Evaluation level
37+
public static final int eval_nothing = 0;
38+
public static final int eval_basicInfo = 1;
39+
public static final int eval_simpleClients = 2;
40+
3741
// The constants for the constraints type identification
3842
public static final int NEW_CONS = 0;
3943
public static final int ASSIGN_CONS = 1;
@@ -52,9 +56,8 @@ public class Constants {
5256
// Some commonly referred to information
5357
public static final RefType exeception_type = RefType.v( "java.lang.Throwable" );
5458

55-
// The parameters that are used to tune the precision and performance tradeoff
56-
public static int max_cons_budget = 40;
57-
public static int max_pts_budget = 80;
58-
public static int cg_refine_times = 1;
59-
59+
// The seed pointers for running constraints distillation
60+
public static final int seedPts_all = 0;
61+
public static final int seedPts_virtualBase = 1;
62+
public static final int seedPts_staticCasts = 2;
6063
}

src/soot/jimple/spark/geom/geomPA/GeomPointsTo.java

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -304,9 +304,9 @@ else if ( solver_encoding == SparkOptions.geom_encoding_PtIns )
304304
typeManager = getTypeManager();
305305

306306
// The tunable parameters
307-
Constants.max_cons_budget = opts.geom_frac_base();
308-
Constants.max_pts_budget = Constants.max_cons_budget * 2;
309-
Constants.cg_refine_times = opts.geom_runs();
307+
Parameters.max_cons_budget = opts.geom_frac_base();
308+
Parameters.max_pts_budget = Parameters.max_cons_budget * 2;
309+
Parameters.cg_refine_times = opts.geom_runs();
310310

311311
// Prepare for the containers
312312
prepareContainers();
@@ -772,8 +772,8 @@ private int updateCallGraph()
772772
p.is_obsoleted = true;
773773
}
774774
else if ( p.base_var != null
775-
&& (!thread_run_callsites.contains( p.sootEdge.srcStmt() ) )
776-
) {
775+
&& (!thread_run_callsites.contains( p.sootEdge.srcStmt() ) ) ) {
776+
// We should care about the thread start method, it is treated specially
777777
// It is a virtual call
778778
keep_this_edge = false;
779779
++all_virtual_edges;
@@ -782,23 +782,28 @@ else if ( p.base_var != null
782782
if ( pn != null ) {
783783
SootMethod sm = p.sootEdge.tgt();
784784

785-
for (AllocNode an : pn.get_all_points_to_objects()) {
786-
Type t = an.getType();
787-
if ( t == null )
788-
continue;
789-
else if ( t instanceof AnySubType )
790-
t = ((AnySubType)t).getBase();
791-
else if ( t instanceof ArrayType )
792-
t = RefType.v( "java.lang.Object" );
793-
794-
// Only the virtual calls do the following test
795-
// We should care about the thread start method, it is treated specially
796-
if ( Scene.v().getOrMakeFastHierarchy().
797-
resolveConcreteDispatch( ((RefType)t).getSootClass(), sm) == sm ) {
798-
keep_this_edge = true;
799-
break;
785+
try {
786+
for (AllocNode an : pn.get_all_points_to_objects()) {
787+
Type t = an.getType();
788+
if ( t == null )
789+
continue;
790+
else if ( t instanceof AnySubType )
791+
t = ((AnySubType)t).getBase();
792+
else if ( t instanceof ArrayType )
793+
t = RefType.v( "java.lang.Object" );
794+
795+
// Only the virtual calls do the following test
796+
if ( Scene.v().getOrMakeFastHierarchy().
797+
resolveConcreteDispatch( ((RefType)t).getSootClass(), sm) == sm ) {
798+
keep_this_edge = true;
799+
break;
800+
}
800801
}
801802
}
803+
catch (RuntimeException e) {
804+
// Perhaps there is a bug, either from soot or geomPTA
805+
keep_this_edge = true;
806+
}
802807

803808
if (keep_this_edge == false) {
804809
p.is_obsoleted = true;
@@ -809,7 +814,7 @@ else if ( t instanceof ArrayType )
809814
}
810815
else {
811816
System.err.println();
812-
throw new RuntimeException("In update_call_graph: oops, what's up?");
817+
throw new RuntimeException("In updateCallGraph: Oops, cannot find the virtual base pointer.");
813818
}
814819
}
815820

@@ -874,9 +879,10 @@ protected int countReachableMethods( int s )
874879
}
875880

876881
/**
877-
* Update the call graph and eliminate the pointers and objects appeared in the unreachable code.
882+
* 1. Update the call graph;
883+
* 2. Eliminate the pointers and objects appeared in the unreachable code.
878884
*/
879-
private void postProcess()
885+
private void finalizeInternalData()
880886
{
881887
// Compute the set of reachable functions after the points-to analysis
882888
for ( int i = 0; i < n_func; ++i ) vis_cg[i] = 0;
@@ -969,18 +975,17 @@ else if ( node instanceof AllocDotField ) {
969975
/**
970976
* Stuff that is useless for querying is released.
971977
*/
972-
public void releaseUselessResources()
978+
private void releaseUselessResources()
973979
{
974980
offlineProcessor.destroy();
975981
IFigureManager.cleanCache();
976982
System.gc(); System.gc(); System.gc(); System.gc(); System.gc();
977983
}
978984

979985
/**
980-
* Programmers can call this function any time to use the up-to-date call graph.
981-
* Geom-pts does not update soot call graph by default.
986+
* Update Soot call graph and reachable methods.
982987
*/
983-
public void updateSootData()
988+
protected void updateSootData()
984989
{
985990
// We first update the Soot call graph
986991
for (CgEdge p : obsoletedEdges) {
@@ -1001,8 +1006,6 @@ public void updateSootData()
10011006
*/
10021007
public void transformToCIResult()
10031008
{
1004-
updateSootData();
1005-
10061009
for ( IVarAbstraction pn : pointers ) {
10071010
Node node = pn.getWrappedNode();
10081011
IVarAbstraction pRep = pn.getRepresentative();
@@ -1023,7 +1026,7 @@ public void solve()
10231026
long mem;
10241027
int rounds;
10251028
int n_obs;
1026-
int useClients = 0;
1029+
int seedPts = Constants.seedPts_all;
10271030

10281031
// Flush all accumulated outputs
10291032
G.v().out.flush();
@@ -1038,7 +1041,7 @@ public void solve()
10381041
offlineProcessor = new OfflineProcessor(n_var, this);
10391042
IFigureManager.cleanCache();
10401043

1041-
for ( rounds = 0, n_obs = 1000; rounds < Constants.cg_refine_times && n_obs > 0; ++rounds ) {
1044+
for ( rounds = 0, n_obs = 1000; rounds < Parameters.cg_refine_times && n_obs > 0; ++rounds ) {
10421045

10431046
ps.println("\n" + "[Geom] Propagation Round " + rounds + " ==> ");
10441047

@@ -1048,7 +1051,7 @@ public void solve()
10481051
// Offline process:
10491052
// substantially use the points-to result for redundancy elimination prior to the analysis
10501053
Date prepare_begin = new Date();
1051-
offlineProcessor.runOptimizations( useClients, rounds == 0, basePointers );
1054+
offlineProcessor.runOptimizations( seedPts, rounds == 0, basePointers );
10521055
Date prepare_end = new Date();
10531056
prepare_time += prepare_end.getTime() - prepare_begin.getTime();
10541057

@@ -1068,7 +1071,7 @@ public void solve()
10681071
solve_time -= update_cg_end.getTime() - update_cg_begin.getTime();
10691072
}
10701073

1071-
if ( rounds < Constants.cg_refine_times )
1074+
if ( rounds < Parameters.cg_refine_times )
10721075
ps.printf( "\nSorry, it's not necessary to iterate more times. We stop here.\n" );
10731076

10741077
Date end = new Date();
@@ -1081,22 +1084,27 @@ public void solve()
10811084
ps.printf("[Geom] Memory used : %.1f MB\n", (double) (mem) / 1024 / 1024 );
10821085

10831086
// Finish points-to analysis and prepare for querying
1084-
postProcess();
1087+
finalizeInternalData();
10851088

10861089
// We perform a set of tests to assess the quality of the points-to results for user pointers
10871090
int evalLevel = opts.geom_eval();
1088-
if ( evalLevel > 0 ) {
1091+
if ( evalLevel != Constants.eval_nothing ) {
10891092
GeomEvaluator ge = new GeomEvaluator(this, ps);
10901093
ge.reportBasicMetrics();
10911094

1092-
if ( evalLevel > 1 ) {
1093-
if ( useClients == 0 || useClients == 1 ) ge.checkCallGraph();
1094-
if ( useClients == 0 || useClients == 2 ) ge.checkCastsSafety();
1095-
if ( useClients == 0 ) ge.checkAliasAnalysis();
1096-
ge.estimateHeapDefuseGraph();
1095+
if ( evalLevel != Constants.eval_basicInfo ) {
1096+
if ( seedPts == Constants.seedPts_all || seedPts == Constants.seedPts_virtualBase ) ge.checkCallGraph();
1097+
if ( seedPts == Constants.seedPts_all || seedPts == Constants.seedPts_staticCasts ) ge.checkCastsSafety();
1098+
if ( seedPts == Constants.seedPts_all ) {
1099+
ge.checkAliasAnalysis();
1100+
//ge.estimateHeapDefuseGraph();
1101+
}
10971102
}
10981103
}
10991104

1105+
// Making changes available to Soot
1106+
updateSootData();
1107+
11001108
if ( !opts.geom_trans() ) {
11011109
// We remove the SPARK points-to information for pointers that have geomPTA results
11021110
// At querying time, the SPARK points-to container will be used as query cache
@@ -1426,7 +1434,9 @@ public FileOutputStream createOutputFile( String file_name ) throws FileNotFound
14261434
new File( dump_dir, file_name ) );
14271435
}
14281436

1437+
// --------------------------------------------------------------------------------------------------------
14291438
// -------------------------------Soot Standard Points-to Query Interface----------------------------------
1439+
// --------------------------------------------------------------------------------------------------------
14301440

14311441
private PointsToSetInternal field_p2set( PointsToSet s, final SparkField f )
14321442
{
@@ -1502,11 +1512,14 @@ public PointsToSet reachingObjects(Context c, Local l)
15021512
return reachingObjects(l);
15031513

15041514
LocalVarNode vn = findLocalVarNode(l);
1505-
if ( vn == null ) return EmptyPointsToSet.v();
1515+
if ( vn == null )
1516+
return EmptyPointsToSet.v();
15061517

15071518
// Lookup the context sensitive points-to information for this pointer
15081519
IVarAbstraction pn = consG.get(vn);
1509-
if ( pn == null ) return reachingObjects(l);
1520+
if ( pn == null )
1521+
return vn.getP2Set();
1522+
15101523
pn = pn.getRepresentative();
15111524

15121525
// Lookup the cache
@@ -1548,10 +1561,12 @@ public PointsToSet reachingObjects(SootField f)
15481561
throw new RuntimeException( "The parameter f must be a *static* field." );
15491562

15501563
VarNode vn = findGlobalVarNode( f );
1551-
if ( vn == null ) return EmptyPointsToSet.v();
1564+
if ( vn == null )
1565+
return EmptyPointsToSet.v();
15521566

15531567
IVarAbstraction pn = consG.get(f);
1554-
if( pn == null ) return vn.getP2Set();
1568+
if( pn == null )
1569+
return vn.getP2Set();
15551570

15561571
// Lookup the cache
15571572
if ( hasTransformed ||
@@ -1598,9 +1613,14 @@ public PointsToSet reachingObjects(AllocNode an, SootField f)
15981613
AllocDotField adf = an.dot(f);
15991614
IVarAbstraction pn = consG.get(adf);
16001615

1601-
if ( adf == null || pn == null )
1616+
// No such pointer seen by SPARK
1617+
if ( adf == null )
16021618
return EmptyPointsToSet.v();
16031619

1620+
// Not seen by geomPTA
1621+
if ( pn == null )
1622+
return adf.getP2Set();
1623+
16041624
if ( hasTransformed ||
16051625
adf.getP2Set() != EmptyPointsToSet.v() ) return adf.getP2Set();
16061626

src/soot/jimple/spark/geom/geomPA/OfflineProcessor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public OfflineProcessor( int size, GeomPointsTo pta )
9696
for ( int i = 0; i < size; ++i ) varGraph.add(null);
9797
}
9898

99-
public void runOptimizations( int useClients, boolean useSpark, Set<VarNode> basePointers )
99+
public void runOptimizations( int seedPts, boolean useSpark, Set<VarNode> basePointers )
100100
{
101101
// We prepare the essential data structure first
102102
n_var = int2var.size(); // The size of the pointers will shrink after each round of analysis
@@ -109,15 +109,16 @@ public void runOptimizations( int useClients, boolean useSpark, Set<VarNode> bas
109109
// The instance graph reverses the assignment relations. E.g., p = q => p -> q
110110
buildInstanceAssignmentGraph( useSpark );
111111

112-
switch (useClients) {
113-
case 1:
112+
switch (seedPts) {
113+
case Constants.seedPts_virtualBase:
114114
setVirualBaseVarsUseful();
115115
break;
116116

117-
case 2:
117+
case Constants.seedPts_staticCasts:
118118
setStaticCastsVarUseful( useSpark );
119119
break;
120120

121+
case Constants.seedPts_all:
121122
default:
122123
setAllUserCodeVariablesUseful();
123124
break;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* Soot - a J*va Optimization Framework
2+
* Copyright (C) 2011-2014 Richard Xiao
3+
*
4+
* This library is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with this library; if not, write to the
16+
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17+
* Boston, MA 02111-1307, USA.
18+
*/
19+
package soot.jimple.spark.geom.geomPA;
20+
21+
/**
22+
* Parameters to control the behaviors of geom points-to solver.
23+
*
24+
* @author xiao
25+
*
26+
*/
27+
public class Parameters
28+
{
29+
// The parameters that are used to tune the precision and performance tradeoff
30+
public static int max_cons_budget = 40;
31+
public static int max_pts_budget = 80;
32+
public static int cg_refine_times = 1;
33+
34+
}

0 commit comments

Comments
 (0)