diff --git a/src/main/java/org/embeddedt/modernfix/ModernFix.java b/src/main/java/org/embeddedt/modernfix/ModernFix.java index 3a0a4274..fbc0614a 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -1,6 +1,7 @@ package org.embeddedt.modernfix; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import net.minecraft.Util; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ServerLevel; @@ -24,6 +25,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.classloading.ModFileScanDataDeduplicator; +import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.core.config.ModernFixConfig; import org.embeddedt.modernfix.entity.EntityDataIDSyncHandler; import org.embeddedt.modernfix.packet.PacketHandler; @@ -32,9 +34,8 @@ import org.embeddedt.modernfix.util.ClassInfoManager; import java.lang.management.ManagementFactory; import java.lang.reflect.Field; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; +import java.lang.reflect.Method; +import java.util.concurrent.*; import java.util.function.BooleanSupplier; // The value here should match an entry in the META-INF/mods.toml file @@ -53,6 +54,26 @@ public class ModernFix { public static CountDownLatch worldLoadSemaphore = null; + private static ExecutorService resourceReloadService = null; + + static { + try { + if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dedicated_reload_executor.ReloadExecutor")) { + Method makeExecutorMethod = ObfuscationReflectionHelper.findMethod(Util.class, "m_137477_", String.class); + resourceReloadService = (ExecutorService)makeExecutorMethod.invoke(null, "ResourceReload"); + } else { + resourceReloadService = Util.backgroundExecutor(); + } + } catch(RuntimeException | ReflectiveOperationException e) { + LOGGER.error("Could not create resource reload executor", e); + resourceReloadService = Util.backgroundExecutor(); + } + } + + public static ExecutorService resourceReloadExecutor() { + return resourceReloadService; + } + /** * Simple mechanism used to delay some background processes until the client is actually in-game, to reduce * launch time. diff --git a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java index 6b3f799a..4270f094 100644 --- a/src/main/java/org/embeddedt/modernfix/ModernFixClient.java +++ b/src/main/java/org/embeddedt/modernfix/ModernFixClient.java @@ -7,6 +7,7 @@ import net.minecraft.client.gui.components.DebugScreenOverlay; import net.minecraft.client.gui.screens.ConnectScreen; import net.minecraft.client.gui.screens.TitleScreen; import net.minecraftforge.client.event.CustomizeGuiOverlayEvent; +import net.minecraft.util.MemoryReserve; import net.minecraftforge.client.event.ScreenEvent; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.SynchedEntityData; @@ -49,8 +50,7 @@ public class ModernFixClient { public ModernFixClient() { // clear reserve as it's not needed - // TODO: port 1.18+ - // ObfuscationReflectionHelper.setPrivateValue(Minecraft.class, null, new byte[0], "field_71444_a"); + MemoryReserve.release(); if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.faster_singleplayer_load.ClientEvents")) { MinecraftForge.EVENT_BUS.register(new LoadEvents()); } diff --git a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java index 1a368935..f9df7610 100644 --- a/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java +++ b/src/main/java/org/embeddedt/modernfix/core/ModernFixMixinPlugin.java @@ -42,7 +42,6 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin { config.getOptionCount(), config.getOptionOverrideCount()); FastAccessTransformerList.attemptReplace(); - ModWorkManagerQueue.replace(); DFUBlaster.blastMaps(); /* https://github.com/FabricMC/Mixin/pull/99 */ 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 d3fcaef3..7afb9339 100644 --- a/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java +++ b/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java @@ -34,6 +34,7 @@ public class ModernFixEarlyConfig { this.addMixinRule("perf.reduce_blockstate_cache_rebuilds", true); this.addMixinRule("perf.model_optimizations", true); this.addMixinRule("perf.dynamic_resources", false); + this.addMixinRule("perf.dedicated_reload_executor", true); /* 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); @@ -65,6 +66,7 @@ public class ModernFixEarlyConfig { /* Mod compat */ disableIfModPresent("mixin.perf.thread_priorities", "smoothboot"); + disableIfModPresent("mixin.perf.boost_worker_count", "smoothboot"); disableIfModPresent("mixin.perf.async_jei", "modernui"); disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge"); disableIfModPresent("mixin.bugfix.mc218112", "performant"); diff --git a/src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java new file mode 100644 index 00000000..9e6dcac0 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/core/BootstrapMixin.java @@ -0,0 +1,26 @@ +package org.embeddedt.modernfix.mixin.core; + +import net.minecraft.server.Bootstrap; +import org.embeddedt.modernfix.load.ModWorkManagerQueue; +import org.slf4j.Logger; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Bootstrap.class) +public class BootstrapMixin { + @Shadow private static boolean isBootstrapped; + + @Shadow @Final private static Logger LOGGER; + + @Inject(method = "bootStrap", at = @At("HEAD")) + private static void doModernFixBootstrap(CallbackInfo ci) { + if(!isBootstrapped) { + LOGGER.info("ModernFix bootstrap"); + ModWorkManagerQueue.replace(); + } + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/CreateWorldScreenMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/CreateWorldScreenMixin.java new file mode 100644 index 00000000..52dcbe9f --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/CreateWorldScreenMixin.java @@ -0,0 +1,22 @@ +package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor; + +import net.minecraft.client.gui.screens.worldselection.CreateWorldScreen; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.util.concurrent.Executor; + +@Mixin(CreateWorldScreen.class) +public class CreateWorldScreenMixin { + @ModifyArg(method = "applyNewPackConfig", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/WorldLoader;load(Lnet/minecraft/server/WorldLoader$InitConfig;Lnet/minecraft/server/WorldLoader$WorldDataSupplier;Lnet/minecraft/server/WorldLoader$ResultFactory;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 3) + private Executor getReloadExecutorService(Executor e) { + return ModernFix.resourceReloadExecutor(); + } + + @ModifyArg(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/WorldLoader;load(Lnet/minecraft/server/WorldLoader$InitConfig;Lnet/minecraft/server/WorldLoader$WorldDataSupplier;Lnet/minecraft/server/WorldLoader$ResultFactory;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 3) + private static Executor getCreationExecutorService(Executor e) { + return ModernFix.resourceReloadExecutor(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java new file mode 100644 index 00000000..bfe0fb84 --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftMixin.java @@ -0,0 +1,18 @@ +package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor; + +import net.minecraft.client.Minecraft; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @Redirect(method = { "", "reloadResourcePacks(Z)Ljava/util/concurrent/CompletableFuture;" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;backgroundExecutor()Ljava/util/concurrent/ExecutorService;", ordinal = 0)) + private ExecutorService getResourceReloadExecutor() { + return ModernFix.resourceReloadExecutor(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java new file mode 100644 index 00000000..118c1bce --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/MinecraftServerMixin.java @@ -0,0 +1,17 @@ +package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor; + +import net.minecraft.server.MinecraftServer; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.util.concurrent.Executor; + +@Mixin(MinecraftServer.class) +public class MinecraftServerMixin { + @ModifyArg(method = "*", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/ReloadableServerResources;loadResources(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/core/RegistryAccess$Frozen;Lnet/minecraft/world/flag/FeatureFlagSet;Lnet/minecraft/commands/Commands$CommandSelection;ILjava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 5) + private Executor getReloadExecutor(Executor asyncExecutor) { + return ModernFix.resourceReloadExecutor(); + } +} diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/WorldOpenFlowsMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/WorldOpenFlowsMixin.java new file mode 100644 index 00000000..d1668b3b --- /dev/null +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dedicated_reload_executor/WorldOpenFlowsMixin.java @@ -0,0 +1,17 @@ +package org.embeddedt.modernfix.mixin.perf.dedicated_reload_executor; + +import net.minecraft.client.gui.screens.worldselection.WorldOpenFlows; +import org.embeddedt.modernfix.ModernFix; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +import java.util.concurrent.Executor; + +@Mixin(WorldOpenFlows.class) +public class WorldOpenFlowsMixin { + @ModifyArg(method = "loadWorldDataBlocking", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/WorldLoader;load(Lnet/minecraft/server/WorldLoader$InitConfig;Lnet/minecraft/server/WorldLoader$WorldDataSupplier;Lnet/minecraft/server/WorldLoader$ResultFactory;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"), index = 3) + private Executor getResourceReloadExecutor(Executor service) { + return ModernFix.resourceReloadExecutor(); + } +} diff --git a/src/main/resources/modernfix.mixins.json b/src/main/resources/modernfix.mixins.json index 264687ff..47fe026f 100644 --- a/src/main/resources/modernfix.mixins.json +++ b/src/main/resources/modernfix.mixins.json @@ -6,9 +6,11 @@ "compatibilityLevel": "JAVA_17", "refmap": "modernfix.refmap.json", "mixins": [ + "core.BootstrapMixin", "bugfix.edge_chunk_not_saved.ChunkManagerMixin", "perf.dynamic_structure_manager.StructureManagerMixin", "bugfix.chunk_deadlock.ServerChunkCacheMixin", + "perf.dedicated_reload_executor.MinecraftServerMixin", "perf.remove_biome_temperature_cache.BiomeMixin", "perf.reduce_blockstate_cache_rebuilds.GameDataMixin", "perf.reduce_blockstate_cache_rebuilds.BlockCallbacksMixin", @@ -41,6 +43,9 @@ "core.SynchedEntityDataMixin", "feature.measure_time.MinecraftMixin", "bugfix.concurrency.MinecraftMixin", + "perf.dedicated_reload_executor.CreateWorldScreenMixin", + "perf.dedicated_reload_executor.MinecraftMixin", + "perf.dedicated_reload_executor.WorldOpenFlowsMixin", "perf.dynamic_resources.BlockElementFaceDeserializerMixin", "perf.dynamic_resources.BlockModelShaperMixin", "perf.dynamic_resources.ItemModelShaperMixin",