Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b080b22a authored by Colin Cross's avatar Colin Cross Committed by Gerrit Code Review
Browse files

Merge "Move inserted method after end of try block"

parents 5027dd10 cebc382d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
    asm-5.2 \
    asm-commons-5.2 \
    asm-tree-5.2 \
    asm-analysis-5.2

    asm-analysis-5.2 \
    guava-20.0 \

include $(BUILD_HOST_JAVA_LIBRARY)
+22 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.TryCatchBlockSorter;
@@ -32,6 +33,10 @@ import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Frame;

import static com.google.common.base.Preconditions.checkElementIndex;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * This visitor does two things:
 *
@@ -140,10 +145,26 @@ class LockFindingClassVisitor extends ClassVisitor {
                    if (operand instanceof LockTargetState) {
                        LockTargetState state = (LockTargetState) operand;
                        for (int j = 0; j < state.getTargets().size(); j++) {
                            // The instruction after a monitor_exit should be a label for the end of the implicit
                            // catch block that surrounds the synchronized block to call monitor_exit when an exception
                            // occurs.
                            checkState(instructions.get(i + 1).getType() == AbstractInsnNode.LABEL,
                                "Expected to find label after monitor exit");

                            int labelIndex = i + 1;
                            checkElementIndex(labelIndex, instructions.size());

                            LabelNode label = (LabelNode)instructions.get(labelIndex);

                            checkNotNull(handlersMap.get(i));
                            checkElementIndex(0, handlersMap.get(i).size());
                            checkState(handlersMap.get(i).get(0).end == label,
                                "Expected label to be the end of monitor exit's try block");

                            LockTarget target = state.getTargets().get(j);
                            MethodInsnNode call = new MethodInsnNode(Opcodes.INVOKESTATIC,
                                    target.getPostOwner(), target.getPostMethod(), "()V", false);
                            insertMethodCallAfter(mn, frameMap, handlersMap, s, i, call);
                            insertMethodCallAfter(mn, frameMap, handlersMap, label, labelIndex, call);
                        }
                    }
                }
+22 −0
Original line number Diff line number Diff line
@@ -228,4 +228,26 @@ public class TestMain {
        Assert.assertEquals(TestTarget.unboostCount, 1);
        Assert.assertEquals(TestTarget.invokeCount, 1);
    }

    @Test
    public void testUnboostThatThrows() {
        TestTarget.resetCount();
        TestTarget t = new TestTarget();
        boolean asserted = false;

        Assert.assertEquals(TestTarget.boostCount, 0);
        Assert.assertEquals(TestTarget.unboostCount, 0);

        try {
            t.synchronizedThrowsOnUnboost();
        } catch (RuntimeException e) {
            asserted = true;
        }

        Assert.assertEquals(asserted, true);
        Assert.assertEquals(TestTarget.boostCount, 1);
        Assert.assertEquals(TestTarget.unboostCount, 0);
        Assert.assertEquals(TestTarget.invokeCount, 1);
    }

}
+12 −0
Original line number Diff line number Diff line
@@ -17,12 +17,17 @@ public class TestTarget {
  public static int boostCount = 0;
  public static int unboostCount = 0;
  public static int invokeCount = 0;
  public static boolean nextUnboostThrows = false;

  public static void boost() {
    boostCount++;
  }

  public static void unboost() {
    if (nextUnboostThrows) {
      nextUnboostThrows = false;
      throw new RuntimeException();
    }
    unboostCount++;
  }

@@ -49,4 +54,11 @@ public class TestTarget {
    invoke();
    return this;
  }

  public void synchronizedThrowsOnUnboost() {
    nextUnboostThrows = true;
    synchronized(this) {
      invoke();
    }
  }
}