diff --git a/Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch b/Spigot-Server-Patches/Improve-BlockPosition-inline-and-hashCode-equals.patch similarity index 74% rename from Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch rename to Spigot-Server-Patches/Improve-BlockPosition-inline-and-hashCode-equals.patch index c354df1322..cc0a724a36 100644 --- a/Spigot-Server-Patches/Speedup-BlockPos-by-fixing-inlining.patch +++ b/Spigot-Server-Patches/Improve-BlockPosition-inline-and-hashCode-equals.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Techcable Date: Wed, 30 Nov 2016 20:56:58 -0600 -Subject: [PATCH] Speedup BlockPos by fixing inlining +Subject: [PATCH] Improve BlockPosition inline and hashCode/equals Normally the JVM can inline virtual getters by having two sets of code, one is the 'optimized' code and the other is the 'deoptimized' code. If a single type is used 99% of the time, then its worth it to inline, and to revert to 'deoptimized' the 1% of the time we encounter other types. @@ -17,9 +17,13 @@ It makes these simple methods much slower than they need to be. This should result in an across the board speedup in anything that accesses blocks or does logic with positions. -This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my mircorbenchmarks. +This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my microbenchmarks. They had 'callq' (invoke) instead of 'mov' (get from memory) instructions. +Co-Authored-By: Aikar +for: +Also cache the hashCode and long values to use it for speeding up hashmap usage + 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 @@ -35,15 +39,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - @Deprecated - private final int c; // Paper start -+ protected int x; +- public boolean isValidLocation() { +- return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256; ++ protected int x; // If these ever become non final, review this entire patch, look for places need to rehash on write + protected int y; + protected int z; - public boolean isValidLocation() { -- return a >= -30000000 && c >= -30000000 && a < 30000000 && c < 30000000 && b >= 0 && b < 256; ++ private int hashCodeCached = 0; ++ private long cachedLong = Long.MAX_VALUE; ++ ++ public final boolean isValidLocation() { + return x >= -30000000 && z >= -30000000 && x < 30000000 && z < 30000000 && y >= 0 && y < 256; } - public boolean isInvalidYLocation() { +- public boolean isInvalidYLocation() { - return b < 0 || b >= 256; ++ public final boolean isInvalidYLocation() { + return y < 0 || y >= 256; } // Paper end @@ -58,7 +67,48 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 } public BaseBlockPosition(double d0, double d1, double d2) { + this(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2)); + } + +- public boolean equals(Object object) { ++ public final boolean equals(Object object) { // Paper + if (this == object) { + return true; + } else if (!(object instanceof BaseBlockPosition)) { @@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { + } else { + BaseBlockPosition baseblockposition = (BaseBlockPosition) object; + +- return this.getX() != baseblockposition.getX() ? false : (this.getY() != baseblockposition.getY() ? false : this.getZ() == baseblockposition.getZ()); ++ return this.asLong() == baseblockposition.asLong(); // Paper + } + } + +- public int hashCode() { +- return (this.getY() + this.getZ() * 31) * 31 + this.getX(); ++ public final int hashCode() { ++ // Paper start ++ if (this.cachedLong == Long.MAX_VALUE) { ++ rebuildCache(); ++ } ++ return this.hashCodeCached; ++ } ++ private void rebuildCache() { ++ this.cachedLong = BlockPosition.asLong(getX(), getY(), getZ()); ++ this.hashCodeCached = (this.getY() + this.getZ() * 1031) * 1031 + this.getX(); ++ } ++ public final long asLong() { ++ if (this.cachedLong == Long.MAX_VALUE) { ++ rebuildCache(); ++ } ++ return this.cachedLong; ++ } ++ public final void rehash() { ++ this.cachedLong = Long.MAX_VALUE; ++ // Paper end + } + + public int compareTo(BaseBlockPosition baseblockposition) { return this.getY() == baseblockposition.getY() ? (this.getZ() == baseblockposition.getZ() ? this.getX() - baseblockposition.getX() : this.getZ() - baseblockposition.getZ()) : this.getY() - baseblockposition.getY(); } @@ -69,17 +119,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.x; } - public int getY() { +- public int getY() { - return this.b; ++ public final int getY() { + return this.y; } - public int getZ() { +- public int getZ() { - return this.c; ++ public final int getZ() { + return this.z; } ++ // Paper end public BaseBlockPosition down() { + return this.down(1); @@ -0,0 +0,0 @@ public class BaseBlockPosition implements Comparable { public BaseBlockPosition shift(EnumDirection enumdirection, int i) { return i == 0 ? this : new BaseBlockPosition(this.getX() + enumdirection.getAdjacentX() * i, this.getY() + enumdirection.getAdjacentY() * i, this.getZ() + enumdirection.getAdjacentZ() * i); @@ -113,6 +167,23 @@ diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/ja 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 implements MinecraftSeriali + return new BlockPosition(b(i), c(i), d(i)); + } + ++ public static long asLong(int x, int y, int z) { return a(x, y, z); } // Paper - OBFHELPER + public static long a(int i, int j, int k) { + long l = 0L; + +@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali + return i & -16L; + } + +- public long asLong() { ++ public long asLong_unused() { // Paper - moved to parent + return a(this.getX(), this.getY(), this.getZ()); + } + @@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali } @@ -172,6 +243,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.x = i; + this.y = j; + this.z = k; ++ rehash(); + // Paper end return this; } @@ -193,18 +265,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public void o(int i) { - this.b = i; + this.x = i; // Paper change to x ++ rehash(); // Paper } public final void setY(final int y) { this.p(y); } // Paper - OBFHELPER public void p(int i) { - this.c = i; + this.y = i; // Paper change to y ++ rehash(); // Paper } public final void setZ(final int z) { this.q(z); } // Paper - OBFHELPER public void q(int i) { - this.d = i; + this.z = i; // Paper change to z ++ rehash(); // Paper } @Override