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

Method computeAllFrames

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

Computes all the stack map frames of the method, from scratch.

()

Source from the content-addressed store, hash-verified

1550
1551 /** Computes all the stack map frames of the method, from scratch. */
1552 private void computeAllFrames() {
1553 // Complete the control flow graph with exception handler blocks.
1554 Handler handler = firstHandler;
1555 while (handler != null) {
1556 String catchTypeDescriptor =
1557 handler.catchTypeDescriptor == null ? "java/lang/Throwable" : handler.catchTypeDescriptor;
1558 int catchType = Frame.getAbstractTypeFromInternalName(symbolTable, catchTypeDescriptor);
1559 // Mark handlerBlock as an exception handler.
1560 Label handlerBlock = handler.handlerPc.getCanonicalInstance();
1561 handlerBlock.flags |= Label.FLAG_JUMP_TARGET;
1562 // Add handlerBlock as a successor of all the basic blocks in the exception handler range.
1563 Label handlerRangeBlock = handler.startPc.getCanonicalInstance();
1564 Label handlerRangeEnd = handler.endPc.getCanonicalInstance();
1565 while (handlerRangeBlock != handlerRangeEnd) {
1566 handlerRangeBlock.outgoingEdges =
1567 new Edge(catchType, handlerBlock, handlerRangeBlock.outgoingEdges);
1568 handlerRangeBlock = handlerRangeBlock.nextBasicBlock;
1569 }
1570 handler = handler.nextHandler;
1571 }
1572
1573 // Create and visit the first (implicit) frame.
1574 Frame firstFrame = firstBasicBlock.frame;
1575 firstFrame.setInputFrameFromDescriptor(symbolTable, accessFlags, descriptor, this.maxLocals);
1576 firstFrame.accept(this);
1577
1578 // Fix point algorithm: add the first basic block to a list of blocks to process (i.e. blocks
1579 // whose stack map frame has changed) and, while there are blocks to process, remove one from
1580 // the list and update the stack map frames of its successor blocks in the control flow graph
1581 // (which might change them, in which case these blocks must be processed too, and are thus
1582 // added to the list of blocks to process). Also compute the maximum stack size of the method,
1583 // as a by-product.
1584 Label listOfBlocksToProcess = firstBasicBlock;
1585 listOfBlocksToProcess.nextListElement = Label.EMPTY_LIST;
1586 int maxStackSize = 0;
1587 while (listOfBlocksToProcess != Label.EMPTY_LIST) {
1588 // Remove a basic block from the list of blocks to process.
1589 Label basicBlock = listOfBlocksToProcess;
1590 listOfBlocksToProcess = listOfBlocksToProcess.nextListElement;
1591 basicBlock.nextListElement = null;
1592 // By definition, basicBlock is reachable.
1593 basicBlock.flags |= Label.FLAG_REACHABLE;
1594 // Update the (absolute) maximum stack size.
1595 int maxBlockStackSize = basicBlock.frame.getInputStackSize() + basicBlock.outputStackMax;
1596 if (maxBlockStackSize > maxStackSize) {
1597 maxStackSize = maxBlockStackSize;
1598 }
1599 // Update the successor blocks of basicBlock in the control flow graph.
1600 Edge outgoingEdge = basicBlock.outgoingEdges;
1601 while (outgoingEdge != null) {
1602 Label successorBlock = outgoingEdge.successor.getCanonicalInstance();
1603 boolean successorBlockChanged =
1604 basicBlock.frame.merge(symbolTable, successorBlock.frame, outgoingEdge.info);
1605 if (successorBlockChanged && successorBlock.nextListElement == null) {
1606 // If successorBlock has changed it must be processed. Thus, if it is not already in the
1607 // list of blocks to process, add it to this list.
1608 successorBlock.nextListElement = listOfBlocksToProcess;
1609 listOfBlocksToProcess = successorBlock;

Callers 1

visitMaxsMethod · 0.95

Calls 11

acceptMethod · 0.95
visitFrameStartMethod · 0.95
visitFrameEndMethod · 0.95
removeRangeMethod · 0.95
getCanonicalInstanceMethod · 0.80
getInputStackSizeMethod · 0.80
mergeMethod · 0.80
acceptMethod · 0.45
maxMethod · 0.45

Tested by

no test coverage detected