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> combined = new THashMap>(); public void addCoverage(Module module, boolean persistOverBranchpointReset) { THashMap branchPointMap = module.getBranchPoints(); if(branchPointMap == null) return; THashMap oldBranchPointMap = combined.get(module.getName()); if(oldBranchPointMap == null) { oldBranchPointMap = new THashMap(); combined.put(module.getName(), oldBranchPointMap); } THashMap oldBranchPointMap_ = oldBranchPointMap; branchPointMap.forEachEntry(new TObjectObjectProcedure() { @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 moduleCoverages = new THashMap(); combined.forEachEntry(new TObjectObjectProcedure>() { @Override public boolean execute(String name, THashMap branchPoints) { moduleCoverages.put(name, CoverageUtils.getCoverage(name, branchPoints)); return true; } }); return CoverageUtils.combineCoverages(moduleCoverages); } }