Skip to content

Commit b6182b4

Browse files
committed
Merge remote-tracking branch 'origin/1.18' into 1.19.2
2 parents c93380d + ce92fed commit b6182b4

File tree

13 files changed

+258
-0
lines changed

13 files changed

+258
-0
lines changed

common/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ dependencies {
2727
transitive = false
2828
}
2929
modCompileOnly("curse.maven:diagonal-fences-458048:${diagonal_fences_version}")
30+
modCompileOnly "curse.maven:spark-361579:${rootProject.spark_version}"
3031
// compile against the JEI API but do not include it at runtime
3132
modCompileOnly("mezz.jei:jei-${minecraft_version}-common:${jei_version}")
3233
modCompileOnly("mezz.jei:jei-${minecraft_version}-gui:${jei_version}")

common/src/main/java/org/embeddedt/modernfix/ModernFix.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public void onServerStarted() {
7171
if(ModernFixPlatformHooks.isDedicatedServer()) {
7272
float gameStartTime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f;
7373
ModernFix.LOGGER.warn("Dedicated server took " + gameStartTime + " seconds to load");
74+
ModernFixPlatformHooks.onLaunchComplete();
7475
}
7576
ClassInfoManager.clear();
7677
}

common/src/main/java/org/embeddedt/modernfix/ModernFixClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public void onScreenOpening(Screen openingScreen) {
7171
} else if (openingScreen instanceof TitleScreen && gameStartTimeSeconds < 0) {
7272
gameStartTimeSeconds = ManagementFactory.getRuntimeMXBean().getUptime() / 1000f;
7373
ModernFix.LOGGER.warn("Game took " + gameStartTimeSeconds + " seconds to start");
74+
ModernFixPlatformHooks.onLaunchComplete();
7475
}
7576
}
7677

common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ else if(isClientOnly && !ModernFixPlatformHooks.isClient())
149149
.put("mixin.perf.faster_item_rendering", false)
150150
.put("mixin.feature.spam_thread_dump", false)
151151
.put("mixin.feature.snapshot_easter_egg", true)
152+
.put("mixin.feature.spark_profile_launch", false)
152153
.put("mixin.devenv", isDevEnv)
153154
.put("mixin.perf.remove_spawn_chunks", isDevEnv)
154155
.build();

