-package org.simantics.scl.compiler.module.coverage;\r
-\r
-import org.simantics.scl.compiler.module.Module;\r
-import org.simantics.scl.runtime.profiling.BranchPoint;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.procedure.TObjectObjectProcedure;\r
-\r
-public class CoverageBuilder {\r
- THashMap<String, THashMap<String, BranchPoint[]>> combined =\r
- new THashMap<String, THashMap<String, BranchPoint[]>>();\r
- \r
- public void addCoverage(Module module) {\r
- THashMap<String, BranchPoint[]> branchPointMap = module.getBranchPoints();\r
- if(branchPointMap == null)\r
- return;\r
- THashMap<String, BranchPoint[]> oldBranchPointMap = combined.get(module.getName());\r
- if(oldBranchPointMap == null) {\r
- oldBranchPointMap = new THashMap<String, BranchPoint[]>();\r
- combined.put(module.getName(), oldBranchPointMap);\r
- }\r
- THashMap<String, BranchPoint[]> oldBranchPointMap_ = oldBranchPointMap;\r
- branchPointMap.forEachEntry(new TObjectObjectProcedure<String, BranchPoint[]>() {\r
- @Override\r
- public boolean execute(String name, BranchPoint[] branchPoints) {\r
- BranchPoint[] oldBranchPoints = oldBranchPointMap_.get(name);\r
- if(oldBranchPoints == null)\r
- oldBranchPointMap_.put(name, branchPoints);\r
- else\r
- combineCounters(oldBranchPoints, branchPoints);\r
- return true;\r
- }\r
- });\r
- }\r
- \r
- private static void combineCounters(BranchPoint[] oldBranchPoints, BranchPoint[] branchPoints) {\r
- if(oldBranchPoints.length != branchPoints.length)\r
- throw new IllegalArgumentException("Incompatible branch points.");\r
- for(int i=0;i<branchPoints.length;++i) {\r
- BranchPoint oldBP = oldBranchPoints[i];\r
- BranchPoint newBP = branchPoints[i];\r
- if(oldBP.location != newBP.location)\r
- throw new IllegalArgumentException("Incompatible branch points.");\r
- oldBP.visitCounter += newBP.visitCounter;\r
- combineCounters(oldBP.children, newBP.children);\r
- }\r
- }\r
- \r
- public CombinedCoverage getCoverage() {\r
- THashMap<String,ModuleCoverage> moduleCoverages =\r
- new THashMap<String,ModuleCoverage>();\r
- combined.forEachEntry(new TObjectObjectProcedure<String, THashMap<String, BranchPoint[]>>() {\r
- @Override\r
- public boolean execute(String name, THashMap<String, BranchPoint[]> branchPoints) {\r
- moduleCoverages.put(name, CoverageUtils.getCoverage(name, branchPoints));\r
- return true;\r
- }\r
- });\r
- return CoverageUtils.combineCoverages(moduleCoverages);\r
- }\r
-}\r
+package org.simantics.scl.compiler.module.coverage;
+
+import org.simantics.scl.compiler.module.Module;
+import org.simantics.scl.runtime.profiling.BranchPoint;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.procedure.TObjectObjectProcedure;
+
+public class CoverageBuilder {
+ THashMap<String, THashMap<String, BranchPoint[]>> combined =
+ new THashMap<String, THashMap<String, BranchPoint[]>>();
+
+ public void addCoverage(Module module, boolean persistOverBranchpointReset) {
+ THashMap<String, BranchPoint[]> branchPointMap = module.getBranchPoints();
+ if(branchPointMap == null)
+ return;
+ THashMap<String, BranchPoint[]> oldBranchPointMap = combined.get(module.getName());
+ if(oldBranchPointMap == null) {
+ oldBranchPointMap = new THashMap<String, BranchPoint[]>();
+ combined.put(module.getName(), oldBranchPointMap);
+ }
+ THashMap<String, BranchPoint[]> oldBranchPointMap_ = oldBranchPointMap;
+ branchPointMap.forEachEntry(new TObjectObjectProcedure<String, BranchPoint[]>() {
+ @Override
+ public boolean execute(String name, BranchPoint[] branchPoints) {
+ BranchPoint[] oldBranchPoints = oldBranchPointMap_.get(name);
+ if(oldBranchPoints == null) {
+ if (persistOverBranchpointReset) {
+ // Clone the branchPoints array so that if will last over a reset
+ BranchPoint[] clonedBranchPoints = cloneBranchPoints(branchPoints);
+ oldBranchPointMap_.put(name, clonedBranchPoints);
+ } else {
+ // No need to copy so resetting branchpoints will reset this as well
+ oldBranchPointMap_.put(name, branchPoints);
+ }
+ } else {
+ combineCounters(oldBranchPoints, branchPoints);
+ }
+ return true;
+ }
+ });
+ }
+
+ private static BranchPoint[] cloneBranchPoints(BranchPoint[] oldBranchPoints) {
+ BranchPoint[] newBranchPoints = new BranchPoint[oldBranchPoints.length];
+ for (int i = 0; i < oldBranchPoints.length; i++) {
+ BranchPoint bp = oldBranchPoints[i];
+ BranchPoint[] children = cloneBranchPoints(bp.getChildren());
+ newBranchPoints[i] = new BranchPoint(bp.getLocation(), bp.getCodeSize(), children);
+ }
+ return newBranchPoints;
+ }
+
+ private static void combineCounters(BranchPoint[] oldBranchPoints, BranchPoint[] branchPoints) {
+ if(oldBranchPoints.length != branchPoints.length)
+ throw new IllegalArgumentException("Incompatible branch points.");
+ for(int i=0;i<branchPoints.length;++i) {
+ BranchPoint oldBP = oldBranchPoints[i];
+ BranchPoint newBP = branchPoints[i];
+ if(oldBP.getLocation() != newBP.getLocation())
+ throw new IllegalArgumentException("Incompatible branch points.");
+ oldBP.incrementVisitCounter(newBP.getVisitCounter());
+ combineCounters(oldBP.getChildren(), newBP.getChildren());
+ }
+ }
+
+ public CombinedCoverage getCoverage() {
+ THashMap<String,ModuleCoverage> moduleCoverages =
+ new THashMap<String,ModuleCoverage>();
+ combined.forEachEntry(new TObjectObjectProcedure<String, THashMap<String, BranchPoint[]>>() {
+ @Override
+ public boolean execute(String name, THashMap<String, BranchPoint[]> branchPoints) {
+ moduleCoverages.put(name, CoverageUtils.getCoverage(name, branchPoints));
+ return true;
+ }
+ });
+ return CoverageUtils.combineCoverages(moduleCoverages);
+ }
+}