Search in sources :

Example 1 with SynchronizedRegion

use of jadx.core.dex.regions.SynchronizedRegion in project jadx by skylot.

the class RegionMakerVisitor method removeSynchronized.

private static void removeSynchronized(MethodNode mth) {
    Region startRegion = mth.getRegion();
    List<IContainer> subBlocks = startRegion.getSubBlocks();
    if (!subBlocks.isEmpty() && subBlocks.get(0) instanceof SynchronizedRegion) {
        SynchronizedRegion synchRegion = (SynchronizedRegion) subBlocks.get(0);
        InsnNode synchInsn = synchRegion.getEnterInsn();
        if (!synchInsn.getArg(0).isThis()) {
            LOG.warn("In synchronized method {}, top region not synchronized by 'this' {}", mth, synchInsn);
            return;
        }
        // replace synchronized block with inner region
        startRegion.getSubBlocks().set(0, synchRegion.getRegion());
        // remove 'monitor-enter' instruction
        InstructionRemover.remove(mth, synchInsn);
        // remove 'monitor-exit' instruction
        for (InsnNode exit : synchRegion.getExitInsns()) {
            InstructionRemover.remove(mth, exit);
        }
        // run region cleaner again
        CleanRegions.process(mth);
    // assume that CodeShrinker will be run after this
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) IRegion(jadx.core.dex.nodes.IRegion) SwitchRegion(jadx.core.dex.regions.SwitchRegion) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer)

Example 2 with SynchronizedRegion

use of jadx.core.dex.regions.SynchronizedRegion in project jadx by skylot.

the class RegionMaker method processMonitorEnter.

private BlockNode processMonitorEnter(IRegion curRegion, BlockNode block, InsnNode insn, RegionStack stack) {
    SynchronizedRegion synchRegion = new SynchronizedRegion(curRegion, insn);
    synchRegion.getSubBlocks().add(block);
    curRegion.getSubBlocks().add(synchRegion);
    Set<BlockNode> exits = new HashSet<BlockNode>();
    Set<BlockNode> cacheSet = new HashSet<BlockNode>();
    traverseMonitorExits(synchRegion, insn.getArg(0), block, exits, cacheSet);
    for (InsnNode exitInsn : synchRegion.getExitInsns()) {
        BlockNode insnBlock = BlockUtils.getBlockByInsn(mth, exitInsn);
        if (insnBlock != null) {
            insnBlock.add(AFlag.SKIP);
        }
        exitInsn.add(AFlag.SKIP);
        InstructionRemover.unbindInsn(mth, exitInsn);
    }
    BlockNode body = getNextBlock(block);
    if (body == null) {
        ErrorsCounter.methodError(mth, "Unexpected end of synchronized block");
        return null;
    }
    BlockNode exit = null;
    if (exits.size() == 1) {
        exit = getNextBlock(exits.iterator().next());
    } else if (exits.size() > 1) {
        cacheSet.clear();
        exit = traverseMonitorExitsCross(body, exits, cacheSet);
    }
    stack.push(synchRegion);
    if (exit != null) {
        stack.addExit(exit);
    } else {
        for (BlockNode exitBlock : exits) {
            // don't add exit blocks which leads to method end blocks ('return', 'throw', etc)
            List<BlockNode> list = BlockUtils.buildSimplePath(exitBlock);
            if (list.isEmpty() || !list.get(list.size() - 1).getSuccessors().isEmpty()) {
                stack.addExit(exitBlock);
            }
        }
    }
    synchRegion.getSubBlocks().add(makeRegion(body, stack));
    stack.pop();
    return exit;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) HashSet(java.util.HashSet)

Aggregations

InsnNode (jadx.core.dex.nodes.InsnNode)2 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)2 BlockNode (jadx.core.dex.nodes.BlockNode)1 IContainer (jadx.core.dex.nodes.IContainer)1 IRegion (jadx.core.dex.nodes.IRegion)1 Region (jadx.core.dex.regions.Region)1 SwitchRegion (jadx.core.dex.regions.SwitchRegion)1 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)1 HashSet (java.util.HashSet)1