diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index c22c8fefb..0b769c353 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -290,6 +290,7 @@ import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.ExitItem; import com.jpexs.decompiler.graph.model.ScriptEndItem; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.stat.Statistics; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -2259,9 +2260,15 @@ public class AVM2Code implements Cloneable { if (Configuration.deobfuscationOldMode.get()) { return removeTrapsOld(constants, trait, info, body, abc, scriptIndex, classIndex, isStatic, path); } else { - new AVM2DeobfuscatorSimple().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, info, body); - new AVM2DeobfuscatorRegisters().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, info, body); - new AVM2DeobfuscatorJumps().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, info, body); + try (Statistics s = new Statistics("AVM2DeobfuscatorSimple")) { + new AVM2DeobfuscatorSimple().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, info, body); + } + try (Statistics s = new Statistics("AVM2DeobfuscatorRegisters")) { + new AVM2DeobfuscatorRegisters().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, info, body); + } + try (Statistics s = new Statistics("AVM2DeobfuscatorJumps")) { + new AVM2DeobfuscatorJumps().deobfuscate(path, classIndex, isStatic, scriptIndex, abc, constants, trait, info, body); + } return 1; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index 36906b19a..21f43885d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -41,6 +41,7 @@ import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; import com.jpexs.helpers.MemoryInputStream; +import com.jpexs.helpers.stat.Statistics; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -292,11 +293,18 @@ public final class MethodBody implements Cloneable { Callable callable = new Callable() { @Override public Void call() throws InterruptedException { - MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits); - HashMap localRegNames = getLocalRegNames(abc); - List convertedItems1 = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted)); - Graph.graphToString(convertedItems1, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); - convertedItems = convertedItems1; + try (Statistics s1 = new Statistics("MethodBody.convert")) { + MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits); + HashMap localRegNames = getLocalRegNames(abc); + List convertedItems1; + try (Statistics s = new Statistics("AVM2Code.toGraphTargetItems")) { + convertedItems1 = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted)); + } + try (Statistics s = new Statistics("Graph.graphToString")) { + Graph.graphToString(convertedItems1, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); + } + convertedItems = convertedItems1; + } return null; } }; @@ -334,22 +342,24 @@ public final class MethodBody implements Cloneable { } int timeout = Configuration.decompilationTimeoutSingleMethod.get(); - if (convertException == null) { - HashMap localRegNames = getLocalRegNames(abc); - //writer.startMethod(this.method_info); - if (Configuration.showMethodBodyId.get()) { - writer.appendNoHilight("// method body id: "); - writer.appendNoHilight(abc.findBodyIndex(this.method_info)); - writer.newLine(); + try (Statistics s = new Statistics("MethodBody.toString")) { + if (convertException == null) { + HashMap localRegNames = getLocalRegNames(abc); + //writer.startMethod(this.method_info); + if (Configuration.showMethodBodyId.get()) { + writer.appendNoHilight("// method body id: "); + writer.appendNoHilight(abc.findBodyIndex(this.method_info)); + writer.newLine(); + } + Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); + //writer.endMethod(); + } else if (convertException instanceof TimeoutException) { + // exception was logged in convert method + Helper.appendTimeoutCommentAs3(writer, timeout, getCode().code.size()); + } else { + // exception was logged in convert method + Helper.appendErrorComment(writer, convertException); } - Graph.graphToString(convertedItems, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); - //writer.endMethod(); - } else if (convertException instanceof TimeoutException) { - // exception was logged in convert method - Helper.appendTimeoutCommentAs3(writer, timeout, getCode().code.size()); - } else { - // exception was logged in convert method - Helper.appendErrorComment(writer, convertException); } } return writer; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java index 41aea0088..37705c33e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/ActionListReader.java @@ -49,6 +49,7 @@ import com.jpexs.decompiler.graph.TranslateStack; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.stat.Statistics; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -179,8 +180,12 @@ public class ActionListReader { } } else if (deobfuscationMode == 1) { try { - new ActionDeobfuscatorSimple().actionListParsed(actions, sis.getSwf()); - new ActionDeobfuscator().actionListParsed(actions, sis.getSwf()); + try (Statistics s = new Statistics("ActionDeobfuscatorSimple")) { + new ActionDeobfuscatorSimple().actionListParsed(actions, sis.getSwf()); + } + try (Statistics s = new Statistics("ActionDeobfuscator")) { + new ActionDeobfuscator().actionListParsed(actions, sis.getSwf()); + } } catch (ThreadDeath | InterruptedException ex) { throw ex; } catch (Throwable ex) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/ExportScriptTask.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/ExportScriptTask.java index 4051cfa6c..4e6ec2bba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/ExportScriptTask.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/script/ExportScriptTask.java @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.helpers.FileTextWriter; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.helpers.Helper; import com.jpexs.helpers.Path; +import com.jpexs.helpers.stat.Statistics; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -103,9 +104,15 @@ public class ExportScriptTask implements Callable { asm.getASMSource(exportMode, writer2, null); asm.getActionSourceSuffix(writer2); } else { - List as = asm.getActions(); + List as; + try (Statistics s = new Statistics("ASMSource.getActions")) { + as = asm.getActions(); + } Action.setActionsAddresses(as, 0); - Action.actionsToSource(asm, as, asm.toString()/*FIXME?*/, writer2); + + try (Statistics s = new Statistics("Action.actionsToSource")) { + Action.actionsToSource(asm, as, asm.toString()/*FIXME?*/, writer2); + } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/stat/StatisticData.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/stat/StatisticData.java new file mode 100644 index 000000000..3ffca1664 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/stat/StatisticData.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.helpers.stat; + +/** + * + * @author JPEXS + */ +public class StatisticData { + + public int count; + + public long value; + + public long min = Long.MAX_VALUE; + + public long max = Long.MIN_VALUE; +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/helpers/stat/Statistics.java b/libsrc/ffdec_lib/src/com/jpexs/helpers/stat/Statistics.java new file mode 100644 index 000000000..62369648b --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/helpers/stat/Statistics.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.helpers.stat; + +import com.jpexs.helpers.Stopwatch; +import java.util.HashMap; +import java.util.Map; + +/** + * + * @author JPEXS + */ +public class Statistics implements AutoCloseable { + + private static final Map map = new HashMap<>(); + + private final String name; + + private final Stopwatch sw; + + public static synchronized void addTime(String name, long duration) { + StatisticData s = map.get(name); + if (s == null) { + s = new StatisticData(); + map.put(name, s); + } + + s.value += duration; + if (duration > s.max) { + s.max = duration; + } + + if (duration < s.min) { + s.min = duration; + } + + s.count++; + } + + public static synchronized void addToMap(Map targetMap) { + for (Map.Entry e : map.entrySet()) { + String name = e.getKey(); + StatisticData d = e.getValue(); + StatisticData d2 = targetMap.get(name); + if (d2 == null) { + d2 = new StatisticData(); + targetMap.put(name, d2); + } + + d2.value += d.value; + d2.count += d.count; + if (d.max > d2.max) { + d2.max = d.max; + } + + if (d.min < d2.min) { + d2.min = d.min; + } + } + } + + public static synchronized void print() { + print(map); + } + + public static synchronized void print(Map map) { + for (Map.Entry e : map.entrySet()) { + String name = e.getKey(); + StatisticData d = e.getValue(); + System.out.println(name + ": count: " + d.count + " / total: " + (d.value / 1000000) + + "ms / min: " + (d.min / 1000) + + "us / max: " + (d.max / 1000) + + "us / avg: " + (d.value / d.count / 1000) + "us"); + } + } + + public static synchronized void clear() { + map.clear(); + } + + public Statistics(String name) { + this.name = name; + sw = Stopwatch.startNew(); + } + + @Override + public void close() { + sw.stop(); + addTime(name, sw.getElapsedNanoseconds()); + } +}