package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.CodeGen; import java.util.Map; import java.util.TreeMap; import org.junit.runner.*; import org.junit.runner.notification.*; // Run existing tests and sum actual allocations, including ones without goldens. // Helpers call record after allocation; ordinary JUnit runs collect nothing. public class SpillStats extends RunListener { private static SpillStats ACTIVE; private Description _test; private int _qualityFailures; private final Map _totals = new TreeMap<>(); @Override public void testStarted(Description test) { _test = test; } public static void record(CodeGen code, String cohort, String cpu, String abi) { if( ACTIVE==null ) return; String test = ACTIVE._test.getTestClass().getSimpleName()+"."+ACTIVE._test.getMethodName(); for( String key : new String[]{cohort+","+cpu+","+abi,cohort+",ALL,ALL"} ) { long[] sum = ACTIVE._totals.computeIfAbsent(key,k -> new long[3]); sum[0]++; sum[1] += code._regAlloc._spills; sum[2] += code._regAlloc._spillScaled; } System.out.println("allocation,"+cohort+","+test+","+cpu+","+abi+","+ code._regAlloc._spills+","+code._regAlloc._spillScaled); } // The same native helpers serve old and new program cohorts. public static void recordNative(CodeGen code, String cpu, String abi) { String cohort = ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter23Test.class ? "Chapter23" : ACTIVE!=null && ACTIVE._test.getTestClass()==Chapter22Test.class ? "Chapter22" : "Chapter21"; record(code,cohort,cpu,abi); } // Keep running every CPU and native result check when measuring quality. // A changed golden still makes spill-stats fail at the end. public static void checkSpills(int expected, int actual) { if( expected==-1 ) return; try { org.junit.Assert.assertEquals("Expect spills:",expected,actual,Math.max(1,expected>>3)); } catch( AssertionError error ) { if( ACTIVE==null ) throw error; ACTIVE._qualityFailures++; System.err.println(ACTIVE._test+": "+error.getMessage()); } } public static void main(String[] args) throws ClassNotFoundException { if( args.length==0 ) args = new String[]{"Chapter20Test","Chapter21Test","Chapter21AllocTest","Chapter22Test","Chapter23Test","Chapter23AllocTest","BrainFuckTest","MergeSortTest"}; Class[] tests = new Class[args.length]; for( int i=0; i