diff --git a/build.gradle b/build.gradle index a40aa23b..4b5f9826 100644 --- a/build.gradle +++ b/build.gradle @@ -106,9 +106,11 @@ tasks.withType(JavaCompile) { options.encoding = "UTF-8" def targetVersion = 17 + /* 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 8d027fd3..1a368935 100644 --- a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -7,6 +7,7 @@ import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.classloading.FastAccessTransformerList; 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; @@ -42,6 +43,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/core/config/ModernFixEarlyConfig.java b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 03308b21..35f549de 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -41,6 +41,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.compress_blockstate", false); this.addMixinRule("bugfix.concurrency", true); this.addMixinRule("bugfix.edge_chunk_not_saved", true); + this.addMixinRule("perf.dynamic_structure_manager", true); this.addMixinRule("bugfix.chunk_deadlock", true); this.addMixinRule("perf.thread_priorities", true); this.addMixinRule("perf.scan_cache", true); 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); + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java new file mode 100644 index 00000000..d18df526 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_structure_manager/StructureManagerMixin.java @@ -0,0 +1,35 @@ +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; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; +import net.minecraft.world.level.storage.LevelStorageSource; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +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.Map; +import java.util.Optional; + +@Mixin(StructureTemplateManager.class) +public class StructureManagerMixin { + @Shadow @Final @Mutable + private Map> structureRepository; + + @Inject(method = "", at = @At("RETURN")) + private void makeStructuresSafe(ResourceManager arg, LevelStorageSource.LevelStorageAccess arg2, DataFixer dataFixer, CallbackInfo ci) { + /* 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 a2b20e27..1a0f026e 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -9,6 +9,7 @@ "bugfix.edge_chunk_not_saved.ChunkManagerMixin", "perf.modern_resourcepacks.VanillaPackResourcesMixin", "perf.modern_resourcepacks.PathPackResourcesMixin", + "perf.dynamic_structure_manager.StructureManagerMixin", "bugfix.chunk_deadlock.ServerChunkCacheMixin", "perf.remove_biome_temperature_cache.BiomeMixin", "perf.reduce_blockstate_cache_rebuilds.GameDataMixin",