From ad7bc8829b88df3581e3fac29c97ccaa1749f250 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 16 Apr 2023 20:14:42 -0400 Subject: [PATCH] Add eviction to some DFU caches --- build.gradle | 2 + .../modernfix/core/ModernFixMixinPlugin.java | 2 + .../embeddedt/modernfix/dfu/DFUBlaster.java | 49 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java diff --git a/build.gradle b/build.gradle index 80727ea5..ac270fca 100644 --- a/build.gradle +++ b/build.gradle @@ -112,9 +112,11 @@ tasks.withType(JavaCompile) { // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used. // We'll use that if it's available, but otherwise we'll use the older option. def targetVersion = 8 + /* if (JavaVersion.current().isJava9Compatible()) { options.release = targetVersion } + */ } java { diff --git a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java index 9255011f..27a12e99 100644 --- a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -13,6 +13,7 @@ import org.embeddedt.modernfix.classloading.FastAccessTransformerList; import org.embeddedt.modernfix.classloading.ModernFixResourceFinder; import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig; import org.embeddedt.modernfix.core.config.Option; +import org.embeddedt.modernfix.dfu.DFUBlaster; import org.embeddedt.modernfix.load.ModWorkManagerQueue; import org.embeddedt.modernfix.util.DummyList; import org.objectweb.asm.Opcodes; @@ -85,6 +86,7 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { FastAccessTransformerList.attemptReplace(); ModWorkManagerQueue.replace(); + DFUBlaster.blastMaps(); /* https://github.com/FabricMC/Mixin/pull/99 */ try { diff --git a/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java b/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java new file mode 100644 index 00000000..1083a9f7 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/dfu/DFUBlaster.java @@ -0,0 +1,49 @@ +package org.embeddedt.modernfix.dfu; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.mojang.datafixers.RewriteResult; +import com.mojang.datafixers.TypeRewriteRule; +import com.mojang.datafixers.functions.PointFreeRule; +import com.mojang.datafixers.types.Type; +import com.mojang.datafixers.util.Pair; +import org.apache.commons.lang3.tuple.Triple; +import org.embeddedt.modernfix.ModernFix; +import sun.misc.Unsafe; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; +import java.util.function.IntFunction; + +public class DFUBlaster { + public static void blastMaps() { + Cache>, Integer>, RewriteResult> hmapApplyCache = CacheBuilder.newBuilder() + .maximumSize(200) /* should mean approximately 50MB used max */ + .expireAfterAccess(3, TimeUnit.MINUTES) + .build(); + Cache, TypeRewriteRule, PointFreeRule>, Optional>> rewriteCache = CacheBuilder.newBuilder() + .maximumSize(1000) + .expireAfterAccess(3, TimeUnit.MINUTES) + .build(); + try { + Class FOLD_CLASS = Class.forName("com.mojang.datafixers.functions.Fold"); + Field hmapField = FOLD_CLASS.getDeclaredField("HMAP_APPLY_CACHE"); + hmapField.setAccessible(true); + final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafe.setAccessible(true); + Unsafe unsafe = (Unsafe)theUnsafe.get(null); + Object base = unsafe.staticFieldBase(hmapField); + long offset = unsafe.staticFieldOffset(hmapField); + unsafe.putObject(base, offset, hmapApplyCache.asMap()); + Field rewriteCacheField = Type.class.getDeclaredField("REWRITE_CACHE"); + rewriteCacheField.setAccessible(true); + base = unsafe.staticFieldBase(rewriteCacheField); + offset = unsafe.staticFieldOffset(rewriteCacheField); + unsafe.putObject(base, offset, rewriteCache.asMap()); + } catch(Throwable e) { + ModernFix.LOGGER.error("Could not replace DFU map", e); + } + } +}