1 /******************************************************************************* 2 * Copyright (c) 2009, 2018 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Evgeny Mandrikov - initial API and implementation 10 * 11 *******************************************************************************/ 12 package org.jacoco.core.internal.analysis.filter; 13 14 import org.objectweb.asm.Opcodes; 15 import org.objectweb.asm.tree.AbstractInsnNode; 16 import org.objectweb.asm.tree.MethodNode; 17 import org.objectweb.asm.tree.TryCatchBlockNode; 18 19 /** 20 * Filters code that is generated for synchronized statement. 21 */ 22 public final class SynchronizedFilter implements IFilter { 23 24 public void filter(final String className, final String superClassName, 25 final MethodNode methodNode, final IFilterOutput output) { 26 for (TryCatchBlockNode tryCatch : methodNode.tryCatchBlocks) { 27 if (tryCatch.type != null) { 28 continue; 29 } 30 if (tryCatch.start == tryCatch.handler) { 31 continue; 32 } 33 final AbstractInsnNode to = new Matcher(tryCatch.handler).match(); 34 if (to == null) { 35 continue; 36 } 37 output.ignore(tryCatch.handler, to); 38 } 39 } 40 41 private static class Matcher extends AbstractMatcher { 42 private final AbstractInsnNode start; 43 44 private Matcher(final AbstractInsnNode start) { 45 this.start = start; 46 } 47 48 private AbstractInsnNode match() { 49 if (nextIsEcj() || nextIsJavac()) { 50 return cursor; 51 } 52 return null; 53 } 54 55 private boolean nextIsJavac() { 56 cursor = start; 57 nextIsVar(Opcodes.ASTORE, "t"); 58 nextIs(Opcodes.ALOAD); 59 nextIs(Opcodes.MONITOREXIT); 60 nextIsVar(Opcodes.ALOAD, "t"); 61 nextIs(Opcodes.ATHROW); 62 return cursor != null; 63 } 64 65 private boolean nextIsEcj() { 66 cursor = start; 67 nextIs(Opcodes.ALOAD); 68 nextIs(Opcodes.MONITOREXIT); 69 nextIs(Opcodes.ATHROW); 70 return cursor != null; 71 } 72 } 73 74 } 75