@@ -304,9 +304,9 @@ else if ( solver_encoding == SparkOptions.geom_encoding_PtIns )
304
304
typeManager = getTypeManager ();
305
305
306
306
// 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 ();
310
310
311
311
// Prepare for the containers
312
312
prepareContainers ();
@@ -772,8 +772,8 @@ private int updateCallGraph()
772
772
p .is_obsoleted = true ;
773
773
}
774
774
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
777
777
// It is a virtual call
778
778
keep_this_edge = false ;
779
779
++all_virtual_edges ;
@@ -782,23 +782,28 @@ else if ( p.base_var != null
782
782
if ( pn != null ) {
783
783
SootMethod sm = p .sootEdge .tgt ();
784
784
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
+ }
800
801
}
801
802
}
803
+ catch (RuntimeException e ) {
804
+ // Perhaps there is a bug, either from soot or geomPTA
805
+ keep_this_edge = true ;
806
+ }
802
807
803
808
if (keep_this_edge == false ) {
804
809
p .is_obsoleted = true ;
@@ -809,7 +814,7 @@ else if ( t instanceof ArrayType )
809
814
}
810
815
else {
811
816
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. " );
813
818
}
814
819
}
815
820
@@ -874,9 +879,10 @@ protected int countReachableMethods( int s )
874
879
}
875
880
876
881
/**
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.
878
884
*/
879
- private void postProcess ()
885
+ private void finalizeInternalData ()
880
886
{
881
887
// Compute the set of reachable functions after the points-to analysis
882
888
for ( int i = 0 ; i < n_func ; ++i ) vis_cg [i ] = 0 ;
@@ -969,18 +975,17 @@ else if ( node instanceof AllocDotField ) {
969
975
/**
970
976
* Stuff that is useless for querying is released.
971
977
*/
972
- public void releaseUselessResources ()
978
+ private void releaseUselessResources ()
973
979
{
974
980
offlineProcessor .destroy ();
975
981
IFigureManager .cleanCache ();
976
982
System .gc (); System .gc (); System .gc (); System .gc (); System .gc ();
977
983
}
978
984
979
985
/**
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.
982
987
*/
983
- public void updateSootData ()
988
+ protected void updateSootData ()
984
989
{
985
990
// We first update the Soot call graph
986
991
for (CgEdge p : obsoletedEdges ) {
@@ -1001,8 +1006,6 @@ public void updateSootData()
1001
1006
*/
1002
1007
public void transformToCIResult ()
1003
1008
{
1004
- updateSootData ();
1005
-
1006
1009
for ( IVarAbstraction pn : pointers ) {
1007
1010
Node node = pn .getWrappedNode ();
1008
1011
IVarAbstraction pRep = pn .getRepresentative ();
@@ -1023,7 +1026,7 @@ public void solve()
1023
1026
long mem ;
1024
1027
int rounds ;
1025
1028
int n_obs ;
1026
- int useClients = 0 ;
1029
+ int seedPts = Constants . seedPts_all ;
1027
1030
1028
1031
// Flush all accumulated outputs
1029
1032
G .v ().out .flush ();
@@ -1038,7 +1041,7 @@ public void solve()
1038
1041
offlineProcessor = new OfflineProcessor (n_var , this );
1039
1042
IFigureManager .cleanCache ();
1040
1043
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 ) {
1042
1045
1043
1046
ps .println ("\n " + "[Geom] Propagation Round " + rounds + " ==> " );
1044
1047
@@ -1048,7 +1051,7 @@ public void solve()
1048
1051
// Offline process:
1049
1052
// substantially use the points-to result for redundancy elimination prior to the analysis
1050
1053
Date prepare_begin = new Date ();
1051
- offlineProcessor .runOptimizations ( useClients , rounds == 0 , basePointers );
1054
+ offlineProcessor .runOptimizations ( seedPts , rounds == 0 , basePointers );
1052
1055
Date prepare_end = new Date ();
1053
1056
prepare_time += prepare_end .getTime () - prepare_begin .getTime ();
1054
1057
@@ -1068,7 +1071,7 @@ public void solve()
1068
1071
solve_time -= update_cg_end .getTime () - update_cg_begin .getTime ();
1069
1072
}
1070
1073
1071
- if ( rounds < Constants .cg_refine_times )
1074
+ if ( rounds < Parameters .cg_refine_times )
1072
1075
ps .printf ( "\n Sorry, it's not necessary to iterate more times. We stop here.\n " );
1073
1076
1074
1077
Date end = new Date ();
@@ -1081,22 +1084,27 @@ public void solve()
1081
1084
ps .printf ("[Geom] Memory used : %.1f MB\n " , (double ) (mem ) / 1024 / 1024 );
1082
1085
1083
1086
// Finish points-to analysis and prepare for querying
1084
- postProcess ();
1087
+ finalizeInternalData ();
1085
1088
1086
1089
// We perform a set of tests to assess the quality of the points-to results for user pointers
1087
1090
int evalLevel = opts .geom_eval ();
1088
- if ( evalLevel > 0 ) {
1091
+ if ( evalLevel != Constants . eval_nothing ) {
1089
1092
GeomEvaluator ge = new GeomEvaluator (this , ps );
1090
1093
ge .reportBasicMetrics ();
1091
1094
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
+ }
1097
1102
}
1098
1103
}
1099
1104
1105
+ // Making changes available to Soot
1106
+ updateSootData ();
1107
+
1100
1108
if ( !opts .geom_trans () ) {
1101
1109
// We remove the SPARK points-to information for pointers that have geomPTA results
1102
1110
// 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
1426
1434
new File ( dump_dir , file_name ) );
1427
1435
}
1428
1436
1437
+ // --------------------------------------------------------------------------------------------------------
1429
1438
// -------------------------------Soot Standard Points-to Query Interface----------------------------------
1439
+ // --------------------------------------------------------------------------------------------------------
1430
1440
1431
1441
private PointsToSetInternal field_p2set ( PointsToSet s , final SparkField f )
1432
1442
{
@@ -1502,11 +1512,14 @@ public PointsToSet reachingObjects(Context c, Local l)
1502
1512
return reachingObjects (l );
1503
1513
1504
1514
LocalVarNode vn = findLocalVarNode (l );
1505
- if ( vn == null ) return EmptyPointsToSet .v ();
1515
+ if ( vn == null )
1516
+ return EmptyPointsToSet .v ();
1506
1517
1507
1518
// Lookup the context sensitive points-to information for this pointer
1508
1519
IVarAbstraction pn = consG .get (vn );
1509
- if ( pn == null ) return reachingObjects (l );
1520
+ if ( pn == null )
1521
+ return vn .getP2Set ();
1522
+
1510
1523
pn = pn .getRepresentative ();
1511
1524
1512
1525
// Lookup the cache
@@ -1548,10 +1561,12 @@ public PointsToSet reachingObjects(SootField f)
1548
1561
throw new RuntimeException ( "The parameter f must be a *static* field." );
1549
1562
1550
1563
VarNode vn = findGlobalVarNode ( f );
1551
- if ( vn == null ) return EmptyPointsToSet .v ();
1564
+ if ( vn == null )
1565
+ return EmptyPointsToSet .v ();
1552
1566
1553
1567
IVarAbstraction pn = consG .get (f );
1554
- if ( pn == null ) return vn .getP2Set ();
1568
+ if ( pn == null )
1569
+ return vn .getP2Set ();
1555
1570
1556
1571
// Lookup the cache
1557
1572
if ( hasTransformed ||
@@ -1598,9 +1613,14 @@ public PointsToSet reachingObjects(AllocNode an, SootField f)
1598
1613
AllocDotField adf = an .dot (f );
1599
1614
IVarAbstraction pn = consG .get (adf );
1600
1615
1601
- if ( adf == null || pn == null )
1616
+ // No such pointer seen by SPARK
1617
+ if ( adf == null )
1602
1618
return EmptyPointsToSet .v ();
1603
1619
1620
+ // Not seen by geomPTA
1621
+ if ( pn == null )
1622
+ return adf .getP2Set ();
1623
+
1604
1624
if ( hasTransformed ||
1605
1625
adf .getP2Set () != EmptyPointsToSet .v () ) return adf .getP2Set ();
1606
1626
0 commit comments