diff --git a/src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java new file mode 100644 index 00000000..34f531a3 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/devenv/GameDataMixin.java @@ -0,0 +1,16 @@ +package org.embeddedt.modernfix.mixin.devenv; + +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.GameData; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(GameData.class) +public class GameDataMixin { + + @Redirect(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/registries/ForgeRegistry;dump(Lnet/minecraft/resources/ResourceLocation;)V")) + private static void noDump(ForgeRegistry reg, ResourceLocation id) { + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java index 6f27929f..8300cf9f 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistryMixin.java @@ -2,11 +2,17 @@ package org.embeddedt.modernfix.mixin.perf.fast_registry_validation; import net.minecraftforge.fml.common.ObfuscationReflectionHelper; import net.minecraftforge.registries.ForgeRegistry; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; 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.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.lang.reflect.Method; +import java.util.BitSet; @Mixin(value = ForgeRegistry.class, remap = false) public class ForgeRegistryMixin { @@ -25,4 +31,31 @@ public class ForgeRegistryMixin { } return bitSetTrimMethod; } + + private int expectedNextBit = -1; + + /** + * Avoid calling nextClearBit and scanning the whole registry for every block registration. + */ + @Redirect(method = "add(ILnet/minecraftforge/registries/IForgeRegistryEntry;Ljava/lang/String;)I", at = @At(value = "INVOKE", target = "Ljava/util/BitSet;nextClearBit(I)I")) + private int useCachedBit(BitSet availabilityMap, int minimum) { + int bit = availabilityMap.nextClearBit(expectedNextBit != -1 ? expectedNextBit : minimum); + expectedNextBit = bit + 1; + return bit; + } + + @Inject(method = { "sync", "clear", "block" }, at = @At("HEAD")) + private void clearBitCache(CallbackInfo ci) { + expectedNextBit = -1; + } + + @Inject(method = "markDummy", at = @At(value = "INVOKE", target = "Ljava/util/BitSet;clear(I)V")) + private void clearBitCache2(CallbackInfoReturnable cir) { + expectedNextBit = -1; + } + + @Redirect(method = "add(ILnet/minecraftforge/registries/IForgeRegistryEntry;Ljava/lang/String;)I", at = @At(value = "INVOKE", target = "Lorg/apache/logging/log4j/Logger;trace(Lorg/apache/logging/log4j/Marker;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V")) + private void skipTrace(Logger logger, Marker marker, String s, Object o, Object o1, Object o2, Object o3, Object o4) { + + } } diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistrySnapshotMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistrySnapshotMixin.java new file mode 100644 index 00000000..ad941ab0 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ForgeRegistrySnapshotMixin.java @@ -0,0 +1,33 @@ +package org.embeddedt.modernfix.mixin.perf.fast_registry_validation; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +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.Set; + +@Mixin(ForgeRegistry.Snapshot.class) +public class ForgeRegistrySnapshotMixin { + @Shadow @Final @Mutable public Map ids; + + @Shadow @Final @Mutable public Set dummied; + + /** + * The only good reason to use tree maps here is to keep the order the same. But we are tracking IDs + * anyway so order shouldn't matter. We replace the maps that will be most used. + */ + @Inject(method = "", at = @At("RETURN")) + private void replaceSnapshotMaps(CallbackInfo ci) { + this.ids = new Object2ObjectOpenHashMap<>(); + this.dummied = new ObjectOpenHashSet<>(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java new file mode 100644 index 00000000..804dce98 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/fast_registry_validation/ResourceKeyMixin.java @@ -0,0 +1,28 @@ +package org.embeddedt.modernfix.mixin.perf.fast_registry_validation; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +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.CallbackInfoReturnable; + +import java.util.Map; + +@Mixin(ResourceKey.class) +public class ResourceKeyMixin { + private static Map>> INTERNING_MAP = new Object2ObjectOpenHashMap<>(); + @Inject(method = "create(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/resources/ResourceKey;", at = @At("HEAD"), cancellable = true) + private static void createEfficient(ResourceLocation parent, ResourceLocation location, CallbackInfoReturnable> cir) { + synchronized (ResourceKey.class) { + Map> keys = INTERNING_MAP.computeIfAbsent(parent, k -> new Object2ObjectOpenHashMap<>()); + ResourceKey key = keys.get(location); + if(key == null) { + key = new ResourceKey<>(parent, location); + keys.put(location, key); + } + cir.setReturnValue((ResourceKey)key); + } + } +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 22dba02c..30e53ddd 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -25,4 +25,5 @@ public net.minecraft.block.AbstractBlock$Properties field_235806_h_ # requiresCo public net.minecraft.block.AbstractBlock$Properties field_200959_g # destroyTime public net.minecraft.world.server.ServerChunkProvider$ChunkExecutor public net.minecraft.nbt.CompoundNBT (Ljava/util/Map;)V # -public net.minecraft.client.renderer.texture.TextureAtlasSprite (Lnet/minecraft/client/renderer/texture/TextureAtlas;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIIILcom/mojang/blaze3d/platform/NativeImage;)V # \ No newline at end of file +public net.minecraft.client.renderer.texture.TextureAtlasSprite (Lnet/minecraft/client/renderer/texture/TextureAtlas;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite$Info;IIIIILcom/mojang/blaze3d/platform/NativeImage;)V # +public net.minecraft.resources.ResourceKey (Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)V # \ No newline at end of file diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index a9af9c66..f8320632 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -64,6 +64,8 @@ "perf.kubejs.CustomIngredientMixin", "perf.nbt_memory_usage.CompoundTagMixin", "perf.fast_registry_validation.ForgeRegistryMixin", + "perf.fast_registry_validation.ForgeRegistrySnapshotMixin", + "perf.fast_registry_validation.ResourceKeyMixin", "perf.cache_strongholds.ChunkGeneratorMixin", "perf.cache_upgraded_structures.StructureManagerMixin", "perf.cache_strongholds.ServerLevelMixin", @@ -73,7 +75,8 @@ "perf.compress_blockstate.BlockBehaviourMixin", "perf.dedup_blockstate_flattening_map.BlockStateDataMixin", "perf.dedup_blockstate_flattening_map.ChunkPalettedStorageFixMixin", - "devenv.MinecraftServerMixin" + "devenv.MinecraftServerMixin", + "devenv.GameDataMixin" ], "client": [ "core.MinecraftMixin",