Commit 14a9bdd2 authored by Christoph Reichenbach's avatar Christoph Reichenbach

Updated BCGen documentation / renamed some bits for clarity

parent fc3578f5
......@@ -6,7 +6,12 @@ import java.util.stream.Collectors;
/**
* Packaged benchmark with datastructure, for easy re-running
* Toplevel class for constructing and running benchmarks.
*
* As long as you are generating benchmarks from traces OR using the default synthesis strategy, you shouldn't
* be calling anything else.
*
* Use the factory methids LIST(), MAP(), SET() to create a BCBenchmarkPackage.
*/
public class BCBenchmarkPackage<T> {
private static int unique_ids_counter = 0; // for BCBenchStep
......@@ -14,10 +19,15 @@ public class BCBenchmarkPackage<T> {
public static final int MAX_TRACE_LENGTH = 100000; // max number of individual entries permitted
private static final String GENTYPE_SYNTH = "Synth";
private static final String GENTYPE_TRACE = "Trace:"; // FIXME: for trace generation later
private static final String GENTYPE_TRACE = "Trace:";
/**
* For simulating traces that are too long, we break them into several BCBenchSteps.
* A complete or partial benchmark.
*
* This class wraps around BenchmarkGenerator to support traces longer than MAX_TRACE_LENGTH,
* which BCBenchmarkPackage breaks into multiple BCBenchSteps.
*
* FIXME: BenchmarkGenerator already has support for this, why do we need it here again?
*/
private class BCBenchStep {
boolean use_global_datastructure_size;
......@@ -26,7 +36,7 @@ public class BCBenchmarkPackage<T> {
int seed;
BenchmarkGenerator<T> generator = null;
MethodSelectionStrategy.Trace trace_method_selector = null; // only used for GENTYPE_TRACE
BCBenchmarkInfo<T> benchinfo;
BCBenchmarkWithTrace<T> benchstate;
public BCBenchStep(int tsize, int sd, boolean dsize_global) {
this.seed = sd;
......@@ -63,18 +73,18 @@ public class BCBenchmarkPackage<T> {
// BCBenchmarkPackage.this.datastructure to be in the correct simulation stetae!
public void
prepareBenchmark() {
this.benchinfo = this.generator.gen("TraceX_" + this.uid,
this.benchstate = this.generator.gen("TraceX_" + this.uid,
this.trace_size, this.seed, this.seed);
}
public void
runBenchmark() {
this.benchinfo.getBenchmark().run(blackhole, datastructure);
this.benchstate.getBenchmark().run(blackhole, datastructure);
}
public void
clearAll() {
this.benchinfo = null;
this.benchstate = null;
}
public void
......@@ -102,11 +112,11 @@ public class BCBenchmarkPackage<T> {
protected BCGen<T> gen;
protected Blackhole blackhole = new Blackhole("Today's password is swordfish. I understand instantiating Blackholes directly is dangerous.");
List<BCBenchStep> bench_steps = new ArrayList<BCBenchStep>();
protected BCBenchmarkInfo<T> combined_benchinfo = null;
protected BCBenchmarkWithTrace<T> combined_benchstate = null;
private void
setupBenchmarksIfNeeded() {
if (this.combined_benchinfo == null) {
if (this.combined_benchstate == null) {
List<String> trace = new ArrayList<>();
this.clearDatastructure();
......@@ -114,17 +124,17 @@ public class BCBenchmarkPackage<T> {
for (BCBenchStep step : this.bench_steps) {
step.initGenerator();
step.prepareBenchmark();
trace.addAll(step.benchinfo.getTrace());
trace.addAll(step.benchstate.getTrace());
}
this.combined_benchinfo = new BCBenchmarkInfo<T>(this.datastructure);
this.combined_benchinfo.setTrace(trace);
this.combined_benchstate = new BCBenchmarkWithTrace<T>(this.datastructure);
this.combined_benchstate.setTrace(trace);
}
}
public BCBenchmarkInfo
public BCBenchmarkWithTrace
getBenchmarkInfo() {
this.setupBenchmarksIfNeeded();
return this.combined_benchinfo;
return this.combined_benchstate;
}
public BCBenchmark
......@@ -285,7 +295,7 @@ public class BCBenchmarkPackage<T> {
step.reset();
}
this.clearAll();
this.combined_benchinfo = null;
this.combined_benchstate = null;
this.setupBenchmarksIfNeeded();
//System.err.println("Pondering FILL" + size);
if (this.bench_steps.size() == 1) {
......@@ -309,7 +319,7 @@ public class BCBenchmarkPackage<T> {
clearAll() {
this.blackhole.evaporate("Yes, I am Stephen Hawking, and know a thing or two about black holes.");
this.clearDatastructure();
this.combined_benchinfo = null;
this.combined_benchstate = null;
for (BCBenchStep step : this.bench_steps) {
step.clearAll();
}
......
......@@ -4,20 +4,22 @@ import java.util.ArrayList;
import java.util.List;
/**
* Result of a benchmark generation pass.
* A synthesised benchmark and its execution trace, plus the benchmark's simulated state.
*
* Used both during benchmark synthesis (benchmark == null) and afterwards (benchmark != null).
*
* Including:
* - benchmark as BCBenchmark object
* - final simulation state
* - runnable benchmark class as BCBenchmark object
* - list of all operations
* - simulated execution state
*/
public final class BCBenchmarkInfo<S> {
public final class BCBenchmarkWithTrace<S> {
private BCBenchmark benchmark;
private List<String> op_names = new ArrayList<>();
private S state;
public
BCBenchmarkInfo(S state) {
BCBenchmarkWithTrace(S state) {
this.state = state;
}
......@@ -31,6 +33,9 @@ public final class BCBenchmarkInfo<S> {
this.op_names.add(op);
}
/**
* List of operation names that will be executed when running the benchmark
*/
public List<String>
getTrace() {
return this.op_names;
......@@ -41,11 +46,29 @@ public final class BCBenchmarkInfo<S> {
this.op_names = trace;
}
/**
* Executable benchmark.
*
* Initially "null"; the benchmark is only set once benchmark synthesis is completed.
*/
public BCBenchmark
getBenchmark() {
return this.benchmark;
}
/**
* The benchmark's "simulation state".
*
* During benchmark synthesis, the simulation state reflects accurately what a container will
* look like after executing the (currently synthesised) operations.
* After benchmark synthesis, the following invariant holds:
*
* <pre>
* Object collection = new ...; // empty collection
* this.getBenchmark().run(blackhole, collection);
* this.getSimulationState().equals(collection);
* </pre>
*/
public S
getSimulationState() {
return this.state;
......
......@@ -12,7 +12,12 @@ import java.lang.reflect.Method;
import java.lang.reflect.Type;
/**
* Benchmark for interfaces
* General-purpose benchmark synthesiser for interfaces.
*
* Use the higher-level BCBenchmarkPackage whenever possible; this class handles the lower-level synthesis
* and provides a less convenient interface.
*
* The mechanism for synthesising the benchmark is controlled by "MethodSelectionStrategy method_selector".
*/
public abstract class BenchmarkGenerator<S> {
// if something generates an iterator, concume it by:
......@@ -262,7 +267,7 @@ public abstract class BenchmarkGenerator<S> {
* @param insn_seed Random seed for generating the sequence of instructions
* @param data_seed Random seed for generating the initial contents of the container
*/
public BCBenchmarkInfo<S>
public BCBenchmarkWithTrace<S>
gen(String pkgname, int length, int insn_seed, int data_seed) {
Random r = new Random(insn_seed);
this.random = new Random(insn_seed + 1001);
......@@ -292,31 +297,7 @@ public abstract class BenchmarkGenerator<S> {
S state = this.state_override == null ? this.initState(data_seed) : this.state_override;
MethodProbabilityTable mpt = new MethodProbabilityTable(state, r);
BCBenchmarkInfo<S> info = new BCBenchmarkInfo<S>(state);
// // run(bhole, target)
// {
// mv = cw.visitMethod(ACC_PUBLIC, "run",
// "(L" + BCBenchmark.BHOLE_NAME.replace('.', '/') + ";Ljava/lang/Object;)V",
// null, null);
// mv.visitCode();
// mv.visitVarInsn(ALOAD, 2);
// // cast target to desired interface type
// mv.visitTypeInsn(CHECKCAST, target_typename_internal);
// mv.visitVarInsn(ASTORE, LOCAL_TARGET);
// // generate all code
// for (int i = 0; i < length; i++) {
// final Label lb = new Label();
// mv.visitLabel(lb);
// mv.visitLineNumber(i, lb);
// this.generateLineOfCode(mv, mpt, state, info);
// }
// mv.visitInsn(RETURN);
// mv.visitMaxs(0, 0); // autocomputed
// mv.visitEnd();
// }
BCBenchmarkWithTrace<S> info = new BCBenchmarkWithTrace<S>(state);
ArrayList<String> executors = new ArrayList<>();
......@@ -477,7 +458,7 @@ public abstract class BenchmarkGenerator<S> {
* Write fresh static method that executes 'steps' next execution steps
*/
public String // return method name
writeNewExecutorMethod(MethodProbabilityTable mpt, S state, BCBenchmarkInfo info, int steps) {
writeNewExecutorMethod(MethodProbabilityTable mpt, S state, BCBenchmarkWithTrace info, int steps) {
final String method_name = "r_" + (this.runners++);
MethodVisitor mv = this.cw.visitMethod(ACC_PRIVATE | ACC_STATIC, method_name,
this.getExecutorSig(),
......@@ -502,7 +483,7 @@ public abstract class BenchmarkGenerator<S> {
public void
generateLineOfCode(MethodVisitor mv, MethodProbabilityTable mpt,
S state, BCBenchmarkInfo<S> info) {
S state, BCBenchmarkWithTrace<S> info) {
mpt.updateEligibility(); // hidden use of state
int method_id = this.method_selector.selectNextMethod(mpt);
if (method_id == MethodSelectionStrategy.SKIP) {
......
......@@ -4,7 +4,7 @@ import java.util.List;
import java.util.Iterator;
/**
* Strategy for choosing the next method
* Strategy for choosing the next method during BenchmarkGenerator.gen().
*/
interface MethodSelectionStrategy {
public static final int SKIP = -1; // skip method
......@@ -42,6 +42,9 @@ interface MethodSelectionStrategy {
return new Trace(trace);
};
/**
* Probability distribution generated from an externally loaded trace
*/
public static class Trace implements MethodSelectionStrategy {
private List<String> trace;
private Iterator<String> trace_iterator = null;
......
......@@ -17,7 +17,7 @@ public class BCBenchmarkGeneratorTest {
return new Blackhole("Today's password is swordfish. I understand instantiating Blackholes directly is dangerous.");
}
static void checkBenchmark(BCBenchmarkInfo<? extends Object> info,
static void checkBenchmark(BCBenchmarkWithTrace<? extends Object> info,
int seed,
Object object) {
BCBenchmark bcr = info.getBenchmark();
......@@ -35,7 +35,7 @@ public class BCBenchmarkGeneratorTest {
for (int i = 0; i < 1000; i++) {
ListBenchmarkGenerator lb = new ListBenchmarkGenerator(0);
BCBenchmarkInfo<List<Object>> bcri = lb.gen("test", 100, i, i); // we could use different seeds
BCBenchmarkWithTrace<List<Object>> bcri = lb.gen("test", 100, i, i); // we could use different seeds
checkBenchmark(bcri, i, new ArrayList<Integer>());
checkBenchmark(bcri, i, new LinkedList<Integer>());
......@@ -48,7 +48,7 @@ public class BCBenchmarkGeneratorTest {
for (int i = 0; i < 1000; i++) {
SetBenchmarkGenerator sb = new SetBenchmarkGenerator(0);
BCBenchmarkInfo<Set<Object>> bcri = sb.gen("test", 100, i, i); // we could use different seeds
BCBenchmarkWithTrace<Set<Object>> bcri = sb.gen("test", 100, i, i); // we could use different seeds
checkBenchmark(bcri, i, new HashSet<Integer>());
checkBenchmark(bcri, i, new LinkedHashSet<Integer>());
......@@ -61,7 +61,7 @@ public class BCBenchmarkGeneratorTest {
for (int i = 0; i < 1000; i++) {
MapBenchmarkGenerator mb = new MapBenchmarkGenerator(0);
BCBenchmarkInfo<Map<Object, Object>> bcri = mb.gen("test", 100, i, i); // we could use different seeds
BCBenchmarkWithTrace<Map<Object, Object>> bcri = mb.gen("test", 100, i, i); // we could use different seeds
checkBenchmark(bcri, i, new HashMap<Integer, Integer>());
checkBenchmark(bcri, i, new LinkedHashMap<Integer, Integer>());
......@@ -73,7 +73,7 @@ public class BCBenchmarkGeneratorTest {
for (int i = 0; i < 1000; i++) {
ListBenchmarkGenerator lb = new ListBenchmarkGenerator(10);
BCBenchmarkInfo<List<Object>> bcri = lb.gen("test2", 100, i, i); // we could use different seeds
BCBenchmarkWithTrace<List<Object>> bcri = lb.gen("test2", 100, i, i); // we could use different seeds
List<Object> list;
list = new ArrayList<>();
......@@ -93,7 +93,7 @@ public class BCBenchmarkGeneratorTest {
for (int i = 0; i < 1000; i++) {
SetBenchmarkGenerator sb = new SetBenchmarkGenerator(10);
BCBenchmarkInfo<Set<Object>> bcri = sb.gen("test2", 100, i, i);
BCBenchmarkWithTrace<Set<Object>> bcri = sb.gen("test2", 100, i, i);
Set<Object> set;
set = new HashSet<>();
......@@ -113,7 +113,7 @@ public class BCBenchmarkGeneratorTest {
for (int i = 0; i < 1000; i++) {
MapBenchmarkGenerator mb = new MapBenchmarkGenerator(10);
BCBenchmarkInfo<Map<Object, Object>> bcri = mb.gen("test2", 100, i, i);
BCBenchmarkWithTrace<Map<Object, Object>> bcri = mb.gen("test2", 100, i, i);
Map<Object, Object> map;
map = new HashMap<>();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment