提交 10fd3652 编写于 作者: S Skylot

core: fix processing same class several times (#274)

Caution: This change can increase memory usage!
However overall decompilation must be faster
上级 4d305107
......@@ -197,8 +197,12 @@ public final class JadxDecompiler {
continue;
}
executor.execute(() -> {
cls.decompile();
SaveCode.save(outDir, args, cls.getClassNode());
try {
cls.decompile();
SaveCode.save(outDir, args, cls.getClassNode());
} catch (Exception e) {
LOG.error("Error saving class: {}", cls.getFullName(), e);
}
});
}
}
......
......@@ -64,6 +64,10 @@ public final class JavaClass implements JavaNode {
}
}
public synchronized void unload() {
cls.unload();
}
ClassNode getClassNode() {
return cls;
}
......@@ -107,12 +111,7 @@ public final class JavaClass implements JavaNode {
rootDecompiler.getMethodsMap().put(m, javaMethod);
}
}
Collections.sort(mths, new Comparator<JavaMethod>() {
@Override
public int compare(JavaMethod o1, JavaMethod o2) {
return o1.getName().compareTo(o2.getName());
}
});
mths.sort(Comparator.comparing(JavaMethod::getName));
this.methods = Collections.unmodifiableList(mths);
}
}
......
......@@ -10,11 +10,9 @@ import jadx.core.dex.visitors.DepthTraversal;
import jadx.core.dex.visitors.IDexTreeVisitor;
import jadx.core.utils.ErrorsCounter;
import static jadx.core.dex.nodes.ProcessState.GENERATED;
import static jadx.core.dex.nodes.ProcessState.NOT_LOADED;
import static jadx.core.dex.nodes.ProcessState.PROCESSED;
import static jadx.core.dex.nodes.ProcessState.STARTED;
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
public final class ProcessClass {
......@@ -38,15 +36,9 @@ public final class ProcessClass {
if (cls.getState() == PROCESSED && codeGen != null) {
processDependencies(cls, passes);
codeGen.visit(cls);
cls.setState(GENERATED);
}
} catch (Exception e) {
ErrorsCounter.classError(cls, e.getClass().getSimpleName(), e);
} finally {
if (cls.getState() == GENERATED) {
cls.unload();
cls.setState(UNLOADED);
}
}
}
}
......
package jadx.core.codegen;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.utils.exceptions.CodegenException;
public class CodeGen extends AbstractVisitor {
public class CodeGen {
@Override
public boolean visit(ClassNode cls) throws CodegenException {
ClassGen clsGen = new ClassGen(cls, cls.root().getArgs());
CodeWriter clsCode = clsGen.makeClass();
......
......@@ -39,6 +39,8 @@ import jadx.core.dex.nodes.parser.StaticValuesParser;
import jadx.core.utils.exceptions.DecodeException;
import jadx.core.utils.exceptions.JadxRuntimeException;
import static jadx.core.dex.nodes.ProcessState.UNLOADED;
public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
private static final Logger LOG = LoggerFactory.getLogger(ClassNode.class);
......@@ -264,6 +266,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
for (ClassNode innerCls : getInnerClasses()) {
innerCls.unload();
}
setState(UNLOADED);
}
private void buildCache() {
......
......@@ -403,8 +403,8 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
}
public void finishBasicBlocks() {
((ArrayList<BlockNode>) blocks).trimToSize();
((ArrayList<BlockNode>) exitBlocks).trimToSize();
trimList(blocks);
trimList(exitBlocks);
blocks = Collections.unmodifiableList(blocks);
exitBlocks = Collections.unmodifiableList(exitBlocks);
......@@ -414,6 +414,12 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
}
}
private void trimList(List<BlockNode> blocks) {
if (blocks instanceof ArrayList) {
((ArrayList<BlockNode>)blocks).trimToSize();
}
}
public List<BlockNode> getBasicBlocks() {
return blocks;
}
......
......@@ -6,6 +6,7 @@ import jadx.api.JadxArgs;
import jadx.core.codegen.CodeWriter;
import jadx.core.dex.attributes.AFlag;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.utils.exceptions.JadxRuntimeException;
public class SaveCode {
......@@ -16,6 +17,9 @@ public class SaveCode {
return;
}
CodeWriter clsCode = cls.getCode();
if (clsCode == null) {
throw new JadxRuntimeException("Code not generated for class " + cls.getFullName());
}
String fileName = cls.getClassInfo().getFullPath() + ".java";
if (args.isFallbackMode()) {
fileName += ".jadx";
......
......@@ -52,6 +52,8 @@ public class JadxWrapper {
Thread.sleep(500);
}
progressMonitor.close();
LOG.info("decompilation complete, freeing memory ...");
decompiler.getClasses().forEach(JavaClass::unload);
LOG.info("done");
} catch (InterruptedException e) {
LOG.error("Save interrupted", e);
......
......@@ -51,6 +51,7 @@ public class JClass extends JLoadableNode {
public synchronized void load() {
if (!loaded) {
cls.decompile();
cls.unload();
loaded = true;
}
update();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册