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 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/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/core/Vec3i.java +++ b/src/main/java/net/minecraft/core/Vec3i.java @@ -0,0 +0,0 @@ public class Vec3i implements Comparable { private int y;public final void setY(final int y) { this.y = y; } // Paper - OBFHELPER private int z;public final void setZ(final int z) { this.z = 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 y < 0 || y >= 256; + } + // 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 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/Level.java +++ b/src/main/java/net/minecraft/world/level/Level.java @@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable { } public static boolean isInWorldBounds(BlockPos pos) { - return !isOutsideBuildHeight(pos) && isInWorldBoundsHorizontal(pos); + return pos.isValidLocation(); // Paper - use better/optimized check } 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 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java @@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager; public interface ChunkAccess extends BlockGetter, FeatureAccess { + BlockState getType(final int x, final int y, final int z); // Paper @Nullable BlockState setBlockState(BlockPos pos, BlockState state, boolean moved); diff --git a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java @@ -0,0 +0,0 @@ import net.minecraft.world.phys.AABB; public class EmptyLevelChunk extends LevelChunk { - private static final Biome[] BIOMES = (Biome[]) Util.make((Object) (new Biome[ChunkBiomeContainer.BIOMES_SIZE]), (abiomebase) -> { + private static final Biome[] BIOMES = Util.make((new Biome[ChunkBiomeContainer.BIOMES_SIZE]), (abiomebase) -> { // Paper - decompile error Arrays.fill(abiomebase, Biomes.PLAINS); }); @@ -0,0 +0,0 @@ public class EmptyLevelChunk extends LevelChunk { super(world, pos, new ChunkBiomeContainer(world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), EmptyLevelChunk.BIOMES)); } + // Paper start + @Override public BlockState getType(int x, int y, int z) { + 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 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java @@ -0,0 +0,0 @@ public class ImposterProtoChunk extends ProtoChunk { public BlockState getBlockState(BlockPos pos) { return this.wrapped.getBlockState(pos); } + // Paper start + public final BlockState getType(final int x, final int y, final int z) { + return this.wrapped.getBlockData(x, y, z); + } + // 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 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java @@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess { return this.sections; } - @Override + // Paper start - Optimize getBlockData to reduce instructions + public final BlockState getBlockData(BlockPos pos) { return getBlockData(pos.getX(), pos.getY(), pos.getZ()); } // Paper public BlockState getBlockState(BlockPos pos) { - int i = pos.getX(); - int j = pos.getY(); - int k = pos.getZ(); + return this.getBlockData(pos.getX(), pos.getY(), pos.getZ()); + } + public BlockState getType(final int x, final int y, final int z) { + return getBlockData(x, y, z); + } + public final BlockState 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.defaultBlockState(); + } + // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int) + return this.sections[i].states.get((y & 15) << 8 | (z & 15) << 4 | x & 15); + } + + public BlockState getBlockData_unused(int i, int j, int k) { + // Paper end if (this.world.isDebug()) { 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 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java @@ -0,0 +0,0 @@ public class LevelChunkSection { public static final Palette GLOBAL_BLOCKSTATE_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState()); private final int bottomBlockY; - private short nonEmptyBlockCount; + short nonEmptyBlockCount; // Paper - package-private private short tickingBlockCount; private short tickingFluidCount; - private final PalettedContainer states; + final PalettedContainer states; // Paper - package-private public LevelChunkSection(int yOffset) { this(yOffset, (short) 0, (short) 0, (short) 0); @@ -0,0 +0,0 @@ public class LevelChunkSection { this.states = new PalettedContainer<>(LevelChunkSection.GLOBAL_BLOCKSTATE_PALETTE, Block.BLOCK_STATE_REGISTRY, NbtUtils::readBlockState, NbtUtils::writeBlockState, Blocks.AIR.defaultBlockState()); } - public BlockState getBlockState(int x, int y, int z) { - return (BlockState) this.states.get(x, y, z); + public final BlockState getBlockState(int x, int y, int z) { // Paper + return this.states.get(y << 8 | z << 4 | x); // Paper - inline } public FluidState getFluidState(int x, int y, int z) { diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java @@ -0,0 +0,0 @@ public class PalettedContainer implements PaletteResize { } public T get(int x, int y, int z) { - return this.get(getIndex(x, y, z)); + return this.get(y << 8 | z << 4 | x); // Paper - inline } protected T get(int index) { 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java @@ -0,0 +0,0 @@ public class ProtoChunk implements ChunkAccess { @Override public BlockState getBlockState(BlockPos pos) { - int i = pos.getY(); - - if (Level.isOutsideBuildHeight(i)) { + return getType(pos.getX(), pos.getY(), pos.getZ()); + } + // Paper start + public BlockState getType(final int x, final int y, final int z) { + if (y < 0 || y >= 256) { return Blocks.VOID_AIR.defaultBlockState(); } else { - LevelChunkSection chunksection = this.getSections()[i >> 4]; - - return LevelChunkSection.isEmpty(chunksection) ? Blocks.AIR.defaultBlockState() : chunksection.getBlockState(pos.getX() & 15, i & 15, pos.getZ() & 15); + LevelChunkSection chunksection = this.getSections()[y >> 4]; + return chunksection == LevelChunk.EMPTY_CHUNK_SECTION || chunksection.isEmpty() ? Blocks.AIR.defaultBlockState() : chunksection.getBlockState(x & 15, y & 15, z & 15); } } + // Paper end @Override public FluidState getFluidState(BlockPos pos) {