From 045ecc611076cb0f1ad03201d4a98e66dbd5d8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bulej?= Date: Wed, 9 Oct 2019 16:44:30 +0200 Subject: [PATCH 1/2] Replace AdvancedSorter with ValidatingTcbSorter This is a backport of a fix from the development branch which allows using ASM version past 6.1, i.e., version 6.2 and later. --- src-disl/ch/usi/dag/disl/util/AsmHelper.java | 17 +-- .../usi/dag/disl/weaver/AdvancedSorter.java | 87 ------------- .../dag/disl/weaver/ValidatingTcbSorter.java | 119 ++++++++++++++++++ src-disl/ch/usi/dag/disl/weaver/Weaver.java | 3 +- 4 files changed, 131 insertions(+), 95 deletions(-) delete mode 100644 src-disl/ch/usi/dag/disl/weaver/AdvancedSorter.java create mode 100644 src-disl/ch/usi/dag/disl/weaver/ValidatingTcbSorter.java diff --git a/src-disl/ch/usi/dag/disl/util/AsmHelper.java b/src-disl/ch/usi/dag/disl/util/AsmHelper.java index 2b3ffd58..71ebafa5 100644 --- a/src-disl/ch/usi/dag/disl/util/AsmHelper.java +++ b/src-disl/ch/usi/dag/disl/util/AsmHelper.java @@ -40,13 +40,16 @@ import ch.usi.dag.disl.exception.DiSLFatalException; public abstract class AsmHelper { - public static boolean offsetBefore(final InsnList ilst, final int from, final int to) { - if (from >= to) { - return false; - } - - for (int i = from; i < to; i++) { - if (ilst.get(i).getOpcode() != -1) { + /** + * Returns {@code true} if the given list of instructions contains any real + * (non-pseudo) instruction node in the range between {@code start} + * (inclusive) and {@code end} exclusive. + */ + public static boolean offsetBefore ( + final InsnList insns, final int start, final int end + ) { + for (int i = start; i < end; i++) { + if (!Insn.isVirtual (insns.get (i))) { return true; } } diff --git a/src-disl/ch/usi/dag/disl/weaver/AdvancedSorter.java b/src-disl/ch/usi/dag/disl/weaver/AdvancedSorter.java deleted file mode 100644 index 296b495b..00000000 --- a/src-disl/ch/usi/dag/disl/weaver/AdvancedSorter.java +++ /dev/null @@ -1,87 +0,0 @@ -package ch.usi.dag.disl.weaver; - -import java.util.Collections; -import java.util.Comparator; - -import org.objectweb.asm.commons.TryCatchBlockSorter; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.TryCatchBlockNode; - -import ch.usi.dag.disl.exception.DiSLFatalException; -import ch.usi.dag.disl.util.AsmHelper; -import ch.usi.dag.disl.util.AsmHelper.Insns; - -public class AdvancedSorter extends TryCatchBlockSorter { - - public AdvancedSorter(MethodNode method) { - super(null, method.access, method.name, method.desc, method.signature, - null); - - this.instructions = method.instructions; - this.tryCatchBlocks = method.tryCatchBlocks; - } - - public void validate() { - - TryCatchBlockNode[] tcbs = new TryCatchBlockNode[tryCatchBlocks.size()]; - tcbs = tryCatchBlocks.toArray(tcbs); - - for (int i = 0; i < tcbs.length; i++) { - int istart = instructions.indexOf(Insns.FORWARD.firstRealInsn (tcbs[i].start)); - int iend = instructions.indexOf(tcbs[i].end); - - for (int j = i; j < tcbs.length; j++) { - int jstart = instructions.indexOf(Insns.FORWARD.firstRealInsn (tcbs[j].start)); - int jend = instructions.indexOf(tcbs[j].end); - - if (( - AsmHelper.offsetBefore(instructions, istart, jstart) && - AsmHelper.offsetBefore(instructions, jstart, iend) && - AsmHelper.offsetBefore(instructions, iend, jend) - ) || ( - AsmHelper.offsetBefore(instructions, jstart, istart) && - AsmHelper.offsetBefore(instructions, istart, jend) && - AsmHelper.offsetBefore(instructions, jend, iend) - )) { - throw new DiSLFatalException (String.format ( - "Overlapping exception handlers #%d [%d,%d) and #%d [%d, %d)", - i, istart, iend, j, jstart, jend - )); - } - } - } - } - - public void visitEnd() { - // Compares TryCatchBlockNodes by the length of their "try" block. - Comparator comp = new Comparator() { - - public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) { - int len1 = blockLength(t1); - int len2 = blockLength(t2); - return len1 - len2; - } - - private int blockLength(TryCatchBlockNode block) { - int startidx = instructions.indexOf(Insns.FORWARD.firstRealInsn (block.start)); - int endidx = instructions.indexOf(block.end); - return endidx - startidx; - } - }; - - Collections.sort(tryCatchBlocks, comp); - } - - public static void sort(MethodNode method) { - try { - AdvancedSorter sorter = new AdvancedSorter(method); - sorter.visitEnd(); - sorter.validate(); - } catch (final Exception ex) { - throw new DiSLFatalException ( - "error instrumenting method %s%s: %s", - method.name, method.desc, ex.getMessage () - ); - } - } -} diff --git a/src-disl/ch/usi/dag/disl/weaver/ValidatingTcbSorter.java b/src-disl/ch/usi/dag/disl/weaver/ValidatingTcbSorter.java new file mode 100644 index 00000000..1e3181e4 --- /dev/null +++ b/src-disl/ch/usi/dag/disl/weaver/ValidatingTcbSorter.java @@ -0,0 +1,119 @@ +package ch.usi.dag.disl.weaver; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.LabelNode; +import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.TryCatchBlockNode; + +import ch.usi.dag.disl.exception.DiSLFatalException; +import ch.usi.dag.disl.util.AsmHelper; +import ch.usi.dag.disl.util.AsmHelper.Insns; + + +class ValidatingTcbSorter { + + private static void __sortAndUpdate ( + final List tcbs, final InsnList insns + ) { + Collections.sort (tcbs, new Comparator () { + @Override + public int compare ( + final TryCatchBlockNode tcbNode1, final TryCatchBlockNode tcbNode2 + ) { + final int orderBySize = Integer.compare ( + blockLength (tcbNode1), blockLength (tcbNode2) + ); + + if (orderBySize == 0) { + return Integer.compare ( + __startIdx (tcbNode1.start, insns), + __startIdx (tcbNode2.start, insns) + ); + + } else { + return orderBySize; + } + } + + + private int blockLength (final TryCatchBlockNode tcbNode) { + return __endIdx (tcbNode.end, insns) - __startIdx (tcbNode.start, insns); + } + }); + + // Update index of each try-catch-block. + for (int i = 0; i < tcbs.size (); i++) { + tcbs.get (i).updateIndex (i); + } + } + + private static int __startIdx (final LabelNode label, final InsnList insns) { + return insns.indexOf (Insns.FORWARD.firstRealInsn (label)); + } + + private static int __endIdx (final LabelNode label, final InsnList insns) { + return insns.indexOf (label); + } + + + private static void __validate ( + final List tryCatchBlocks, final InsnList insns + ) { + final TryCatchBlockNode [] tcbs = tryCatchBlocks.toArray ( + new TryCatchBlockNode [tryCatchBlocks.size ()] + ); + + for (int i = 0; i < tcbs.length - 1; i++) { + final int istart = __startIdx (tcbs [i].start, insns); + final int iend = __endIdx (tcbs [i].end, insns); + + for (int j = i + 1; j < tcbs.length; j++) { + final int jstart = __startIdx (tcbs [j].start, insns); + final int jend = __endIdx (tcbs [j].end, insns); + + if (( + AsmHelper.offsetBefore (insns, istart, jstart) // I starts before J starts + && AsmHelper.offsetBefore (insns, iend, jend) // I ends before J ends + && AsmHelper.offsetBefore (insns, jstart, iend) // but J starts before I ends + ) || ( + AsmHelper.offsetBefore (insns, jstart, istart) // J starts before I starts + && AsmHelper.offsetBefore (insns, jend, iend) // J ends before I ends + && AsmHelper.offsetBefore (insns, istart, jend) // but I starts before J ends + )) { + throw new DiSLFatalException ( + "Overlapping exception handlers #%d [%d,%d) and #%d [%d, %d)", + i, istart, iend, j, jstart, jend + ); + } + } + } + } + + + /** + * Sorts exceptions handlers from inner to outer and ensures that don't + * overlap. + * + * @throws DiSLFataException + * If any of the exception handlers overlap. + */ + public static void sortTcbs (final MethodNode method) { + __sortAndUpdate (method.tryCatchBlocks, method.instructions); + __validate (method.tryCatchBlocks, method.instructions); + } + + // + + @SuppressWarnings ("unused") + private static void __printTcbs (final MethodNode method) { + for (final TryCatchBlockNode tcb : method.tryCatchBlocks) { + final int startIdx = method.instructions.indexOf (tcb.start); + final int endIdx = method.instructions.indexOf (tcb.end); + System.err.printf ("%d -> %d (%d)\n", startIdx, endIdx, endIdx - startIdx); + } + } +} diff --git a/src-disl/ch/usi/dag/disl/weaver/Weaver.java b/src-disl/ch/usi/dag/disl/weaver/Weaver.java index 2f4210f4..404ce21b 100644 --- a/src-disl/ch/usi/dag/disl/weaver/Weaver.java +++ b/src-disl/ch/usi/dag/disl/weaver/Weaver.java @@ -381,7 +381,8 @@ public class Weaver { new RewriteThreadLocalVarAccessesCodeTransformer (threadLocalVars) ); - AdvancedSorter.sort(methodNode); + // Sort exception handlers from inner to outer + ValidatingTcbSorter.sortTcbs (methodNode); } } -- GitLab From d465c480983f9263f62bedf72065516bee73077b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bulej?= Date: Wed, 9 Oct 2019 16:49:14 +0200 Subject: [PATCH 2/2] Bump ASM to version 7.2 --- dependencies.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies.properties b/dependencies.properties index ac435ff7..1bb0e2dd 100644 --- a/dependencies.properties +++ b/dependencies.properties @@ -6,7 +6,7 @@ ant-contrib.org=ant-contrib junit.rev=4.12 junit.org=junit -asm.rev=6.1 +asm.rev=7.2 asm.org=org.ow2.asm log4j.rev=1.2.17 -- GitLab