001// ASM: a very small and fast Java bytecode manipulation framework
002// Copyright (c) 2000-2011 INRIA, France Telecom
003// All rights reserved.
004//
005// Redistribution and use in source and binary forms, with or without
006// modification, are permitted provided that the following conditions
007// are met:
008// 1. Redistributions of source code must retain the above copyright
009//    notice, this list of conditions and the following disclaimer.
010// 2. Redistributions in binary form must reproduce the above copyright
011//    notice, this list of conditions and the following disclaimer in the
012//    documentation and/or other materials provided with the distribution.
013// 3. Neither the name of the copyright holders nor the names of its
014//    contributors may be used to endorse or promote products derived from
015//    this software without specific prior written permission.
016//
017// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
020// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
021// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
022// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
023// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
024// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
025// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
026// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
027// THE POSSIBILITY OF SUCH DAMAGE.
028package io.ebean.enhance.asm;
029
030/**
031 * A position in the bytecode of a method. Labels are used for jump, goto, and switch instructions,
032 * and for try catch blocks. A label designates the <i>instruction</i> that is just after. Note
033 * however that there can be other elements between a label and the instruction it designates (such
034 * as other labels, stack map frames, line numbers, etc.).
035 *
036 * @author Eric Bruneton
037 */
038public class Label {
039
040  /**
041   * A flag indicating that a label is only used for debug attributes. Such a label is not the start
042   * of a basic block, the target of a jump instruction, or an exception handler. It can be safely
043   * ignored in control flow graph analysis algorithms (for optimization purposes).
044   */
045  static final int FLAG_DEBUG_ONLY = 1;
046
047  /**
048   * A flag indicating that a label is the target of a jump instruction, or the start of an
049   * exception handler.
050   */
051  static final int FLAG_JUMP_TARGET = 2;
052
053  /** A flag indicating that the bytecode offset of a label is known. */
054  static final int FLAG_RESOLVED = 4;
055
056  /** A flag indicating that a label corresponds to a reachable basic block. */
057  static final int FLAG_REACHABLE = 8;
058
059  /**
060   * A flag indicating that the basic block corresponding to a label ends with a subroutine call. By
061   * construction in {@link MethodWriter#visitJumpInsn}, labels with this flag set have at least two
062   * outgoing edges:
063   *
064   * <ul>
065   *   <li>the first one corresponds to the instruction that follows the jsr instruction in the
066   *       bytecode, i.e. where execution continues when it returns from the jsr call. This is a
067   *       virtual control flow edge, since execution never goes directly from the jsr to the next
068   *       instruction. Instead, it goes to the subroutine and eventually returns to the instruction
069   *       following the jsr. This virtual edge is used to compute the real outgoing edges of the
070   *       basic blocks ending with a ret instruction, in {@link #addSubroutineRetSuccessors}.
071   *   <li>the second one corresponds to the target of the jsr instruction,
072   * </ul>
073   */
074  static final int FLAG_SUBROUTINE_CALLER = 16;
075
076  /**
077   * A flag indicating that the basic block corresponding to a label is the start of a subroutine.
078   */
079  static final int FLAG_SUBROUTINE_START = 32;
080
081  /** A flag indicating that the basic block corresponding to a label is the end of a subroutine. */
082  static final int FLAG_SUBROUTINE_END = 64;
083
084  /** A flag indicating that this label has at least one associated line number. */
085  static final int FLAG_LINE_NUMBER = 128;
086
087  /**
088   * The number of elements to add to the {@link #otherLineNumbers} array when it needs to be
089   * resized to store a new source line number.
090   */
091  static final int LINE_NUMBERS_CAPACITY_INCREMENT = 4;
092
093  /**
094   * The number of elements to add to the {@link #forwardReferences} array when it needs to be
095   * resized to store a new forward reference.
096   */
097  static final int FORWARD_REFERENCES_CAPACITY_INCREMENT = 6;
098
099  /**
100   * The bit mask to extract the type of a forward reference to this label. The extracted type is
101   * either {@link #FORWARD_REFERENCE_TYPE_SHORT} or {@link #FORWARD_REFERENCE_TYPE_WIDE}.
102   *
103   * @see #forwardReferences
104   */
105  static final int FORWARD_REFERENCE_TYPE_MASK = 0xF0000000;
106
107  /**
108   * The type of forward references stored with two bytes in the bytecode. This is the case, for
109   * instance, of a forward reference from an ifnull instruction.
110   */
111  static final int FORWARD_REFERENCE_TYPE_SHORT = 0x10000000;
112
113  /**
114   * The type of forward references stored in four bytes in the bytecode. This is the case, for
115   * instance, of a forward reference from a lookupswitch instruction.
116   */
117  static final int FORWARD_REFERENCE_TYPE_WIDE = 0x20000000;
118
119  /**
120   * The bit mask to extract the 'handle' of a forward reference to this label. The extracted handle
121   * is the bytecode offset where the forward reference value is stored (using either 2 or 4 bytes,
122   * as indicated by the {@link #FORWARD_REFERENCE_TYPE_MASK}).
123   *
124   * @see #forwardReferences
125   */
126  static final int FORWARD_REFERENCE_HANDLE_MASK = 0x0FFFFFFF;
127
128  /**
129   * A sentinel element used to indicate the end of a list of labels.
130   *
131   * @see #nextListElement
132   */
133  static final Label EMPTY_LIST = new Label();
134
135  /**
136   * A user managed state associated with this label. Warning: this field is used by the ASM tree
137   * package. In order to use it with the ASM tree package you must override the getLabelNode method
138   * in MethodNode.
139   */
140  public Object info;
141
142  /**
143   * The type and status of this label or its corresponding basic block. Must be zero or more of
144   * {@link #FLAG_DEBUG_ONLY}, {@link #FLAG_JUMP_TARGET}, {@link #FLAG_RESOLVED}, {@link
145   * #FLAG_REACHABLE}, {@link #FLAG_SUBROUTINE_CALLER}, {@link #FLAG_SUBROUTINE_START}, {@link
146   * #FLAG_SUBROUTINE_END}.
147   */
148  short flags;
149
150  /**
151   * The source line number corresponding to this label, if {@link #FLAG_LINE_NUMBER} is set. If
152   * there are several source line numbers corresponding to this label, the first one is stored in
153   * this field, and the remaining ones are stored in {@link #otherLineNumbers}.
154   */
155  private short lineNumber;
156
157  /**
158   * The source line numbers corresponding to this label, in addition to {@link #lineNumber}, or
159   * null. The first element of this array is the number n of source line numbers it contains, which
160   * are stored between indices 1 and n (inclusive).
161   */
162  private int[] otherLineNumbers;
163
164  /**
165   * The offset of this label in the bytecode of its method, in bytes. This value is set if and only
166   * if the {@link #FLAG_RESOLVED} flag is set.
167   */
168  int bytecodeOffset;
169
170  /**
171   * The forward references to this label. The first element is the number of forward references,
172   * times 2 (this corresponds to the index of the last element actually used in this array). Then,
173   * each forward reference is described with two consecutive integers noted
174   * 'sourceInsnBytecodeOffset' and 'reference':
175   *
176   * <ul>
177   *   <li>'sourceInsnBytecodeOffset' is the bytecode offset of the instruction that contains the
178   *       forward reference,
179   *   <li>'reference' contains the type and the offset in the bytecode where the forward reference
180   *       value must be stored, which can be extracted with {@link #FORWARD_REFERENCE_TYPE_MASK}
181   *       and {@link #FORWARD_REFERENCE_HANDLE_MASK}.
182   * </ul>
183   *
184   * <p>For instance, for an ifnull instruction at bytecode offset x, 'sourceInsnBytecodeOffset' is
185   * equal to x, and 'reference' is of type {@link #FORWARD_REFERENCE_TYPE_SHORT} with value x + 1
186   * (because the ifnull instruction uses a 2 bytes bytecode offset operand stored one byte after
187   * the start of the instruction itself). For the default case of a lookupswitch instruction at
188   * bytecode offset x, 'sourceInsnBytecodeOffset' is equal to x, and 'reference' is of type {@link
189   * #FORWARD_REFERENCE_TYPE_WIDE} with value between x + 1 and x + 4 (because the lookupswitch
190   * instruction uses a 4 bytes bytecode offset operand stored one to four bytes after the start of
191   * the instruction itself).
192   */
193  private int[] forwardReferences;
194
195  // -----------------------------------------------------------------------------------------------
196
197  // Fields for the control flow and data flow graph analysis algorithms (used to compute the
198  // maximum stack size or the stack map frames). A control flow graph contains one node per "basic
199  // block", and one edge per "jump" from one basic block to another. Each node (i.e., each basic
200  // block) is represented with the Label object that corresponds to the first instruction of this
201  // basic block. Each node also stores the list of its successors in the graph, as a linked list of
202  // Edge objects.
203  //
204  // The control flow analysis algorithms used to compute the maximum stack size or the stack map
205  // frames are similar and use two steps. The first step, during the visit of each instruction,
206  // builds information about the state of the local variables and the operand stack at the end of
207  // each basic block, called the "output frame", <i>relatively</i> to the frame state at the
208  // beginning of the basic block, which is called the "input frame", and which is <i>unknown</i>
209  // during this step. The second step, in {@link MethodWriter#computeAllFrames} and {@link
210  // MethodWriter#computeMaxStackAndLocal}, is a fix point algorithm
211  // that computes information about the input frame of each basic block, from the input state of
212  // the first basic block (known from the method signature), and by the using the previously
213  // computed relative output frames.
214  //
215  // The algorithm used to compute the maximum stack size only computes the relative output and
216  // absolute input stack heights, while the algorithm used to compute stack map frames computes
217  // relative output frames and absolute input frames.
218
219  /**
220   * The number of elements in the input stack of the basic block corresponding to this label. This
221   * field is computed in {@link MethodWriter#computeMaxStackAndLocal}.
222   */
223  short inputStackSize;
224
225  /**
226   * The number of elements in the output stack, at the end of the basic block corresponding to this
227   * label. This field is only computed for basic blocks that end with a RET instruction.
228   */
229  short outputStackSize;
230
231  /**
232   * The maximum height reached by the output stack, relatively to the top of the input stack, in
233   * the basic block corresponding to this label. This maximum is always positive or {@literal
234   * null}.
235   */
236  short outputStackMax;
237
238  /**
239   * The id of the subroutine to which this basic block belongs, or 0. If the basic block belongs to
240   * several subroutines, this is the id of the "oldest" subroutine that contains it (with the
241   * convention that a subroutine calling another one is "older" than the callee). This field is
242   * computed in {@link MethodWriter#computeMaxStackAndLocal}, if the method contains JSR
243   * instructions.
244   */
245  short subroutineId;
246
247  /**
248   * The input and output stack map frames of the basic block corresponding to this label. This
249   * field is only used when the {@link MethodWriter#COMPUTE_ALL_FRAMES} or {@link
250   * MethodWriter#COMPUTE_INSERTED_FRAMES} option is used.
251   */
252  Frame frame;
253
254  /**
255   * The successor of this label, in the order they are visited in {@link MethodVisitor#visitLabel}.
256   * This linked list does not include labels used for debug info only. If the {@link
257   * MethodWriter#COMPUTE_ALL_FRAMES} or {@link MethodWriter#COMPUTE_INSERTED_FRAMES} option is used
258   * then it does not contain either successive labels that denote the same bytecode offset (in this
259   * case only the first label appears in this list).
260   */
261  Label nextBasicBlock;
262
263  /**
264   * The outgoing edges of the basic block corresponding to this label, in the control flow graph of
265   * its method. These edges are stored in a linked list of {@link Edge} objects, linked to each
266   * other by their {@link Edge#nextEdge} field.
267   */
268  Edge outgoingEdges;
269
270  /**
271   * The next element in the list of labels to which this label belongs, or {@literal null} if it
272   * does not belong to any list. All lists of labels must end with the {@link #EMPTY_LIST}
273   * sentinel, in order to ensure that this field is null if and only if this label does not belong
274   * to a list of labels. Note that there can be several lists of labels at the same time, but that
275   * a label can belong to at most one list at a time (unless some lists share a common tail, but
276   * this is not used in practice).
277   *
278   * <p>List of labels are used in {@link MethodWriter#computeAllFrames} and {@link
279   * MethodWriter#computeMaxStackAndLocal} to compute stack map frames and the maximum stack size,
280   * respectively, as well as in {@link #markSubroutine} and {@link #addSubroutineRetSuccessors} to
281   * compute the basic blocks belonging to subroutines and their outgoing edges. Outside of these
282   * methods, this field should be null (this property is a precondition and a postcondition of
283   * these methods).
284   */
285  Label nextListElement;
286
287  // -----------------------------------------------------------------------------------------------
288  // Constructor and accessors
289  // -----------------------------------------------------------------------------------------------
290
291  /** Constructs a new label. */
292  public Label() {
293    // Nothing to do.
294  }
295
296  /**
297   * Returns the bytecode offset corresponding to this label. This offset is computed from the start
298   * of the method's bytecode. <i>This method is intended for {@link Attribute} sub classes, and is
299   * normally not needed by class generators or adapters.</i>
300   *
301   * @return the bytecode offset corresponding to this label.
302   * @throws IllegalStateException if this label is not resolved yet.
303   */
304  public int getOffset() {
305    if ((flags & FLAG_RESOLVED) == 0) {
306      throw new IllegalStateException("Label offset position has not been resolved yet");
307    }
308    return bytecodeOffset;
309  }
310
311  /**
312   * Returns the "canonical" {@link Label} instance corresponding to this label's bytecode offset,
313   * if known, otherwise the label itself. The canonical instance is the first label (in the order
314   * of their visit by {@link MethodVisitor#visitLabel}) corresponding to this bytecode offset. It
315   * cannot be known for labels which have not been visited yet.
316   *
317   * <p><i>This method should only be used when the {@link MethodWriter#COMPUTE_ALL_FRAMES} option
318   * is used.</i>
319   *
320   * @return the label itself if {@link #frame} is null, otherwise the Label's frame owner. This
321   *     corresponds to the "canonical" label instance described above thanks to the way the label
322   *     frame is set in {@link MethodWriter#visitLabel}.
323   */
324  final Label getCanonicalInstance() {
325    return frame == null ? this : frame.owner;
326  }
327
328  // -----------------------------------------------------------------------------------------------
329  // Methods to manage line numbers
330  // -----------------------------------------------------------------------------------------------
331
332  /**
333   * Adds a source line number corresponding to this label.
334   *
335   * @param lineNumber a source line number (which should be strictly positive).
336   */
337  final void addLineNumber(final int lineNumber) {
338    if ((flags & FLAG_LINE_NUMBER) == 0) {
339      flags |= FLAG_LINE_NUMBER;
340      this.lineNumber = (short) lineNumber;
341    } else {
342      if (otherLineNumbers == null) {
343        otherLineNumbers = new int[LINE_NUMBERS_CAPACITY_INCREMENT];
344      }
345      int otherLineNumberIndex = ++otherLineNumbers[0];
346      if (otherLineNumberIndex >= otherLineNumbers.length) {
347        int[] newLineNumbers = new int[otherLineNumbers.length + LINE_NUMBERS_CAPACITY_INCREMENT];
348        System.arraycopy(otherLineNumbers, 0, newLineNumbers, 0, otherLineNumbers.length);
349        otherLineNumbers = newLineNumbers;
350      }
351      otherLineNumbers[otherLineNumberIndex] = lineNumber;
352    }
353  }
354
355  /**
356   * Makes the given visitor visit this label and its source line numbers, if applicable.
357   *
358   * @param methodVisitor a method visitor.
359   * @param visitLineNumbers whether to visit of the label's source line numbers, if any.
360   */
361  final void accept(final MethodVisitor methodVisitor, final boolean visitLineNumbers) {
362    methodVisitor.visitLabel(this);
363    if (visitLineNumbers && (flags & FLAG_LINE_NUMBER) != 0) {
364      methodVisitor.visitLineNumber(lineNumber & 0xFFFF, this);
365      if (otherLineNumbers != null) {
366        for (int i = 1; i <= otherLineNumbers[0]; ++i) {
367          methodVisitor.visitLineNumber(otherLineNumbers[i], this);
368        }
369      }
370    }
371  }
372
373  // -----------------------------------------------------------------------------------------------
374  // Methods to compute offsets and to manage forward references
375  // -----------------------------------------------------------------------------------------------
376
377  /**
378   * Puts a reference to this label in the bytecode of a method. If the bytecode offset of the label
379   * is known, the relative bytecode offset between the label and the instruction referencing it is
380   * computed and written directly. Otherwise, a null relative offset is written and a new forward
381   * reference is declared for this label.
382   *
383   * @param code the bytecode of the method. This is where the reference is appended.
384   * @param sourceInsnBytecodeOffset the bytecode offset of the instruction that contains the
385   *     reference to be appended.
386   * @param wideReference whether the reference must be stored in 4 bytes (instead of 2 bytes).
387   */
388  final void put(
389      final ByteVector code, final int sourceInsnBytecodeOffset, final boolean wideReference) {
390    if ((flags & FLAG_RESOLVED) == 0) {
391      if (wideReference) {
392        addForwardReference(sourceInsnBytecodeOffset, FORWARD_REFERENCE_TYPE_WIDE, code.length);
393        code.putInt(-1);
394      } else {
395        addForwardReference(sourceInsnBytecodeOffset, FORWARD_REFERENCE_TYPE_SHORT, code.length);
396        code.putShort(-1);
397      }
398    } else {
399      if (wideReference) {
400        code.putInt(bytecodeOffset - sourceInsnBytecodeOffset);
401      } else {
402        code.putShort(bytecodeOffset - sourceInsnBytecodeOffset);
403      }
404    }
405  }
406
407  /**
408   * Adds a forward reference to this label. This method must be called only for a true forward
409   * reference, i.e. only if this label is not resolved yet. For backward references, the relative
410   * bytecode offset of the reference can be, and must be, computed and stored directly.
411   *
412   * @param sourceInsnBytecodeOffset the bytecode offset of the instruction that contains the
413   *     reference stored at referenceHandle.
414   * @param referenceType either {@link #FORWARD_REFERENCE_TYPE_SHORT} or {@link
415   *     #FORWARD_REFERENCE_TYPE_WIDE}.
416   * @param referenceHandle the offset in the bytecode where the forward reference value must be
417   *     stored.
418   */
419  private void addForwardReference(
420      final int sourceInsnBytecodeOffset, final int referenceType, final int referenceHandle) {
421    if (forwardReferences == null) {
422      forwardReferences = new int[FORWARD_REFERENCES_CAPACITY_INCREMENT];
423    }
424    int lastElementIndex = forwardReferences[0];
425    if (lastElementIndex + 2 >= forwardReferences.length) {
426      int[] newValues = new int[forwardReferences.length + FORWARD_REFERENCES_CAPACITY_INCREMENT];
427      System.arraycopy(forwardReferences, 0, newValues, 0, forwardReferences.length);
428      forwardReferences = newValues;
429    }
430    forwardReferences[++lastElementIndex] = sourceInsnBytecodeOffset;
431    forwardReferences[++lastElementIndex] = referenceType | referenceHandle;
432    forwardReferences[0] = lastElementIndex;
433  }
434
435  /**
436   * Sets the bytecode offset of this label to the given value and resolves the forward references
437   * to this label, if any. This method must be called when this label is added to the bytecode of
438   * the method, i.e. when its bytecode offset becomes known. This method fills in the blanks that
439   * where left in the bytecode by each forward reference previously added to this label.
440   *
441   * @param code the bytecode of the method.
442   * @param bytecodeOffset the bytecode offset of this label.
443   * @return {@literal true} if a blank that was left for this label was too small to store the
444   *     offset. In such a case the corresponding jump instruction is replaced with an equivalent
445   *     ASM specific instruction using an unsigned two bytes offset. These ASM specific
446   *     instructions are later replaced with standard bytecode instructions with wider offsets (4
447   *     bytes instead of 2), in ClassReader.
448   */
449  final boolean resolve(final byte[] code, final int bytecodeOffset) {
450    this.flags |= FLAG_RESOLVED;
451    this.bytecodeOffset = bytecodeOffset;
452    if (forwardReferences == null) {
453      return false;
454    }
455    boolean hasAsmInstructions = false;
456    for (int i = forwardReferences[0]; i > 0; i -= 2) {
457      final int sourceInsnBytecodeOffset = forwardReferences[i - 1];
458      final int reference = forwardReferences[i];
459      final int relativeOffset = bytecodeOffset - sourceInsnBytecodeOffset;
460      int handle = reference & FORWARD_REFERENCE_HANDLE_MASK;
461      if ((reference & FORWARD_REFERENCE_TYPE_MASK) == FORWARD_REFERENCE_TYPE_SHORT) {
462        if (relativeOffset < Short.MIN_VALUE || relativeOffset > Short.MAX_VALUE) {
463          // Change the opcode of the jump instruction, in order to be able to find it later in
464          // ClassReader. These ASM specific opcodes are similar to jump instruction opcodes, except
465          // that the 2 bytes offset is unsigned (and can therefore represent values from 0 to
466          // 65535, which is sufficient since the size of a method is limited to 65535 bytes).
467          int opcode = code[sourceInsnBytecodeOffset] & 0xFF;
468          if (opcode < Opcodes.IFNULL) {
469            // Change IFEQ ... JSR to ASM_IFEQ ... ASM_JSR.
470            code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_OPCODE_DELTA);
471          } else {
472            // Change IFNULL and IFNONNULL to ASM_IFNULL and ASM_IFNONNULL.
473            code[sourceInsnBytecodeOffset] = (byte) (opcode + Constants.ASM_IFNULL_OPCODE_DELTA);
474          }
475          hasAsmInstructions = true;
476        }
477        code[handle++] = (byte) (relativeOffset >>> 8);
478        code[handle] = (byte) relativeOffset;
479      } else {
480        code[handle++] = (byte) (relativeOffset >>> 24);
481        code[handle++] = (byte) (relativeOffset >>> 16);
482        code[handle++] = (byte) (relativeOffset >>> 8);
483        code[handle] = (byte) relativeOffset;
484      }
485    }
486    return hasAsmInstructions;
487  }
488
489  // -----------------------------------------------------------------------------------------------
490  // Methods related to subroutines
491  // -----------------------------------------------------------------------------------------------
492
493  /**
494   * Finds the basic blocks that belong to the subroutine starting with the basic block
495   * corresponding to this label, and marks these blocks as belonging to this subroutine. This
496   * method follows the control flow graph to find all the blocks that are reachable from the
497   * current basic block WITHOUT following any jsr target.
498   *
499   * <p>Note: a precondition and postcondition of this method is that all labels must have a null
500   * {@link #nextListElement}.
501   *
502   * @param subroutineId the id of the subroutine starting with the basic block corresponding to
503   *     this label.
504   */
505  final void markSubroutine(final short subroutineId) {
506    // Data flow algorithm: put this basic block in a list of blocks to process (which are blocks
507    // belonging to subroutine subroutineId) and, while there are blocks to process, remove one from
508    // the list, mark it as belonging to the subroutine, and add its successor basic blocks in the
509    // control flow graph to the list of blocks to process (if not already done).
510    Label listOfBlocksToProcess = this;
511    listOfBlocksToProcess.nextListElement = EMPTY_LIST;
512    while (listOfBlocksToProcess != EMPTY_LIST) {
513      // Remove a basic block from the list of blocks to process.
514      Label basicBlock = listOfBlocksToProcess;
515      listOfBlocksToProcess = listOfBlocksToProcess.nextListElement;
516      basicBlock.nextListElement = null;
517
518      // If it is not already marked as belonging to a subroutine, mark it as belonging to
519      // subroutineId and add its successors to the list of blocks to process (unless already done).
520      if (basicBlock.subroutineId == 0) {
521        basicBlock.subroutineId = subroutineId;
522        listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess);
523      }
524    }
525  }
526
527  /**
528   * Finds the basic blocks that end a subroutine starting with the basic block corresponding to
529   * this label and, for each one of them, adds an outgoing edge to the basic block following the
530   * given subroutine call. In other words, completes the control flow graph by adding the edges
531   * corresponding to the return from this subroutine, when called from the given caller basic
532   * block.
533   *
534   * <p>Note: a precondition and postcondition of this method is that all labels must have a null
535   * {@link #nextListElement}.
536   *
537   * @param subroutineCaller a basic block that ends with a jsr to the basic block corresponding to
538   *     this label. This label is supposed to correspond to the start of a subroutine.
539   */
540  final void addSubroutineRetSuccessors(final Label subroutineCaller) {
541    // Data flow algorithm: put this basic block in a list blocks to process (which are blocks
542    // belonging to a subroutine starting with this label) and, while there are blocks to process,
543    // remove one from the list, put it in a list of blocks that have been processed, add a return
544    // edge to the successor of subroutineCaller if applicable, and add its successor basic blocks
545    // in the control flow graph to the list of blocks to process (if not already done).
546    Label listOfProcessedBlocks = EMPTY_LIST;
547    Label listOfBlocksToProcess = this;
548    listOfBlocksToProcess.nextListElement = EMPTY_LIST;
549    while (listOfBlocksToProcess != EMPTY_LIST) {
550      // Move a basic block from the list of blocks to process to the list of processed blocks.
551      Label basicBlock = listOfBlocksToProcess;
552      listOfBlocksToProcess = basicBlock.nextListElement;
553      basicBlock.nextListElement = listOfProcessedBlocks;
554      listOfProcessedBlocks = basicBlock;
555
556      // Add an edge from this block to the successor of the caller basic block, if this block is
557      // the end of a subroutine and if this block and subroutineCaller do not belong to the same
558      // subroutine.
559      if ((basicBlock.flags & FLAG_SUBROUTINE_END) != 0
560          && basicBlock.subroutineId != subroutineCaller.subroutineId) {
561        basicBlock.outgoingEdges =
562            new Edge(
563                basicBlock.outputStackSize,
564                // By construction, the first outgoing edge of a basic block that ends with a jsr
565                // instruction leads to the jsr continuation block, i.e. where execution continues
566                // when ret is called (see {@link #FLAG_SUBROUTINE_CALLER}).
567                subroutineCaller.outgoingEdges.successor,
568                basicBlock.outgoingEdges);
569      }
570      // Add its successors to the list of blocks to process. Note that {@link #pushSuccessors} does
571      // not push basic blocks which are already in a list. Here this means either in the list of
572      // blocks to process, or in the list of already processed blocks. This second list is
573      // important to make sure we don't reprocess an already processed block.
574      listOfBlocksToProcess = basicBlock.pushSuccessors(listOfBlocksToProcess);
575    }
576    // Reset the {@link #nextListElement} of all the basic blocks that have been processed to null,
577    // so that this method can be called again with a different subroutine or subroutine caller.
578    while (listOfProcessedBlocks != EMPTY_LIST) {
579      Label newListOfProcessedBlocks = listOfProcessedBlocks.nextListElement;
580      listOfProcessedBlocks.nextListElement = null;
581      listOfProcessedBlocks = newListOfProcessedBlocks;
582    }
583  }
584
585  /**
586   * Adds the successors of this label in the method's control flow graph (except those
587   * corresponding to a jsr target, and those already in a list of labels) to the given list of
588   * blocks to process, and returns the new list.
589   *
590   * @param listOfLabelsToProcess a list of basic blocks to process, linked together with their
591   *     {@link #nextListElement} field.
592   * @return the new list of blocks to process.
593   */
594  private Label pushSuccessors(final Label listOfLabelsToProcess) {
595    Label newListOfLabelsToProcess = listOfLabelsToProcess;
596    Edge outgoingEdge = outgoingEdges;
597    while (outgoingEdge != null) {
598      // By construction, the second outgoing edge of a basic block that ends with a jsr instruction
599      // leads to the jsr target (see {@link #FLAG_SUBROUTINE_CALLER}).
600      boolean isJsrTarget =
601          (flags & Label.FLAG_SUBROUTINE_CALLER) != 0 && outgoingEdge == outgoingEdges.nextEdge;
602      if (!isJsrTarget && outgoingEdge.successor.nextListElement == null) {
603        // Add this successor to the list of blocks to process, if it does not already belong to a
604        // list of labels.
605        outgoingEdge.successor.nextListElement = newListOfLabelsToProcess;
606        newListOfLabelsToProcess = outgoingEdge.successor;
607      }
608      outgoingEdge = outgoingEdge.nextEdge;
609    }
610    return newListOfLabelsToProcess;
611  }
612
613  // -----------------------------------------------------------------------------------------------
614  // Overridden Object methods
615  // -----------------------------------------------------------------------------------------------
616
617  /**
618   * Returns a string representation of this label.
619   *
620   * @return a string representation of this label.
621   */
622  @Override
623  public String toString() {
624    return "L" + System.identityHashCode(this);
625  }
626}