From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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 a3b5793e4824718c8bf3d0a4f963de0ca94a738e..71089442c189336fc0061852a661581784a64013 100644
--- a/src/main/java/net/minecraft/server/BaseBlockPosition.java
+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
@@ -13,6 +13,14 @@ public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
     private final int b;
     @Deprecated
     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/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
index 8f3eee5ea812320af02e1bb6d2378fbbbef62e3c..4b162a768ed7f0a319309430b081943bf9c39b9c 100644
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -304,12 +304,24 @@ public class Chunk implements IChunkAccess {
         return this.sections;
     }
 
-    @Override
+    // Paper start - Optimize getBlockData to reduce instructions
+    public final IBlockData getBlockData(BlockPosition pos) { return getBlockData(pos.getX(), pos.getY(), pos.getZ()); } // Paper
     public IBlockData getType(BlockPosition blockposition) {
-        int i = blockposition.getX();
-        int j = blockposition.getY();
-        int k = blockposition.getZ();
+        return this.getBlockData(blockposition.getX(), blockposition.getY(), blockposition.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 getBlockData_unused(int i, int j, int k) {
+        // Paper end
         if (this.world.P() == 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 638b0e39798a3f75566fcf9ea48b81024e60b471..e056fbcb216977401fd2778fcd3ee7ed5f020214 100644
--- a/src/main/java/net/minecraft/server/ChunkSection.java
+++ b/src/main/java/net/minecraft/server/ChunkSection.java
@@ -9,7 +9,7 @@ public class ChunkSection {
     private short nonEmptyBlockCount;
     private short tickingBlockCount;
     private short e;
-    private final DataPaletteBlock<IBlockData> blockIds;
+    final DataPaletteBlock<IBlockData> blockIds;
 
     public ChunkSection(int i) {
         this(i, (short) 0, (short) 0, (short) 0);
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e7337fc368327876139f4610642a45321d0ecce2..6b1ff8f64f87e1d5fc98fd9733d6b45d312c1f69 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -171,11 +171,11 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
     }
 
     public static boolean isValidLocation(BlockPosition blockposition) {
-        return !isOutsideWorld(blockposition) && blockposition.getX() >= -30000000 && blockposition.getZ() >= -30000000 && blockposition.getX() < 30000000 && blockposition.getZ() < 30000000;
+        return blockposition.isValidLocation();
     }
 
     public static boolean isOutsideWorld(BlockPosition blockposition) {
-        return b(blockposition.getY());
+        return blockposition.isInvalidYLocation();
     }
 
     public static boolean b(int i) {
