Paper/patches/server/0076-Optimize-isInWorldBounds-and-getBlockState-for-inlin.patch

167 lines
8.3 KiB
Diff
Raw Normal View History

2021-06-11 14:02:28 +02:00
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 isInWorldBounds and getBlockState for inlining
2021-06-11 14:02:28 +02:00
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/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
2023-03-14 19:36:39 +01:00
index 1b29c6872ebe54351f28c1f1f38b22561ba785ee..40950db0c242c65dfd4de247c86249354d12108f 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/core/Vec3i.java
+++ b/src/main/java/net/minecraft/core/Vec3i.java
2023-03-14 19:36:39 +01:00
@@ -31,6 +31,12 @@ public class Vec3i implements Comparable<Vec3i> {
});
2021-11-23 13:15:10 +01:00
}
2021-06-11 14:02:28 +02:00
+ // Paper start
+ public final boolean isInsideBuildHeightAndWorldBoundsHorizontal(net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
2021-06-14 17:10:25 +02:00
+ return getX() >= -30000000 && getZ() >= -30000000 && getX() < 30000000 && getZ() < 30000000 && !levelHeightAccessor.isOutsideBuildHeight(getY());
2021-06-11 14:02:28 +02:00
+ }
+ // Paper end
+
public Vec3i(int x, int y, int z) {
this.x = x;
this.y = y;
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
2023-06-08 07:21:04 +02:00
index 809f7db469583ea90fbb165cf180dc87055c6105..e5194f0650af2bce8aac24e34752b21015b92d4e 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
2023-06-07 20:49:17 +02:00
@@ -284,7 +284,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
2021-06-11 14:02:28 +02:00
}
2021-06-12 04:24:43 +02:00
public boolean isInWorldBounds(BlockPos pos) {
- return !this.isOutsideBuildHeight(pos) && Level.isInWorldBoundsHorizontal(pos);
+ return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check
2021-06-11 14:02:28 +02:00
}
public static boolean isInSpawnableBounds(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
2023-06-07 20:49:17 +02:00
index 2caac1a3d80e6c490aa16aa6bc1067065b665c69..525c89bc926f13af6f94fc46c897525e37477eca 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
2023-06-07 20:49:17 +02:00
@@ -166,6 +166,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
2022-12-07 19:52:24 +01:00
return GameEventListenerRegistry.NOOP;
2021-06-12 04:24:43 +02:00
}
2021-06-11 14:02:28 +02:00
+ public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
2021-06-11 14:02:28 +02:00
@Nullable
2021-11-23 13:15:10 +01:00
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
2023-06-07 20:49:17 +02:00
index f49cc61840c6588fca301b4c5c3aaeede03a323e..785fa679860413b736122f8e88a92e683cbdd99f 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
Rewrite chunk system (#8177) Patch documentation to come Issues with the old system that are fixed now: - World generation does not scale with cpu cores effectively. - Relies on the main thread for scheduling and maintaining chunk state, dropping chunk load/generate rates at lower tps. - Unreliable prioritisation of chunk gen/load calls that block the main thread. - Shutdown logic is utterly unreliable, as it has to wait for all chunks to unload - is it guaranteed that the chunk system is in a state on shutdown that it can reliably do this? Watchdog shutdown also typically failed due to thread checks, which is now resolved. - Saving of data is not unified (i.e can save chunk data without saving entity data, poses problems for desync if shutdown is really abnormal. - Entities are not loaded with chunks. This caused quite a bit of headache for Chunk#getEntities API, but now the new chunk system loads entities with chunks so that they are ready whenever the chunk loads in. Effectively brings the behavior back to 1.16 era, but still storing entities in their own separate regionfiles. The above list is not complete. The patch documentation will complete it. New chunk system hard relies on starlight and dataconverter, and most importantly the new concurrent utilities in ConcurrentUtil. Some of the old async chunk i/o interface (i.e the old file io thread reroutes _some_ calls to the new file io thread) is kept for plugin compat reasons. It will be removed in the next major version of minecraft. The old legacy chunk system patches have been moved to the removed folder in case we need them again.
2022-09-26 10:02:51 +02:00
@@ -55,6 +55,12 @@ public class EmptyLevelChunk extends LevelChunk {
public void setBlockEmptinessMap(final boolean[] emptinessMap) {}
// Paper end - starlight
2021-06-11 14:02:28 +02:00
+ // Paper start
+ @Override
+ public BlockState getBlockState(int x, int y, int z) {
2021-06-11 14:02:28 +02:00
+ return Blocks.VOID_AIR.defaultBlockState();
+ }
+ // Paper end
@Override
public BlockState getBlockState(BlockPos pos) {
return Blocks.VOID_AIR.defaultBlockState();
diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
2023-06-07 20:49:17 +02:00
index 60e760b42dd6471a229dfd45490dcf8c51979d35..4a3ac7dedf5cb1e76f16ec4f18e82afc717d0ced 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
2023-06-07 20:49:17 +02:00
@@ -91,6 +91,12 @@ public class ImposterProtoChunk extends ProtoChunk {
2021-06-11 14:02:28 +02:00
public BlockState getBlockState(BlockPos pos) {
return this.wrapped.getBlockState(pos);
}
+ // Paper start
+ @Override
+ public final BlockState getBlockState(final int x, final int y, final int z) {
+ return this.wrapped.getBlockStateFinal(x, y, z);
2021-06-11 14:02:28 +02:00
+ }
+ // Paper end
@Override
public FluidState getFluidState(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
2023-06-08 23:13:43 +02:00
index 36701f196756dc7c6820cac516ff880d00a43b17..72637bb342f1260debf925f5b3fde8ec7dd3cfff 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
2023-06-07 20:49:17 +02:00
@@ -295,12 +295,29 @@ public class LevelChunk extends ChunkAccess {
2022-06-07 21:55:39 +02:00
}
2021-06-11 14:02:28 +02:00
}
+ // Paper start - Optimize getBlockData to reduce instructions
2021-06-12 04:24:43 +02:00
@Override
2021-06-11 14:02:28 +02:00
public BlockState getBlockState(BlockPos pos) {
- int i = pos.getX();
- int j = pos.getY();
- int k = pos.getZ();
+ return this.getBlockStateFinal(pos.getX(), pos.getY(), pos.getZ());
2021-06-11 14:02:28 +02:00
+ }
2023-03-23 22:57:03 +01:00
+
+ @Override
+ public BlockState getBlockState(final int x, final int y, final int z) {
+ return this.getBlockStateFinal(x, y, z);
2021-06-11 14:02:28 +02:00
+ }
+ public final BlockState getBlockStateFinal(final int x, final int y, final int z) {
2021-06-11 14:02:28 +02:00
+ // Method body / logic copied from below
2021-06-12 04:24:43 +02:00
+ final int i = this.getSectionIndex(y);
+ if (i < 0 || i >= this.sections.length || this.sections[i].nonEmptyBlockCount == 0 || this.sections[i].hasOnlyAir()) {
2021-06-11 14:02:28 +02:00
+ return Blocks.AIR.defaultBlockState();
+ }
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
+ return this.sections[i].states.get((y & 15) << 8 | (z & 15) << 4 | x & 15);
2023-03-23 22:57:03 +01:00
2021-06-11 14:02:28 +02:00
+ }
+
+ public BlockState getBlockState_unused(int i, int j, int k) {
2021-06-11 14:02:28 +02:00
+ // Paper end
2021-06-12 04:24:43 +02:00
if (this.level.isDebug()) {
2021-06-11 14:02:28 +02:00
BlockState iblockdata = null;
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
2023-06-07 20:49:17 +02:00
index d59392c322936ce89b759ac9787c8f4f0b228af6..2c3ea88bac229df67bd742e16d2106d80bcc8889 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
2023-06-07 20:49:17 +02:00
@@ -19,7 +19,7 @@ public class LevelChunkSection {
public static final int SECTION_HEIGHT = 16;
2021-06-12 04:24:43 +02:00
public static final int SECTION_SIZE = 4096;
2021-11-23 13:15:10 +01:00
public static final int BIOME_CONTAINER_BITS = 2;
2021-06-11 14:02:28 +02:00
- private short nonEmptyBlockCount;
+ short nonEmptyBlockCount; // Paper - package-private
private short tickingBlockCount;
private short tickingFluidCount;
2021-11-23 13:15:10 +01:00
public final PalettedContainer<BlockState> states;
2021-06-11 14:02:28 +02:00
diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
2023-06-07 20:49:17 +02:00
index b2c0c7fd06fcd720b4c0875f08a90b6b672c96b2..6c72eb36020bc05104b21e52cea89de09b85f2d7 100644
2021-06-11 14:02:28 +02:00
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
2023-06-07 20:49:17 +02:00
@@ -92,14 +92,18 @@ public class ProtoChunk extends ChunkAccess {
2021-06-11 14:02:28 +02:00
@Override
public BlockState getBlockState(BlockPos pos) {
- int i = pos.getY();
2021-06-12 04:24:43 +02:00
- if (this.isOutsideBuildHeight(i)) {
+ // Paper start
+ return getBlockState(pos.getX(), pos.getY(), pos.getZ());
2021-06-11 14:02:28 +02:00
+ }
+ public BlockState getBlockState(final int x, final int y, final int z) {
2021-06-12 04:24:43 +02:00
+ if (this.isOutsideBuildHeight(y)) {
2021-06-11 14:02:28 +02:00
return Blocks.VOID_AIR.defaultBlockState();
} else {
2021-11-23 13:15:10 +01:00
- LevelChunkSection levelChunkSection = this.getSection(this.getSectionIndex(i));
- return levelChunkSection.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : levelChunkSection.getBlockState(pos.getX() & 15, i & 15, pos.getZ() & 15);
+ LevelChunkSection levelChunkSection = this.getSections()[this.getSectionIndex(y)];
+ return levelChunkSection.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : levelChunkSection.getBlockState(x & 15, y & 15, z & 15);
2021-06-11 14:02:28 +02:00
}
}
+ // Paper end
@Override
public FluidState getFluidState(BlockPos pos) {