From 0aa0eba1114143df750021e52ed4cdd0e6b69776 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sat, 19 Sep 2020 11:51:01 -0400 Subject: [PATCH] Optimize some methods for inlining Adds final to some methods to improve inlining ability --- .../Add-World-Util-Methods.patch | 12 ++- Spigot-Server-Patches/MC-Utils.patch | 87 ++++++++++++++++--- ...e-getChunkAt-calls-for-loaded-chunks.patch | 19 ---- ...imize-World.isLoaded-BlockPosition-Z.patch | 5 +- 4 files changed, 84 insertions(+), 39 deletions(-) diff --git a/Spigot-Server-Patches/Add-World-Util-Methods.patch b/Spigot-Server-Patches/Add-World-Util-Methods.patch index ba7611bedf..f9d960b1d1 100644 --- a/Spigot-Server-Patches/Add-World-Util-Methods.patch +++ b/Spigot-Server-Patches/Add-World-Util-Methods.patch @@ -10,15 +10,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- 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 { + } + + @Override +- public Fluid getFluidIfLoaded(BlockPosition blockposition) { ++ public final Fluid getFluidIfLoaded(BlockPosition blockposition) { + IChunkAccess chunk = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); return chunk == null ? null : chunk.getFluid(blockposition); } + -+ public boolean isLoadedAndInBounds(BlockPosition blockposition) { ++ public final boolean isLoadedAndInBounds(BlockPosition blockposition) { // Paper - final for inline + return getWorldBorder().isInBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; + } + -+ public Chunk getChunkIfLoaded(int x, int z) { ++ public Chunk getChunkIfLoaded(int x, int z) { // Overridden in WorldServer for ABI compat which has final + return ((WorldServer) this).getChunkProvider().getChunkAtIfLoadedImmediately(x, z); + } + public final Chunk getChunkIfLoaded(BlockPosition blockposition) { @@ -26,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + + // reduces need to do isLoaded before getType -+ public IBlockData getTypeIfLoadedAndInBounds(BlockPosition blockposition) { ++ public final IBlockData getTypeIfLoadedAndInBounds(BlockPosition blockposition) { + return getWorldBorder().isInBounds(blockposition) ? getTypeIfLoaded(blockposition) : null; + } // Paper end diff --git a/Spigot-Server-Patches/MC-Utils.patch b/Spigot-Server-Patches/MC-Utils.patch index efb24f2adb..47f6f32c1e 100644 --- a/Spigot-Server-Patches/MC-Utils.patch +++ b/Spigot-Server-Patches/MC-Utils.patch @@ -4000,14 +4000,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + // Paper end + // CraftBukkit start - public Chunk getFullChunk() { +- public Chunk getFullChunk() { ++ public final Chunk getFullChunk() { // Paper - final for inline if (!getChunkState(this.oldTicketLevel).isAtLeast(PlayerChunk.State.BORDER)) return null; // note: using oldTicketLevel for isLoaded checks -@@ -0,0 +0,0 @@ public class PlayerChunk { + CompletableFuture> statusFuture = this.getStatusFutureUnchecked(ChunkStatus.FULL); + Either either = (Either) statusFuture.getNow(null); return either == null ? null : (Chunk) either.left().orElse(null); } // CraftBukkit end + // Paper start - "real" get full chunk immediately -+ public Chunk getFullChunkIfCached() { ++ public final Chunk getFullChunkIfCached() { + // Note: Copied from above without ticket level check + CompletableFuture> statusFuture = this.getStatusFutureUnchecked(ChunkStatus.FULL); + Either either = (Either) statusFuture.getNow(null); @@ -4021,20 +4023,53 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return getChunkStatus(this.ticketLevel).b(chunkstatus) ? this.getStatusFutureUnchecked(chunkstatus) : PlayerChunk.UNLOADED_CHUNK_ACCESS_FUTURE; } +- public CompletableFuture> a() { + public final CompletableFuture> getTickingFuture() { return this.a(); } // Paper - OBFHELPER - public CompletableFuture> a() { ++ public final CompletableFuture> a() { // Paper - final for inline return this.tickingFuture; } +- public CompletableFuture> b() { + public final CompletableFuture> getEntityTickingFuture() { return this.b(); } // Paper - OBFHELPER - public CompletableFuture> b() { ++ public final CompletableFuture> b() { // Paper - final for inline return this.entityTickingFuture; } +- public CompletableFuture> c() { + public final CompletableFuture> getFullChunkFuture() { return this.c(); } // Paper - OBFHELPER - public CompletableFuture> c() { ++ public final CompletableFuture> c() { // Paper - final for inline return this.fullChunkFuture; } + + @Nullable +- public Chunk getChunk() { ++ public final Chunk getChunk() { // Paper - final for inline + CompletableFuture> completablefuture = this.a(); + Either either = (Either) completablefuture.getNow(null); // CraftBukkit - decompile error + +@@ -0,0 +0,0 @@ public class PlayerChunk { + return null; + } + +- public CompletableFuture getChunkSave() { ++ public final CompletableFuture getChunkSave() { // Paper - final for inline + return this.chunkSave; + } + +@@ -0,0 +0,0 @@ public class PlayerChunk { + }); + } + +- public ChunkCoordIntPair i() { ++ public final ChunkCoordIntPair i() { // Paper - final for inline + return this.location; + } + +- public int getTicketLevel() { ++ public final int getTicketLevel() { // Paper - final for inline + return this.ticketLevel; + } + @@ -0,0 +0,0 @@ public class PlayerChunk { this.hasBeenLoaded |= flag3; @@ -4373,18 +4408,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.world = new CraftWorld((WorldServer) this, gen, env); this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL); + return i < 0 || i >= 256; } +- public Chunk getChunkAtWorldCoords(BlockPosition blockposition) { ++ public final Chunk getChunkAtWorldCoords(BlockPosition blockposition) { // Paper - help inline + return this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); + } + + @Override +- public Chunk getChunkAt(int i, int j) { +- return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL); ++ public final Chunk getChunkAt(int i, int j) { // Paper - final to help inline ++ return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL, true); // Paper - avoid a method jump ++ } ++ + // Paper start - if loaded + @Nullable + @Override -+ public IChunkAccess getChunkIfLoadedImmediately(int x, int z) { ++ public final IChunkAccess getChunkIfLoadedImmediately(int x, int z) { + return ((WorldServer)this).chunkProvider.getChunkAtIfLoadedImmediately(x, z); -+ } -+ -+ @Override -+ public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + } + + @Override +- public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { ++ public final IBlockData getTypeIfLoaded(BlockPosition blockposition) { + // CraftBukkit start - tree generation + if (captureTreeGeneration) { + CraftBlockState previous = capturedBlockStates.get(blockposition); @@ -4409,9 +4457,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + // Paper end + - @Override - public IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { ++ @Override ++ public final IChunkAccess getChunkAt(int i, int j, ChunkStatus chunkstatus, boolean flag) { // Paper - final for inline IChunkAccess ichunkaccess = this.getChunkProvider().getChunkAt(i, j, chunkstatus, flag); + + if (ichunkaccess == null && flag) { +@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { + } + + @Override +- public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { ++ public final boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { // Paper - final for inline + return this.a(blockposition, iblockdata, i, 512); + } + @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public void a(BlockPosition blockposition, IBlockData iblockdata, IBlockData iblockdata1) {} diff --git a/Spigot-Server-Patches/Optimise-getChunkAt-calls-for-loaded-chunks.patch b/Spigot-Server-Patches/Optimise-getChunkAt-calls-for-loaded-chunks.patch index eb693e8b37..1e7dce7ddc 100644 --- a/Spigot-Server-Patches/Optimise-getChunkAt-calls-for-loaded-chunks.patch +++ b/Spigot-Server-Patches/Optimise-getChunkAt-calls-for-loaded-chunks.patch @@ -64,22 +64,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } } -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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 { - - @Override - public Chunk getChunkAt(int i, int j) { -+ // Paper start - optimise this for loaded chunks -+ if (Thread.currentThread() == this.serverThread) { -+ Chunk ifLoaded = ((WorldServer) this).getChunkProvider().getChunkAtIfLoadedMainThread(i, j); -+ if (ifLoaded != null) { -+ return ifLoaded; -+ } -+ } -+ // Paper end - return (Chunk) this.getChunkAt(i, j, ChunkStatus.FULL); - } - diff --git a/Spigot-Server-Patches/Optimize-World.isLoaded-BlockPosition-Z.patch b/Spigot-Server-Patches/Optimize-World.isLoaded-BlockPosition-Z.patch index 68a6564a12..3e4ef873bb 100644 --- a/Spigot-Server-Patches/Optimize-World.isLoaded-BlockPosition-Z.patch +++ b/Spigot-Server-Patches/Optimize-World.isLoaded-BlockPosition-Z.patch @@ -13,11 +13,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 return chunk == null ? null : chunk.getFluid(blockposition); } -+ public boolean isLoaded(BlockPosition blockposition) { ++ public final boolean isLoaded(BlockPosition blockposition) { + return getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; // Paper + } + -+ - public boolean isLoadedAndInBounds(BlockPosition blockposition) { + public final boolean isLoadedAndInBounds(BlockPosition blockposition) { // Paper - final for inline return getWorldBorder().isInBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null; }