diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java index 1369af832..c2a12e648 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java @@ -408,6 +408,10 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails, return exitBlock.getPredecessors().contains(block); } + public void resetLoops() { + this.loops = new ArrayList<>(); + } + public void registerLoop(LoopInfo loop) { if (loops.isEmpty()) { loops = new ArrayList<>(5); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockProcessor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockProcessor.java index 12760dca8..f60d4735e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockProcessor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/blocks/BlockProcessor.java @@ -94,6 +94,33 @@ public class BlockProcessor extends AbstractVisitor { updateCleanSuccessors(mth); } + /** + * Recalculate all additional info attached to blocks: + * + *
+	 * - dominators
+	 * - dominance frontier
+	 * - post dominators (only if {@link AFlag#COMPUTE_POST_DOM} added to method)
+	 * - loops and nested loop info
+	 * 
+ * + * This method should be called after changing a block tree in custom passes added before + * {@link BlockFinisher}. + */ + public static void updateBlocksData(MethodNode mth) { + clearBlocksState(mth); + DominatorTree.compute(mth); + markLoops(mth); + + DominatorTree.computeDominanceFrontier(mth); + registerLoops(mth); + processNestedLoops(mth); + + PostDominatorTree.compute(mth); + + updateCleanSuccessors(mth); + } + static void updateCleanSuccessors(MethodNode mth) { mth.getBasicBlocks().forEach(BlockNode::updateCleanSuccessors); } @@ -245,6 +272,7 @@ public class BlockProcessor extends AbstractVisitor { } private static void registerLoops(MethodNode mth) { + mth.resetLoops(); mth.getBasicBlocks().forEach(block -> { if (block.contains(AFlag.LOOP_START)) { block.getAll(AType.LOOP).forEach(mth::registerLoop);