common/src/main/java/org/embeddedt/modernfix/platform/ModernFixPlatformHooks.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,14 @@ public static void onServerCommandRegister(Consumer<CommandDispatcher<CommandSou
9292
public static Multimap<String, String> getCustomModOptions() {
9393
throw new AssertionError();
9494
}
95+
96+
@ExpectPlatform
97+
public static void onLaunchComplete() {
98+
99+
}
100+
101+
@ExpectPlatform
102+
public static String getPlatformName() {
103+
throw new AssertionError();
104+
}
95105
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package org.embeddedt.modernfix.spark;
2+
3+
import com.google.common.util.concurrent.ThreadFactoryBuilder;
4+
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
5+
import me.lucko.spark.common.SparkPlatform;
6+
import me.lucko.spark.common.SparkPlugin;
7+
import me.lucko.spark.common.command.sender.CommandSender;
8+
import me.lucko.spark.common.platform.PlatformInfo;
9+
import me.lucko.spark.common.sampler.Sampler;
10+
import me.lucko.spark.common.sampler.SamplerSettings;
11+
import me.lucko.spark.common.sampler.ThreadDumper;
12+
import me.lucko.spark.common.sampler.ThreadGrouper;
13+
import me.lucko.spark.common.sampler.async.AsyncSampler;
14+
import me.lucko.spark.common.sampler.async.SampleCollector;
15+
import me.lucko.spark.common.sampler.java.JavaSampler;
16+
import me.lucko.spark.common.sampler.node.MergeMode;
17+
import me.lucko.spark.common.util.MethodDisambiguator;
18+
import me.lucko.spark.lib.adventure.text.Component;
19+
import me.lucko.spark.proto.SparkSamplerProtos;
20+
import net.minecraft.SharedConstants;
21+
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
22+
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
23+
24+
import java.nio.file.Path;
25+
import java.util.Map;
26+
import java.util.UUID;
27+
import java.util.concurrent.ExecutorService;
28+
import java.util.concurrent.Executors;
29+
import java.util.logging.Level;
30+
import java.util.stream.Stream;
31+
32+
/* Inspired by CensoredASM */
33+
public class SparkLaunchProfiler {
34+
private static PlatformInfo platformInfo = new ModernFixPlatformInfo();
35+
private static CommandSender commandSender = new ModernFixCommandSender();
36+
private static Map<String, Sampler> ongoingSamplers = new Object2ReferenceOpenHashMap<>();
37+
private static ExecutorService executor = Executors.newSingleThreadScheduledExecutor((new ThreadFactoryBuilder()).setNameFormat("spark-modernfix-async-worker").build());
38+
private static final SparkPlatform platform = new SparkPlatform(new ModernFixSparkPlugin());
39+
40+
private static final boolean USE_JAVA_SAMPLER_FOR_LAUNCH = true; //Boolean.getBoolean("modernfix.profileLaunchWithJavaSampler");
41+
42+
public static void start(String key) {
43+
if (!ongoingSamplers.containsKey(key)) {
44+
Sampler sampler;
45+
SamplerSettings settings = new SamplerSettings(4000, ThreadDumper.ALL, ThreadGrouper.BY_NAME, -1, false);
46+
try {
47+
if(USE_JAVA_SAMPLER_FOR_LAUNCH) {
48+
throw new UnsupportedOperationException();
49+
}
50+
sampler = new AsyncSampler(platform, settings, new SampleCollector.Execution(4000));
51+
} catch (UnsupportedOperationException e) {
52+
sampler = new JavaSampler(platform, settings, true, true);
53+
}
54+
ongoingSamplers.put(key, sampler);
55+
ModernFixMixinPlugin.instance.logger.warn("Profiler has started for stage [{}]...", key);
56+
sampler.start();
57+
}
58+
}
59+
60+
public static void stop(String key) {
61+
Sampler sampler = ongoingSamplers.remove(key);
62+
if (sampler != null) {
63+
sampler.stop(true);
64+
output(key, sampler);
65+
}
66+
}
67+
68+
private static void output(String key, Sampler sampler) {
69+
executor.execute(() -> {
70+
ModernFixMixinPlugin.instance.logger.warn("Stage [{}] profiler has stopped! Uploading results...", key);
71+
SparkSamplerProtos.SamplerData output = sampler.toProto(platform, new Sampler.ExportProps()
72+
.creator(new CommandSender.Data(commandSender.getName(), commandSender.getUniqueId()))
73+
.comment("Stage: " + key)
74+
.mergeMode(() -> MergeMode.separateParentCalls(new MethodDisambiguator()))
75+
.classSourceLookup(platform::createClassSourceLookup));
76+
try {
77+
String urlKey = platform.getBytebinClient().postContent(output, "application/x-spark-sampler").key();
78+
String url = "https://spark.lucko.me/" + urlKey;
79+
ModernFixMixinPlugin.instance.logger.warn("Profiler results for Stage [{}]: {}", key, url);
80+
} catch (Exception e) {
81+
ModernFixMixinPlugin.instance.logger.fatal("An error occurred whilst uploading the results.", e);
82+
}
83+
});
84+
}
85+
86+
static class ModernFixPlatformInfo implements PlatformInfo {
87+
88+
@Override
89+
public Type getType() {
90+
return ModernFixPlatformHooks.isClient() ? Type.CLIENT : Type.SERVER;
91+
}
92+
93+
@Override
94+
public String getName() {
95+
return ModernFixPlatformHooks.getPlatformName();
96+
}
97+
98+
@Override
99+
public String getVersion() {
100+
return ModernFixPlatformHooks.getVersionString();
101+
}
102+
103+
@Override
104+
public String getMinecraftVersion() {
105+
return SharedConstants.getCurrentVersion().getName();
106+
}
107+
108+
}
109+
110+
public static class ModernFixCommandSender implements CommandSender {
111+
112+
private final UUID uuid = UUID.randomUUID();
113+
private final String name;
114+
115+
public ModernFixCommandSender() {
116+
this.name = "ModernFix";
117+
}
118+
119+
@Override
120+
public String getName() {
121+
return name;
122+
}
123+
124+
@Override
125+
public UUID getUniqueId() {
126+
return uuid;
127+
}
128+
129+
@Override
130+
public boolean hasPermission(String s) {
131+
return true;
132+
}
133+
134+
@Override
135+
public void sendMessage(Component component) {
136+
137+
}
138+
}
139+
140+
static class ModernFixSparkPlugin implements SparkPlugin {
141+
142+
@Override
143+
public String getVersion() {
144+
return "1.0";
145+
}
146+
147+
@Override
148+
public Path getPluginDirectory() {
149+
return ModernFixPlatformHooks.getGameDirectory().resolve("spark-modernfix");
150+
}
151+
152+
@Override
153+
public String getCommandName() {
154+
return "spark-modernfix";
155+
}
156+
157+
@Override
158+
public Stream<? extends CommandSender> getCommandSenders() {
159+
return Stream.of();
160+
}
161+
162+
@Override
163+
public void executeAsync(Runnable runnable) {
164+
executor.execute(runnable);
165+
}
166+
167+
@Override
168+
public void log(Level level, String s) {
169+
ModernFixMixinPlugin.instance.logger.warn(s);
170+
}
171+
172+
@Override
173+
public PlatformInfo getPlatformInfo() {
174+
return platformInfo;
175+
}
176+
}
177+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.embeddedt.modernfix.util;
2+
3+
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
4+
5+
public class CommonModUtil {
6+
/**
7+
* Avoid using this, it's bad practice but cleanest way of suppressing errors for nonessential mod-dependent
8+
* functionality.
9+
*/
10+
public static void runWithoutCrash(Runnable r, String errorMsg) {
11+
try {
12+
r.run();
13+
} catch(Throwable e) {
14+
ModernFixMixinPlugin.instance.logger.error(errorMsg, e);
15+
}
16+
}
17+
}

fabric/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ dependencies {
3434
modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
3535
modImplementation(fabricApi.module("fabric-data-generation-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
3636
modCompileOnly("com.terraformersmc:modmenu:${rootProject.modmenu_version}") { transitive false }
37+
modImplementation "curse.maven:spark-361579:${rootProject.spark_version}"
3738
modRuntimeOnly("net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}") { exclude group: 'net.fabricmc', module: 'fabric-loader' }
3839
// Remove the next line if you don't want to depend on the API
3940
// modApi "me.shedaniel:architectury-fabric:${rootProject.architectury_version}"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.embeddedt.modernfix;
2+
3+
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
4+
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
5+
import org.embeddedt.modernfix.spark.SparkLaunchProfiler;
6+
import org.embeddedt.modernfix.util.CommonModUtil;
7+
8+
public class ModernFixPreLaunchFabric implements PreLaunchEntrypoint {
9+
@Override
10+
public void onPreLaunch() {
11+
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spark_profile_launch.OnFabric")) {
12+
CommonModUtil.runWithoutCrash(() -> SparkLaunchProfiler.start("launch"), "Failed to start profiler");
13+
}
14+
}
15+
}

fabric/src/main/java/org/embeddedt/modernfix/platform/fabric/ModernFixPlatformHooksImpl.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import net.minecraft.server.packs.resources.ResourceManager;
2020
import org.embeddedt.modernfix.ModernFixFabric;
2121
import org.embeddedt.modernfix.api.constants.IntegrationConstants;
22+
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
23+
import org.embeddedt.modernfix.spark.SparkLaunchProfiler;
24+
import org.embeddedt.modernfix.util.CommonModUtil;
2225
import org.objectweb.asm.tree.*;
2326

2427
import java.nio.file.Path;
@@ -109,4 +112,14 @@ public static Multimap<String, String> getCustomModOptions() {
109112
}
110113
return modOptions;
111114
}
115+
116+
public static void onLaunchComplete() {
117+
if(ModernFixMixinPlugin.instance.isOptionEnabled("feature.spark_profile_launch.OnFabric")) {
118+
CommonModUtil.runWithoutCrash(() -> SparkLaunchProfiler.stop("launch"), "Failed to stop profiler");
119+
}
120+
}
121+
122+
public static String getPlatformName() {
123+
return "Fabric";
124+
}
112125
}

0 commit comments

Comments
 (0)