Merge remote-tracking branch 'origin/1.20' into 1.21.1

This commit is contained in:
embeddedt 2025-06-02 19:18:13 -04:00
commit ae7df998bf
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
8 changed files with 75 additions and 67 deletions

View File

@ -9,6 +9,7 @@ import org.embeddedt.modernfix.api.constants.IntegrationConstants;
import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
import org.embeddedt.modernfix.spark.SparkLaunchProfiler;
import org.embeddedt.modernfix.util.ClassInfoManager;
import org.embeddedt.modernfix.world.IntegratedWatchdog;
@ -90,6 +91,9 @@ public class ModernFixClient {
ModernFix.LOGGER.warn("Time from main menu to in-game was " + timeSpentLoading + " seconds");
ModernFix.LOGGER.warn("Total time to load game and open world was " + (timeSpentLoading + gameStartTimeSeconds) + " seconds");
}
if (ModernFixPlatformHooks.INSTANCE.modPresent("spark") && ModernFixMixinPlugin.instance.isOptionEnabled("feature.spark_profile_world_join.WorldJoin")) {
SparkLaunchProfiler.stop("world_join");
}
resetWorldLoadStateMachine();
}
}

View File

@ -0,0 +1,18 @@
package org.embeddedt.modernfix.common.mixin.feature.spark_profile_world_join;
import net.minecraft.client.Minecraft;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.spark.SparkLaunchProfiler;
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;
@Mixin(Minecraft.class)
@ClientOnlyMixin
public class MinecraftMixin {
@Inject(method = "prepareForMultiplayer", at = @At("HEAD"))
private void startProfiling(CallbackInfo ci) {
SparkLaunchProfiler.start("world_join");
}
}

View File

@ -0,0 +1,18 @@
package org.embeddedt.modernfix.common.mixin.feature.spark_profile_world_join;
import net.minecraft.server.WorldLoader;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.spark.SparkLaunchProfiler;
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;
@Mixin(WorldLoader.class)
@ClientOnlyMixin
public class WorldLoaderMixin {
@Inject(method = "load", at = @At("HEAD"))
private static void startProfiling(CallbackInfoReturnable<?> cir) {
SparkLaunchProfiler.start("world_join");
}
}

View File

