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