1 package org.simantics.scl.compiler.module.coverage;
3 import org.simantics.scl.compiler.module.Module;
4 import org.simantics.scl.runtime.profiling.BranchPoint;
6 import gnu.trove.map.hash.THashMap;
7 import gnu.trove.procedure.TObjectObjectProcedure;
9 public class CoverageBuilder {
10 THashMap<String, THashMap<String, BranchPoint[]>> combined =
11 new THashMap<String, THashMap<String, BranchPoint[]>>();
13 public void addCoverage(Module module, boolean persistOverBranchpointReset) {
14 THashMap<String, BranchPoint[]> branchPointMap = module.getBranchPoints();
15 if(branchPointMap == null)
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);
22 THashMap<String, BranchPoint[]> oldBranchPointMap_ = oldBranchPointMap;
23 branchPointMap.forEachEntry(new TObjectObjectProcedure<String, BranchPoint[]>() {
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);
33 // No need to copy so resetting branchpoints will reset this as well
34 oldBranchPointMap_.put(name, branchPoints);
37 combineCounters(oldBranchPoints, branchPoints);
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);
51 return newBranchPoints;
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());
67 public CombinedCoverage getCoverage() {
68 THashMap<String,ModuleCoverage> moduleCoverages =
69 new THashMap<String,ModuleCoverage>();
70 combined.forEachEntry(new TObjectObjectProcedure<String, THashMap<String, BranchPoint[]>>() {
72 public boolean execute(String name, THashMap<String, BranchPoint[]> branchPoints) {
73 moduleCoverages.put(name, CoverageUtils.getCoverage(name, branchPoints));
77 return CoverageUtils.combineCoverages(moduleCoverages);