diff --git a/Spigot-Server-Patches/Optimize-getBlockData.patch b/Spigot-Server-Patches/Optimize-getBlockData.patch deleted file mode 100644 index b90165bf27..0000000000 --- a/Spigot-Server-Patches/Optimize-getBlockData.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Thu, 3 Mar 2016 02:07:55 -0600 -Subject: [PATCH] Optimize getBlockData - -Hot method, so reduce # of instructions for the method. - -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -0,0 +0,0 @@ public class Chunk { - return this.a(i, j, k).c(); - } - -+ // Paper - Optimize getBlockData - public IBlockData getBlockData(BlockPosition blockposition) { -- return this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ if (blockposition.getY() >= 0 && blockposition.getY() >> 4 < this.sections.length) { -+ ChunkSection chunksection = this.sections[blockposition.getY() >> 4]; -+ if (chunksection != null) { -+ return chunksection.getType(blockposition.getX() & 15, blockposition.getY() & 15, blockposition.getZ() & 15); -+ } -+ } -+ return Blocks.AIR.getBlockData(); - } - - public IBlockData a(final int i, final int j, final int k) { --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Optimize-isValidLocation-for-inlining.patch b/Spigot-Server-Patches/Optimize-isValidLocation-for-inlining.patch deleted file mode 100644 index 6c60332f08..0000000000 --- a/Spigot-Server-Patches/Optimize-isValidLocation-for-inlining.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aikar -Date: Tue, 22 Mar 2016 23:41:34 -0400 -Subject: [PATCH] Optimize isValidLocation for inlining - -Move test to the blockPosition class so that it can access local variables. - -Replace all calls to the new place to the unnecessary forward. - -diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BaseBlockPosition.java -+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java -@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { - private final int a; - private final int b; - private final int c; -+ // Paper start -+ public boolean isValidLocation() { -+ return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256; -+ } -+ // Paper end - - public BaseBlockPosition(int i, int j, int k) { - this.a = i; -diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/net/minecraft/server/BlockPosition.java -+++ b/src/main/java/net/minecraft/server/BlockPosition.java -@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { - protected int b; - protected int c; - protected int d; -+ // Paper start -+ @Override -+ public boolean isValidLocation() { -+ return this.getX() >= -30000000 && this.getZ() >= -30000000 && this.getX() < 30000000 && this.getZ() < 30000000 && this.getY() >= 0 && this.getY() < 256; -+ } -+ // Paper end - - public MutableBlockPosition() { - this(0, 0, 0); -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 IBlockAccess { - return this.getType(blockposition1); - } - -- private boolean isValidLocation(BlockPosition blockposition) { -- return !this.E(blockposition) && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000; -+ private static boolean isValidLocation(BlockPosition blockposition) { // Paper -+ return blockposition.isValidLocation(); // Paper - } - - private boolean E(BlockPosition blockposition) { -@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { - // Paper start - test if meets light level, return faster - // logic copied from below - public boolean isLightLevel(BlockPosition blockposition, int level) { -- if (isValidLocation(blockposition)) { -+ if (blockposition.isValidLocation()) { - if (this.getType(blockposition).f()) { - if (this.c(blockposition.up(), false) >= level) { - return true; -@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { - blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); - } - -- if (!this.isValidLocation(blockposition)) { -+ if (!blockposition.isValidLocation()) { // Paper - return enumskyblock.c; - } else if (!this.isLoaded(blockposition)) { - return enumskyblock.c; -@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { - } - - public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { -- if (this.isValidLocation(blockposition)) { -+ if (blockposition.isValidLocation()) { // Paper - if (this.isLoaded(blockposition)) { - Chunk chunk = this.getChunkAtWorldCoords(blockposition); - -@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { - // CraftBukkit end - Chunk chunk = this.getChunkIfLoaded(blockposition); - if (chunk != null) { -- return this.isValidLocation(blockposition) ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData(); -+ return blockposition.isValidLocation() ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData(); - } - return null; - } --- \ No newline at end of file diff --git a/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch b/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch new file mode 100644 index 0000000000..c2ecbca7b3 --- /dev/null +++ b/Spigot-Server-Patches/Optimize-isValidLocation-getType-and-getBlockData-fo.patch @@ -0,0 +1,257 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Aikar +Date: Thu, 3 Mar 2016 02:07:55 -0600 +Subject: [PATCH] Optimize isValidLocation, getType and getBlockData for inling + +Hot methods, so reduce # of instructions for the method. + +Move is valid location test to the BlockPosition class so that it can access local variables. + +Replace all calls to the new place to the unnecessary forward. + +Optimize getType and getBlockData to manually inline and optimize the calls + +diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/BaseBlockPosition.java ++++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java +@@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { + private final int a; + private final int b; + private final int c; ++ // Paper start ++ public boolean isValidLocation() { ++ return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256; ++ } ++ public boolean isInvalidYLocation() { ++ return b < 0 || b >= 256; ++ } ++ // Paper end + + public BaseBlockPosition(int i, int j, int k) { + this.a = i; +diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/BlockPosition.java ++++ b/src/main/java/net/minecraft/server/BlockPosition.java +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition { + protected int b; + protected int c; + protected int d; ++ // Paper start ++ @Override ++ public boolean isValidLocation() { ++ return b >= -30000000 && d >= -30000000 && b < 30000000 && d < 30000000 && c >= 0 && c < 256; ++ } ++ @Override ++ public boolean isInvalidYLocation() { ++ return c < 0 || c >= 256; ++ } ++ // Paper end + + public MutableBlockPosition() { + this(0, 0, 0); +diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/Chunk.java ++++ b/src/main/java/net/minecraft/server/Chunk.java +@@ -0,0 +0,0 @@ public class Chunk { + return this.a(i, j, k).c(); + } + +- public IBlockData getBlockData(BlockPosition blockposition) { +- return this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ()); ++ // Paper start - Optimize getBlockData to reduce instructions ++ public final IBlockData getBlockData(final BlockPosition pos) { ++ return getBlockData(pos.getX(), pos.getY(), pos.getZ()); ++ } ++ ++ public final IBlockData getBlockData(final int x, final int y, final int z) { ++ // Method body / logic copied from below ++ final int i = y >> 4; ++ if (y >= 0 && i < this.sections.length && this.sections[i] != null) { ++ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int) ++ return this.sections[i].blockIds.a((y & 15) << 8 | (z & 15) << 4 | x & 15); ++ } ++ return Blocks.AIR.getBlockData(); + } + + public IBlockData a(final int i, final int j, final int k) { ++ return getBlockData(i, j, k); ++ } ++ public IBlockData unused(final int i, final int j, final int k) { ++ // Paper end + if (this.world.L() == WorldType.DEBUG_ALL_BLOCK_STATES) { + IBlockData iblockdata = null; + +diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/server/ChunkSection.java ++++ b/src/main/java/net/minecraft/server/ChunkSection.java +@@ -0,0 +0,0 @@ public class ChunkSection { + private final int yPos; + private int nonEmptyBlockCount; + private int tickingBlockCount; +- private final DataPaletteBlock blockIds; ++ final DataPaletteBlock blockIds; // Paper - package + private NibbleArray emittedLight; + private NibbleArray skyLight; + +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 IBlockAccess { + return this.getType(blockposition1); + } + +- private boolean isValidLocation(BlockPosition blockposition) { +- return !this.E(blockposition) && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000; ++ private static boolean isValidLocation(BlockPosition blockposition) { // Paper - unused but incase reflection / future uses ++ return blockposition.isValidLocation(); // Paper + } + +- private boolean E(BlockPosition blockposition) { +- return blockposition.getY() < 0 || blockposition.getY() >= 256; ++ private static boolean E(BlockPosition blockposition) { // Paper - unused but incase reflection / future uses ++ return blockposition.isInvalidYLocation(); // Paper + } + + public boolean isEmpty(BlockPosition blockposition) { +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + return true; + } + // CraftBukkit end +- if (this.E(blockposition)) { ++ if (blockposition.isInvalidYLocation()) { // Paper + return false; + } else if (!this.isClientSide && this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) { + return false; +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + // Paper start - test if meets light level, return faster + // logic copied from below + public boolean isLightLevel(BlockPosition blockposition, int level) { +- if (isValidLocation(blockposition)) { ++ if (blockposition.isValidLocation()) { + if (this.getType(blockposition).f()) { + if (this.c(blockposition.up(), false) >= level) { + return true; +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + blockposition = new BlockPosition(blockposition.getX(), 0, blockposition.getZ()); + } + +- if (!this.isValidLocation(blockposition)) { ++ if (!blockposition.isValidLocation()) { // Paper + return enumskyblock.c; + } else if (!this.isLoaded(blockposition)) { + return enumskyblock.c; +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + } + + public void a(EnumSkyBlock enumskyblock, BlockPosition blockposition, int i) { +- if (this.isValidLocation(blockposition)) { ++ if (blockposition.isValidLocation()) { // Paper + if (this.isLoaded(blockposition)) { + Chunk chunk = this.getChunkAtWorldCoords(blockposition); + +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + // Paper start - reduces need to do isLoaded before getType + public IBlockData getTypeIfLoaded(BlockPosition blockposition) { + // CraftBukkit start - tree generation ++ final int x = blockposition.getX(); ++ final int y = blockposition.getY(); ++ final int z = blockposition.getZ(); + if (captureTreeGeneration) { +- Iterator it = capturedBlockStates.iterator(); +- while (it.hasNext()) { +- BlockState previous = it.next(); +- if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { +- return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData()); +- } ++ final IBlockData previous = getCapturedBlockType(x, y, z); ++ if (previous != null) { ++ return previous; + } + } + // CraftBukkit end +- Chunk chunk = this.getChunkIfLoaded(blockposition); ++ Chunk chunk = ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x >> 4, z >> 4); + if (chunk != null) { +- return this.isValidLocation(blockposition) ? chunk.getBlockData(blockposition) : Blocks.AIR.getBlockData(); ++ return chunk.getBlockData(x, y, z); + } + return null; + } +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + + public IBlockData getType(BlockPosition blockposition) { + // CraftBukkit start - tree generation ++ // Paper start - optimize getType lookup to reduce instructions - getBlockData already enforces valid Y, move tree out ++ final int x = blockposition.getX(); ++ final int y = blockposition.getY(); ++ final int z = blockposition.getZ(); + if (captureTreeGeneration) { +- Iterator it = capturedBlockStates.iterator(); +- while (it.hasNext()) { +- BlockState previous = it.next(); +- if (previous.getX() == blockposition.getX() && previous.getY() == blockposition.getY() && previous.getZ() == blockposition.getZ()) { +- return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData()); +- } ++ final IBlockData previous = getCapturedBlockType(x, y, z); ++ if (previous != null) { ++ return previous; + } + } + // CraftBukkit end +- if (this.E(blockposition)) { +- return Blocks.AIR.getBlockData(); +- } else { +- Chunk chunk = this.getChunkAtWorldCoords(blockposition); ++ return this.chunkProvider.getChunkAt(x >> 4, z >> 4).getBlockData(x, y, z); ++ // Paper end ++ } + +- return chunk.getBlockData(blockposition); ++ // Paper start ++ private IBlockData getCapturedBlockType(int x, int y, int z) { ++ Iterator it = capturedBlockStates.iterator(); ++ while (it.hasNext()) { ++ BlockState previous = it.next(); ++ if (previous.getX() == x && previous.getY() == y && previous.getZ() == z) { ++ return CraftMagicNumbers.getBlock(previous.getTypeId()).fromLegacyData(previous.getRawData()); ++ } + } ++ return null; + } ++ // Paper end + + public boolean B() { + return this.J < 4; +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + public Map capturedTileEntities = Maps.newHashMap(); + @Nullable + public TileEntity getTileEntity(BlockPosition blockposition) { +- if (this.E(blockposition)) { ++ if (blockposition.isInvalidYLocation()) { // Paper + return null; + } else { + // CraftBukkit start +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + } + + public void setTileEntity(BlockPosition blockposition, @Nullable TileEntity tileentity) { +- if (!this.E(blockposition)) { ++ if (!blockposition.isInvalidYLocation()) { // Paper + if (tileentity != null && !tileentity.x()) { + // CraftBukkit start + if (captureBlockStates) { +@@ -0,0 +0,0 @@ public abstract class World implements IBlockAccess { + } + + public boolean d(BlockPosition blockposition, boolean flag) { +- if (this.E(blockposition)) { ++ if (blockposition.isInvalidYLocation()) { // Paper + return false; + } else { + Chunk chunk = this.chunkProvider.getLoadedChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4); +-- \ No newline at end of file