提交 13609a5c 编写于 作者: S Skylot

fix: allow to inline variables around 'monitor-exit' in synchronized block

上级 d6ad21f6
......@@ -21,6 +21,7 @@ import jadx.core.dex.visitors.ModVisitor;
import jadx.core.utils.BlockUtils;
import jadx.core.utils.InsnList;
import jadx.core.utils.InsnRemover;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.JadxRuntimeException;
@JadxVisitor(
......@@ -109,7 +110,7 @@ public class CodeShrinkVisitor extends AbstractVisitor {
BlockNode assignBlock = BlockUtils.getBlockByInsn(mth, assignInsn);
if (assignBlock != null
&& assignInsn != arg.getParentInsn()
&& canMoveBetweenBlocks(assignInsn, assignBlock, block, argsInfo.getInsn())) {
&& canMoveBetweenBlocks(mth, assignInsn, assignBlock, block, argsInfo.getInsn())) {
if (assignInline) {
assignInline(mth, arg, assignInsn, assignBlock);
} else {
......@@ -150,7 +151,7 @@ public class CodeShrinkVisitor extends AbstractVisitor {
return replaced;
}
private static boolean canMoveBetweenBlocks(InsnNode assignInsn, BlockNode assignBlock,
private static boolean canMoveBetweenBlocks(MethodNode mth, InsnNode assignInsn, BlockNode assignBlock,
BlockNode useBlock, InsnNode useInsn) {
if (!BlockUtils.isPathExists(assignBlock, useBlock)) {
return false;
......@@ -176,8 +177,12 @@ public class CodeShrinkVisitor extends AbstractVisitor {
for (BlockNode block : pathsBlocks) {
if (block.contains(AFlag.DONT_GENERATE)) {
if (BlockUtils.checkLastInsnType(block, InsnType.MONITOR_EXIT)) {
// don't move from synchronized block
return false;
if (RegionUtils.isBlocksInSameRegion(mth, assignBlock, useBlock)) {
// allow move inside same synchronized region
} else {
// don't move from synchronized block
return false;
}
}
// skip checks for not generated blocks
continue;
......
......@@ -19,6 +19,8 @@ import jadx.core.dex.nodes.IBranchRegion;
import jadx.core.dex.nodes.IContainer;
import jadx.core.dex.nodes.IRegion;
import jadx.core.dex.nodes.InsnNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.dex.regions.Region;
import jadx.core.dex.trycatch.CatchAttr;
import jadx.core.dex.trycatch.ExceptionHandler;
import jadx.core.dex.trycatch.TryCatchBlock;
......@@ -329,6 +331,26 @@ public class RegionUtils {
}
}
/**
* Check if two blocks in same region on same level
* TODO: Add 'region' annotation to all blocks to speed up checks
*/
public static boolean isBlocksInSameRegion(MethodNode mth, BlockNode firstBlock, BlockNode secondBlock) {
Region region = mth.getRegion();
if (region == null) {
return false;
}
IContainer firstContainer = getBlockContainer(region, firstBlock);
if (firstContainer instanceof IRegion) {
if (firstContainer instanceof IBranchRegion) {
return false;
}
List<IContainer> subBlocks = ((IRegion) firstContainer).getSubBlocks();
return subBlocks.contains(secondBlock);
}
return false;
}
public static boolean isDominatedBy(BlockNode dom, IContainer cont) {
if (dom == cont) {
return true;
......
......@@ -26,6 +26,8 @@ public class TestSynchronized4 extends SmaliTest {
public void test() {
assertThat(getClassNodeFromSmali())
.code()
.containsOne("synchronized (this.obj) {");
.containsOne("synchronized (this.obj) {")
.containsOne("return call(this.obj, i);")
.containsOne("return getField() == null;");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册