]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/coverage/CoverageBuilder.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / module / coverage / CoverageBuilder.java
1 package org.simantics.scl.compiler.module.coverage;
2
3 import org.simantics.scl.compiler.module.Module;
4 import org.simantics.scl.runtime.profiling.BranchPoint;
5
6 import gnu.trove.map.hash.THashMap;
7 import gnu.trove.procedure.TObjectObjectProcedure;
8
9 public class CoverageBuilder {
10     THashMap<String, THashMap<String, BranchPoint[]>> combined =
11             new THashMap<String, THashMap<String, BranchPoint[]>>();
12     
13     public void addCoverage(Module module, boolean persistOverBranchpointReset) {
14         THashMap<String, BranchPoint[]> branchPointMap = module.getBranchPoints();
15         if(branchPointMap == null)
16             return;
17         THashMap<String, BranchPoint[]> oldBranchPointMap = combined.get(module.getName());
18         if(oldBranchPointMap == null) {
19             oldBranchPointMap = new THashMap<String, BranchPoint[]>();
20             combined.put(module.getName(), oldBranchPointMap);
21         }
22         THashMap<String, BranchPoint[]> oldBranchPointMap_ = oldBranchPointMap;
23         branchPointMap.forEachEntry(new TObjectObjectProcedure<String, BranchPoint[]>() {
24             @Override
25             public boolean execute(String name, BranchPoint[] branchPoints) {
26                 BranchPoint[] oldBranchPoints = oldBranchPointMap_.get(name);
27                 if(oldBranchPoints == null) {
28                     if (persistOverBranchpointReset) {
29                         // Clone the branchPoints array so that if will last over a reset
30                         BranchPoint[] clonedBranchPoints = cloneBranchPoints(branchPoints);
31                         oldBranchPointMap_.put(name, clonedBranchPoints);
32                     } else {
33                         // No need to copy so resetting branchpoints will reset this as well
34                         oldBranchPointMap_.put(name, branchPoints);
35                     }
36                 } else {
37                     combineCounters(oldBranchPoints, branchPoints);
38                 }
39                 return true;
40             }
41         });
42     }
43     
44     private static BranchPoint[] cloneBranchPoints(BranchPoint[] oldBranchPoints) {
45         BranchPoint[] newBranchPoints = new BranchPoint[oldBranchPoints.length];
46         for (int i = 0; i < oldBranchPoints.length; i++) {
47             BranchPoint bp = oldBranchPoints[i];
48             BranchPoint[] children = cloneBranchPoints(bp.getChildren());
49             newBranchPoints[i] = new BranchPoint(bp.getLocation(), bp.getCodeSize(), children);
50         }
51         return newBranchPoints;
52     }
53     
54     private static void combineCounters(BranchPoint[] oldBranchPoints, BranchPoint[] branchPoints) {
55         if(oldBranchPoints.length != branchPoints.length)
56             throw new IllegalArgumentException("Incompatible branch points.");
57         for(int i=0;i<branchPoints.length;++i) {
58             BranchPoint oldBP = oldBranchPoints[i];
59             BranchPoint newBP = branchPoints[i];
60             if(oldBP.getLocation() != newBP.getLocation())
61                 throw new IllegalArgumentException("Incompatible branch points.");
62             oldBP.incrementVisitCounter(newBP.getVisitCounter());
63             combineCounters(oldBP.getChildren(), newBP.getChildren());
64         }
65     }
66     
67     public CombinedCoverage getCoverage() {
68         THashMap<String,ModuleCoverage> moduleCoverages =
69                 new THashMap<String,ModuleCoverage>();
70         combined.forEachEntry(new TObjectObjectProcedure<String, THashMap<String, BranchPoint[]>>() {
71             @Override
72             public boolean execute(String name, THashMap<String, BranchPoint[]> branchPoints) {
73                 moduleCoverages.put(name, CoverageUtils.getCoverage(name, branchPoints));
74                 return true;
75             }
76         });
77         return CoverageUtils.combineCoverages(moduleCoverages);
78     }
79 }