more efficient turbo transformer

This commit is contained in:
FalsePattern committed 2024-05-27 14:34:34 +02:00
1 parent 2c65097889
commit bd5772cbce
5 files changed
+55 -24

No files matched your search

@@ -64,11 +64,12 @@ public class ConfigOrderTransformer implements TurboClassTransformer {
}
@Override
public void transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode) {
public boolean transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode) {
val cn = classNode.getNode();
if (cn == null)
return;
return false;
int order = 0;
boolean changed = false;
outer:
for (val field : cn.fields) {
if ((field.access & Opcodes.ACC_PUBLIC) == 0
@@ -85,6 +86,8 @@ public class ConfigOrderTransformer implements TurboClassTransformer {
val annVisitor = field.visitAnnotation(DESC_ORDER, true);
annVisitor.visit("value", order++);
annVisitor.visitEnd();
changed = true;
}
return changed;
}
}
@@ -73,32 +73,43 @@ public class MixinPluginTransformer implements TurboClassTransformer {
if (IMIXINPLUGIN.equals(className) ||
IMIXINCONFIGPLUGIN.equals(className))
return true;
if (!classNode.isPresent())
return false;
if (classNode.isOriginal()) {
val meta = classNode.getOriginalMetadata();
if (meta != null && meta.interfacesCount == 0)
return false;
}
val cn = classNode.getNode();
if (cn == null)
return false;
return cn.interfaces.stream()
.anyMatch((i) -> IMIXINPLUGIN_INTERNAL.equals(i) ||
IMIXINCONFIGPLUGIN_INTERNAL.equals(i));
for (String i : cn.interfaces) {
if (IMIXINPLUGIN_INTERNAL.equals(i) || IMIXINCONFIGPLUGIN_INTERNAL.equals(i)) {
return true;
}
}
return false;
}
@Override
public void transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode) {
public boolean transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode) {
val cn = classNode.getNode();
if (cn == null)
return;
return false;
if (IMIXINCONFIGPLUGIN.equals(className)) {
extractMixinConfigPluginData(cn);
return extractMixinConfigPluginData(cn);
} else {
transformPlugin(cn);
return transformPlugin(cn);
}
}
private static void extractMixinConfigPluginData(ClassNode cn) {
private static boolean extractMixinConfigPluginData(ClassNode cn) {
boolean changed = false;
for (val method : cn.methods) {
switch (method.name) {
case "preApply":
@@ -114,29 +125,39 @@ public class MixinPluginTransformer implements TurboClassTransformer {
for (val local : method.localVariables) {
if (local.desc.contains("ClassNode;")) {
local.desc = local.desc.replaceAll("L[a-zA-Z/$]+[a-zA-Z$]+/ClassNode;", CLASSNODE_REAL);
changed = true;
}
}
}
}
return changed;
}
private static void transformPlugin(ClassNode cn) {
private static boolean transformPlugin(ClassNode cn) {
if (PREAPPLY_DESC == null) {
PREAPPLY_DESC = extractMethodWithReflection("preApply");
}
if (POSTAPPLY_DESC == null) {
POSTAPPLY_DESC = extractMethodWithReflection("postApply");
}
boolean changed = false;
for (val method : cn.methods) {
switch (method.name) {
case "preApply":
method.desc = PREAPPLY_DESC;
if (!PREAPPLY_DESC.equals(method.desc)) {
method.desc = PREAPPLY_DESC;
changed = true;
}
break;
case "postApply":
method.desc = POSTAPPLY_DESC;
if (!POSTAPPLY_DESC.equals(method.desc)) {
method.desc = POSTAPPLY_DESC;
changed = true;
}
break;
}
}
return changed;
}
private static String extractMethodWithReflection(String m) {
@@ -48,10 +48,10 @@ public class TypeDiscovererModuleInfoSilencer implements TurboClassTransformer {
}
@Override
public void transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode) {
public boolean transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode) {
val cn = classNode.getNode();
if (cn == null)
return;
return false;
for (val method : cn.methods) {
if (!method.name.equals("<clinit>")) {
continue;
@@ -63,10 +63,11 @@ public class TypeDiscovererModuleInfoSilencer implements TurboClassTransformer {
val ldc = (LdcInsnNode) insn;
if (ldc.cst.equals("[^\\s\\$]+(\\$[^\\s]+)?\\.class$")) {
ldc.cst = "(?!module-info)[^\\s\\$]+(\\$[^\\s]+)?\\.class$";
return;
return true;
}
}
}
}
return false;
}
}
@@ -32,22 +32,26 @@ import java.util.List;
public class TransformerUtil {
private static final Logger LOG = LogManager.getLogger("ASM");
public static boolean executeTransformers(String transformedName, ClassNodeHandle handle, List<TurboClassTransformer> transformers) {
boolean didTransformation = false;
boolean modified = false;
for (val transformer: transformers) {
try {
if (transformer.shouldTransformClass(transformedName, handle)) {
if (!didTransformation) {
LOG.debug("Transforming {}!", transformedName);
LOG.trace("Transforming {} with {}, owner: {}", transformedName, transformer.name(), transformer.owner());
if (transformer.transformClass(transformedName, handle)) {
LOG.trace("Transformed.");
modified = true;
} else {
LOG.trace("No change.");
}
didTransformation = true;
transformer.transformClass(transformedName, handle);
LOG.debug("Successfully transformed class {} with {}, owner: {}", transformedName, transformer.name(), transformer.owner());
}
} catch (Exception e) {
LOG.error("Failed to transform class {} with {}, owner: {}", transformedName, transformer.name(), transformer.owner());
LOG.error("Exception stacktrace:", e);
}
}
return didTransformation;
if (modified) {
LOG.trace("Transformed class {}", transformedName);
}
return modified;
}
}
@@ -58,7 +58,9 @@ public interface TurboClassTransformer {
* (Optionally) transform a given class. No ClassReader flags are used for maximum efficiency, so stack frames are not expanded.
* @param className The name of the transformed class (in the dot-separated format).
* @param classNode The handle to the lazily ASM-parsed class to modify, and metadata used for class writing.
* @return True if the class has been modified in any way by this transformer. If all transformers return false,
* then the ClassNode instance will not be re-serialized.
*/
@Expose
void transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode);
boolean transformClass(@NotNull String className, @NotNull ClassNodeHandle classNode);
}