diff --git a/Spigot-Server-Patches/0505-Stop-copy-on-write-operations-for-updating-light-dat.patch b/Spigot-Server-Patches/0505-Stop-copy-on-write-operations-for-updating-light-dat.patch new file mode 100644 index 000000000..33af1075d --- /dev/null +++ b/Spigot-Server-Patches/0505-Stop-copy-on-write-operations-for-updating-light-dat.patch @@ -0,0 +1,300 @@ +From 4ba6af90544b8cf6d3da553a565e88c397dc8041 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Mon, 27 Apr 2020 04:05:38 -0700 +Subject: [PATCH] Stop copy-on-write operations for updating light data + +Causes huge memory allocations + gc issues + +diff --git a/src/main/java/net/minecraft/server/LightEngineStorage.java b/src/main/java/net/minecraft/server/LightEngineStorage.java +index a3f919816e..88277d23c3 100644 +--- a/src/main/java/net/minecraft/server/LightEngineStorage.java ++++ b/src/main/java/net/minecraft/server/LightEngineStorage.java +@@ -19,8 +19,8 @@ public abstract class LightEngineStorage> e + protected final LongSet b = new LongOpenHashSet(); + protected final LongSet c = new LongOpenHashSet(); + protected final LongSet d = new LongOpenHashSet(); +- protected volatile M e; +- protected final M f; ++ protected volatile M e_visible; protected final Object visibleUpdateLock = new Object(); // Paper - diff on change, should be "visible" - force compile fail on usage change ++ protected final M f; // Paper - diff on change, should be "updating" + protected final LongSet g = new LongOpenHashSet(); + protected final LongSet h = new LongOpenHashSet(); + protected final Long2ObjectMap i = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap()); +@@ -33,8 +33,8 @@ public abstract class LightEngineStorage> e + this.l = enumskyblock; + this.m = ilightaccess; + this.f = m0; +- this.e = m0.b(); +- this.e.d(); ++ this.e_visible = m0.b(); // Paper - avoid copying light data ++ this.e_visible.d(); // Paper - avoid copying light data + } + + protected boolean g(long i) { +@@ -43,7 +43,15 @@ public abstract class LightEngineStorage> e + + @Nullable + protected NibbleArray a(long i, boolean flag) { +- return this.a(flag ? this.f : this.e, i); ++ // Paper start - avoid copying light data ++ if (flag) { ++ return this.a(this.f, i); ++ } else { ++ synchronized (this.visibleUpdateLock) { ++ return this.a(this.e_visible, i); ++ } ++ } ++ // Paper end - avoid copying light data + } + + @Nullable +@@ -340,10 +348,12 @@ public abstract class LightEngineStorage> e + + protected void e() { + if (!this.g.isEmpty()) { ++ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data + M m0 = this.f.b(); + + m0.d(); +- this.e = m0; ++ this.e_visible = m0; // Paper - avoid copying light data ++ } // Paper - avoid copying light data + this.g.clear(); + } + +diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java +index b978723a66..278aec8846 100644 +--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java ++++ b/src/main/java/net/minecraft/server/LightEngineStorageArray.java +@@ -8,10 +8,17 @@ public abstract class LightEngineStorageArray a; ++ protected final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object data; // Paper - avoid copying light data ++ protected final boolean isVisible; // Paper - avoid copying light data + +- protected LightEngineStorageArray(Long2ObjectOpenHashMap long2objectopenhashmap) { +- this.a = long2objectopenhashmap; ++ // Paper start - avoid copying light data ++ protected LightEngineStorageArray(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object data, boolean isVisible) { ++ if (isVisible) { ++ data.performUpdatesLockMap(); ++ } ++ this.data = data; ++ this.isVisible = isVisible; ++ // Paper end - avoid copying light data + this.c(); + this.d = true; + } +@@ -19,12 +26,13 @@ public abstract class LightEngineStorageArray { + + protected LightEngineStorageBlock(ILightAccess ilightaccess) { +- super(EnumSkyBlock.BLOCK, ilightaccess, new LightEngineStorageBlock.a(new Long2ObjectOpenHashMap())); ++ super(EnumSkyBlock.BLOCK, ilightaccess, new LightEngineStorageBlock.a(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), false)); // Paper - avoid copying light data + } + + @Override +@@ -18,13 +18,13 @@ public class LightEngineStorageBlock extends LightEngineStorage { + +- public a(Long2ObjectOpenHashMap long2objectopenhashmap) { +- super(long2objectopenhashmap); ++ public a(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object long2objectopenhashmap, boolean isVisible) { // Paper - avoid copying light data ++ super(long2objectopenhashmap, isVisible); // Paper - avoid copying light data + } + + @Override + public LightEngineStorageBlock.a b() { +- return new LightEngineStorageBlock.a(this.a.clone()); ++ return new a(this.data, true); // Paper - avoid copying light data + } + } + } +diff --git a/src/main/java/net/minecraft/server/LightEngineStorageSky.java b/src/main/java/net/minecraft/server/LightEngineStorageSky.java +index 75d9065b32..06bc8371fe 100644 +--- a/src/main/java/net/minecraft/server/LightEngineStorageSky.java ++++ b/src/main/java/net/minecraft/server/LightEngineStorageSky.java +@@ -17,15 +17,16 @@ public class LightEngineStorageSky extends LightEngineStorage(), new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int(), Integer.MAX_VALUE, false)); // Paper - avoid copying light data + } + + @Override + protected int d(long i) { + long j = SectionPosition.e(i); + int k = SectionPosition.c(j); +- LightEngineStorageSky.a lightenginestoragesky_a = (LightEngineStorageSky.a) this.e; +- int l = lightenginestoragesky_a.c.get(SectionPosition.f(j)); ++ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data ++ LightEngineStorageSky.a lightenginestoragesky_a = (LightEngineStorageSky.a) this.e_visible; // Paper - avoid copying light data - must be after lock acquire ++ int l = lightenginestoragesky_a.otherData.getVisibleAsync(SectionPosition.f(j)); // Paper - avoid copying light data + + if (l != lightenginestoragesky_a.b && k < l) { + NibbleArray nibblearray = this.a(lightenginestoragesky_a, j); // Paper - decompile fix +@@ -46,6 +47,7 @@ public class LightEngineStorageSky extends LightEngineStorage j) { + ((LightEngineStorageSky.a) this.f).b = j; +- ((LightEngineStorageSky.a) this.f).c.defaultReturnValue(((LightEngineStorageSky.a) this.f).b); ++ ((LightEngineStorageSky.a) this.f).otherData.queueDefaultReturnValue(((LightEngineStorageSky.a) this.f).b); // Paper - avoid copying light data + } + + long k = SectionPosition.f(i); +- int l = ((LightEngineStorageSky.a) this.f).c.get(k); ++ int l = ((LightEngineStorageSky.a) this.f).otherData.getUpdating(k); // Paper - avoid copying light data + + if (l < j + 1) { +- ((LightEngineStorageSky.a) this.f).c.put(k, j + 1); ++ ((LightEngineStorageSky.a) this.f).otherData.queueUpdate(k, j + 1); // Paper - avoid copying light data + if (this.o.contains(k)) { + this.q(i); + if (l > ((LightEngineStorageSky.a) this.f).b) { +@@ -101,7 +103,7 @@ public class LightEngineStorageSky extends LightEngineStorage= k; + } +@@ -321,18 +323,20 @@ public class LightEngineStorageSky extends LightEngineStorage { + + private int b; +- private final Long2IntOpenHashMap c; ++ private final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int otherData; // Paper - avoid copying light data + +- public a(Long2ObjectOpenHashMap long2objectopenhashmap, Long2IntOpenHashMap long2intopenhashmap, int i) { +- super(long2objectopenhashmap); +- this.c = long2intopenhashmap; +- long2intopenhashmap.defaultReturnValue(i); ++ // Paper start - avoid copying light data ++ public a(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object data, com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int otherData, int i, boolean isVisible) { ++ super(data, isVisible); ++ this.otherData = otherData; ++ // Paper end - avoid copying light data + this.b = i; + } + + @Override + public LightEngineStorageSky.a b() { +- return new LightEngineStorageSky.a(this.a.clone(), this.c.clone(), this.b); ++ this.otherData.performUpdatesLockMap(); // Paper - avoid copying light data ++ return new LightEngineStorageSky.a(this.data, this.otherData, this.b, true); // Paper - avoid copying light data + } + } + } +-- +2.26.0 +