diff options
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)"
|