memory usage optimizations

This commit is contained in:
2015-03-19 16:29:15 +01:00
parent db40ad295d
commit ad228cb16e
15 changed files with 107 additions and 39 deletions
@@ -48,7 +48,9 @@ public class IdentifiersDeobfuscation {
public static final String VALID_NEXT_CHARACTERS = VALID_FIRST_CHARACTERS + "\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}";
public static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[" + VALID_FIRST_CHARACTERS + "][" + VALID_NEXT_CHARACTERS + "]*$");
private static final Pattern VALID_NAME_PATTERN = Pattern.compile("^[a-zA-Z_\\$][a-zA-Z0-9_\\$]*$");
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[" + VALID_FIRST_CHARACTERS + "][" + VALID_NEXT_CHARACTERS + "]*$");
public static final String FOO_CHARACTERS = "bcdfghjklmnpqrstvwz";
@@ -88,8 +90,9 @@ public class IdentifiersDeobfuscation {
return false;
}
String[] reservedWords = as3 ? reservedWordsAS3 : reservedWordsAS2;
s = s.trim();
for (String rw : reservedWords) {
if (rw.equals(s.trim())) {
if (rw.equals(s)) {
return true;
}
}
@@ -240,7 +243,7 @@ public class IdentifiersDeobfuscation {
}
// simple fast test
if (s.matches("^[a-zA-Z_\\$][a-zA-Z0-9_\\$]*$")) {
if (VALID_NAME_PATTERN.matcher(s).matches()) {
return true;
}
// unicode test
@@ -527,7 +527,7 @@ public class ABC {
class_info = new ArrayList<>(class_count);
for (int i = 0; i < class_count; i++) {
ais.newDumpLevel("class", "class_info");
ClassInfo ci = new ClassInfo();
ClassInfo ci = new ClassInfo(null); // do not create Traits in constructor
ci.cinit_index = ais.readU30("cinit_index");
ci.static_traits = ais.readTraits("static_traits");
class_info.add(ci);
@@ -537,7 +537,7 @@ public class ABC {
script_info = new ArrayList<>(script_count);
for (int i = 0; i < script_count; i++) {
ais.newDumpLevel("script", "script_info");
ScriptInfo si = new ScriptInfo();
ScriptInfo si = new ScriptInfo(null); // do not create Traits in constructor
si.init_index = ais.readU30("init_index");
si.traits = ais.readTraits("traits");
script_info.add(si);
@@ -548,7 +548,7 @@ public class ABC {
bodies = new ArrayList<>(bodies_count);
for (int i = 0; i < bodies_count; i++) {
ais.newDumpLevel("method_body", "method_body_info");
MethodBody mb = new MethodBody();
MethodBody mb = new MethodBody(null, null, null); // do not create Traits in constructor
mb.method_info = ais.readU30("method_info");
mb.max_stack = ais.readU30("max_stack");
mb.max_regs = ais.readU30("max_regs");
@@ -50,6 +50,8 @@ public class ABCInputStream implements AutoCloseable {
public static final boolean DEBUG_READ = false;
public DumpInfo dumpInfo;
private byte[] stringDataBuffer = new byte[256];
public void startBuffer() {
if (bufferOs == null) {
@@ -251,7 +253,8 @@ public class ABCInputStream implements AutoCloseable {
}
private long readLong() throws IOException {
byte[] readBuffer = safeRead(8);
safeRead(8, stringDataBuffer);
byte[] readBuffer = stringDataBuffer;
return (((long) readBuffer[7] << 56)
+ ((long) (readBuffer[6] & 255) << 48)
+ ((long) (readBuffer[5] & 255) << 40)
@@ -270,12 +273,10 @@ public class ABCInputStream implements AutoCloseable {
return ret;
}
private byte[] safeRead(int count) throws IOException {
byte[] ret = new byte[count];
private void safeRead(int count, byte[] data) throws IOException {
for (int i = 0; i < count; i++) {
ret[i] = (byte) readInternal();
data[i] = (byte) readInternal();
}
return ret;
}
public Namespace readNamespace(String name) throws IOException {
@@ -423,8 +424,7 @@ public class ABCInputStream implements AutoCloseable {
public Traits readTraits(String name) throws IOException {
newDumpLevel(name, "Traits");
int count = readU30("count");
Traits traits = new Traits();
traits.traits = new ArrayList<>();
Traits traits = new Traits(count);
for (int i = 0; i < count; i++) {
traits.traits.add(readTrait("trait"));
}
@@ -456,7 +456,7 @@ public class ABCInputStream implements AutoCloseable {
public InstanceInfo readInstanceInfo(String name) throws IOException {
newDumpLevel(name, "instance_info");
InstanceInfo ret = new InstanceInfo();
InstanceInfo ret = new InstanceInfo(null); // do not create Traits in constructor
ret.name_index = readU30("name_index");
ret.super_index = readU30("super_index");
ret.flags = readInternal();
@@ -477,8 +477,19 @@ public class ABCInputStream implements AutoCloseable {
public String readString(String name) throws IOException {
newDumpLevel(name, "String");
int length = readU30Internal();
byte[] b = safeRead(length);
String r = new String(b, Utf8Helper.charset);
// avoid creating new byte array every time
if (stringDataBuffer.length < length) {
int newLength = stringDataBuffer.length * 2;
while (newLength < length) {
newLength *= 2;
}
stringDataBuffer = new byte[newLength];
}
safeRead(length, stringDataBuffer);
String r = new String(stringDataBuffer, 0, length, Utf8Helper.charset);
endDumpLevel(r);
return r;
}
@@ -1619,7 +1619,6 @@ public class AVM2SourceGenerator implements SourceGenerator {
MethodBody mbody = new MethodBody();
if (needsActivation) {
mbody.traits = new Traits();
int slotId = 1;
for (int i = 1; i < slotNames.size(); i++) {
TraitSlotConst tsc = new TraitSlotConst();
@@ -24,10 +24,18 @@ public class ClassInfo {
public int cinit_index; //MethodInfo - static initializer
public Traits static_traits = new Traits();
public Traits static_traits;
public boolean deleted;
public ClassInfo() {
static_traits = new Traits();
}
public ClassInfo(Traits traits) {
static_traits = traits;
}
@Override
public String toString() {
return "method_index=" + cinit_index + "\r\n" + static_traits.toString();
@@ -39,7 +39,7 @@ public class InstanceInfo {
public int iinit_index; // MethodInfo - constructor
public Traits instance_traits = new Traits();
public Traits instance_traits;
public static final int CLASS_SEALED = 1; //not dynamic
@@ -51,6 +51,14 @@ public class InstanceInfo {
public boolean deleted;
public InstanceInfo() {
instance_traits = new Traits();
}
public InstanceInfo(Traits traits) {
instance_traits = traits;
}
@Override
public String toString() {
return "name_index=" + name_index + " super_index=" + super_index + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString();
@@ -39,17 +39,18 @@ public class MetadataInfo {
}
public String toString(AVM2ConstantPool constants) {
String s = "name=" + constants.getString(name_index);
StringBuilder sb = new StringBuilder();
sb.append("name=").append(constants.getString(name_index));
if (keys.length > 0) {
s += "\r\n";
sb.append("\r\n");
}
for (int i = 0; i < keys.length; i++) {
if (keys[i] == 0) {
s += "\"" + constants.getString(values[i]) + "\"\r\n";
sb.append("\"").append(constants.getString(values[i])).append("\"\r\n");
} else {
s += "\"" + constants.getString(keys[i]) + "\"=\"" + constants.getString(values[i]) + "\"\r\n";
sb.append("\"").append(constants.getString(keys[i])).append("\"=\"").append(constants.getString(values[i])).append("\"\r\n");
}
}
return s;
return sb.toString();
}
}
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFField;
import com.jpexs.decompiler.graph.Graph;
import com.jpexs.decompiler.graph.GraphTargetItem;
@@ -64,18 +65,32 @@ public final class MethodBody implements Cloneable {
public int max_scope_depth;
@SWFField
private byte[] codeBytes = new byte[0];
private byte[] codeBytes;
private AVM2Code code;
public ABCException[] exceptions = new ABCException[0];
public ABCException[] exceptions;
public Traits traits = new Traits();
public Traits traits;
@Internal
public transient List<GraphTargetItem> convertedItems;
@Internal
public transient Throwable convertException;
public MethodBody() {
this.traits = new Traits();
this.codeBytes = new byte[0];
this.exceptions = new ABCException[0];
}
public MethodBody(Traits traits, byte[] codeBytes, ABCException[] exceptions) {
this.traits = traits;
this.codeBytes = codeBytes;
this.exceptions = exceptions;
}
public synchronized void setCodeBytes(byte codeBytes[]) {
this.codeBytes = codeBytes;
this.code = null;
@@ -280,10 +280,10 @@ public class Multiname {
return "";
}
if (name_index == 0) {
return (isAttribute() ? "@*" : "*");
return isAttribute() ? "@*" : "*";
} else {
String name = constants.getString(name_index);
if ((fullyQualifiedNames != null) && fullyQualifiedNames.contains(name)) {
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(name)) {
return getNameWithNamespace(constants, raw);
}
return (isAttribute() ? "@" : "") + (raw ? name : IdentifiersDeobfuscation.printIdentifier(true, name));
@@ -32,13 +32,13 @@ public class NamespaceSet {
}
public String toString(AVM2ConstantPool constants) {
String s = "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < this.namespaces.length; i++) {
if (i > 0) {
s += ", ";
sb.append(", ");
}
s += constants.getNamespace(namespaces[i]).getNameWithKind(constants);
sb.append(constants.getNamespace(namespaces[i]).getNameWithKind(constants));
}
return s;
return sb.toString();
}
}
@@ -31,8 +31,16 @@ public class ScriptInfo {
public int init_index; //MethodInfo
public Traits traits = new Traits();
public Traits traits;
public ScriptInfo() {
traits = new Traits();
}
public ScriptInfo(Traits traits) {
this.traits = traits;
}
public List<MyEntry<ClassPath, ScriptPack>> getPacks(ABC abc, int scriptIndex) {
List<MyEntry<ClassPath, ScriptPack>> ret = new ArrayList<>();
@@ -52,8 +60,8 @@ public class ScriptInfo {
Namespace ns = name.getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL)
|| (ns.kind == Namespace.KIND_PACKAGE)) {
String packageName = ns.getName(abc.constants, false); //assume not null package
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
String packageName = ns.getName(abc.constants, false); // assume not null package
String objectName = name.getName(abc.constants, null, false);
List<Integer> traitIndices = new ArrayList<>();
traitIndices.add(j);
@@ -30,13 +30,15 @@ import java.util.List;
public abstract class Trait implements Serializable {
private static final int[] EMPTY_METADATA_ARRAY = new int[0];
public int name_index;
public int kindType;
public int kindFlags;
public int[] metadata = new int[0];
public int[] metadata = EMPTY_METADATA_ARRAY;
public long fileOffset;
@@ -34,8 +34,16 @@ import java.util.logging.Logger;
public class Traits implements Serializable {
public List<Trait> traits = new ArrayList<>();
public List<Trait> traits;
public Traits() {
traits = new ArrayList<>();
}
public Traits(int initialCapacity) {
traits = new ArrayList<>(initialCapacity);
}
public void delete(ABC abc, boolean d) {
for (Trait t : traits) {
t.delete(abc, d);