@ -2,15 +2,22 @@ package org.embeddedt.modernfix.common.mixin.perf.memoize_creative_tab_build;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.CreativeModeTab;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@Mixin(CreativeModeTab.class)
public class CreativeModeTabMixin {
public abstract class CreativeModeTabMixin {
@Shadow public abstract CreativeModeTab.Type getType();
@Unique
private CreativeModeTab.ItemDisplayParameters mfix$oldParameters;
@Unique
private static boolean MFIX$REBUILT_NON_CATEGORY = false;
/**
* @author embeddedt
* @reason Vanilla already does similar memoization in the CreativeModeTabs class, but mods often have to bypass
@ -20,9 +27,26 @@ public class CreativeModeTabMixin {
*/
@WrapMethod(method = "buildContents")
private synchronized void buildContentsIfChanged(CreativeModeTab.ItemDisplayParameters parameters, Operation<Void> original) {
if (mfix$oldParameters == null || mfix$oldParameters.needsUpdate(parameters.enabledFeatures(), parameters.hasPermissions(), parameters.holders())) {
original.call(parameters);
synchronized (CreativeModeTab.class) {
if (mfix$oldParameters == null || mfix$oldParameters.needsUpdate(parameters.enabledFeatures(), parameters.hasPermissions(), parameters.holders())) {
original.call(parameters);
if (this.getType() == CreativeModeTab.Type.CATEGORY) {
if (MFIX$REBUILT_NON_CATEGORY) {
// We must mark every other tab that's not a category as needing rebuild. Not doing this causes mods
// that build a search tab early on without having built the dependencies to permanently leave it
// in a broken state.
for (CreativeModeTab tab : BuiltInRegistries.CREATIVE_MODE_TAB) {
if (tab.getType() != CreativeModeTab.Type.CATEGORY) {
((CreativeModeTabMixin)(Object)tab).mfix$oldParameters = null;
}
}
MFIX$REBUILT_NON_CATEGORY = false;
}
} else {
MFIX$REBUILT_NON_CATEGORY = true;
}
}
mfix$oldParameters = parameters;
}
mfix$oldParameters = parameters;
}
}

View File

@ -1,20 +0,0 @@
package org.embeddedt.modernfix.common.mixin.perf.nbt_memory_usage;
import net.minecraft.nbt.Tag;
import org.embeddedt.modernfix.util.CanonizingStringMap;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import java.util.Map;
@Mixin(targets = "net/minecraft/nbt/CompoundTag$1")
public class CompoundTag1Mixin {
@ModifyVariable(method = "loadCompound", at = @At(value = "INVOKE_ASSIGN", target = "Lcom/google/common/collect/Maps;newHashMap()Ljava/util/HashMap;", remap = false))
private static Map<String, Tag> modifyMap(Map<String, Tag> map) {
CanonizingStringMap<Tag> newMap = new CanonizingStringMap<>();
if(map != null)
newMap.putAll(map);
return newMap;
}
}

View File

@ -1,40 +0,0 @@
package org.embeddedt.modernfix.common.mixin.perf.nbt_memory_usage;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import org.embeddedt.modernfix.util.CanonizingStringMap;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Map;
@Mixin(CompoundTag.class)
public class CompoundTagMixin {
@Shadow @Final
private Map<String, Tag> tags;
/**
* Ensure that the default backing map is a CanonizingStringMap.
*/
@ModifyArg(method = "<init>()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/CompoundTag;<init>(Ljava/util/Map;)V"), index = 0)
private static Map<String, Tag> useCanonizingStringMap(Map<String, Tag> incoming) {
CanonizingStringMap<Tag> newMap = new CanonizingStringMap<>();
if(incoming != null)
newMap.putAll(incoming);
return newMap;
}
/**
* @author embeddedt
* @reason use more efficient method when copying canonizing string map
*/
@Inject(method = "copy()Lnet/minecraft/nbt/CompoundTag;", at = @At("HEAD"), cancellable = true)
public void copyEfficient(CallbackInfoReturnable<Tag> cir) {
if(this.tags instanceof CanonizingStringMap) {
cir.setReturnValue(new CompoundTag(CanonizingStringMap.deepCopy((CanonizingStringMap<Tag>)this.tags, Tag::copy)));
}
}
}

View File

@ -181,6 +181,7 @@ public class ModernFixEarlyConfig {
.put("mixin.feature.snapshot_easter_egg", true)
.put("mixin.feature.warn_missing_perf_mods", true)
.put("mixin.feature.spark_profile_launch", false)
.put("mixin.feature.spark_profile_world_join", false)
.put("mixin.feature.log_stdout_in_log_files", true)
.put("mixin.devenv", isDevEnv)
.putConditionally(() -> !isFabric, "mixin.bugfix.fix_config_crashes", true)
@ -237,6 +238,7 @@ public class ModernFixEarlyConfig {
disableIfModPresent("mixin.bugfix.buffer_builder_leak", "isometric-renders", "witherstormmod");
disableIfModPresent("mixin.feature.remove_chat_signing", "nochatreports");
disableIfModPresent("mixin.perf.faster_texture_loading", "stitch", "optifine", "changed");
disableIfModPresent("mixin.perf.faster_ingredients", "vmp");
if(isFabric) {
disableIfModPresent("mixin.bugfix.packet_leak", "memoryleakfix");
}

View File

@ -36,17 +36,19 @@ public class SparkLaunchProfiler {
private static ExecutorService executor = Executors.newSingleThreadScheduledExecutor((new ThreadFactoryBuilder()).setNameFormat("spark-modernfix-async-worker").build());
private static final SparkPlatform platform = new SparkPlatform(new ModernFixSparkPlugin());
private static final boolean USE_JAVA_SAMPLER_FOR_LAUNCH = true; //Boolean.getBoolean("modernfix.profileLaunchWithJavaSampler");
private static final boolean USE_JAVA_SAMPLER_FOR_LAUNCH = !Boolean.getBoolean("modernfix.profileWithAsyncSampler");
private static final int SAMPLING_INTERVAL = Integer.getInteger("modernfix.profileSamplingIntervalMicroseconds", 4000);
private static final String THREAD_GROUPER = System.getProperty("modernfix.profileSamplingThreadGrouper", "by-pool");
public static void start(String key) {
if (!ongoingSamplers.containsKey(key)) {
Sampler sampler;
SamplerSettings settings = new SamplerSettings(4000, ThreadDumper.ALL, ThreadGrouper.BY_NAME.get(), -1, false, true);
SamplerSettings settings = new SamplerSettings(SAMPLING_INTERVAL, ThreadDumper.ALL, ThreadGrouper.parseConfigSetting(THREAD_GROUPER).get(), -1, false, true);
try {
if(USE_JAVA_SAMPLER_FOR_LAUNCH) {
throw new UnsupportedOperationException();
}
sampler = new AsyncSampler(platform, settings, new SampleCollector.Execution(4000));
sampler = new AsyncSampler(platform, settings, new SampleCollector.Execution(SAMPLING_INTERVAL));
} catch (UnsupportedOperationException e) {
sampler = new JavaSampler(platform, settings);
}