MCPcopy Index your code
hub / github.com/clojure/clojure / computeMaxStackAndLocal

Method computeMaxStackAndLocal

src/jvm/clojure/asm/MethodWriter.java:1654–1758  ·  view source on GitHub ↗

Computes the maximum stack size of the method.

()

Source from the content-addressed store, hash-verified

1652
1653 /** Computes the maximum stack size of the method. */
1654 private void computeMaxStackAndLocal() {
1655 // Complete the control flow graph with exception handler blocks.
1656 Handler handler = firstHandler;
1657 while (handler != null) {
1658 Label handlerBlock = handler.handlerPc;
1659 Label handlerRangeBlock = handler.startPc;
1660 Label handlerRangeEnd = handler.endPc;
1661 // Add handlerBlock as a successor of all the basic blocks in the exception handler range.
1662 while (handlerRangeBlock != handlerRangeEnd) {
1663 if ((handlerRangeBlock.flags & Label.FLAG_SUBROUTINE_CALLER) == 0) {
1664 handlerRangeBlock.outgoingEdges =
1665 new Edge(Edge.EXCEPTION, handlerBlock, handlerRangeBlock.outgoingEdges);
1666 } else {
1667 // If handlerRangeBlock is a JSR block, add handlerBlock after the first two outgoing
1668 // edges to preserve the hypothesis about JSR block successors order (see
1669 // {@link #visitJumpInsn}).
1670 handlerRangeBlock.outgoingEdges.nextEdge.nextEdge =
1671 new Edge(
1672 Edge.EXCEPTION, handlerBlock, handlerRangeBlock.outgoingEdges.nextEdge.nextEdge);
1673 }
1674 handlerRangeBlock = handlerRangeBlock.nextBasicBlock;
1675 }
1676 handler = handler.nextHandler;
1677 }
1678
1679 // Complete the control flow graph with the successor blocks of subroutines, if needed.
1680 if (hasSubroutines) {
1681 // First step: find the subroutines. This step determines, for each basic block, to which
1682 // subroutine(s) it belongs. Start with the main "subroutine":
1683 short numSubroutines = 1;
1684 firstBasicBlock.markSubroutine(numSubroutines);
1685 // Then, mark the subroutines called by the main subroutine, then the subroutines called by
1686 // those called by the main subroutine, etc.
1687 for (short currentSubroutine = 1; currentSubroutine <= numSubroutines; ++currentSubroutine) {
1688 Label basicBlock = firstBasicBlock;
1689 while (basicBlock != null) {
1690 if ((basicBlock.flags & Label.FLAG_SUBROUTINE_CALLER) != 0
1691 && basicBlock.subroutineId == currentSubroutine) {
1692 Label jsrTarget = basicBlock.outgoingEdges.nextEdge.successor;
1693 if (jsrTarget.subroutineId == 0) {
1694 // If this subroutine has not been marked yet, find its basic blocks.
1695 jsrTarget.markSubroutine(++numSubroutines);
1696 }
1697 }
1698 basicBlock = basicBlock.nextBasicBlock;
1699 }
1700 }
1701 // Second step: find the successors in the control flow graph of each subroutine basic block
1702 // 'r' ending with a RET instruction. These successors are the virtual successors of the basic
1703 // blocks ending with JSR instructions (see {@link #visitJumpInsn)} that can reach 'r'.
1704 Label basicBlock = firstBasicBlock;
1705 while (basicBlock != null) {
1706 if ((basicBlock.flags & Label.FLAG_SUBROUTINE_CALLER) != 0) {
1707 // By construction, jsr targets are stored in the second outgoing edge of basic blocks
1708 // that ends with a jsr instruction (see {@link #FLAG_SUBROUTINE_CALLER}).
1709 Label subroutine = basicBlock.outgoingEdges.nextEdge.successor;
1710 subroutine.addSubroutineRetSuccessors(basicBlock);
1711 }

Callers 1

visitMaxsMethod · 0.95

Calls 2

markSubroutineMethod · 0.95

Tested by

no test coverage detected