mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-04 22:14:40 +01:00
207 lines
10 KiB
Diff
207 lines
10 KiB
Diff
|
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
|
||
|
inlining
|
||
|
|
||
|
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/core/BaseBlockPosition.java b/src/main/java/net/minecraft/core/BaseBlockPosition.java
|
||
|
index 25fdd55a7548cfaa45a541ad77f22f33c33e7471..4b56683336fdab06804efdc8ca1f7c130b77291f 100644
|
||
|
--- a/src/main/java/net/minecraft/core/BaseBlockPosition.java
|
||
|
+++ b/src/main/java/net/minecraft/core/BaseBlockPosition.java
|
||
|
@@ -22,6 +22,15 @@ public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
|
||
|
private int b;public final void setY(final int y) { this.b = y; } // Paper - OBFHELPER
|
||
|
private int e;public final void setZ(final int z) { this.e = z; } // Paper - OBFHELPER
|
||
|
|
||
|
+ // Paper start
|
||
|
+ public boolean isValidLocation() {
|
||
|
+ return getX() >= -30000000 && getZ() >= -30000000 && getX() < 30000000 && getZ() < 30000000 && getY() >= 0 && getY() < 256;
|
||
|
+ }
|
||
|
+ public boolean isInvalidYLocation() {
|
||
|
+ return b < 0 || b >= 256;
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
+
|
||
|
public BaseBlockPosition(int i, int j, int k) {
|
||
|
this.a = i;
|
||
|
this.b = j;
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
|
||
|
index a570998e4ef6c3ff83403881bf1d24c8cbcfcf67..a22be13b097052b2a88707c9436b88c84298e46b 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/World.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/World.java
|
||
|
@@ -239,7 +239,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||
|
}
|
||
|
|
||
|
public static boolean isValidLocation(BlockPosition blockposition) {
|
||
|
- return !isOutsideWorld(blockposition) && D(blockposition);
|
||
|
+ return blockposition.isValidLocation(); // Paper - use better/optimized check
|
||
|
}
|
||
|
|
||
|
public static boolean l(BlockPosition blockposition) {
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/Chunk.java b/src/main/java/net/minecraft/world/level/chunk/Chunk.java
|
||
|
index 4b3de29b1a6e9d75b28962073c62bbe8d666165f..fdc491f978560c394eec22116572585f9bbdec9f 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/Chunk.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/Chunk.java
|
||
|
@@ -348,12 +348,27 @@ 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 IBlockData getType(final int x, final int y, final int z) {
|
||
|
+ return getBlockData(x, y, z);
|
||
|
+ }
|
||
|
+ 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 || this.sections[i].nonEmptyBlockCount == 0) {
|
||
|
+ return Blocks.AIR.getBlockData();
|
||
|
+ }
|
||
|
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
|
||
|
+ return this.sections[i].blockIds.a((y & 15) << 8 | (z & 15) << 4 | x & 15);
|
||
|
+ }
|
||
|
|
||
|
+ public IBlockData getBlockData_unused(int i, int j, int k) {
|
||
|
+ // Paper end
|
||
|
if (this.world.isDebugWorld()) {
|
||
|
IBlockData iblockdata = null;
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkEmpty.java b/src/main/java/net/minecraft/world/level/chunk/ChunkEmpty.java
|
||
|
index 395d21afaabcbd99f9ce0551d647f5db9507a518..89efd0b68b04457e1cd617dcc8bb1a6ea1c4717c 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkEmpty.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkEmpty.java
|
||
|
@@ -23,7 +23,7 @@ import net.minecraft.world.phys.AxisAlignedBB;
|
||
|
|
||
|
public class ChunkEmpty extends Chunk {
|
||
|
|
||
|
- private static final BiomeBase[] b = (BiomeBase[]) SystemUtils.a((Object) (new BiomeBase[BiomeStorage.a]), (abiomebase) -> {
|
||
|
+ private static final BiomeBase[] b = SystemUtils.a((new BiomeBase[BiomeStorage.a]), (abiomebase) -> { // Paper - decompile error
|
||
|
Arrays.fill(abiomebase, BiomeRegistry.a);
|
||
|
});
|
||
|
|
||
|
@@ -31,6 +31,11 @@ public class ChunkEmpty extends Chunk {
|
||
|
super(world, chunkcoordintpair, new BiomeStorage(world.r().b(IRegistry.ay), ChunkEmpty.b));
|
||
|
}
|
||
|
|
||
|
+ // Paper start
|
||
|
+ @Override public IBlockData getType(int x, int y, int z) {
|
||
|
+ return Blocks.VOID_AIR.getBlockData();
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
@Override
|
||
|
public IBlockData getType(BlockPosition blockposition) {
|
||
|
return Blocks.VOID_AIR.getBlockData();
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/ChunkSection.java
|
||
|
index a4e2eb1a753e8fcb48982d78fe80e505bce5c476..eea4a30428293eaf7afbe303a37adec60b44c2b4 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkSection.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkSection.java
|
||
|
@@ -13,10 +13,10 @@ public class ChunkSection {
|
||
|
|
||
|
public static final DataPalette<IBlockData> GLOBAL_PALETTE = new DataPaletteGlobal<>(Block.REGISTRY_ID, Blocks.AIR.getBlockData());
|
||
|
private final int yPos;
|
||
|
- private short nonEmptyBlockCount;
|
||
|
+ short nonEmptyBlockCount; // Paper - package-private
|
||
|
private short tickingBlockCount;
|
||
|
private short e;
|
||
|
- private final DataPaletteBlock<IBlockData> blockIds;
|
||
|
+ final DataPaletteBlock<IBlockData> blockIds; // Paper - package-private
|
||
|
|
||
|
public ChunkSection(int i) {
|
||
|
this(i, (short) 0, (short) 0, (short) 0);
|
||
|
@@ -30,8 +30,8 @@ public class ChunkSection {
|
||
|
this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData());
|
||
|
}
|
||
|
|
||
|
- public IBlockData getType(int i, int j, int k) {
|
||
|
- return (IBlockData) this.blockIds.a(i, j, k);
|
||
|
+ public final IBlockData getType(int i, int j, int k) { // Paper
|
||
|
+ return this.blockIds.a(j << 8 | k << 4 | i); // Paper - inline
|
||
|
}
|
||
|
|
||
|
public Fluid b(int i, int j, int k) {
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/DataPaletteBlock.java b/src/main/java/net/minecraft/world/level/chunk/DataPaletteBlock.java
|
||
|
index e397b871b846c3a90bc75d0e1cf0683b6a3d0ca9..8928157b01bb4f0dfe043732777b33708c23cda7 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/DataPaletteBlock.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/DataPaletteBlock.java
|
||
|
@@ -133,7 +133,7 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||
|
}
|
||
|
|
||
|
public T a(int i, int j, int k) {
|
||
|
- return this.a(b(i, j, k));
|
||
|
+ return this.a(j << 8 | k << 4 | i); // Paper - inline
|
||
|
}
|
||
|
|
||
|
protected T a(int i) {
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/IChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/IChunkAccess.java
|
||
|
index 2cd04abd72f1135446182ad6294003e526f99a4b..e570dc58efa56bd0aa5ada5575b4054ee38d505e 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/IChunkAccess.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/IChunkAccess.java
|
||
|
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.LogManager;
|
||
|
|
||
|
public interface IChunkAccess extends IBlockAccess, IStructureAccess {
|
||
|
|
||
|
+ IBlockData getType(final int x, final int y, final int z); // Paper
|
||
|
@Nullable
|
||
|
IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag);
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||
|
index 7572ca53a5cca8ca5085d18c24048b85dda4daa9..9eeb99a21a6ed7f71ff64cf4cfdff646d31abbcf 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||
|
@@ -113,16 +113,18 @@ public class ProtoChunk implements IChunkAccess {
|
||
|
|
||
|
@Override
|
||
|
public IBlockData getType(BlockPosition blockposition) {
|
||
|
- int i = blockposition.getY();
|
||
|
-
|
||
|
- if (World.b(i)) {
|
||
|
+ return getType(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||
|
+ }
|
||
|
+ // Paper start
|
||
|
+ public IBlockData getType(final int x, final int y, final int z) {
|
||
|
+ if (y < 0 || y >= 256) {
|
||
|
return Blocks.VOID_AIR.getBlockData();
|
||
|
} else {
|
||
|
- ChunkSection chunksection = this.getSections()[i >> 4];
|
||
|
-
|
||
|
- return ChunkSection.a(chunksection) ? Blocks.AIR.getBlockData() : chunksection.getType(blockposition.getX() & 15, i & 15, blockposition.getZ() & 15);
|
||
|
+ ChunkSection chunksection = this.getSections()[y >> 4];
|
||
|
+ return chunksection == Chunk.EMPTY_CHUNK_SECTION || chunksection.c() ? Blocks.AIR.getBlockData() : chunksection.getType(x & 15, y & 15, z & 15);
|
||
|
}
|
||
|
}
|
||
|
+ // Paper end
|
||
|
|
||
|
@Override
|
||
|
public Fluid getFluid(BlockPosition blockposition) {
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunkExtension.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunkExtension.java
|
||
|
index c059d3d055c35b492680556e8605966e2caaf7fd..9351e6ba541d440c485b6e4a3209170c5756e31e 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunkExtension.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunkExtension.java
|
||
|
@@ -42,6 +42,11 @@ public class ProtoChunkExtension extends ProtoChunk {
|
||
|
public IBlockData getType(BlockPosition blockposition) {
|
||
|
return this.a.getType(blockposition);
|
||
|
}
|
||
|
+ // Paper start
|
||
|
+ public final IBlockData getType(final int x, final int y, final int z) {
|
||
|
+ return this.a.getBlockData(x, y, z);
|
||
|
+ }
|
||
|
+ // Paper end
|
||
|
|
||
|
@Override
|
||
|
public Fluid getFluid(BlockPosition blockposition) {
|