aboutsummaryrefslogtreecommitdiffstats
path: root/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2014-05-01 06:15:21 +0200
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2014-05-01 06:15:21 +0200
commit72793f84314a393b86c5dc344499888b7113d20b (patch)
treefa2fe561a4e12ab1e225fb14569952f1e94851fe /org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
parent9d79259f33e7117a4bf4ec1db2848e9429455325 (diff)
downloadplatform_external_jacoco-72793f84314a393b86c5dc344499888b7113d20b.tar.gz
platform_external_jacoco-72793f84314a393b86c5dc344499888b7113d20b.tar.bz2
platform_external_jacoco-72793f84314a393b86c5dc344499888b7113d20b.zip
GitHub #201: Fixed failure with default methods in in Java 8 interfaces
Diffstat (limited to 'org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java')
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java146
1 files changed, 6 insertions, 140 deletions
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
index dd1bf899..a1aec588 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
@@ -13,50 +13,32 @@ package org.jacoco.core.internal.instr;
import org.jacoco.core.internal.flow.ClassProbesVisitor;
import org.jacoco.core.internal.flow.MethodProbesVisitor;
-import org.jacoco.core.runtime.IExecutionDataAccessorGenerator;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
/**
* Adapter that instruments a class for coverage tracing.
*/
public class ClassInstrumenter extends ClassProbesVisitor {
- private static final Object[] STACK_ARRZ = new Object[] { InstrSupport.DATAFIELD_DESC };
- private static final Object[] NO_LOCALS = new Object[0];
-
- private final long id;
-
- private final IExecutionDataAccessorGenerator accessorGenerator;
-
- private IProbeArrayStrategy probeArrayStrategy;
+ private final IProbeArrayStrategy probeArrayStrategy;
private String className;
- private boolean withFrames;
-
- private int probeCount;
-
/**
* Emits a instrumented version of this class to the given class visitor.
*
- * @param id
- * unique identifier given to this class
- * @param accessorGenerator
- * this generator will be used for instrumentation
+ * @param probeArrayStrategy
+ * this strategy will be used to access the probe array
* @param cv
* next delegate in the visitor chain will receive the
* instrumented class
*/
- public ClassInstrumenter(final long id,
- final IExecutionDataAccessorGenerator accessorGenerator,
+ public ClassInstrumenter(final IProbeArrayStrategy probeArrayStrategy,
final ClassVisitor cv) {
super(cv);
- this.id = id;
- this.accessorGenerator = accessorGenerator;
+ this.probeArrayStrategy = probeArrayStrategy;
}
@Override
@@ -64,12 +46,6 @@ public class ClassInstrumenter extends ClassProbesVisitor {
final String signature, final String superName,
final String[] interfaces) {
this.className = name;
- withFrames = (version & 0xff) >= Opcodes.V1_6;
- if ((access & Opcodes.ACC_INTERFACE) == 0) {
- this.probeArrayStrategy = new ClassTypeStrategy();
- } else {
- this.probeArrayStrategy = new InterfaceTypeStrategy();
- }
super.visit(version, access, name, signature, superName, interfaces);
}
@@ -101,117 +77,7 @@ public class ClassInstrumenter extends ClassProbesVisitor {
@Override
public void visitTotalProbeCount(final int count) {
- probeCount = count;
- }
-
- @Override
- public void visitEnd() {
- probeArrayStrategy.addMembers(cv);
- super.visitEnd();
- }
-
- // === probe array strategies ===
-
- private class ClassTypeStrategy implements IProbeArrayStrategy {
-
- public int storeInstance(final MethodVisitor mv, final int variable) {
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, className,
- InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC,
- false);
- mv.visitVarInsn(Opcodes.ASTORE, variable);
- return 1;
- }
-
- public void addMembers(final ClassVisitor delegate) {
- createDataField();
- createInitMethod(probeCount);
- }
-
- private void createDataField() {
- cv.visitField(InstrSupport.DATAFIELD_ACC,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC,
- null, null);
- }
-
- private void createInitMethod(final int probeCount) {
- final MethodVisitor mv = cv.visitMethod(
- InstrSupport.INITMETHOD_ACC, InstrSupport.INITMETHOD_NAME,
- InstrSupport.INITMETHOD_DESC, null, null);
- mv.visitCode();
-
- // Load the value of the static data field:
- mv.visitFieldInsn(Opcodes.GETSTATIC, className,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC);
- mv.visitInsn(Opcodes.DUP);
-
- // Stack[1]: [Z
- // Stack[0]: [Z
-
- // Skip initialization when we already have a data array:
- final Label alreadyInitialized = new Label();
- mv.visitJumpInsn(Opcodes.IFNONNULL, alreadyInitialized);
-
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.POP);
- final int size = genInitializeDataField(mv, probeCount);
-
- // Stack[0]: [Z
-
- // Return the class' probe array:
- if (withFrames) {
- mv.visitFrame(Opcodes.F_NEW, 0, NO_LOCALS, 1, STACK_ARRZ);
- }
- mv.visitLabel(alreadyInitialized);
- mv.visitInsn(Opcodes.ARETURN);
-
- mv.visitMaxs(Math.max(size, 2), 0); // Maximum local stack size is 2
- mv.visitEnd();
- }
-
- /**
- * Generates the byte code to initialize the static coverage data field
- * within this class.
- *
- * The code will push the [Z data array on the operand stack.
- *
- * @param mv
- * generator to emit code to
- */
- private int genInitializeDataField(final MethodVisitor mv,
- final int probeCount) {
- final int size = accessorGenerator.generateDataAccessor(id,
- className, probeCount, mv);
-
- // Stack[0]: [Z
-
- mv.visitInsn(Opcodes.DUP);
-
- // Stack[1]: [Z
- // Stack[0]: [Z
-
- mv.visitFieldInsn(Opcodes.PUTSTATIC, className,
- InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC);
-
- // Stack[0]: [Z
-
- return Math.max(size, 2); // Maximum local stack size is 2
- }
- }
-
- private class InterfaceTypeStrategy implements IProbeArrayStrategy {
-
- public int storeInstance(final MethodVisitor mv, final int variable) {
- final int maxStack = accessorGenerator.generateDataAccessor(id,
- className, probeCount, mv);
- mv.visitVarInsn(Opcodes.ASTORE, variable);
- return maxStack;
- }
-
- public void addMembers(final ClassVisitor delegate) {
- // nothing to do
- }
-
+ probeArrayStrategy.addMembers(cv, count);
}
}