Class transformer optimizations (#5159)

* Filter packages for deobf transformation
* Only serialize transformed class with TerminalTransformer if bytecode changed
This commit is contained in:
gegy1000 authored and LexManos committed 2018-09-27 14:27:21 -07:00
1 parent fcd00bd4af
commit 10036aa764
2 files changed
+46 -2

No files matched your search

@@ -19,8 +19,12 @@
package net.minecraftforge.fml.common.asm.transformers;
import java.util.Arrays;
import net.minecraft.launchwrapper.IClassNameTransformer;
import net.minecraft.launchwrapper.IClassTransformer;
import net.minecraft.launchwrapper.Launch;
import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper;
import net.minecraftforge.fml.common.asm.transformers.deobf.FMLRemappingAdapter;
@@ -29,6 +33,22 @@ import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.RemappingClassAdapter;
public class DeobfuscationTransformer implements IClassTransformer, IClassNameTransformer {
private static final String[] EXEMPT_LIBS = new String[] {
"com.google.",
"com.mojang.",
"joptsimple.",
"io.netty.",
"it.unimi.dsi.fastutil.",
"oshi.",
"com.sun.",
"com.ibm.",
"paulscode.",
"com.jcraft"
};
private static final String[] EXEMPT_DEV = new String[] {
"net.minecraft.",
"net.minecraftforge."
};
private static final boolean RECALC_FRAMES = Boolean.parseBoolean(System.getProperty("FORGE_FORCE_FRAME_RECALC", "false"));
private static final int WRITER_FLAGS = ClassWriter.COMPUTE_MAXS | (RECALC_FRAMES ? ClassWriter.COMPUTE_FRAMES : 0);
@@ -38,6 +58,8 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr
// If reported we need to add a custom implementation of ClassWriter.getCommonSuperClass
// that does not cause class loading.
private boolean deobfuscatedEnvironment = (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
@Override
public byte[] transform(String name, String transformedName, byte[] bytes)
{
@@ -45,6 +67,9 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr
{
return null;
}
if (!shouldTransform(name)) return bytes;
ClassReader classReader = new ClassReader(bytes);
ClassWriter classWriter = new ClassWriter(WRITER_FLAGS);
RemappingClassAdapter remapAdapter = new FMLRemappingAdapter(classWriter);
@@ -52,6 +77,20 @@ public class DeobfuscationTransformer implements IClassTransformer, IClassNameTr
return classWriter.toByteArray();
}
private boolean shouldTransform(String name)
{
boolean transformLib = Arrays.stream(EXEMPT_LIBS).noneMatch(name::startsWith);
if (deobfuscatedEnvironment)
{
return transformLib && Arrays.stream(EXEMPT_DEV).noneMatch(name::startsWith);
}
else
{
return transformLib;
}
}
@Override
public String remapClassName(String name)
{
@@ -34,16 +34,18 @@ public class TerminalTransformer implements IClassTransformer
ClassReader reader = new ClassReader(basicClass);
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
ClassVisitor visitor = writer;
visitor = new ExitVisitor(visitor);
ExitVisitor visitor = new ExitVisitor(writer);
reader.accept(visitor, 0);
if (!visitor.dirty) return basicClass;
return writer.toByteArray();
}
public static class ExitVisitor extends ClassVisitor
{
private String clsName = null;
private boolean dirty;
private static final String callbackOwner = org.objectweb.asm.Type.getInternalName(ExitVisitor.class);
private ExitVisitor(ClassVisitor cv)
@@ -89,6 +91,7 @@ public class TerminalTransformer implements IClassTransformer
}
owner = ExitVisitor.callbackOwner;
name = "systemExitCalled";
dirty = true;
}
else if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/Runtime") && name.equals("exit") && desc.equals("(I)V"))
{
@@ -104,6 +107,7 @@ public class TerminalTransformer implements IClassTransformer
owner = ExitVisitor.callbackOwner;
name = "runtimeExitCalled";
desc = "(Ljava/lang/Runtime;I)V";
dirty = true;
}
else if (opcode == Opcodes.INVOKEVIRTUAL && owner.equals("java/lang/Runtime") && name.equals("halt") && desc.equals("(I)V"))
{
@@ -119,6 +123,7 @@ public class TerminalTransformer implements IClassTransformer
owner = ExitVisitor.callbackOwner;
name = "runtimeHaltCalled";
desc = "(Ljava/lang/Runtime;I)V";
dirty = true;
}
super.visitMethodInsn(opcode, owner, name, desc, isIntf);