Directly inject probe array instance into companion class

This obsolets the runtime access hacks.
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java
index 68f25fc..d6c7999 100644
--- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java
+++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/CoverageTransformerTest.java
@@ -222,7 +222,7 @@
 	}
 
 	private CoverageTransformer createTransformer() {
-		return new CoverageTransformer(runtime, options, recorder);
+		return new CoverageTransformer(runtime, options, null, recorder);
 	}
 
 	private static byte[] getClassData(Class<?> clazz) throws IOException {
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java
index d2175c3..724f5d4 100644
--- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java
+++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/CoverageTransformer.java
@@ -19,6 +19,7 @@
 import org.jacoco.core.instr.Instrumenter;
 import org.jacoco.core.runtime.AgentOptions;
 import org.jacoco.core.runtime.IRuntime;
+import org.jacoco.core.runtime.RuntimeData;
 import org.jacoco.core.runtime.WildcardMatcher;
 
 /**
@@ -33,6 +34,8 @@
 		AGENT_PREFIX = toVMName(name.substring(0, name.lastIndexOf('.')));
 	}
 
+	private final RuntimeData runtimeData;
+
 	private final Instrumenter instrumenter;
 
 	private final IExceptionLogger logger;
@@ -58,7 +61,9 @@
 	 *            logger for exceptions during instrumentation
 	 */
 	public CoverageTransformer(final IRuntime runtime,
-			final AgentOptions options, final IExceptionLogger logger) {
+			final AgentOptions options, final RuntimeData runtimeData,
+			final IExceptionLogger logger) {
+		this.runtimeData = runtimeData;
 		this.instrumenter = new Instrumenter(runtime);
 		this.logger = logger;
 		// Class names will be reported in VM notation:
@@ -90,7 +95,8 @@
 
 		try {
 			classFileDumper.dump(classname, classfileBuffer);
-			return instrumenter.instrument(classfileBuffer, classname, loader);
+			return instrumenter.instrument(classfileBuffer, classname, loader,
+					runtimeData);
 		} catch (final Exception ex) {
 			final IllegalClassFormatException wrapper = new IllegalClassFormatException(
 					ex.getMessage());
diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/PreMain.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/PreMain.java
index e87d203..227ef3d 100644
--- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/PreMain.java
+++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/PreMain.java
@@ -47,7 +47,7 @@
 		final IRuntime runtime = createRuntime(inst);
 		runtime.startup(agent.getData());
 		inst.addTransformer(new CoverageTransformer(runtime, agentOptions,
-				IExceptionLogger.SYSTEM_ERR));
+				agent.getData(), IExceptionLogger.SYSTEM_ERR));
 	}
 
 	private static IRuntime createRuntime(final Instrumentation inst)
diff --git a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
index d3b7861..6130f90 100644
--- a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
+++ b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
@@ -31,6 +31,7 @@
 import org.jacoco.core.internal.instr.ProbeArrayStrategyFactory;
 import org.jacoco.core.internal.instr.SignatureRemover;
 import org.jacoco.core.runtime.IExecutionDataAccessorGenerator;
+import org.jacoco.core.runtime.RuntimeData;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
@@ -77,11 +78,11 @@
 	 * 
 	 */
 	public byte[] instrument(final ClassReader reader) {
-		return instrument(reader, null);
+		return instrument(reader, null, null);
 	}
 
 	public byte[] instrument(final ClassReader reader,
-			final ClassLoader classLoader) {
+			final ClassLoader classLoader, final RuntimeData runtimeData) {
 		final ClassWriter writer = new ClassWriter(reader, 0);
 		final IProbeArrayStrategy strategy;
 		if (classLoader == null) {
@@ -90,7 +91,7 @@
 		} else {
 			final long classId = CRC64.checksum(reader.b);
 			strategy = new CompanionClassStrategy(reader.getClassName(),
-					classId, accessorGenerator, classLoader);
+					classId, classLoader, runtimeData);
 		}
 		final ClassVisitor visitor = new ClassProbesAdapter(
 				new ClassInstrumenter(strategy, writer), true);
