|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Nassim Jahnke <nassim@njahnke.dev> |
| 3 | +Date: Fri, 17 Jul 2026 16:15:46 +0200 |
| 4 | +Subject: [PATCH] Pre-load data off-main during startup |
| 5 | + |
| 6 | + |
| 7 | +diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java |
| 8 | +index a4d608d64b7d3477c9144d93547fd3b4f39a1b02..e2939cc39a8c103e4c4d7b01d39b5546486e4fbc 100644 |
| 9 | +--- a/net/minecraft/server/Main.java |
| 10 | ++++ b/net/minecraft/server/Main.java |
| 11 | +@@ -102,7 +102,10 @@ public class Main { |
| 12 | + writePidFile(pidFilePath); |
| 13 | + } |
| 14 | + |
| 15 | +- CrashReport.preload(); |
| 16 | ++ // Paper start - Perf: Run CrashReport preload asynchronously |
| 17 | ++ // The actual result is discarded/irrelevant, but hardware and software info is memoized |
| 18 | ++ Thread.ofPlatform().daemon().name("CrashReport preload thread").start(CrashReport::preload); |
| 19 | ++ // Paper end - Perf: Run CrashReport preload asynchronously |
| 20 | + if (options.has("jfrProfile")) { // CraftBukkit |
| 21 | + JvmProfiler.INSTANCE.start(Environment.SERVER); |
| 22 | + } |
| 23 | +@@ -110,6 +113,12 @@ public class Main { |
| 24 | + io.papermc.paper.plugin.PluginInitializerManager.load(options); // Paper |
| 25 | + Bootstrap.bootStrap(); |
| 26 | + Bootstrap.validate(); |
| 27 | ++ // Paper start - Perf: Init DataConverter asynchronously |
| 28 | ++ // Init for both of these are fairly expensive class-loading wise. Both are called again below/in MinecraftServer.spin, |
| 29 | ++ // so failure during class init will become visible there. |
| 30 | ++ Thread.ofPlatform().daemon().name("DataConverter MCTypeRegistry init thread").start(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry::init); |
| 31 | ++ Thread.ofPlatform().daemon().name("DataFixers init thread").start(DataFixers::getDataFixer); |
| 32 | ++ // Paper end - Perf: Init DataConverter asynchronously |
| 33 | + Util.startTimerHackThread(); |
| 34 | + Path settingsFile = Paths.get("server.properties"); |
| 35 | + DedicatedServerSettings settings = new DedicatedServerSettings(options); // CraftBukkit - CLI argument support |
| 36 | +diff --git a/net/minecraft/world/level/block/Blocks.java b/net/minecraft/world/level/block/Blocks.java |
| 37 | +index 3ee7f5c578e4721fd95390d76105d6f8976747a1..f94f8049572c860652c97c10ecd888ef2c338262 100644 |
| 38 | +--- a/net/minecraft/world/level/block/Blocks.java |
| 39 | ++++ b/net/minecraft/world/level/block/Blocks.java |
| 40 | +@@ -5996,11 +5996,23 @@ public class Blocks { |
| 41 | + } |
| 42 | + |
| 43 | + static { |
| 44 | ++ // Paper start - Perf: Optimize block state cache initialization |
| 45 | ++ // initCache of the first state of every block runs directly (to make sure Blocks is always called here) before the rest are put off-thread |
| 46 | ++ final java.util.List<BlockState> statesToInit = new java.util.ArrayList<>(); |
| 47 | + for (Block block : BuiltInRegistries.BLOCK) { |
| 48 | ++ boolean first = true; |
| 49 | + for (BlockState state : block.getStateDefinition().getPossibleStates()) { |
| 50 | + Block.BLOCK_STATE_REGISTRY.add(state); |
| 51 | +- state.initCache(); |
| 52 | ++ if (first) { |
| 53 | ++ first = false; |
| 54 | ++ state.initCache(); |
| 55 | ++ } else { |
| 56 | ++ statesToInit.add(state); |
| 57 | ++ } |
| 58 | + } |
| 59 | + } |
| 60 | ++ // Make sure this stays as a method reference, else the synthetic lambda method makes this blow up |
| 61 | ++ statesToInit.parallelStream().forEach(BlockBehaviour.BlockStateBase::initCache); |
| 62 | ++ // Paper end - Perf: Optimize block state cache initialization |
| 63 | + } |
| 64 | + } |
0 commit comments