aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src/org
diff options
context:
space:
mode:
Diffstat (limited to 'org.jacoco.core/src/org')
-rw-r--r--org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java8
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java52
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java48
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java8
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/IExecutionData.java129
-rw-r--r--org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java4
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java8
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java17
-rw-r--r--org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java4
-rw-r--r--org.jacoco.core/src/org/jacoco/core/runtime/OfflineInstrumentationAccessGenerator.java6
-rw-r--r--org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java20
11 files changed, 252 insertions, 52 deletions
diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
index 76b7be3c..7759b89d 100644
--- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
@@ -20,7 +20,7 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
-import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.IExecutionData;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.internal.ContentTypeDetector;
import org.jacoco.core.internal.InputStreams;
@@ -78,16 +78,18 @@ public class Analyzer {
*/
private ClassVisitor createAnalyzingVisitor(final long classid,
final String className) {
- final ExecutionData data = executionData.get(classid);
+ // BEGIN android-change
+ final IExecutionData data = executionData.get(classid);
final boolean[] probes;
final boolean noMatch;
if (data == null) {
probes = null;
noMatch = executionData.contains(className);
} else {
- probes = data.getProbes();
+ probes = data.getProbesCopy();
noMatch = false;
}
+ // END android-change
final ClassCoverageImpl coverage = new ClassCoverageImpl(className,
classid, noMatch);
final ClassAnalyzer analyzer = new ClassAnalyzer(coverage, probes,
diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java
index d98775eb..a728e033 100644
--- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java
+++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionData.java
@@ -20,7 +20,9 @@ import java.util.Arrays;
* has to be taken about the probe data array of type <code>boolean[]</code>
* which can be modified.
*/
-public final class ExecutionData {
+// BEGIN android-change
+public final class ExecutionData implements IExecutionData {
+// END android-change
private final long id;
@@ -81,15 +83,43 @@ public final class ExecutionData {
return name;
}
+ // BEGIN android-change
/**
- * Returns the execution data probes. A value of <code>true</code> indicates
- * that the corresponding probe was executed.
+ * Returns a copy of the current probe values.
+ *
+ * @return copy of the probe array
+ */
+ public boolean[] getProbesCopy() {
+ return Arrays.copyOf(probes, probes.length);
+ }
+
+ /**
+ * The number of probes in this ExecutionData.
+ *
+ * @return the number of probes
+ */
+ public int getProbeCount() {
+ return probes.length;
+ }
+
+ /**
+ * Returns the execution data probe for a given index. A value of
+ * <code>true</code> indicates that the corresponding probe was
+ * executed.
*
* @return probe data
*/
- public boolean[] getProbes() {
- return probes;
+ public boolean getProbe(final int index) {
+ return probes[index];
+ }
+
+ /**
+ * Sets the execution data probe for a given index to <code>true</code>.
+ */
+ public void setProbe(final int index) {
+ probes[index] = true;
}
+ // END android-change
/**
* Sets all probes to <code>false</code>.
@@ -127,7 +157,9 @@ public final class ExecutionData {
* @param other
* execution data to merge
*/
- public void merge(final ExecutionData other) {
+ // BEGIN android-change
+ public void merge(final IExecutionData other) {
+ // END android-change
merge(other, true);
}
@@ -154,10 +186,12 @@ public final class ExecutionData {
* @param flag
* merge mode
*/
- public void merge(final ExecutionData other, final boolean flag) {
+ public void merge(final IExecutionData other, final boolean flag) {
+ // BEGIN android-change
assertCompatibility(other.getId(), other.getName(),
- other.getProbes().length);
- final boolean[] otherData = other.getProbes();
+ other.getProbeCount());
+ final boolean[] otherData = other.getProbesCopy();
+ // END android-change
for (int i = 0; i < probes.length; i++) {
if (otherData[i]) {
probes[i] = flag;
diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java
index 3e567a3b..ce0bec47 100644
--- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java
+++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataStore.java
@@ -28,7 +28,9 @@ import java.util.Set;
*/
public final class ExecutionDataStore implements IExecutionDataVisitor {
- private final Map<Long, ExecutionData> entries = new HashMap<Long, ExecutionData>();
+ // BEGIN android-change
+ private final Map<Long, IExecutionData> entries = new HashMap<Long, IExecutionData>();
+ // END android-change
private final Set<String> names = new HashSet<String>();
@@ -44,9 +46,11 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* to a corresponding one, that is already contained
* @see ExecutionData#assertCompatibility(long, String, int)
*/
- public void put(final ExecutionData data) throws IllegalStateException {
+ // BEGIN android-change
+ public void put(final IExecutionData data) throws IllegalStateException {
final Long id = Long.valueOf(data.getId());
- final ExecutionData entry = entries.get(id);
+ final IExecutionData entry = entries.get(id);
+ // END android-change
if (entry == null) {
entries.put(id, data);
names.add(data.getName());
@@ -68,9 +72,11 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* to a corresponding one, that is already contained
* @see ExecutionData#assertCompatibility(long, String, int)
*/
- public void subtract(final ExecutionData data) throws IllegalStateException {
+ // BEGIN android-change
+ public void subtract(final IExecutionData data) throws IllegalStateException {
final Long id = Long.valueOf(data.getId());
- final ExecutionData entry = entries.get(id);
+ final IExecutionData entry = entries.get(id);
+ // END android-change
if (entry != null) {
entry.merge(data, false);
}
@@ -84,7 +90,9 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* @see #subtract(ExecutionData)
*/
public void subtract(final ExecutionDataStore store) {
- for (final ExecutionData data : store.getContents()) {
+ // BEGIN android-change
+ for (final IExecutionData data : store.getContents()) {
+ // END android-change
subtract(data);
}
}
@@ -97,7 +105,9 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* class id
* @return execution data or <code>null</code>
*/
- public ExecutionData get(final long id) {
+ // BEGIN android-change
+ public IExecutionData get(final long id) {
+ // END android-change
return entries.get(Long.valueOf(id));
}
@@ -126,9 +136,11 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* probe data length
* @return execution data
*/
- public ExecutionData get(final Long id, final String name,
+ // BEGIN android-change
+ public IExecutionData get(final Long id, final String name,
final int probecount) {
- ExecutionData entry = entries.get(id);
+ IExecutionData entry = entries.get(id);
+ // END android-change
if (entry == null) {
entry = new ExecutionData(id.longValue(), name, probecount);
entries.put(id, entry);
@@ -144,7 +156,9 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* execution data objects itself are not removed.
*/
public void reset() {
- for (final ExecutionData executionData : this.entries.values()) {
+ // BEGIN android-change
+ for (final IExecutionData executionData : this.entries.values()) {
+ // END android-change
executionData.reset();
}
}
@@ -154,9 +168,11 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
*
* @return current contents
*/
- public Collection<ExecutionData> getContents() {
- return new ArrayList<ExecutionData>(entries.values());
+ // BEGIN android-change
+ public Collection<IExecutionData> getContents() {
+ return new ArrayList<IExecutionData>(entries.values());
}
+ // END android-change
/**
* Writes the content of the store to the given visitor interface.
@@ -165,14 +181,18 @@ public final class ExecutionDataStore implements IExecutionDataVisitor {
* interface to write content to
*/
public void accept(final IExecutionDataVisitor visitor) {
- for (final ExecutionData data : getContents()) {
+ // BEGIN android-change
+ for (final IExecutionData data : getContents()) {
+ // END android-change
visitor.visitClassExecution(data);
}
}
// === IExecutionDataVisitor ===
- public void visitClassExecution(final ExecutionData data) {
+ // BEGIN android-change
+ public void visitClassExecution(final IExecutionData data) {
+ // END android-change
put(data);
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java
index e697dda3..bdf3445d 100644
--- a/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java
+++ b/org.jacoco.core/src/org/jacoco/core/data/ExecutionDataWriter.java
@@ -94,13 +94,17 @@ public class ExecutionDataWriter implements ISessionInfoVisitor,
}
}
- public void visitClassExecution(final ExecutionData data) {
+ // BEGIN android-change
+ public void visitClassExecution(final IExecutionData data) {
+ // END android-change
if (data.hasHits()) {
try {
out.writeByte(BLOCK_EXECUTIONDATA);
out.writeLong(data.getId());
out.writeUTF(data.getName());
- out.writeBooleanArray(data.getProbes());
+ // BEGIN android-change
+ out.writeBooleanArray(data.getProbesCopy());
+ // END android-change
} catch (final IOException e) {
throw new RuntimeException(e);
}
diff --git a/org.jacoco.core/src/org/jacoco/core/data/IExecutionData.java b/org.jacoco.core/src/org/jacoco/core/data/IExecutionData.java
new file mode 100644
index 00000000..289c3726
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/data/IExecutionData.java
@@ -0,0 +1,129 @@
+// BEGIN android-change
+package org.jacoco.core.data;
+
+/**
+ * Interface for interacting with execution data for a single Java class.
+ */
+public interface IExecutionData {
+
+ /**
+ * Return the unique identifier for this class. The identifier is the CRC64
+ * checksum of the raw class file definition.
+ *
+ * @return class identifier
+ */
+ public abstract long getId();
+
+ /**
+ * The VM name of the class.
+ *
+ * @return VM name
+ */
+ public abstract String getName();
+
+ /**
+ * The number of instrumentation probes for this class.
+ *
+ * @return number of probes
+ */
+ public abstract int getProbeCount();
+
+ /**
+ * Returns a copy of the probe data as a boolean array.
+ *
+ * Changes to the returned array will not be reflected in the execution data.
+ *
+ * @return copy of the probe data
+ */
+ public abstract boolean[] getProbesCopy();
+
+ /**
+ * Sets all probes to <code>false</code>.
+ */
+ public abstract void reset();
+
+ /**
+ * Checks whether any probe has been hit.
+ *
+ * @return <code>true</code>, if at least one probe has been hit
+ */
+ public abstract boolean hasHits();
+
+ /**
+ * Merges the given execution data into the probe data of this object. I.e.
+ * a probe entry in this object is marked as executed (<code>true</code>) if
+ * this probe or the corresponding other probe was executed. So the result
+ * is
+ *
+ * <pre>
+ * A or B
+ * </pre>
+ *
+ * The probe array of the other object is not modified.
+ *
+ * @param other
+ * execution data to merge
+ */
+ public abstract void merge(final IExecutionData other);
+
+ /**
+ * Merges the given execution data into the probe data of this object. A
+ * probe in this object is set to the value of <code>flag</code> if the
+ * corresponding other probe was executed. For <code>flag==true</code> this
+ * corresponds to
+ *
+ * <pre>
+ * A or B
+ * </pre>
+ *
+ * For <code>flag==false</code> this can be considered as a subtraction
+ *
+ * <pre>
+ * A and not B
+ * </pre>
+ *
+ * The probe array of the other object is not modified.
+ *
+ * @param other
+ * execution data to merge
+ * @param flag
+ * merge mode
+ */
+ public abstract void merge(final IExecutionData other, boolean flag);
+
+ /**
+ * Asserts that this execution data object is compatible with the given
+ * parameters. The purpose of this check is to detect a very unlikely class
+ * id collision.
+ *
+ * @param id
+ * other class id, must be the same
+ * @param name
+ * other name, must be equal to this name
+ * @param probecount
+ * probe data length, must be the same as for this data
+ * @throws IllegalStateException
+ * if the given parameters do not match this instance
+ */
+ public abstract void assertCompatibility(final long id, final String name, final int probeCount) throws IllegalStateException;
+
+ /**
+ * Returns the execution data probe for a given index. A value of
+ * <code>true</code> indicates that the corresponding probe was
+ * executed.
+ *
+ * @param index the probe's index to look up
+ *
+ * @return probe data
+ */
+ public abstract boolean getProbe(final int index);
+
+ /**
+ * Sets the execution data probe at the given index to <code>true</code>.
+ *
+ * @param index the probe's index to set
+ * @param value the value to set the probe to
+ */
+ public abstract void setProbe(final int index);
+}
+// END android-change
diff --git a/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java b/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java
index 6cea7c57..659aa51d 100644
--- a/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java
+++ b/org.jacoco.core/src/org/jacoco/core/data/IExecutionDataVisitor.java
@@ -24,6 +24,8 @@ public interface IExecutionDataVisitor {
* @param data
* execution data for a class
*/
- void visitClassExecution(ExecutionData data);
+ // BEGIN android-change
+ public void visitClassExecution(IExecutionData data);
+ // END android-change
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java
index 85e83a3a..4d4e1ba1 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java
@@ -77,7 +77,9 @@ public final class InstrSupport {
* Data type of the field that stores coverage information for a class (
* <code>boolean[]</code>).
*/
- public static final String DATAFIELD_DESC = "[Z";
+ // BEGIN android-change
+ public static final String DATAFIELD_DESC = "Lorg/jacoco/core/data/IExecutionData;";
+ // END android-change
// === Init Method ===
@@ -89,7 +91,9 @@ public final class InstrSupport {
/**
* Descriptor of the initialization method.
*/
- public static final String INITMETHOD_DESC = "()[Z";
+ // BEGIN android-change
+ public static final String INITMETHOD_DESC = "()Lorg/jacoco/core/data/IExecutionData;";
+ // END android-change
/**
* Access modifiers of the initialization method.
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java
index 63fbf765..0cac8f8f 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java
@@ -67,25 +67,20 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
public void insertProbe(final int id) {
- // For a probe we set the corresponding position in the boolean[] array
- // to true.
+ // BEGIN android-change
+ // For a probe we call setProbe on the IExecutionData object.
mv.visitVarInsn(Opcodes.ALOAD, variable);
- // Stack[0]: [Z
+ // Stack[0]: Lorg/jacoco/core/data/IExecutionData;
InstrSupport.push(mv, id);
// Stack[1]: I
- // Stack[0]: [Z
+ // Stack[0]: Lorg/jacoco/core/data/IExecutionData;
- mv.visitInsn(Opcodes.ICONST_1);
-
- // Stack[2]: I
- // Stack[1]: I
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.BASTORE);
+ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "org/jacoco/core/data/IExecutionData", "setProbe", "(I)V", true);
+ // END android-change
}
@Override
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java
index 72553956..bef42030 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/LoggerRuntime.java
@@ -168,7 +168,9 @@ public class LoggerRuntime extends AbstractRuntime {
@Override
public void publish(final LogRecord record) {
if (key.equals(record.getMessage())) {
- data.getProbes(record.getParameters());
+ // BEGIN android-change
+ data.getExecutionData(record.getParameters());
+ // END android-change
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/OfflineInstrumentationAccessGenerator.java b/org.jacoco.core/src/org/jacoco/core/runtime/OfflineInstrumentationAccessGenerator.java
index af6671ee..a5e88b60 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/OfflineInstrumentationAccessGenerator.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/OfflineInstrumentationAccessGenerator.java
@@ -50,8 +50,10 @@ public class OfflineInstrumentationAccessGenerator implements
mv.visitLdcInsn(Long.valueOf(classid));
mv.visitLdcInsn(classname);
InstrSupport.push(mv, probecount);
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeClassName, "getProbes",
- "(JLjava/lang/String;I)[Z", false);
+ // BEGIN android-change
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, runtimeClassName, "getExecutionData",
+ "(JLjava/lang/String;I)Lorg/jacoco/core/data/IExecutionData;", false);
+ // END android-change
return 4;
}
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java b/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java
index afb5b7f3..c0fbb654 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/RuntimeData.java
@@ -11,7 +11,7 @@
*******************************************************************************/
package org.jacoco.core.runtime;
-import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.IExecutionData;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.data.IExecutionDataVisitor;
import org.jacoco.core.data.ISessionInfoVisitor;
@@ -128,15 +128,18 @@ public class RuntimeData {
* probe data length
* @return execution data
*/
- public ExecutionData getExecutionData(final Long id, final String name,
+ // BEGIN android-change
+ public IExecutionData getExecutionData(final Long id, final String name,
final int probecount) {
+ // END android-change
synchronized (store) {
return store.get(id, name, probecount);
}
}
+ // BEGIN android-change
/**
- * Retrieves the execution probe array for a given class. The passed
+ * Retrieves the execution data for a given class. The passed
* {@link Object} array instance is used for parameters and the return value
* as follows. Call parameters:
*
@@ -149,18 +152,19 @@ public class RuntimeData {
* Return value:
*
* <ul>
- * <li>args[0]: probe array (<code>boolean[]</code>)
+ * <li>args[0]: execution data ({@link IExecutionData})
* </ul>
*
* @param args
* parameter array of length 3
*/
- public void getProbes(final Object[] args) {
+ public void getExecutionData(final Object[] args) {
final Long classid = (Long) args[0];
final String name = (String) args[1];
final int probecount = ((Integer) args[2]).intValue();
- args[0] = getExecutionData(classid, name, probecount).getProbes();
+ args[0] = getExecutionData(classid, name, probecount);
}
+ // END android-change
/**
* In violation of the regular semantic of {@link Object#equals(Object)}
@@ -173,7 +177,9 @@ public class RuntimeData {
@Override
public boolean equals(final Object args) {
if (args instanceof Object[]) {
- getProbes((Object[]) args);
+ // BEGIN android-change
+ getExecutionData((Object[]) args);
+ // END android-change
}
return super.equals(args);
}