1e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/******************************************************************************* 234cd880f4e52a32b9f88ed4ea687b8f3f892395bEvgeny Mandrikov * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors 3e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * All rights reserved. This program and the accompanying materials 4e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * are made available under the terms of the Eclipse Public License v1.0 5e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * which accompanies this distribution, and is available at 6e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * http://www.eclipse.org/legal/epl-v10.html 7e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 8e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Contributors: 9e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Marc R. Hoffmann - initial API and implementation 10e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 11e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov *******************************************************************************/ 12e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovpackage org.jacoco.core.internal.flow; 13e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 14e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovimport org.objectweb.asm.Label; 15e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 16e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov/** 17e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Data container that is attached to {@link Label#info} objects to store flow 18e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * and instrumentation specific information. The information is only valid 19e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * locally in specific contexts. 20e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 21e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikovpublic final class LabelInfo { 22e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 23e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 24e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Reserved ID for "no probe". 25e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 26e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static final int NO_PROBE = -1; 27e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 28e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private boolean target = false; 29e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 30e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private boolean multiTarget = false; 31e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 32e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private boolean successor = false; 33e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 34873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann private boolean methodInvocationLine = false; 35873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann 36e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private boolean done = false; 37e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 38e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private int probeid = NO_PROBE; 39e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 40e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private Label intermediate = null; 41e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 42e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private Instruction instruction = null; 43e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 44e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov // instances are only created within this class 45e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private LabelInfo() { 46e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 47e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 48e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 49e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Defines that the given label is a jump target. 50e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 51e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 52e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to define 53e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 54e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void setTarget(final Label label) { 55e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = create(label); 56e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (info.target || info.successor) { 57e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov info.multiTarget = true; 58e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } else { 59e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov info.target = true; 60e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 61e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 62e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 63e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 64e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Defines that the given label is the possible successor of the previous 65e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * instruction in the method. 66e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 67e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 68e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to define 69e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 70e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void setSuccessor(final Label label) { 71e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = create(label); 72e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov info.successor = true; 73e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (info.target) { 74e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov info.multiTarget = true; 75e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 76e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 77e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 78e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 79e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Checks whether multiple control paths lead to a label. Control flow path 80e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * to a certain label are: jump targets, exception handlers and normal 813ceb0a9087cdb0f07c0e9d074345a278ed8a5d3cCarsten Otto * control flow from its predecessor instruction (unless this is an 82e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * unconditional jump or method exit). 83e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 84e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 85e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to check 86e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return <code>true</code> if the given multiple control paths lead to the 87e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * given label 88e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 89e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static boolean isMultiTarget(final Label label) { 90e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 91e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info == null ? false : info.multiTarget; 92e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 93e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 94e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 95e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Checks whether this label is the possible successor of the previous 96e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * instruction in the method. This is the case if the predecessor isn't a 97e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * unconditional jump or method exit instruction. 98e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 99e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 100e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to check 101e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return <code>true</code> if the label is a possible instruction 102e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * successor 103e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 104e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static boolean isSuccessor(final Label label) { 105e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 106e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info == null ? false : info.successor; 107e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 108e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 109e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 110873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * Mark a given label as the beginning of a line with method invocations. 111873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * 112873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * @param label 113873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * label to mark 114873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann */ 115873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann public static void setMethodInvocationLine(final Label label) { 116873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann create(label).methodInvocationLine = true; 117873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann } 118873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann 119873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann /** 120873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * Checks whether the a given label has been marked as a line with method 121873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * invocations. 122873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * 123873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * @param label 124873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * label to check 125873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * @return <code>true</code> if the label represents a line with method 126873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * invocations 127873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann */ 128873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann public static boolean isMethodInvocationLine(final Label label) { 129873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann final LabelInfo info = get(label); 130873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann return info == null ? false : info.methodInvocationLine; 131873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann } 132873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann 133873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann /** 134873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * Determines whether the given label needs a probe to be inserted before. 135873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * 136873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * @param label 137873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * label to test 138873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann * @return <code>true</code> if a probe should be inserted before 139873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann */ 140873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann public static boolean needsProbe(final Label label) { 141873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann final LabelInfo info = get(label); 142873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann return info != null && info.successor 143873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann && (info.multiTarget || info.methodInvocationLine); 144873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann } 145873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann 146873114568ee148ea2e15cd036d57bf7b43ba154dMarc R. Hoffmann /** 147e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Mark a given label as done. 148e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 149e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 150e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to mark 151e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 152e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void setDone(final Label label) { 153e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov create(label).done = true; 154e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 155e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 156e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 157e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Resets the "done" status of a given label. 158e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 159e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 160e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to reset 161e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 162e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void resetDone(final Label label) { 163e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 164e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (info != null) { 165e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov info.done = false; 166e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 167e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 168e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 169e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 170e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Resets the "done" status of all given labels. 171e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 172e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param labels 173e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * labels to reset 174e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 175e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void resetDone(final Label[] labels) { 176e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov for (final Label label : labels) { 177e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov resetDone(label); 178e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 179e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 180e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 181e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 182e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Checks whether this label is marked as done. 183e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 184e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 185e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to check 186e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return <code>true</code> if this label is marked as done 187e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 188e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static boolean isDone(final Label label) { 189e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 190e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info == null ? false : info.done; 191e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 192e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 193e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 194e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Sets the given probe id to the given label. 195e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 196e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 197e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to assign a probe to 198e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param id 199e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * id of the probe 200e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 201e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void setProbeId(final Label label, final int id) { 202e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov create(label).probeid = id; 203e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 204e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 205e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 206e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Returns the assigned probe id. 207e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 208e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 209e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to check 210e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return probe id or {@link #NO_PROBE} if no probe is assigned to the 211e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label 212e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 213e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static int getProbeId(final Label label) { 214e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 215e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info == null ? NO_PROBE : info.probeid; 216e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 217e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 218e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 219e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Defines an intermediate label for the given label. Such intermediate 220e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * labels are required during instrumentation to add probes to jump targets. 221e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 222e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 223e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to define for 224e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param intermediate 225e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * intermediate label 226e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 227e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void setIntermediateLabel(final Label label, 228e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final Label intermediate) { 229e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov create(label).intermediate = intermediate; 230e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 231e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 232e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 233e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Returns the intermediate label for the given label if one has been 234e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * defined. 235e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 236e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 237e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to look for 238e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return intermediate label or <code>null</code> 239e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 240e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static Label getIntermediateLabel(final Label label) { 241e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 242e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info == null ? null : info.intermediate; 243e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 244e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 245e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 246e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Sets the instruction corresponding to this label. 247e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 248e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 249e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to set the instruction for 250e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param instruction 251e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * corresponding instruction 252e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 253e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static void setInstruction(final Label label, 254e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final Instruction instruction) { 255e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov create(label).instruction = instruction; 256e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 257e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 258e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov /** 259e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * Returns the corresponding instruction for the given label if one has been 260e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * defined. 261e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * 262e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @param label 263e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * label to look for 264e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov * @return corresponding instruction or <code>null</code> 265e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov */ 266e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov public static Instruction getInstruction(final Label label) { 267e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final LabelInfo info = get(label); 268e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info == null ? null : info.instruction; 269e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 270e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 271e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static LabelInfo get(final Label label) { 272e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov final Object info = label.info; 273e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info instanceof LabelInfo ? (LabelInfo) info : null; 274e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 275e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 276e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov private static LabelInfo create(final Label label) { 277e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov LabelInfo info = get(label); 278e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov if (info == null) { 279e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov info = new LabelInfo(); 280e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov label.info = info; 281e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 282e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov return info; 283e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov } 284e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov 285e69ba4dbb015949c5d84ba7bbb0b53efac28bb23Evgeny Mandrikov} 286