diff --git a/Spigot-Server-Patches/Avoid-Chunk-Lookups-for-Entity-TileEntity-Current-Ch.patch b/Spigot-Server-Patches/Avoid-Chunk-Lookups-for-Entity-TileEntity-Current-Ch.patch new file mode 100644 index 0000000000..4c11298abd --- /dev/null +++ b/Spigot-Server-Patches/Avoid-Chunk-Lookups-for-Entity-TileEntity-Current-Ch.patch @@ -0,0 +1,74 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Wed, 4 Jul 2018 03:39:51 -0400 +Subject: [PATCH] Avoid Chunk Lookups for Entity/TileEntity Current Chunk + +SPECIAL 1.14.1 NOTE: +This patch caused a memory leak since the tile entity's chunk was set to null +before it was removed. Ensure this issue is resolved! + +In many places where we simply want the current chunk the entity +is in, instead of doing a hashmap lookup for it, we now have access +to the object directly on the Entity/TileEntity object we can directly grab. + +Use that local value instead to reduce lookups in many hot places. + + +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 985f30372..67159b8a8 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + if (!tileentity.isRemoved() && tileentity.hasWorld()) { + BlockPosition blockposition = tileentity.getPosition(); + +- if (this.chunkProvider.a(blockposition) && this.getWorldBorder().a(blockposition)) { ++ if (tileentity.getCurrentChunk() != null && this.getWorldBorder().a(blockposition)) { // Paper + try { + gameprofilerfiller.a(() -> { + return String.valueOf(TileEntityTypes.a(tileentity.getTileType())); +@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + this.tileEntityListTick.remove(tileTickPosition--); + // Spigot end + //this.tileEntityList.remove(tileentity); // Paper - remove unused list +- if (this.isLoaded(tileentity.getPosition())) { +- this.getChunkAtWorldCoords(tileentity.getPosition()).removeTileEntity(tileentity.getPosition()); ++ // Paper start - use local chunk reference ++ Chunk chunk = tileentity.getCurrentChunk(); ++ if (chunk != null) { ++ chunk.removeTileEntity(tileentity.getPosition()); ++ // Paper end + } + } + } +@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + } + // CraftBukkit end */ + +- if (this.isLoaded(tileentity1.getPosition())) { +- Chunk chunk = this.getChunkAtWorldCoords(tileentity1.getPosition()); ++ Chunk chunk = tileentity1.getCurrentChunk(); // Paper ++ if (chunk != null) { // Paper + IBlockData iblockdata = chunk.getType(tileentity1.getPosition()); + + chunk.setTileEntity(tileentity1.getPosition(), tileentity1); +diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java +index 83fb8737a..c473c7d16 100644 +--- a/src/main/java/net/minecraft/server/WorldServer.java ++++ b/src/main/java/net/minecraft/server/WorldServer.java +@@ -0,0 +0,0 @@ public class WorldServer extends World { + } + + private void removeEntityFromChunk(Entity entity) { +- IChunkAccess ichunkaccess = this.getChunkAt(entity.chunkX, entity.chunkZ, ChunkStatus.FULL, false); ++ // Paper start ++ if (!entity.inChunk) return; ++ IChunkAccess ichunkaccess = this.getChunkIfLoaded(entity.chunkX, entity.chunkZ); ++ // Paper start + +- if (ichunkaccess instanceof Chunk) { ++ if (ichunkaccess != null) { // Paper + ((Chunk) ichunkaccess).b(entity); + } + +-- \ No newline at end of file