Skip to content

Commit 2a1871b

Browse files
committed
Use static ThreadLocal for light engine propagator
The propagator has been changed so that its world may be updated. This reduces extra memory by only requiring one propagator to be cached per thread, rather than one propagator per world per thread. This change also avoids the dodgy behavior of ThreadLocal retaining references to values long after they would be collectable. Fixes #13234
1 parent b5b7c79 commit 2a1871b

File tree

1 file changed

+87
-51
lines changed

1 file changed

+87
-51
lines changed

paper-server/patches/features/0001-Moonrise-optimisation-patches.patch

Lines changed: 87 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18182,7 +18182,7 @@ index 0000000000000000000000000000000000000000..ed80017c8f257b981d626a37ffc5480d
1818218182
+}
1818318183
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java b/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java
1818418184
new file mode 100644
18185-
index 0000000000000000000000000000000000000000..fa7b784a89626e8528c249d7889a598bd7ee3d49
18185+
index 0000000000000000000000000000000000000000..b623fb6974f5c4875a1ddc09053e72e6e67dda17
1818618186
--- /dev/null
1818718187
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/BlockStarLightEngine.java
1818818188
@@ -0,0 +1,280 @@
@@ -18208,8 +18208,8 @@ index 0000000000000000000000000000000000000000..fa7b784a89626e8528c249d7889a598b
1820818208
+
1820918209
+public final class BlockStarLightEngine extends StarLightEngine {
1821018210
+
18211-
+ public BlockStarLightEngine(final Level world) {
18212-
+ super(false, world);
18211+
+ public BlockStarLightEngine() {
18212+
+ super(false);
1821318213
+ }
1821418214
+
1821518215
+ @Override
@@ -18915,10 +18915,10 @@ index 0000000000000000000000000000000000000000..5c7b3804cdbcb0a873a0d195325c2658
1891518915
+}
1891618916
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java b/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java
1891718917
new file mode 100644
18918-
index 0000000000000000000000000000000000000000..f9aef289e9a2d6f63c98c72c56ef32b8793f57f4
18918+
index 0000000000000000000000000000000000000000..cdb679fb6e3d342efc776329124209d1f433cc8f
1891918919
--- /dev/null
1892018920
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/SkyStarLightEngine.java
18921-
@@ -0,0 +1,681 @@
18921+
@@ -0,0 +1,689 @@
1892218922
+package ca.spottedleaf.moonrise.patches.starlight.light;
1892318923
+
1892418924
+import ca.spottedleaf.moonrise.common.util.WorldUtil;
@@ -18971,11 +18971,21 @@ index 0000000000000000000000000000000000000000..f9aef289e9a2d6f63c98c72c56ef32b8
1897118971
+ Arrays.fill(this.heightMapBlockChange, Integer.MIN_VALUE); // clear heightmap
1897218972
+ }
1897318973
+
18974-
+ protected final boolean[] nullPropagationCheckCache;
18974+
+ protected boolean[] nullPropagationCheckCache;
1897518975
+
18976-
+ public SkyStarLightEngine(final Level world) {
18977-
+ super(true, world);
18978-
+ this.nullPropagationCheckCache = new boolean[WorldUtil.getTotalLightSections(world)];
18976+
+ public SkyStarLightEngine() {
18977+
+ super(true);
18978+
+ }
18979+
+
18980+
+ @Override
18981+
+ public void setWorld(final Level world) {
18982+
+ super.setWorld(world);
18983+
+ if (world != null) {
18984+
+ final int minArraySize = WorldUtil.getTotalLightSections(world);
18985+
+ if (this.nullPropagationCheckCache == null || this.nullPropagationCheckCache.length < minArraySize) {
18986+
+ this.nullPropagationCheckCache = new boolean[minArraySize];
18987+
+ }
18988+
+ }
1897918989
+ }
1898018990
+
1898118991
+ @Override
@@ -19361,8 +19371,6 @@ index 0000000000000000000000000000000000000000..f9aef289e9a2d6f63c98c72c56ef32b8
1936119371
+ this.performLightDecrease(lightAccess);
1936219372
+ }
1936319373
+
19364-
+ protected final int[] heightMapGen = new int[32 * 32];
19365-
+
1936619374
+ @Override
1936719375
+ protected void lightChunk(final LightChunkGetter lightAccess, final ChunkAccess chunk, final boolean needsEdgeChecks) {
1936819376
+ this.rewriteNibbleCacheForSkylight(chunk);
@@ -19602,10 +19610,10 @@ index 0000000000000000000000000000000000000000..f9aef289e9a2d6f63c98c72c56ef32b8
1960219610
+}
1960319611
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java b/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java
1960419612
new file mode 100644
19605-
index 0000000000000000000000000000000000000000..7ba2b8d58a78662fda7f2b8f4c8c87b8e8ecb275
19613+
index 0000000000000000000000000000000000000000..c6222bfb75706052df41d821f2fcfc4620ce3672
1960619614
--- /dev/null
1960719615
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/StarLightEngine.java
19608-
@@ -0,0 +1,1438 @@
19616+
@@ -0,0 +1,1450 @@
1960919617
+package ca.spottedleaf.moonrise.patches.starlight.light;
1961019618
+
1961119619
+import ca.spottedleaf.concurrentutil.util.IntegerUtil;
@@ -19696,17 +19704,17 @@ index 0000000000000000000000000000000000000000..7ba2b8d58a78662fda7f2b8f4c8c87b8
1969619704
+ // for the y chunk section it's from [minLightSection, maxLightSection] or [0, maxLightSection - minLightSection]
1969719705
+ // index = x + (z * 5) + (y * 25)
1969819706
+ // null index indicates the chunk section doesn't exist (empty or out of bounds)
19699-
+ protected final LevelChunkSection[] sectionCache;
19707+
+ protected LevelChunkSection[] sectionCache;
1970019708
+
1970119709
+ // the exact same as above, except for storing fast access to SWMRNibbleArray
1970219710
+ // for the y chunk section it's from [minLightSection, maxLightSection] or [0, maxLightSection - minLightSection]
1970319711
+ // index = x + (z * 5) + (y * 25)
19704-
+ protected final SWMRNibbleArray[] nibbleCache;
19712+
+ protected SWMRNibbleArray[] nibbleCache;
1970519713
+
1970619714
+ // the exact same as above, except for storing fast access to nibbles to call change callbacks for
1970719715
+ // for the y chunk section it's from [minLightSection, maxLightSection] or [0, maxLightSection - minLightSection]
1970819716
+ // index = x + (z * 5) + (y * 25)
19709-
+ protected final boolean[] notifyUpdateCache;
19717+
+ protected boolean[] notifyUpdateCache;
1971019718
+
1971119719
+ // always initialsed during start of lighting.
1971219720
+ // index = x + (z * 5)
@@ -19732,27 +19740,39 @@ index 0000000000000000000000000000000000000000..7ba2b8d58a78662fda7f2b8f4c8c87b8
1973219740
+
1973319741
+ protected final boolean skylightPropagator;
1973419742
+ protected final int emittedLightMask;
19735-
+ protected final boolean isClientSide;
19743+
+ protected boolean isClientSide;
1973619744
+
19737-
+ protected final Level world;
19738-
+ protected final int minLightSection;
19739-
+ protected final int maxLightSection;
19740-
+ protected final int minSection;
19741-
+ protected final int maxSection;
19745+
+ protected Level world;
19746+
+ protected int minLightSection;
19747+
+ protected int maxLightSection;
19748+
+ protected int minSection;
19749+
+ protected int maxSection;
1974219750
+
19743-
+ protected StarLightEngine(final boolean skylightPropagator, final Level world) {
19751+
+ protected StarLightEngine(final boolean skylightPropagator) {
1974419752
+ this.skylightPropagator = skylightPropagator;
1974519753
+ this.emittedLightMask = skylightPropagator ? 0 : 0xF;
19746-
+ this.isClientSide = world.isClientSide();
19754+
+ }
19755+
+
19756+
+ public void setWorld(final Level world) {
1974719757
+ this.world = world;
19748-
+ this.minLightSection = WorldUtil.getMinLightSection(world);
19749-
+ this.maxLightSection = WorldUtil.getMaxLightSection(world);
19750-
+ this.minSection = WorldUtil.getMinSection(world);
19751-
+ this.maxSection = WorldUtil.getMaxSection(world);
19758+
+ if (world != null) {
19759+
+ this.isClientSide = world.isClientSide();
19760+
+ this.minLightSection = WorldUtil.getMinLightSection(world);
19761+
+ this.maxLightSection = WorldUtil.getMaxLightSection(world);
19762+
+ this.minSection = WorldUtil.getMinSection(world);
19763+
+ this.maxSection = WorldUtil.getMaxSection(world);
19764+
+ final int minArraySize = 5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2); // add two extra sections for buffer
1975219765
+
19753-
+ this.sectionCache = new LevelChunkSection[5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2)]; // add two extra sections for buffer
19754-
+ this.nibbleCache = new SWMRNibbleArray[5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2)]; // add two extra sections for buffer
19755-
+ this.notifyUpdateCache = new boolean[5 * 5 * ((this.maxLightSection - this.minLightSection + 1) + 2)]; // add two extra sections for buffer
19766+
+ if (this.sectionCache == null || this.sectionCache.length < minArraySize) {
19767+
+ this.sectionCache = new LevelChunkSection[minArraySize];
19768+
+ }
19769+
+ if (this.nibbleCache == null || this.nibbleCache.length < minArraySize) {
19770+
+ this.nibbleCache = new SWMRNibbleArray[minArraySize];
19771+
+ }
19772+
+ if (this.notifyUpdateCache == null || this.notifyUpdateCache.length < minArraySize) {
19773+
+ this.notifyUpdateCache = new boolean[minArraySize];
19774+
+ }
19775+
+ }
1975619776
+ }
1975719777
+
1975819778
+ protected final void setupEncodeOffset(final int centerX, final int centerY, final int centerZ) {
@@ -21046,10 +21066,10 @@ index 0000000000000000000000000000000000000000..7ba2b8d58a78662fda7f2b8f4c8c87b8
2104621066
+}
2104721067
diff --git a/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java b/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
2104821068
new file mode 100644
21049-
index 0000000000000000000000000000000000000000..649042cd0a83aaf6866b09b21dfc54b337320111
21069+
index 0000000000000000000000000000000000000000..7faf226b753a03e03b0dec9bbfcc94a6c3f5bc0f
2105021070
--- /dev/null
2105121071
+++ b/ca/spottedleaf/moonrise/patches/starlight/light/StarLightInterface.java
21052-
@@ -0,0 +1,920 @@
21072+
@@ -0,0 +1,936 @@
2105321073
+package ca.spottedleaf.moonrise.patches.starlight.light;
2105421074
+
2105521075
+import ca.spottedleaf.concurrentutil.collection.MultiThreadedQueue;
@@ -21099,8 +21119,8 @@ index 0000000000000000000000000000000000000000..649042cd0a83aaf6866b09b21dfc54b3
2109921119
+ public final Level world;
2110021120
+ public final LightChunkGetter lightAccess;
2110121121
+
21102-
+ private final ThreadLocal<SkyStarLightEngine> cachedSkyPropagator;
21103-
+ private final ThreadLocal<BlockStarLightEngine> cachedBlockPropagator;
21122+
+ private static final ThreadLocal<SkyStarLightEngine> SKY_PROPAGATOR = new ThreadLocal<>();
21123+
+ private static final ThreadLocal<BlockStarLightEngine> BLOCK_PROPAGATOR = new ThreadLocal<>();
2110421124
+
2110521125
+ private final LightQueue lightQueue;
2110621126
+
@@ -21121,8 +21141,6 @@ index 0000000000000000000000000000000000000000..649042cd0a83aaf6866b09b21dfc54b3
2112121141
+ public StarLightInterface(final LightChunkGetter lightAccess, final boolean hasSkyLight, final boolean hasBlockLight, final LevelLightEngine lightEngine) {
2112221142
+ this.lightAccess = lightAccess;
2112321143
+ this.world = lightAccess == null ? null : (Level)lightAccess.getLevel();
21124-
+ this.cachedSkyPropagator = hasSkyLight && lightAccess != null ? new ThreadLocal<>() : null;
21125-
+ this.cachedBlockPropagator = hasBlockLight && lightAccess != null ? new ThreadLocal<>() : null;
2112621144
+ this.isClientSide = !(this.world instanceof ServerLevel);
2112721145
+ if (this.world == null) {
2112821146
+ this.minSection = -4;
@@ -21411,43 +21429,61 @@ index 0000000000000000000000000000000000000000..649042cd0a83aaf6866b09b21dfc54b3
2141121429
+ }
2141221430
+
2141321431
+ public SkyStarLightEngine getSkyLightEngine() {
21414-
+ if (this.cachedSkyPropagator == null) {
21432+
+ if (!this.hasSkyLight || this.world == null) {
2141521433
+ return null;
2141621434
+ }
21417-
+ final SkyStarLightEngine ret = this.cachedSkyPropagator.get();
21418-
+ this.cachedSkyPropagator.set(null);
21435+
+
21436+
+ SkyStarLightEngine ret = SKY_PROPAGATOR.get();
21437+
+ SKY_PROPAGATOR.set(null);
2141921438
+
2142021439
+ if (ret == null) {
21421-
+ return new SkyStarLightEngine(this.world);
21440+
+ ret = new SkyStarLightEngine();
2142221441
+ }
21442+
+
21443+
+ ret.setWorld(this.world);
21444+
+
2142321445
+ return ret;
2142421446
+ }
2142521447
+
2142621448
+ public void releaseSkyLightEngine(final SkyStarLightEngine engine) {
21427-
+ if (this.cachedSkyPropagator == null || this.cachedSkyPropagator.get() != null) {
21449+
+ if (engine != null) {
21450+
+ engine.setWorld(null);
21451+
+ }
21452+
+
21453+
+ if (!this.hasSkyLight || this.world == null || SKY_PROPAGATOR.get() != null) {
2142821454
+ return;
2142921455
+ }
21430-
+ this.cachedSkyPropagator.set(engine);
21456+
+
21457+
+ SKY_PROPAGATOR.set(engine);
2143121458
+ }
2143221459
+
2143321460
+ public BlockStarLightEngine getBlockLightEngine() {
21434-
+ if (this.cachedBlockPropagator == null) {
21461+
+ if (!this.hasBlockLight || this.world == null) {
2143521462
+ return null;
2143621463
+ }
21437-
+ final BlockStarLightEngine ret = this.cachedBlockPropagator.get();
21438-
+ this.cachedBlockPropagator.set(null);
21464+
+
21465+
+ BlockStarLightEngine ret = BLOCK_PROPAGATOR.get();
21466+
+ BLOCK_PROPAGATOR.set(null);
2143921467
+
2144021468
+ if (ret == null) {
21441-
+ return new BlockStarLightEngine(this.world);
21469+
+ ret = new BlockStarLightEngine();
2144221470
+ }
21471+
+
21472+
+ ret.setWorld(this.world);
21473+
+
2144321474
+ return ret;
2144421475
+ }
2144521476
+
2144621477
+ public void releaseBlockLightEngine(final BlockStarLightEngine engine) {
21447-
+ if (this.cachedBlockPropagator == null || this.cachedBlockPropagator.get() != null) {
21478+
+ if (engine != null) {
21479+
+ engine.setWorld(null);
21480+
+ }
21481+
+
21482+
+ if (!this.hasBlockLight || this.world == null || BLOCK_PROPAGATOR.get() != null) {
2144821483
+ return;
2144921484
+ }
21450-
+ this.cachedBlockPropagator.set(engine);
21485+
+
21486+
+ BLOCK_PROPAGATOR.set(engine);
2145121487
+ }
2145221488
+
2145321489
+ public LightQueue.ChunkTasks blockChange(final BlockPos pos) {
@@ -21934,7 +21970,7 @@ index 0000000000000000000000000000000000000000..649042cd0a83aaf6866b09b21dfc54b3
2193421970
+ }
2193521971
+
2193621972
+ public boolean markTicketAdded() {
21937-
+ return !this.ticketAdded.get() && !this.ticketAdded.getAndSet(true);
21973+
+ return !this.ticketAdded.get() && false == this.ticketAdded.compareAndExchange(false, true);
2193821974
+ }
2193921975
+
2194021976
+ public void schedule() {
@@ -27000,7 +27036,7 @@ index 704733ff5e558a12f2f9dde924ab4c507745595d..5e305c9a64e856de70ed787901c01d09
2700027036
}
2700127037

2700227038
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
27003-
index a5bc4e8a3dde40c416c05e91dfec25bc7efdd013..66c25f323b9a19e25fcaea782dc72f477fd32629 100644
27039+
index 53623b518266edc1436dbba3d965386dc31e6e6c..ecc39329af8722c3c3341d67bee1d22d7ccc7a4d 100644
2700427040
--- a/net/minecraft/server/level/ServerPlayer.java
2700527041
+++ b/net/minecraft/server/level/ServerPlayer.java
2700627042
@@ -201,7 +201,7 @@ import net.minecraft.world.scores.Team;

0 commit comments

Comments
 (0)