aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--org.jacoco.agent.rt/META-INF/MANIFEST.MF2
-rw-r--r--org.jacoco.build/pom.xml2
-rw-r--r--org.jacoco.core.test/META-INF/MANIFEST.MF2
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/instr/FrameTrackerTest.java84
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java180
-rw-r--r--org.jacoco.core/META-INF/MANIFEST.MF6
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java16
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/FrameTracker.java44
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/IFrameInserter.java8
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/LazyFrameTracker.java47
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java141
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html5
-rw-r--r--org.jacoco.report/META-INF/MANIFEST.MF2
13 files changed, 160 insertions, 379 deletions
diff --git a/org.jacoco.agent.rt/META-INF/MANIFEST.MF b/org.jacoco.agent.rt/META-INF/MANIFEST.MF
index 16a32b82..76516c09 100644
--- a/org.jacoco.agent.rt/META-INF/MANIFEST.MF
+++ b/org.jacoco.agent.rt/META-INF/MANIFEST.MF
@@ -9,4 +9,4 @@ Import-Package: org.jacoco.core;bundle-version="[0.6.1,0.6.2)",
org.jacoco.core.data;bundle-version="[0.6.1,0.6.2)",
org.jacoco.core.instr;bundle-version="[0.6.1,0.6.2)",
org.jacoco.core.runtime;bundle-version="[0.6.1,0.6.2)",
- org.objectweb.asm;version="[4.0.0,4.1.0)"
+ org.objectweb.asm;version="[4.1.0,4.2.0)"
diff --git a/org.jacoco.build/pom.xml b/org.jacoco.build/pom.xml
index 3544e7fe..e60a05b5 100644
--- a/org.jacoco.build/pom.xml
+++ b/org.jacoco.build/pom.xml
@@ -132,7 +132,7 @@
<tycho.version>0.13.0</tycho.version>
<!-- Dependencies versions -->
- <asm.version>4.0</asm.version>
+ <asm.version>4.1</asm.version>
<ant.version>1.7.0</ant.version>
<junit.version>4.8.2</junit.version>
diff --git a/org.jacoco.core.test/META-INF/MANIFEST.MF b/org.jacoco.core.test/META-INF/MANIFEST.MF
index 222304c7..e846d604 100644
--- a/org.jacoco.core.test/META-INF/MANIFEST.MF
+++ b/org.jacoco.core.test/META-INF/MANIFEST.MF
@@ -8,4 +8,4 @@ Fragment-Host: org.jacoco.core
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.junit;version="[4.8.0,5.0.0)",
org.junit.rules;version="[4.8.0,5.0.0)",
- org.objectweb.asm.util;version="[4.0.0,4.1.0)"
+ org.objectweb.asm.util;version="[4.1.0,4.2.0)"
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/FrameTrackerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/FrameTrackerTest.java
index 8a7d694a..2b286cbe 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/FrameTrackerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/FrameTrackerTest.java
@@ -75,7 +75,8 @@ public class FrameTrackerTest {
// Ignore labels inserted by the tracker
}
};
- FrameTracker tracker = new FrameTracker(noLabels, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", noLabels);
before.accept(tracker);
mv.instructions.accept(tracker);
tracker.insertFrame();
@@ -90,47 +91,101 @@ public class FrameTrackerTest {
@Test(expected = IllegalArgumentException.class)
public void testVisitFrameIllegalFrameType() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitFrame(F_APPEND, 0, null, 0, null);
}
@Test(expected = IllegalArgumentException.class)
public void testVisitInsnIllegalOpcode() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitInsn(GOTO);
}
@Test(expected = IllegalArgumentException.class)
public void testVisitIntInsnIllegalOpcode() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitIntInsn(NOP, 0);
}
@Test(expected = IllegalArgumentException.class)
public void testVisitVarInsnIllegalOpcode() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitVarInsn(NOP, 0);
}
@Test(expected = IllegalArgumentException.class)
public void testVisitTypeInsnIllegalOpcode() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitTypeInsn(NOP, "A");
}
@Test(expected = IllegalArgumentException.class)
public void testVisitFieldInsnIllegalOpcode() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitFieldInsn(NOP, "A", "x", "I");
}
@Test(expected = IllegalArgumentException.class)
public void testVisitJumpInsnIllegalOpcode() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitJumpInsn(NOP, new Label());
}
@Test
+ public void testArgumentsConstructor() {
+ FrameBuilder expectedFrame = new FrameBuilder();
+ expectedFrame.locals(UNINITIALIZED_THIS);
+ testArguments(0, "<init>", "()V", expectedFrame);
+ }
+
+ @Test
+ public void testArgumentsStatic() {
+ FrameBuilder expectedFrame = new FrameBuilder();
+ testArguments(Opcodes.ACC_STATIC, "test", "()V", expectedFrame);
+ }
+
+ @Test
+ public void testArgumentsStaticIJZ() {
+ FrameBuilder expectedFrame = new FrameBuilder();
+ expectedFrame.locals(INTEGER, LONG, INTEGER);
+ testArguments(Opcodes.ACC_STATIC, "test", "(IJZ)V", expectedFrame);
+ }
+
+ @Test
+ public void testArgumentsStaticLArr() {
+ FrameBuilder expectedFrame = new FrameBuilder();
+ expectedFrame.locals("Foo", "[[S");
+ testArguments(Opcodes.ACC_STATIC, "test", "(LFoo;[[S)V", expectedFrame);
+ }
+
+ @Test
+ public void testArgumentsFD() {
+ FrameBuilder expectedFrame = new FrameBuilder();
+ expectedFrame.locals("Test", FLOAT, DOUBLE);
+ testArguments(0, "test", "(FD)V", expectedFrame);
+ }
+
+ private void testArguments(int access, String name, String desc,
+ FrameBuilder expectedFrame) {
+ MethodRecorder actual = new MethodRecorder();
+ FrameTracker tracker = new FrameTracker("Test", access, name, desc,
+ actual.getVisitor());
+ tracker.insertFrame();
+
+ MethodRecorder expected = new MethodRecorder();
+ expectedFrame.accept(expected.getVisitor());
+
+ assertEquals(expected, actual);
+ }
+
+ @Test
public void testFrameGaps() {
before.locals().stack(INTEGER);
mv.visitVarInsn(ISTORE, 3);
@@ -147,13 +202,6 @@ public class FrameTrackerTest {
}
@Test
- public void AALOAD() {
- before.locals().stack("[Ljava/lang/String;", INTEGER);
- mv.visitInsn(AALOAD);
- after.locals().stack("java/lang/String");
- }
-
- @Test
public void AALOAD_multidim_obj() {
before.locals().stack("[[Ljava/lang/String;", INTEGER);
mv.visitInsn(AALOAD);
@@ -1130,7 +1178,8 @@ public class FrameTrackerTest {
@Test(expected = IllegalArgumentException.class)
public void LDC_invalidType() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitLdcInsn(Byte.valueOf((byte) 123));
}
@@ -1320,7 +1369,8 @@ public class FrameTrackerTest {
@Test(expected = IllegalArgumentException.class)
public void NEWARRAY_invalidOperand() {
- FrameTracker tracker = new FrameTracker(null, "Test");
+ FrameTracker tracker = new FrameTracker("Test", ACC_STATIC, "test",
+ "()V", null);
tracker.visitIntInsn(NEWARRAY, -1);
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java
index d15287e1..f7b548bd 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/ProbeInserterTest.java
@@ -18,8 +18,6 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.objectweb.asm.ClassVisitor;
-import org.objectweb.asm.Handle;
-import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -63,7 +61,6 @@ public class ProbeInserterTest {
actualVisitor, arrayStrategy);
pi.insertProbe(0);
- expectedVisitor.visitLdcInsn("init");
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 0);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
@@ -76,7 +73,6 @@ public class ProbeInserterTest {
arrayStrategy);
pi.insertProbe(0);
- expectedVisitor.visitLdcInsn("init");
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 1);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
@@ -89,7 +85,6 @@ public class ProbeInserterTest {
actualVisitor, arrayStrategy);
pi.insertProbe(0);
- expectedVisitor.visitLdcInsn("init");
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 4);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
@@ -102,7 +97,6 @@ public class ProbeInserterTest {
arrayStrategy);
pi.insertProbe(0);
- expectedVisitor.visitLdcInsn("init");
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 5);
expectedVisitor.visitInsn(Opcodes.ICONST_0);
expectedVisitor.visitInsn(Opcodes.ICONST_1);
@@ -110,47 +104,12 @@ public class ProbeInserterTest {
}
@Test
- public void testVisitProlog() {
- ProbeInserter pi = new ProbeInserter(0, "(I)V", actualVisitor,
- arrayStrategy);
- Label label = new Label();
- pi.visitLabel(label);
- pi.visitLineNumber(123, label);
- pi.visitFrame(Opcodes.F_NEW, 1, new Object[] { "I" }, 0, new Object[0]);
- pi.visitInsn(Opcodes.NOP);
-
- expectedVisitor.visitFrame(Opcodes.F_NEW, 1, new Object[] { "I" }, 0,
- new Object[0]);
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitLabel(label);
- expectedVisitor.visitLineNumber(123, label);
- expectedVisitor.visitInsn(Opcodes.NOP);
- }
-
- @Test
- public void testVisitLabel() {
+ public void testVisitCode() {
ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
arrayStrategy);
- Label label = new Label();
- pi.visitInsn(Opcodes.NOP);
- pi.visitLabel(label);
+ pi.visitCode();
expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInsn(Opcodes.NOP);
- expectedVisitor.visitLabel(label);
- }
-
- @Test
- public void testVisitLineNumber() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- Label label = new Label();
- pi.visitInsn(Opcodes.NOP);
- pi.visitLineNumber(123, label);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInsn(Opcodes.NOP);
- expectedVisitor.visitLineNumber(123, label);
}
@Test
@@ -164,7 +123,6 @@ public class ProbeInserterTest {
pi.visitVarInsn(Opcodes.ISTORE, 3);
pi.visitVarInsn(Opcodes.FSTORE, 4);
- expectedVisitor.visitLdcInsn("init");
// Argument variables stay at the same position:
expectedVisitor.visitVarInsn(Opcodes.ALOAD, 0);
expectedVisitor.visitVarInsn(Opcodes.ILOAD, 1);
@@ -185,7 +143,6 @@ public class ProbeInserterTest {
pi.visitIincInsn(3, 103);
pi.visitIincInsn(4, 104);
- expectedVisitor.visitLdcInsn("init");
// Argument variables stay at the same position:
expectedVisitor.visitIincInsn(0, 100);
expectedVisitor.visitIincInsn(1, 101);
@@ -207,7 +164,6 @@ public class ProbeInserterTest {
pi.visitLocalVariable(null, null, null, null, null, 3);
pi.visitLocalVariable(null, null, null, null, null, 4);
- expectedVisitor.visitLdcInsn("init");
// Argument variables stay at the same position:
expectedVisitor.visitLocalVariable(null, null, null, null, null, 0);
expectedVisitor.visitLocalVariable(null, null, null, null, null, 1);
@@ -219,119 +175,13 @@ public class ProbeInserterTest {
}
@Test
- public void testVisitIntInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- pi.visitIntInsn(Opcodes.BIPUSH, 15);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitIntInsn(Opcodes.BIPUSH, 15);
- }
-
- @Test
- public void testVisitTypeInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- pi.visitTypeInsn(Opcodes.NEW, "Foo");
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitTypeInsn(Opcodes.NEW, "Foo");
- }
-
- @Test
- public void testVisitFieldInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- pi.visitFieldInsn(Opcodes.GETFIELD, "Foo", "i", "I");
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitFieldInsn(Opcodes.GETFIELD, "Foo", "i", "I");
- }
-
- @Test
- public void testVisitMethodInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- pi.visitMethodInsn(Opcodes.INVOKEINTERFACE, "Foo", "doit", "()V");
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "Foo", "doit",
- "()V");
- }
-
- @Test
- public void testInvokeDynamicInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- Handle handle = new Handle(0, null, null, null);
- pi.visitInvokeDynamicInsn("foo", "()V", handle);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInvokeDynamicInsn("foo", "()V", handle);
- }
-
- @Test
- public void testVisitJumpInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- Label label = new Label();
- pi.visitJumpInsn(Opcodes.GOTO, label);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitJumpInsn(Opcodes.GOTO, label);
- }
-
- @Test
- public void testVisitLdcInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- pi.visitLdcInsn("JaCoCo");
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitLdcInsn("JaCoCo");
- }
-
- @Test
- public void testVisitTableSwitchInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- Label dflt = new Label();
- pi.visitTableSwitchInsn(0, 1, dflt, new Label[0]);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitTableSwitchInsn(0, 1, dflt, new Label[0]);
- }
-
- @Test
- public void testVisitLookupSwitchInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- Label dflt = new Label();
- pi.visitLookupSwitchInsn(dflt, new int[0], new Label[0]);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitLookupSwitchInsn(dflt, new int[0], new Label[0]);
- }
-
- @Test
- public void testVisitMultiANewArrayInsn() {
- ProbeInserter pi = new ProbeInserter(0, "()V", actualVisitor,
- arrayStrategy);
- pi.visitMultiANewArrayInsn("[[[I", 3);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitMultiANewArrayInsn("[[[I", 3);
- }
-
- @Test
public void testVisitMaxs1() {
ProbeInserter pi = new ProbeInserter(0, "(II)V", actualVisitor,
arrayStrategy);
- pi.visitInsn(Opcodes.NOP);
+ pi.visitCode();
pi.visitMaxs(0, 8);
expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInsn(Opcodes.NOP);
expectedVisitor.visitMaxs(5, 9);
}
@@ -339,11 +189,10 @@ public class ProbeInserterTest {
public void testVisitMaxs2() {
ProbeInserter pi = new ProbeInserter(0, "(II)V", actualVisitor,
arrayStrategy);
- pi.visitInsn(Opcodes.NOP);
+ pi.visitCode();
pi.visitMaxs(10, 8);
expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInsn(Opcodes.NOP);
expectedVisitor.visitMaxs(13, 9);
}
@@ -352,20 +201,9 @@ public class ProbeInserterTest {
ProbeInserter pi = new ProbeInserter(0, "(J)V", actualVisitor,
arrayStrategy);
- pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", Opcodes.LONG },
- 0, new Object[0]);
- pi.visitInsn(Opcodes.NOP);
pi.visitFrame(Opcodes.F_NEW, 3, new Object[] { "Foo", Opcodes.LONG,
"java/lang/String" }, 0, new Object[0]);
- // The first (implicit) frame must not be modified:
- expectedVisitor.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo",
- Opcodes.LONG }, 0, new Object[0]);
-
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInsn(Opcodes.NOP);
-
- // Starting from the second frame on the probe variable is inserted:
expectedVisitor.visitFrame(Opcodes.F_NEW, 4, new Object[] { "Foo",
Opcodes.LONG, "[Z", "java/lang/String" }, 0, new Object[0]);
}
@@ -375,10 +213,6 @@ public class ProbeInserterTest {
ProbeInserter pi = new ProbeInserter(0, "(J)V", actualVisitor,
arrayStrategy);
- pi.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo", Opcodes.LONG },
- 0, new Object[0]);
- pi.visitInsn(Opcodes.RETURN);
-
// Such sequences are generated by ASM to replace dead code, see
// http://asm.ow2.org/doc/developer-guide.html#deadcode
pi.visitFrame(Opcodes.F_NEW, 0, new Object[] {}, 1,
@@ -387,12 +221,6 @@ public class ProbeInserterTest {
pi.visitInsn(Opcodes.NOP);
pi.visitInsn(Opcodes.ATHROW);
- // The first (implicit) frame must not be modified:
- expectedVisitor.visitFrame(Opcodes.F_NEW, 2, new Object[] { "Foo",
- Opcodes.LONG }, 0, new Object[0]);
- expectedVisitor.visitLdcInsn("init");
- expectedVisitor.visitInsn(Opcodes.RETURN);
-
// The locals in this frame are filled with TOP up to the probe variable
expectedVisitor.visitFrame(Opcodes.F_NEW, 3, new Object[] {
Opcodes.TOP, Opcodes.TOP, "[Z", }, 1,
diff --git a/org.jacoco.core/META-INF/MANIFEST.MF b/org.jacoco.core/META-INF/MANIFEST.MF
index 194be14e..b7538cea 100644
--- a/org.jacoco.core/META-INF/MANIFEST.MF
+++ b/org.jacoco.core/META-INF/MANIFEST.MF
@@ -11,6 +11,6 @@ Export-Package: org.jacoco.core;version="0.6.1",
org.jacoco.core.instr;version="0.6.1",
org.jacoco.core.internal.analysis;version="0.6.1"; x-internal=true,
org.jacoco.core.runtime;version="0.6.1"
-Import-Package: org.objectweb.asm;version="[4.0.0,4.1.0)",
- org.objectweb.asm.tree;version="[4.0.0,4.1.0)",
- org.objectweb.asm.commons;version="[4.0.0,4.1.0)"
+Import-Package: org.objectweb.asm;version="[4.1.0,4.2.0)",
+ org.objectweb.asm.tree;version="[4.1.0,4.2.0)",
+ org.objectweb.asm.commons;version="[4.1.0,4.2.0)"
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 2aa2606c..44d3c214 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
@@ -97,10 +97,15 @@ public class ClassInstrumenter extends ClassProbesVisitor {
final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv);
final ProbeInserter probeVariableInserter = new ProbeInserter(access,
desc, frameEliminator, probeArrayStrategy);
- final LazyFrameTracker frameTracker = new LazyFrameTracker(
- probeVariableInserter, className);
- return new MethodInstrumenter(frameTracker, probeVariableInserter,
- frameTracker);
+ if (withFrames) {
+ final FrameTracker frameTracker = new FrameTracker(className,
+ access, name, desc, probeVariableInserter);
+ return new MethodInstrumenter(frameTracker, probeVariableInserter,
+ frameTracker);
+ } else {
+ return new MethodInstrumenter(probeVariableInserter,
+ probeVariableInserter, IFrameInserter.NOP);
+ }
}
@Override
@@ -162,9 +167,6 @@ public class ClassInstrumenter extends ClassProbesVisitor {
InstrSupport.INITMETHOD_ACC, InstrSupport.INITMETHOD_NAME,
InstrSupport.INITMETHOD_DESC, null, null);
mv.visitCode();
- if (withFrames) {
- mv.visitFrame(Opcodes.F_NEW, 0, NO_LOCALS, 0, STACK_ARRZ);
- }
// Load the value of the static data field:
mv.visitFieldInsn(Opcodes.GETSTATIC, className,
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/FrameTracker.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/FrameTracker.java
index de0e3579..ed396bf3 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/FrameTracker.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/FrameTracker.java
@@ -31,13 +31,26 @@ class FrameTracker extends MethodVisitor implements IFrameInserter {
private Object[] stack;
private int stackSize;
- public FrameTracker(final MethodVisitor mv, final String owner) {
+ public FrameTracker(final String owner, final int access,
+ final String name, final String desc, final MethodVisitor mv) {
super(Opcodes.ASM4, mv);
this.owner = owner;
local = new Object[8];
localSize = 0;
stack = new Object[8];
stackSize = 0;
+
+ if ((access & Opcodes.ACC_STATIC) == 0) {
+ if ("<init>".equals(name)) {
+ set(localSize, Opcodes.UNINITIALIZED_THIS);
+ } else {
+ set(localSize, owner);
+ }
+ }
+ for (final Type t : Type.getArgumentTypes(desc)) {
+ set(localSize, t);
+ }
+
}
public void insertFrame() {
@@ -607,6 +620,35 @@ class FrameTracker extends MethodVisitor implements IFrameInserter {
local[pos] = type;
}
+ private void set(final int pos, final Type type) {
+ switch (type.getSort()) {
+ case Type.BOOLEAN:
+ case Type.BYTE:
+ case Type.CHAR:
+ case Type.INT:
+ case Type.SHORT:
+ set(pos, Opcodes.INTEGER);
+ break;
+ case Type.FLOAT:
+ set(pos, Opcodes.FLOAT);
+ break;
+ case Type.LONG:
+ set(pos, Opcodes.LONG);
+ set(pos + 1, Opcodes.TOP);
+ break;
+ case Type.DOUBLE:
+ set(pos, Opcodes.DOUBLE);
+ set(pos + 1, Opcodes.TOP);
+ break;
+ case Type.ARRAY:
+ case Type.OBJECT:
+ set(pos, type.getInternalName());
+ break;
+ default:
+ throw new AssertionError(type);
+ }
+ }
+
private Object get(final int pos) {
return local[pos];
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/IFrameInserter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/IFrameInserter.java
index 581aa529..9f98860f 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/IFrameInserter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/IFrameInserter.java
@@ -18,6 +18,14 @@ package org.jacoco.core.internal.instr;
interface IFrameInserter {
/**
+ * Empty implementation.
+ */
+ static final IFrameInserter NOP = new IFrameInserter() {
+ public void insertFrame() {
+ }
+ };
+
+ /**
* Inserts an additional frame reflecting the current locals and stack
* types.
*/
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/LazyFrameTracker.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/LazyFrameTracker.java
deleted file mode 100644
index 6edddbfd..00000000
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/LazyFrameTracker.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 Mountainminds GmbH & Co. KG and Contributors
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Marc R. Hoffmann - initial API and implementation
- *
- *******************************************************************************/
-package org.jacoco.core.internal.instr;
-
-import org.objectweb.asm.MethodVisitor;
-import org.objectweb.asm.Opcodes;
-
-/**
- * Internal wrapper for the FrameTracker which activates frame tracking lazily
- * when the first frame is reported.
- */
-class LazyFrameTracker extends MethodVisitor implements IFrameInserter {
-
- private final String owner;
- private FrameTracker tracker;
-
- public LazyFrameTracker(final MethodVisitor mv, final String owner) {
- super(Opcodes.ASM4, mv);
- this.owner = owner;
- this.tracker = null;
- }
-
- @Override
- public void visitFrame(final int type, final int nLocal,
- final Object[] local, final int nStack, final Object[] stack) {
- if (tracker == null) {
- mv = tracker = new FrameTracker(mv, owner);
- }
- tracker.visitFrame(type, nLocal, local, nStack, stack);
- }
-
- public void insertFrame() {
- if (tracker != null) {
- tracker.insertFrame();
- }
- }
-
-}
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 5bc80c1a..c45883b9 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
@@ -11,14 +11,10 @@
*******************************************************************************/
package org.jacoco.core.internal.instr;
-import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
-import org.objectweb.asm.tree.InsnList;
-import org.objectweb.asm.tree.LabelNode;
-import org.objectweb.asm.tree.LineNumberNode;
/**
* Internal utility to add probes into the control flow of a method. The code
@@ -36,15 +32,9 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
/** Index the inserted variable. */
private final int variableIdx;
- /** Indicated whether the probe variable has already been inserted. */
- private boolean inserted;
-
/** Maximum stack usage of the code to access the probe array. */
private int accessorStackSize;
- /** Labels and line numbers preceding the first real instruction. */
- private final InsnList prolog;
-
/**
* Creates a new {@link ProbeInserter}.
*
@@ -70,13 +60,10 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
}
variableIdx = idx;
variable = pos;
- inserted = false;
- prolog = new InsnList();
}
public void insertProbe(final int id) {
- checkLoad();
// For a probe we set the corresponding position in the boolean[] array
// to true.
@@ -98,41 +85,19 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
mv.visitInsn(Opcodes.BASTORE);
}
- private void checkLoad() {
- if (!inserted) {
- accessorStackSize = arrayStrategy.storeInstance(mv, variable);
- prolog.accept(mv);
- inserted = true;
- }
- }
-
- @Override
- public final void visitLabel(final Label label) {
- if (!inserted) {
- prolog.add(new LabelNode(label));
- } else {
- mv.visitLabel(label);
- }
- }
-
@Override
- public void visitLineNumber(final int line, final Label start) {
- if (!inserted) {
- prolog.add(new LineNumberNode(line, new LabelNode(start)));
- } else {
- mv.visitLineNumber(line, start);
- }
+ public void visitCode() {
+ accessorStackSize = arrayStrategy.storeInstance(mv, variable);
+ mv.visitCode();
}
@Override
public final void visitVarInsn(final int opcode, final int var) {
- checkLoad();
mv.visitVarInsn(opcode, map(var));
}
@Override
public final void visitIincInsn(final int var, final int increment) {
- checkLoad();
mv.visitIincInsn(map(var), increment);
}
@@ -140,82 +105,16 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
public final void visitLocalVariable(final String name, final String desc,
final String signature, final Label start, final Label end,
final int index) {
- checkLoad();
mv.visitLocalVariable(name, desc, signature, start, end, map(index));
}
@Override
- public final void visitInsn(final int opcode) {
- checkLoad();
- mv.visitInsn(opcode);
- }
-
- @Override
- public final void visitIntInsn(final int opcode, final int operand) {
- checkLoad();
- mv.visitIntInsn(opcode, operand);
- }
-
- @Override
- public final void visitTypeInsn(final int opcode, final String type) {
- checkLoad();
- mv.visitTypeInsn(opcode, type);
- }
-
- @Override
public final void visitFieldInsn(final int opcode, final String owner,
final String name, final String desc) {
- checkLoad();
mv.visitFieldInsn(opcode, owner, name, desc);
}
@Override
- public final void visitMethodInsn(final int opcode, final String owner,
- final String name, final String desc) {
- checkLoad();
- mv.visitMethodInsn(opcode, owner, name, desc);
- }
-
- @Override
- public void visitInvokeDynamicInsn(final String name, final String desc,
- final Handle bsm, final Object... bsmArgs) {
- checkLoad();
- mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
- }
-
- @Override
- public final void visitJumpInsn(final int opcode, final Label label) {
- checkLoad();
- mv.visitJumpInsn(opcode, label);
- }
-
- @Override
- public final void visitLdcInsn(final Object cst) {
- checkLoad();
- mv.visitLdcInsn(cst);
- }
-
- @Override
- public final void visitTableSwitchInsn(final int min, final int max,
- final Label dflt, final Label... labels) {
- checkLoad();
- mv.visitTableSwitchInsn(min, max, dflt, labels);
- }
-
- @Override
- public final void visitLookupSwitchInsn(final Label dflt, final int[] keys,
- final Label[] labels) {
- checkLoad();
- mv.visitLookupSwitchInsn(dflt, keys, labels);
- }
-
- @Override
- public final void visitMultiANewArrayInsn(final String desc, final int dims) {
- checkLoad();
- mv.visitMultiANewArrayInsn(desc, dims);
- }
-
- @Override
public void visitMaxs(final int maxStack, final int maxLocals) {
// Max stack size of the probe code is 3 which can add to the
// original stack size depending on the probe locations. The accessor
@@ -242,28 +141,22 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
"ClassReader.accept() should be called with EXPAND_FRAMES flag");
}
- if (inserted) {
- final int n = Math.max(nLocal, variableIdx) + 1;
- final Object[] newLocal = new Object[n];
- for (int i = 0; i < n; i++) {
- if (i < variableIdx) {
- // For dead code it is possible to specify less locals than
- // we have method parameters.
- newLocal[i] = i < nLocal ? local[i] : Opcodes.TOP;
- continue;
- }
- if (i > variableIdx) {
- newLocal[i] = local[i - 1];
- continue;
- }
- newLocal[i] = InstrSupport.DATAFIELD_DESC;
+ final int n = Math.max(nLocal, variableIdx) + 1;
+ final Object[] newLocal = new Object[n];
+ for (int i = 0; i < n; i++) {
+ if (i < variableIdx) {
+ // For dead code it is possible to specify less locals than
+ // we have method parameters.
+ newLocal[i] = i < nLocal ? local[i] : Opcodes.TOP;
+ continue;
}
- mv.visitFrame(type, n, newLocal, nStack, stack);
- } else {
- mv.visitFrame(type, nLocal, local, nStack, stack);
+ if (i > variableIdx) {
+ newLocal[i] = local[i - 1];
+ continue;
+ }
+ newLocal[i] = InstrSupport.DATAFIELD_DESC;
}
-
- checkLoad();
+ mv.visitFrame(type, n, newLocal, nStack, stack);
}
}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index cdde19b9..8557fa59 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -20,6 +20,11 @@
<h2>Trunk Build @qualified.bundle.version@ (@build.date@)</h2>
+<h3>Non-functional Changes</h3>
+<ul>
+ <li>Upgrade to ASM 4.1 (GitHub #37)</li>
+</ul>
+
<h2>Release 0.6.0 (2012/10/06)</h2>
<h3>New Features</h3>
diff --git a/org.jacoco.report/META-INF/MANIFEST.MF b/org.jacoco.report/META-INF/MANIFEST.MF
index e2caaef6..bbf42c2d 100644
--- a/org.jacoco.report/META-INF/MANIFEST.MF
+++ b/org.jacoco.report/META-INF/MANIFEST.MF
@@ -12,4 +12,4 @@ Export-Package: org.jacoco.report;version="0.6.1",
Import-Package: org.jacoco.core;bundle-version="[0.6.1,0.6.2)",
org.jacoco.core.analysis;bundle-version="[0.6.1,0.6.2)",
org.jacoco.core.data;bundle-version="[0.6.1,0.6.2)",
- org.objectweb.asm;version="[4.0.0,4.1.0)"
+ org.objectweb.asm;version="[4.1.0,4.2.0)"