From 395e14ba9baee50d084e0f06f3ba941aff52be9b Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 8 Apr 2023 19:08:03 -0400 Subject: [PATCH] Fix leaking mixin injectors --- .../modernfix/core/ModernFixMixinPlugin.java | 15 ++ .../embeddedt/modernfix/util/DummyList.java | 131 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/main/java/org/embeddedt/modernfix/util/DummyList.java diff --git a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java index 37c436a7..0c22fd8d 100644 --- a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -10,9 +10,12 @@ import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.classloading.ModernFixResourceFinder; import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig; import org.embeddedt.modernfix.core.config.Option; +import org.embeddedt.modernfix.util.DummyList; import org.objectweb.asm.tree.*; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import org.spongepowered.asm.mixin.injection.struct.InjectionInfo; +import org.spongepowered.asm.mixin.injection.struct.InjectorGroupInfo; import java.io.File; import java.io.IOException; @@ -72,6 +75,18 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { } catch(RuntimeException | ReflectiveOperationException e) { logger.error("Failed to make classloading changes", e); } + + /* https://github.com/FabricMC/Mixin/pull/99 */ + try { + Field groupMembersField = InjectorGroupInfo.class.getDeclaredField("members"); + groupMembersField.setAccessible(true); + Field noGroupField = InjectorGroupInfo.Map.class.getDeclaredField("NO_GROUP"); + noGroupField.setAccessible(true); + InjectorGroupInfo noGroup = (InjectorGroupInfo)noGroupField.get(null); + groupMembersField.set(noGroup, new DummyList<>()); + } catch(RuntimeException | ReflectiveOperationException e) { + logger.error("Failed to patch mixin memory leak", e); + } } private Method defineClassMethod = null; diff --git a/src/main/java/org/embeddedt/modernfix/util/DummyList.java b/src/main/java/org/embeddedt/modernfix/util/DummyList.java new file mode 100644 index 00000000..221c6506 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/util/DummyList.java @@ -0,0 +1,131 @@ +package org.embeddedt.modernfix.util; + +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * List with no-op methods. + */ +public class DummyList implements List { + @Override + public int size() { + return 0; + } + + @Override + public boolean isEmpty() { + return true; + } + + @Override + public boolean contains(Object o) { + return false; + } + + @NotNull + @Override + public Iterator iterator() { + return Collections.emptyIterator(); + } + + @NotNull + @Override + public Object[] toArray() { + return new Object[0]; + } + + @NotNull + @Override + public T1[] toArray(@NotNull T1[] t1s) { + return Arrays.copyOf(t1s, 0); + } + + @Override + public boolean add(T t) { + return false; + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean containsAll(@NotNull Collection collection) { + return false; + } + + @Override + public boolean addAll(@NotNull Collection collection) { + return false; + } + + @Override + public boolean addAll(int i, @NotNull Collection collection) { + return false; + } + + @Override + public boolean removeAll(@NotNull Collection collection) { + return false; + } + + @Override + public boolean retainAll(@NotNull Collection collection) { + return false; + } + + @Override + public void clear() { + + } + + @Override + public T get(int i) { + return null; + } + + @Override + public T set(int i, T t) { + return null; + } + + @Override + public void add(int i, T t) { + + } + + @Override + public T remove(int i) { + return null; + } + + @Override + public int indexOf(Object o) { + return -1; + } + + @Override + public int lastIndexOf(Object o) { + return -1; + } + + @NotNull + @Override + public ListIterator listIterator() { + return Collections.emptyListIterator(); + } + + @NotNull + @Override + public ListIterator listIterator(int i) { + return Collections.emptyListIterator(); + } + + @NotNull + @Override + public List subList(int i, int i1) { + return new DummyList<>(); + } +}