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);