aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/removed/1.18/No longer needed/0463-Optimize-NibbleArray-to-use-pooled-buffers.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/removed/1.18/No longer needed/0463-Optimize-NibbleArray-to-use-pooled-buffers.patch')
-rw-r--r--patches/removed/1.18/No longer needed/0463-Optimize-NibbleArray-to-use-pooled-buffers.patch378
1 files changed, 0 insertions, 378 deletions
diff --git a/patches/removed/1.18/No longer needed/0463-Optimize-NibbleArray-to-use-pooled-buffers.patch b/patches/removed/1.18/No longer needed/0463-Optimize-NibbleArray-to-use-pooled-buffers.patch
deleted file mode 100644
index bff1c4bc34..0000000000
--- a/patches/removed/1.18/No longer needed/0463-Optimize-NibbleArray-to-use-pooled-buffers.patch
+++ /dev/null
@@ -1,378 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Aikar <[email protected]>
-Date: Wed, 6 May 2020 23:30:30 -0400
-Subject: [PATCH] Optimize NibbleArray to use pooled buffers
-
-Massively reduces memory allocation of 2048 byte buffers by using
-an object pool for these.
-
-Uses lots of advanced new capabilities of the Paper codebase :)
-
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java
-index 7825d6f0fdcfda6212cff8033ec55fb7db236154..2218ddb8d075d042bb7c41886aa9dd2082a5a40f 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLevelChunkWithLightPacket.java
-@@ -2,8 +2,11 @@ package net.minecraft.network.protocol.game;
-
- import java.util.BitSet;
- import javax.annotation.Nullable;
-+
-+import io.netty.channel.ChannelFuture;
- import net.minecraft.network.FriendlyByteBuf;
- import net.minecraft.network.protocol.Packet;
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.world.level.ChunkPos;
- import net.minecraft.world.level.chunk.LevelChunk;
- import net.minecraft.world.level.lighting.LevelLightEngine;
-@@ -14,6 +17,23 @@ public class ClientboundLevelChunkWithLightPacket implements Packet<ClientGamePa
- private final ClientboundLevelChunkPacketData chunkData;
- private final ClientboundLightUpdatePacketData lightData;
-
-+ // Paper start
-+ @Override
-+ public void onPacketDispatch(ServerPlayer player) {
-+ lightData.onPacketDispatch(player);
-+ }
-+
-+ @Override
-+ public void onPacketDispatchFinish(ServerPlayer player, ChannelFuture future) {
-+ lightData.onPacketDispatchFinish(player, future);
-+ }
-+
-+ @Override
-+ public boolean hasFinishListener() {
-+ return true;
-+ }
-+ // Paper end
-+
- public ClientboundLevelChunkWithLightPacket(LevelChunk chunk, LevelLightEngine lightProvider, @Nullable BitSet skyBits, @Nullable BitSet blockBits, boolean nonEdge) {
- ChunkPos chunkPos = chunk.getPos();
- this.x = chunkPos.x;
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacket.java
-index 15350c301ba670cd86c83c7051c3571ff2759d8f..da46695e4d45f701a216767a048b21e289f056f6 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacket.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacket.java
-@@ -2,8 +2,11 @@ package net.minecraft.network.protocol.game;
-
- import java.util.BitSet;
- import javax.annotation.Nullable;
-+
-+import io.netty.channel.ChannelFuture;
- import net.minecraft.network.FriendlyByteBuf;
- import net.minecraft.network.protocol.Packet;
-+import net.minecraft.server.level.ServerPlayer;
- import net.minecraft.world.level.ChunkPos;
- import net.minecraft.world.level.lighting.LevelLightEngine;
-
-@@ -12,6 +15,23 @@ public class ClientboundLightUpdatePacket implements Packet<ClientGamePacketList
- private final int z;
- private final ClientboundLightUpdatePacketData lightData;
-
-+ // Paper start
-+ @Override
-+ public void onPacketDispatch(ServerPlayer player) {
-+ lightData.onPacketDispatch(player);
-+ }
-+
-+ @Override
-+ public void onPacketDispatchFinish(ServerPlayer player, ChannelFuture future) {
-+ lightData.onPacketDispatchFinish(player, future);
-+ }
-+
-+ @Override
-+ public boolean hasFinishListener() {
-+ return true;
-+ }
-+ // Paper end
-+
- public ClientboundLightUpdatePacket(ChunkPos chunkPos, LevelLightEngine lightProvider, @Nullable BitSet skyBits, @Nullable BitSet blockBits, boolean nonEdge) {
- this.x = chunkPos.x;
- this.z = chunkPos.z;
-diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java
-index fe9cfb2c6e3ecbe8966bc33a16785f03f870e7cf..e887317e8fcf71740ec96d85b7ea5b819a39d468 100644
---- a/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java
-+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java
-@@ -19,6 +19,27 @@ public class ClientboundLightUpdatePacketData {
- private final List<byte[]> skyUpdates;
- private final List<byte[]> blockUpdates;
- private final boolean trustEdges;
-+ // Paper start
-+ java.lang.Runnable cleaner1;
-+ java.lang.Runnable cleaner2;
-+ java.util.concurrent.atomic.AtomicInteger remainingSends = new java.util.concurrent.atomic.AtomicInteger(0);
-+
-+ public void onPacketDispatch(net.minecraft.server.level.ServerPlayer player) {
-+ remainingSends.incrementAndGet();
-+ }
-+
-+ public void onPacketDispatchFinish(net.minecraft.server.level.ServerPlayer player, io.netty.channel.ChannelFuture future) {
-+ if (remainingSends.decrementAndGet() <= 0) {
-+ // incase of any race conditions, schedule this delayed
-+ net.minecraft.server.MCUtil.scheduleTask(5, () -> {
-+ if (remainingSends.get() == 0) {
-+ cleaner1.run();
-+ cleaner2.run();
-+ }
-+ }, "Light Packet Release");
-+ }
-+ }
-+ // Paper end
-
- public ClientboundLightUpdatePacketData(ChunkPos pos, LevelLightEngine lightProvider, @Nullable BitSet skyBits, @Nullable BitSet blockBits, boolean nonEdge) {
- this.trustEdges = nonEdge;
-@@ -26,8 +47,8 @@ public class ClientboundLightUpdatePacketData {
- this.blockYMask = new BitSet();
- this.emptySkyYMask = new BitSet();
- this.emptyBlockYMask = new BitSet();
-- this.skyUpdates = Lists.newArrayList();
-- this.blockUpdates = Lists.newArrayList();
-+ this.skyUpdates = Lists.newArrayList();this.cleaner1 = net.minecraft.server.MCUtil.registerListCleaner(this, this.skyUpdates, DataLayer::releaseBytes); // Paper
-+ this.blockUpdates = Lists.newArrayList();this.cleaner2 = net.minecraft.server.MCUtil.registerListCleaner(this, this.blockUpdates, DataLayer::releaseBytes); // Paper
-
- for(int i = 0; i < lightProvider.getLightSectionCount(); ++i) {
- if (skyBits == null || skyBits.get(i)) {
-@@ -72,7 +93,7 @@ public class ClientboundLightUpdatePacketData {
- uninitialized.set(y);
- } else {
- initialized.set(y);
-- nibbles.add((byte[])dataLayer.getData().clone());
-+ nibbles.add((byte[])dataLayer.getCloneIfSet()); // Paper
- }
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/chunk/DataLayer.java b/src/main/java/net/minecraft/world/level/chunk/DataLayer.java
-index 81701abd11fbc4671393a76a42973f53835ca234..e8cf0088e94925934acd02ba05b9411bd7cf186e 100644
---- a/src/main/java/net/minecraft/world/level/chunk/DataLayer.java
-+++ b/src/main/java/net/minecraft/world/level/chunk/DataLayer.java
-@@ -13,11 +13,65 @@ public final class DataLayer {
- private static final int NIBBLE_SIZE = 4;
- @Nullable
- protected byte[] data;
-+ // Paper start
-+ public static byte[] EMPTY_NIBBLE = new byte[2048];
-+ private static final int nibbleBucketSizeMultiplier = Integer.getInteger("Paper.nibbleBucketSize", 3072);
-+ private static final int maxPoolSize = Integer.getInteger("Paper.maxNibblePoolSize", (int) Math.min(6, Math.max(1, Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024)) * (nibbleBucketSizeMultiplier * 8));
-+ public static final com.destroystokyo.paper.util.pooled.PooledObjects<byte[]> BYTE_2048 = new com.destroystokyo.paper.util.pooled.PooledObjects<>(() -> new byte[2048], maxPoolSize);
-+ public static void releaseBytes(byte[] bytes) {
-+ if (bytes != null && bytes != EMPTY_NIBBLE && bytes.length == 2048) {
-+ System.arraycopy(EMPTY_NIBBLE, 0, bytes, 0, 2048);
-+ BYTE_2048.release(bytes);
-+ }
-+ }
-
-+ public DataLayer markPoolSafe(byte[] bytes) {
-+ if (bytes != EMPTY_NIBBLE) this.data = bytes;
-+ return markPoolSafe();
-+ }
-+ public DataLayer markPoolSafe() {
-+ poolSafe = true;
-+ return this;
-+ }
-+ public byte[] getIfSet() {
-+ return this.data != null ? this.data : EMPTY_NIBBLE;
-+ }
-+ public byte[] getCloneIfSet() {
-+ if (data == null) {
-+ return EMPTY_NIBBLE;
-+ }
-+ byte[] ret = BYTE_2048.acquire();
-+ System.arraycopy(getIfSet(), 0, ret, 0, 2048);
-+ return ret;
-+ }
-+
-+ public DataLayer cloneAndSet(byte[] bytes) {
-+ if (bytes != null && bytes != EMPTY_NIBBLE) {
-+ this.data = BYTE_2048.acquire();
-+ System.arraycopy(bytes, 0, this.data, 0, 2048);
-+ }
-+ return this;
-+ }
-+ boolean poolSafe = false;
-+ public java.lang.Runnable cleaner;
-+ private void registerCleaner() {
-+ if (!poolSafe) {
-+ cleaner = net.minecraft.server.MCUtil.registerCleaner(this, this.data, DataLayer::releaseBytes);
-+ } else {
-+ cleaner = net.minecraft.server.MCUtil.once(() -> DataLayer.releaseBytes(this.data));
-+ }
-+ }
- public DataLayer() {}
-
- public DataLayer(byte[] bytes) {
-+ // Paper start
-+ this(bytes, false);
-+ }
-+ public DataLayer(byte[] bytes, boolean isSafe) {
- this.data = bytes;
-+ if (!isSafe) this.data = getCloneIfSet(); // Paper - clone for safety
-+ registerCleaner();
-+ // Paper end
- if (bytes.length != 2048) {
- throw (IllegalArgumentException) Util.pauseInIde(new IllegalArgumentException("DataLayer should be 2048 bytes not: " + bytes.length));
- }
-@@ -52,7 +106,8 @@ public final class DataLayer {
-
- private void set(int index, int value) {
- if (this.data == null) {
-- this.data = new byte[2048];
-+ this.data = BYTE_2048.acquire(); // Paper
-+ registerCleaner(); // Paper
- }
-
- int k = DataLayer.getByteIndex(index);
-@@ -74,13 +129,33 @@ public final class DataLayer {
- public byte[] getData() {
- if (this.data == null) {
- this.data = new byte[2048];
-+ } else { // Paper start
-+ // Accessor may need this object past garbage collection so need to clone it and return pooled value
-+ // If we know its safe for pre GC access, use asBytesPoolSafe(). If you just need read, use getIfSet()
-+ Runnable cleaner = this.cleaner;
-+ if (cleaner != null) {
-+ this.data = this.data.clone();
-+ cleaner.run(); // release the previously pooled value
-+ this.cleaner = null;
-+ }
- }
-+ // Paper end
-
- return this.data;
- }
-
-+ @javax.annotation.Nonnull
-+ public byte[] asBytesPoolSafe() {
-+ if (this.data == null) {
-+ this.data = BYTE_2048.acquire(); // Paper
-+ registerCleaner(); // Paper
-+ }
-+
-+ return this.data;
-+ }
-+ // Paper end
- public DataLayer copy() {
-- return this.data == null ? new DataLayer() : new DataLayer((byte[]) this.data.clone());
-+ return this.data == null ? new DataLayer() : new DataLayer(this.data); // Paper - clone in ctor
- }
-
- public String toString() {
-diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
-index 980c784b8e5365b62cbeef7f32af9f4383cc01e6..46beea026eec707c69194da6d1d51dc66b61f54e 100644
---- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
-+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
-@@ -502,11 +502,11 @@ public class ChunkSerializer {
- }
-
- if (nibblearray != null && !nibblearray.isEmpty()) {
-- nbttagcompound1.putByteArray("BlockLight", nibblearray.getData());
-+ nbttagcompound1.putByteArray("BlockLight", nibblearray.asBytesPoolSafe().clone()); // Paper
- }
-
- if (nibblearray1 != null && !nibblearray1.isEmpty()) {
-- nbttagcompound1.putByteArray("SkyLight", nibblearray1.getData());
-+ nbttagcompound1.putByteArray("SkyLight", nibblearray1.asBytesPoolSafe().clone()); // Paper
- }
-
- if (!nbttagcompound1.isEmpty()) {
-diff --git a/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java b/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
-index f357a3473682c2d37a20fb862522c67b9979402a..52682471adc13dffc0383fc4abacbd3397f3bb10 100644
---- a/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
-+++ b/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
-@@ -34,7 +34,9 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
-
- public void copyDataLayer(long pos) {
- if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
-- this.data.queueUpdate(pos, ((DataLayer) this.data.getUpdating(pos)).copy()); // Paper - avoid copying light data
-+ DataLayer updating = this.data.getUpdating(pos); // Paper - pool nibbles
-+ this.data.queueUpdate(pos, new DataLayer().markPoolSafe(updating.getCloneIfSet())); // Paper - avoid copying light data - pool safe clone
-+ if (updating.cleaner != null) net.minecraft.server.MCUtil.scheduleTask(2, updating.cleaner, "Light Engine Release"); // Paper - delay clean incase anything holding ref was still using it
- this.clearCache();
- }
-
-diff --git a/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
-index 4f7b63f2cc8a69fa8efb3a84f6abc3d3dcf05b49..cae559b37b5404851fa99d1d206232b5e7ab770c 100644
---- a/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
-+++ b/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
-@@ -157,7 +157,7 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
-
- protected DataLayer createDataLayer(long sectionPos) {
- DataLayer dataLayer = this.queuedSections.get(sectionPos);
-- return dataLayer != null ? dataLayer : new DataLayer();
-+ return dataLayer != null ? dataLayer : new DataLayer().markPoolSafe(); // Paper
- }
-
- protected void clearQueuedSectionBlocks(LayerLightEngine<?, ?> storage, long sectionPos) {
-@@ -318,12 +318,12 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
-
- protected void queueSectionData(long sectionPos, @Nullable DataLayer array, boolean nonEdge) {
- if (array != null) {
-- this.queuedSections.put(sectionPos, array);
-+ DataLayer remove = this.queuedSections.put(sectionPos, array); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
- if (!nonEdge) {
- this.untrustedSections.add(sectionPos);
- }
- } else {
-- this.queuedSections.remove(sectionPos);
-+ DataLayer remove = this.queuedSections.remove(sectionPos); if (remove != null && remove.cleaner != null) remove.cleaner.run(); // Paper - clean up when removed
- }
-
- }
-diff --git a/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
-index 9797254e981d08d3934f7ca8f369dd78a6ef1a48..4012d87dc27c3b1096fdaa60bfdfd68f27a22da7 100644
---- a/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
-+++ b/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
-@@ -163,14 +163,14 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
-
- return repeatFirstLayer(dataLayer2);
- } else {
-- return new DataLayer();
-+ return new DataLayer().markPoolSafe(); // Paper - mark pool use as safe (no auto cleaner)
- }
- }
- }
-
- private static DataLayer repeatFirstLayer(DataLayer source) {
- if (source.isEmpty()) {
-- return new DataLayer();
-+ return new DataLayer().markPoolSafe(); // Paper - mark pool use as safe (no auto cleaner)
- } else {
- byte[] bs = source.getData();
- byte[] cs = new byte[2048];
-@@ -179,7 +179,7 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
- System.arraycopy(bs, 0, cs, i * 128, 128);
- }
-
-- return new DataLayer(cs);
-+ return new DataLayer(cs).markPoolSafe(cs); // Paper - mark pool use as safe (no auto cleaner)
- }
- }
-
-@@ -197,7 +197,7 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
- this.updatingSectionData.copyDataLayer(l);
- }
-
-- Arrays.fill(this.getDataLayer(l, true).getData(), (byte)-1);
-+ Arrays.fill(this.getDataLayer(l, true).asBytesPoolSafe(), (byte)-1); // Paper
- int j = SectionPos.sectionToBlockCoord(SectionPos.x(l));
- int k = SectionPos.sectionToBlockCoord(SectionPos.y(l));
- int m = SectionPos.sectionToBlockCoord(SectionPos.z(l));
-diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-index 7bc1219523eeb0880493e6fb42692f1fdb30c110..187366c33c86b220581c3deac9168d6b6a2c5a3e 100644
---- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
-@@ -339,14 +339,14 @@ public class CraftChunk implements Chunk {
- sectionSkyLights[i] = CraftChunk.emptyLight;
- } else {
- sectionSkyLights[i] = new byte[2048];
-- System.arraycopy(skyLightArray.getData(), 0, sectionSkyLights[i], 0, 2048);
-+ System.arraycopy(skyLightArray.getIfSet(), 0, sectionSkyLights[i], 0, 2048); // Paper
- }
- DataLayer emitLightArray = lightengine.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(x, i, z));
- if (emitLightArray == null) {
- sectionEmitLights[i] = CraftChunk.emptyLight;
- } else {
- sectionEmitLights[i] = new byte[2048];
-- System.arraycopy(emitLightArray.getData(), 0, sectionEmitLights[i], 0, 2048);
-+ System.arraycopy(emitLightArray.getIfSet(), 0, sectionEmitLights[i], 0, 2048); // Paper
- }
-
- if (biome != null) {