@@ -111,13 +112,14 @@
 	 */
 	public byte[] instrument(final byte[] buffer, final String name)
 			throws IOException {
-		return instrument(buffer, name, null);
+		return instrument(buffer, name, null, null);
 	}
 
 	public byte[] instrument(final byte[] buffer, final String name,
-			final ClassLoader classLoader) throws IOException {
+			final ClassLoader classLoader, final RuntimeData runtimeData)
+			throws IOException {
 		try {
-			return instrument(new ClassReader(buffer), classLoader);
+			return instrument(new ClassReader(buffer), classLoader, runtimeData);
 		} catch (final RuntimeException e) {
 			throw instrumentError(name, e);
 		}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/CompanionClassStrategy.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/CompanionClassStrategy.java
index 458e2fa..d95ad59 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/CompanionClassStrategy.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/CompanionClassStrategy.java
@@ -14,7 +14,7 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
-import org.jacoco.core.runtime.IExecutionDataAccessorGenerator;
+import org.jacoco.core.runtime.RuntimeData;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.MethodVisitor;
@@ -43,18 +43,17 @@
 	private final String className;
 	private final String companionName;
 	private final long classId;
-	private final IExecutionDataAccessorGenerator accessorGenerator;
 	private final ClassLoader classLoader;
+	private final RuntimeData runtimeData;
 
 	public CompanionClassStrategy(final String className, final long classId,
-			final IExecutionDataAccessorGenerator accessorGenerator,
-			final ClassLoader classLoader) {
+			final ClassLoader classLoader, final RuntimeData runtimeData) {
 		this.className = className;
 		this.classLoader = classLoader;
 		this.companionName = String.format("%s$jacoco%016x", className,
 				Long.valueOf(classId));
 		this.classId = classId;
-		this.accessorGenerator = accessorGenerator;
+		this.runtimeData = runtimeData;
 	}
 
 	public int storeInstance(final MethodVisitor mv, final int variable) {
@@ -66,35 +65,26 @@
 
 	public void addMembers(final ClassVisitor cv, final int probeCount) {
 		// we reuse this to create and load the companion class
-		loadCompanionClass(createCompanionClass(probeCount));
+		loadCompanionClass(createCompanionClass(), probeCount);
 	}
 
-	private byte[] createCompanionClass(final int probeCount) {
+	private byte[] createCompanionClass() {
 		final ClassWriter cw = new ClassWriter(0);
 
-		cw.visit(Opcodes.V1_1, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL,
-				companionName, null, "java/lang/Object", null);
+		cw.visit(Opcodes.V1_1, Opcodes.ACC_SYNTHETIC | Opcodes.ACC_PUBLIC
+				| Opcodes.ACC_FINAL, companionName, null, "java/lang/Object",
+				null);
 
-		cw.visitField(Opcodes.ACC_STATIC | Opcodes.ACC_TRANSIENT
-				| Opcodes.ACC_FINAL, InstrSupport.DATAFIELD_NAME,
+		cw.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
+				| Opcodes.ACC_TRANSIENT, InstrSupport.DATAFIELD_NAME,
 				InstrSupport.DATAFIELD_DESC, null, null);
 
-		final MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>",
-				"()V", null, null);
-		mv.visitCode();
-		final int stackSize = accessorGenerator.generateDataAccessor(classId,
-				className, probeCount, mv);
-		mv.visitFieldInsn(Opcodes.PUTSTATIC, companionName,
-				InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC);
-		mv.visitInsn(Opcodes.RETURN);
-		mv.visitMaxs(stackSize, 0);
-		mv.visitEnd();
-
 		cw.visitEnd();
 		return cw.toByteArray();
 	}
 
-	private void loadCompanionClass(final byte[] definition) {
+	private void loadCompanionClass(final byte[] definition,
+			final int probeCount) {
 		try {
 			classLoader.loadClass(companionName);
 			// companion does already exist:
@@ -103,15 +93,22 @@
 			// expected
 		}
 		try {
-			DEFINE_CLASS.invoke(classLoader, companionName.replace('/', '.'),
-					definition, Integer.valueOf(0),
-					Integer.valueOf(definition.length));
+			final Class<?> companion = (Class<?>) DEFINE_CLASS.invoke(
+					classLoader, companionName.replace('/', '.'), definition,
+					Integer.valueOf(0), Integer.valueOf(definition.length));
+
+			final boolean[] probes = runtimeData.getExecutionData(
+					Long.valueOf(classId), className, probeCount).getProbes();
+			companion.getField(InstrSupport.DATAFIELD_NAME).set(null, probes);
+
 		} catch (final IllegalArgumentException e) {
 			throw new RuntimeException(e);
 		} catch (final IllegalAccessException e) {
 			throw new RuntimeException(e);
 		} catch (final InvocationTargetException e) {
 			throw new RuntimeException(e.getTargetException());
+		} catch (final NoSuchFieldException e) {
+			throw new RuntimeException(e);
 		}
 	}