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] 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",