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
}
}
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;
}
Aggregations