From c8c316a06fffe661f85a0db95e21d81a30d1bee5 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 31 Jul 2023 15:45:33 -0400 Subject: [PATCH 1/3] Enforce 512MB heap for dev runs --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 38e67e4c..c971d173 100644 --- a/build.gradle +++ b/build.gradle @@ -200,6 +200,12 @@ configure(subprojects.findAll {it.name == "forge" || it.name == "fabric"}) { sourceSet project(':common').sourceSets.main } } + runs { + client { + vmArgs "-Xmx512m" + vmArgs "-Xms512m" + } + } } def copyJarNameConsistent = tasks.register('copyJarNameConsistent', Copy) { From 11fe75578c817c0ce47293f68221d2b78e9e7439 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 31 Jul 2023 21:51:45 -0400 Subject: [PATCH 2/3] Add option to generate block codecs on the fly instead of at startup --- .../StateDefinitionMixin.java | 23 +++++++ .../StateHolderMixin.java | 60 +++++++++++++++++++ .../core/config/ModernFixEarlyConfig.java | 1 + .../main/resources/modernfix.accesswidener | 1 + 4 files changed, 85 insertions(+) create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java create mode 100644 common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java new file mode 100644 index 00000000..0649452a --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java @@ -0,0 +1,23 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_block_codecs; + +import com.mojang.serialization.MapCodec; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.StateHolder; +import org.spongepowered.asm.mixin.Final; +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.ModifyVariable; + +@Mixin(StateDefinition.class) +public class StateDefinitionMixin> { + @Shadow @Final private O owner; + + @ModifyVariable(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Maps;newLinkedHashMap()Ljava/util/LinkedHashMap;"), ordinal = 0) + private MapCodec replaceMapCodec(MapCodec codec) { + if(this.owner instanceof Block) + return null; + return codec; + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java new file mode 100644 index 00000000..eaa4f8d6 --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java @@ -0,0 +1,60 @@ +package org.embeddedt.modernfix.common.mixin.perf.dynamic_block_codecs; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.mojang.serialization.Codec; +import com.mojang.serialization.Decoder; +import com.mojang.serialization.Encoder; +import com.mojang.serialization.MapCodec; +import net.minecraft.core.Registry; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.StateHolder; +import net.minecraft.world.level.block.state.properties.Property; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.concurrent.ExecutionException; +import java.util.function.Function; +import java.util.function.Supplier; + +@Mixin(StateHolder.class) +public class StateHolderMixin { + private static final LoadingCache> MODERNFIX_CODEC_CACHE = CacheBuilder.newBuilder() + .maximumSize(100000) + .build(new CacheLoader>() { + @Override + public MapCodec load(Block block) throws Exception { + System.out.println("Generating codec for " + Registry.BLOCK.getKey(block)); + Supplier stateSupplier = block::defaultBlockState; + MapCodec mapCodec = MapCodec.of(Encoder.empty(), Decoder.unit(stateSupplier)); + for(Property property : block.getStateDefinition().getProperties()) { + mapCodec = StateDefinition.appendPropertyCodec(mapCodec, stateSupplier, property.getName(), property); + } + return mapCodec; + } + }); + + @Redirect(method = "codec", at = @At(value = "INVOKE", target = "Lcom/mojang/serialization/Codec;dispatch(Ljava/lang/String;Ljava/util/function/Function;Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;")) + private static > Codec obtainCodec(Codec codec, String typeKey, Function type, Function> codecFn, Codec codecMethodArg, Function stateSupplier) { + return codec.dispatch(typeKey, type, block -> { + if(block instanceof Block) { + S state = stateSupplier.apply(block); + if(state.getValues().isEmpty()) + return Codec.unit(state); + MapCodec mapCodec; + try { + mapCodec = (MapCodec)MODERNFIX_CODEC_CACHE.get((Block)block); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + return mapCodec.fieldOf("Properties").codec(); + } else { + return codecFn.apply(block); + } + }); + } +} diff --git a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java index 5c589b05..353919c6 100644 --- a/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -161,6 +161,7 @@ public class ModernFixEarlyConfig { private static final ImmutableMap DEFAULT_SETTING_OVERRIDES = new DefaultSettingMapBuilder() .put("mixin.perf.dynamic_resources", false) .put("mixin.perf.reuse_datapacks", false) + .put("mixin.perf.dynamic_block_codecs", false) .put("mixin.feature.direct_stack_trace", false) .putConditionally(ModernFixPlatformHooks.INSTANCE::isDevEnv, "mixin.perf.rewrite_registry", false) .put("mixin.perf.clear_mixin_classinfo", false) diff --git a/common/src/main/resources/modernfix.accesswidener b/common/src/main/resources/modernfix.accesswidener index 62759631..aa5fa80f 100644 --- a/common/src/main/resources/modernfix.accesswidener +++ b/common/src/main/resources/modernfix.accesswidener @@ -31,3 +31,4 @@ accessible field net/minecraft/client/renderer/RenderStateShard name Ljava/lang/ accessible method net/minecraft/client/gui/screens/Screen addButton (Lnet/minecraft/client/gui/components/AbstractWidget;)Lnet/minecraft/client/gui/components/AbstractWidget; accessible field net/minecraft/server/packs/resources/SimpleReloadableResourceManager namespacedPacks Ljava/util/Map; accessible field net/minecraft/client/renderer/entity/EnderDragonRenderer$DragonModel entity Lnet/minecraft/world/entity/boss/enderdragon/EnderDragon; +accessible method net/minecraft/world/level/block/state/StateDefinition appendPropertyCodec (Lcom/mojang/serialization/MapCodec;Ljava/util/function/Supplier;Ljava/lang/String;Lnet/minecraft/world/level/block/state/properties/Property;)Lcom/mojang/serialization/MapCodec; \ No newline at end of file From 25dc08eb7966f9737bf78f1e346e1212d87e73ed Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 31 Jul 2023 22:18:26 -0400 Subject: [PATCH 3/3] Make dynamic codecs actually work --- .../StateDefinitionMixin.java | 15 +++++++++------ .../dynamic_block_codecs/StateHolderMixin.java | 2 -- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java index 0649452a..82ae09df 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateDefinitionMixin.java @@ -1,23 +1,26 @@ package org.embeddedt.modernfix.common.mixin.perf.dynamic_block_codecs; -import com.mojang.serialization.MapCodec; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.StateHolder; +import net.minecraft.world.level.block.state.properties.Property; import org.spongepowered.asm.mixin.Final; 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.ModifyVariable; +import java.util.Map; +import java.util.function.Function; + @Mixin(StateDefinition.class) public class StateDefinitionMixin> { @Shadow @Final private O owner; - @ModifyVariable(method = "", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/Maps;newLinkedHashMap()Ljava/util/LinkedHashMap;"), ordinal = 0) - private MapCodec replaceMapCodec(MapCodec codec) { - if(this.owner instanceof Block) - return null; - return codec; + @ModifyVariable(method = "", at = @At("HEAD"), ordinal = 0, argsOnly = true) + private static > StateDefinition.Factory replaceMapCodec(StateDefinition.Factory factory, Function function, O object, StateDefinition.Factory factory2, Map> map) { + if(object instanceof Block) + return (o, m, c) -> factory.create(o, m, null); + return factory; } } diff --git a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java index eaa4f8d6..7455fcbb 100644 --- a/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java +++ b/common/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_block_codecs/StateHolderMixin.java @@ -7,7 +7,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.Decoder; import com.mojang.serialization.Encoder; import com.mojang.serialization.MapCodec; -import net.minecraft.core.Registry; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; @@ -28,7 +27,6 @@ public class StateHolderMixin { .build(new CacheLoader>() { @Override public MapCodec load(Block block) throws Exception { - System.out.println("Generating codec for " + Registry.BLOCK.getKey(block)); Supplier stateSupplier = block::defaultBlockState; MapCodec mapCodec = MapCodec.of(Encoder.empty(), Decoder.unit(stateSupplier)); for(Property property : block.getStateDefinition().getProperties()) {