From c561d818f398f9b9f6b826db34b705a97c187f74 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 30 Apr 2023 19:07:06 -0400 Subject: [PATCH 1/4] Implement improved version of LazyDFU (having it installed is still beneficial) Now DFU classes are not loaded until the first time DFU is actually needed to update something. This saves quite a bit of RAM. This is a better version of dedup_blockstate_flattening_map so the latter is removed. --- .../core/config/ModernFixEarlyConfig.java | 2 +- .../modernfix/dfu/LazyDataFixer.java | 96 +++++++++++++++++++ .../BlockStateDataMixin.java | 21 ---- .../ChunkPalettedStorageFixMixin.java | 31 ------ .../perf/dynamic_dfu/DataFixersMixin.java | 30 ++++++ src/main/resources/modernfix.mixins.json | 3 +- 6 files changed, 128 insertions(+), 55 deletions(-) create mode 100644 src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java delete mode 100644 src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/BlockStateDataMixin.java delete mode 100644 src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/ChunkPalettedStorageFixMixin.java create mode 100644 src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java 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 60483967..f3019646 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -62,7 +62,6 @@ public class ModernFixEarlyConfig { /* Use a simpler ArrayMap if FerriteCore is using the map intelligently anyway */ this.addMixinRule("perf.state_definition_construct", modPresent("ferritecore")); this.addMixinRule("perf.cache_strongholds", true); - this.addMixinRule("perf.dedup_blockstate_flattening_map", false); this.addMixinRule("perf.clear_mixin_classinfo", false); this.addMixinRule("perf.cache_upgraded_structures", true); this.addMixinRule("perf.biome_zoomer", true); @@ -93,6 +92,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.nbt_memory_usage", true); this.addMixinRule("perf.patchouli_deduplicate_books", modPresent("patchouli")); this.addMixinRule("perf.datapack_reload_exceptions", true); + this.addMixinRule("perf.dynamic_dfu", true); this.addMixinRule("perf.async_locator", true); this.addMixinRule("perf.faster_texture_stitching", true); this.addMixinRule("perf.faster_texture_loading", true); diff --git a/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java b/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java new file mode 100644 index 00000000..dd9dfbdb --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/dfu/LazyDataFixer.java @@ -0,0 +1,96 @@ +package org.embeddedt.modernfix.dfu; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFix; +import com.mojang.datafixers.DataFixUtils; +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.schemas.Schema; +import com.mojang.datafixers.types.Type; +import com.mojang.datafixers.types.constant.EmptyPart; +import com.mojang.datafixers.types.templates.TypeTemplate; +import com.mojang.serialization.Dynamic; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.SharedConstants; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.Collections; +import java.util.Map; +import java.util.function.Supplier; + +public class LazyDataFixer implements DataFixer { + private static final Logger LOGGER = LogManager.getLogger("ModernFix"); + private DataFixer backingDataFixer; + private final Supplier dfuSupplier; + private static final Schema FAKE_SCHEMA = new EmptySchema(); + + public LazyDataFixer(Supplier dfuSupplier) { + LOGGER.info("Bypassed Mojang DFU"); + this.backingDataFixer = null; + this.dfuSupplier = dfuSupplier; + } + @Override + public Dynamic update(DSL.TypeReference type, Dynamic input, int version, int newVersion) { + if(version >= newVersion) + return input; + synchronized (this) { + if(backingDataFixer == null) { + LOGGER.info("Instantiating Mojang DFU"); + backingDataFixer = dfuSupplier.get(); + } + } + return backingDataFixer.update(type, input, version, newVersion); + } + + /** + * "getSchema is only there for checks that are not important" - fry, 2021 + */ + @Override + public Schema getSchema(int key) { + return FAKE_SCHEMA; + } + + /** + * Empty schema that also returns empty Type instances to prevent crashes. + */ + static class EmptySchema extends Schema { + public EmptySchema() { + super(DataFixUtils.makeKey(SharedConstants.getCurrentVersion().getWorldVersion()), null); + } + + private static final Type EMPTY_TYPE = new EmptyPart(); + private static final TypeTemplate FAKE_TEMPLATE = EMPTY_TYPE.template(); + + + @Override + protected Map> buildTypes() { + Object2ObjectOpenHashMap> map = new Object2ObjectOpenHashMap<>(); + map.defaultReturnValue(new EmptyPart()); + return map; + } + + @Override + public TypeTemplate resolveTemplate(String name) { + return FAKE_TEMPLATE; + } + + @Override + public Type getChoiceType(DSL.TypeReference type, String choiceName) { + return EMPTY_TYPE; + } + + @Override + public void registerTypes(Schema schema, Map> entityTypes, Map> blockEntityTypes) { + } + + @Override + public Map> registerEntities(Schema schema) { + return Collections.emptyMap(); + } + + @Override + public Map> registerBlockEntities(Schema schema) { + return Collections.emptyMap(); + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/BlockStateDataMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/BlockStateDataMixin.java deleted file mode 100644 index 63da3acc..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/BlockStateDataMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.dedup_blockstate_flattening_map; - -import net.minecraft.util.datafix.fixes.BlockStateData; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(BlockStateData.class) -public class BlockStateDataMixin { - @Inject(method = {"register", "finalizeMaps"}, at = @At("HEAD"), cancellable = true) - private static void noFlattening(CallbackInfo ci) { - ci.cancel(); - } - - @Inject(method = {"upgradeBlockStateTag", "upgradeBlock(I)Ljava/lang/String;", "upgradeBlock(Ljava/lang/String;)Ljava/lang/String;", "getTag"}, at = @At("HEAD"), require = 4) - private static void preventCorruption(CallbackInfoReturnable cir) { - throw new UnsupportedOperationException("Performing the Flattening is currently disabled in the ModernFix config."); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/ChunkPalettedStorageFixMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/ChunkPalettedStorageFixMixin.java deleted file mode 100644 index 962a7fee..00000000 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedup_blockstate_flattening_map/ChunkPalettedStorageFixMixin.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.embeddedt.modernfix.mixin.perf.dedup_blockstate_flattening_map; - -import com.mojang.serialization.Dynamic; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtOps; -import net.minecraft.util.datafix.fixes.ChunkPalettedStorageFix; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.function.Consumer; - -@Mixin(ChunkPalettedStorageFix.class) -public class ChunkPalettedStorageFixMixin { - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lcom/mojang/datafixers/DataFixUtils;make(Ljava/lang/Object;Ljava/util/function/Consumer;)Ljava/lang/Object;")) - private static Object skipMakingMap(Object o, Consumer consumer) { - return o; - } - - @Redirect(method = "", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/datafix/fixes/BlockStateData;getTag(I)Lcom/mojang/serialization/Dynamic;")) - private static Dynamic getFakeAirTag(int id) { - return new Dynamic<>(NbtOps.INSTANCE, new CompoundTag()); - } - - @Inject(method = "fix", at = @At("HEAD")) - private void skipFix(CallbackInfoReturnable> cir) { - throw new UnsupportedOperationException("No Flattening for you."); - } -} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java new file mode 100644 index 00000000..f8e48cfa --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_dfu/DataFixersMixin.java @@ -0,0 +1,30 @@ +package org.embeddedt.modernfix.mixin.perf.dynamic_dfu; + +import com.mojang.datafixers.DataFixer; +import net.minecraft.util.datafix.DataFixers; +import org.embeddedt.modernfix.dfu.LazyDataFixer; +import org.spongepowered.asm.mixin.Mixin; +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.CallbackInfoReturnable; + +@Mixin(DataFixers.class) +public abstract class DataFixersMixin { + @Shadow protected static DataFixer createFixerUpper() { + throw new AssertionError(); + } + + private static LazyDataFixer lazyDataFixer; + + /** + * Avoid classloading the DFU logic until we actually need it. + */ + @Inject(method = "createFixerUpper", at = @At("HEAD"), cancellable = true) + private static void createLazyFixerUpper(CallbackInfoReturnable cir) { + if(lazyDataFixer == null) { + lazyDataFixer = new LazyDataFixer(DataFixersMixin::createFixerUpper); + cir.setReturnValue(lazyDataFixer); + } + } +} diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 6b05bb8c..1e8dca49 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -24,6 +24,7 @@ "bugfix.chunk_deadlock.ServerChunkCacheMixin", "bugfix.chunk_deadlock.valhesia.BlockStateBaseMixin", "perf.dedicated_reload_executor.MinecraftServerMixin", + "perf.dynamic_dfu.DataFixersMixin", "perf.remove_biome_temperature_cache.BiomeMixin", "perf.resourcepacks.ModFileResourcePackMixin", "perf.resourcepacks.VanillaPackMixin", @@ -75,8 +76,6 @@ "perf.biome_zoomer.FuzzyOffsetBiomeZoomerMixin", "perf.compress_blockstate.BlockStateBaseMixin", "perf.compress_blockstate.BlockBehaviourMixin", - "perf.dedup_blockstate_flattening_map.BlockStateDataMixin", - "perf.dedup_blockstate_flattening_map.ChunkPalettedStorageFixMixin", "perf.remove_spawn_chunks.ServerChunkCacheAccessor", "perf.remove_spawn_chunks.MinecraftServerMixin", "perf.remove_spawn_chunks.ServerLevelMixin", From fead01b1428c6a84f6eb2c092b52dc4fc392f668 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 30 Apr 2023 19:17:04 -0400 Subject: [PATCH 2/4] Update LazyDFU warning --- src/main/resources/assets/modernfix/lang/en_us.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/modernfix/lang/en_us.json b/src/main/resources/assets/modernfix/lang/en_us.json index ddd8c10b..108f5124 100644 --- a/src/main/resources/assets/modernfix/lang/en_us.json +++ b/src/main/resources/assets/modernfix/lang/en_us.json @@ -2,7 +2,7 @@ "key.modernfix": "ModernFix", "key.modernfix.config": "Open config screen", "modernfix.jei_load": "Loading JEI, this may take a while", - "modernfix.no_lazydfu": "ModernFix detected that DFU rules were compiled on startup. This slows down game launching. Installing LazyDFU to resolve this is highly recommended.", + "modernfix.no_lazydfu": "LazyDFU is not installed. If Minecraft needs to update game data from an older version, there may be noticeable lag.", "modernfix.config": "ModernFix mixin config", "modernfix.config.done_restart": "Done (restart required)", "modernfix.option.on": "on", From cc78749e87ad6f919859dba6ad51e5b9aac615c8 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 30 Apr 2023 19:17:20 -0400 Subject: [PATCH 3/4] Remove LazyDFU from dev, as rule optimization would now only be performed if older game data is loaded --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4ab0f76e..ec910a7b 100644 --- a/build.gradle +++ b/build.gradle @@ -86,7 +86,6 @@ dependencies { // your forge dependency, this is **required** when using Forge Loom in forge mode! forge "net.minecraftforge:forge:${project.forge_version}" - modRuntimeOnly "curse.maven:lazydfu-460819:${lazydfu_version}" modCompileOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") //modRuntimeOnly("mezz.jei:jei-${minecraft_version}:${jei_version}") From 7e87aae3f66b2f92e2136fd7ae55ead8d51fa7be Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sun, 30 Apr 2023 19:20:04 -0400 Subject: [PATCH 4/4] Hide LazyDFU missing warning in dev --- src/main/java/org/embeddedt/modernfix/ModernFix.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/embeddedt/modernfix/ModernFix.java b/src/main/java/org/embeddedt/modernfix/ModernFix.java index 5ee1161f..06924e2c 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -129,7 +129,7 @@ public class ModernFix { if(ModList.get().isLoaded(modId)) return true; } - return false; + return !FMLLoader.isProduction(); } @SubscribeEvent