From 10036aa764f9678ef2c86cde40ddcaf72d32dc95 Mon Sep 17 00:00:00 2001 From: gegy1000 Date: Thu, 27 Sep 2018 23:27:21 +0200 Subject: [PATCH] Class transformer optimizations (#5159) * Filter packages for deobf transformation * Only serialize transformed class with TerminalTransformer if bytecode changed --- .../DeobfuscationTransformer.java | 39 +++++++++++++++++++ .../asm/transformers/TerminalTransformer.java | 9 ++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java index 75e48dabe5..e8675d476c 100644 --- a/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/DeobfuscationTransformer.java @@ -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) { diff --git a/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java b/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java index 7107bf7914..043b380f77 100644 --- a/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java +++ b/src/main/java/net/minecraftforge/fml/common/asm/transformers/TerminalTransformer.java @@ -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);