diff options
author | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2014-05-01 06:15:21 +0200 |
---|---|---|
committer | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2014-05-01 06:15:21 +0200 |
commit | 72793f84314a393b86c5dc344499888b7113d20b (patch) | |
tree | fa2fe561a4e12ab1e225fb14569952f1e94851fe /org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java | |
parent | 9d79259f33e7117a4bf4ec1db2848e9429455325 (diff) | |
download | platform_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.java | 146 |
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); } } |