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 1/2] 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); + } + } +} From 274c41d6376af0ea978db5c16e8f1abe95bd8730 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 16 Apr 2023 20:54:41 -0400 Subject: [PATCH 2/2] Allow unloading unused structures --- .../modernfix/core/config/ModernFixEarlyConfig.java | 2 +- .../StructureManagerMixin.java | 11 ++++++++--- src/main/resources/modernfix.mixins.json | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) rename src/main/java/org/embeddedt/modernfix/mixin/{bugfix/structure_manager_crash => perf/dynamic_structure_manager}/StructureManagerMixin.java (70%) diff --git a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 5af30d73..7037ea3b 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -47,7 +47,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("bugfix.concurrency", true); this.addMixinRule("bugfix.edge_chunk_not_saved", true); this.addMixinRule("bugfix.packet_leak", false); - this.addMixinRule("bugfix.structure_manager_crash", true); + this.addMixinRule("perf.dynamic_structure_manager", true); this.addMixinRule("bugfix.mc218112", true); this.addMixinRule("bugfix.chunk_deadlock", true); this.addMixinRule("bugfix.chunk_deadlock.valhesia", modPresent("valhelsia_structures")); diff --git a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/structure_manager_crash/StructureManagerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java similarity index 70% rename from src/main/java/org/embeddedt/modernfix/mixin/bugfix/structure_manager_crash/StructureManagerMixin.java rename to src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java index 8ee6dd8d..4384dbcf 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/bugfix/structure_manager_crash/StructureManagerMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java @@ -1,5 +1,7 @@ -package org.embeddedt.modernfix.mixin.bugfix.structure_manager_crash; +package org.embeddedt.modernfix.mixin.perf.dynamic_structure_manager; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import com.mojang.datafixers.DataFixer; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.resources.ResourceManager; @@ -14,7 +16,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.Collections; import java.util.Map; @Mixin(StructureManager.class) @@ -24,6 +25,10 @@ public class StructureManagerMixin { @Inject(method = "", at = @At("RETURN")) private void makeStructuresSafe(ResourceManager arg, LevelStorageSource.LevelStorageAccess arg2, DataFixer dataFixer, CallbackInfo ci) { - this.structureRepository = Collections.synchronizedMap(this.structureRepository); + /* Structures needing to be reloaded is not a huge issue since we optimize loading them already */ + Cache structureCache = CacheBuilder.newBuilder() + .softValues() + .build(); + this.structureRepository = structureCache.asMap(); } } diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 6464cc72..5d575391 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -7,7 +7,7 @@ "refmap": "modernfix.refmap.json", "mixins": [ "bugfix.edge_chunk_not_saved.ChunkManagerMixin", - "bugfix.structure_manager_crash.StructureManagerMixin", + "perf.dynamic_structure_manager.StructureManagerMixin", "bugfix.tf_cme_on_load.TwilightForestModMixin", "bugfix.refinedstorage.te_bug.ItemExternalStorageProviderMixin", "bugfix.refinedstorage.te_bug.FluidExternalStorageProviderMixin",