From f5b994768f2adc7fdc9c05a140cf9f44bcac22a4 Mon Sep 17 00:00:00 2001 From: Taiyou06 Date: Sat, 6 Jul 2024 23:59:45 +0300 Subject: [PATCH] inline world height and reduce alloc more remove entity tracker alloc mixin --- .../entity_tracker/EntityTrackerMixin.java | 17 ++- .../math/fast_blockops/BlockPosMixin.java | 127 ++++++++++++++++++ .../math/fast_blockops/DirectionMixin.java | 54 ++++++++ .../world/inline_height/WorldChunkMixin.java | 62 +++++++++ .../mixin/world/inline_height/WorldMixin.java | 99 ++++++++++++++ src/main/resources/mixins.core.json | 5 +- 6 files changed, 354 insertions(+), 10 deletions(-) create mode 100644 src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/BlockPosMixin.java create mode 100644 src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/DirectionMixin.java create mode 100644 src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldChunkMixin.java create mode 100644 src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldMixin.java diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/alloc/entity_tracker/EntityTrackerMixin.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/alloc/entity_tracker/EntityTrackerMixin.java index 2fe201a..1e46646 100644 --- a/src/main/java/net/gensokyoreimagined/nitori/mixin/alloc/entity_tracker/EntityTrackerMixin.java +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/alloc/entity_tracker/EntityTrackerMixin.java @@ -1,4 +1,4 @@ -//package net.gensokyoreimagined.nitori.mixin.alloc; +//package net.gensokyoreimagined.nitori.mixin.alloc.entity_tracker; // //import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; //import net.minecraft.server.network.ServerPlayerConnection; @@ -7,24 +7,23 @@ //import org.spongepowered.asm.mixin.injection.At; //import org.spongepowered.asm.mixin.injection.Redirect; // -//import java.util.Set; -// //@Mixin(ChunkMap.TrackedEntity.class) //public class EntityTrackerMixin { // // /** -// * Uses less memory, and will cache the returned iterator. +// * Uses less memory and will cache the returned iterator. // */ // @Redirect( // method = "", -// require = 0, // at = @At( -// value = "INVOKE", -// target = "Lit/unimi/dsi/fastutil/objects/ReferenceOpenHashSet;()V", +// value = "NEW", +// target = "it/unimi/dsi/fastutil/objects/ReferenceOpenHashSet", // remap = false // ) // ) -// private Set useFasterCollection() { +// private ReferenceOpenHashSet useFasterCollection() { // return new ReferenceOpenHashSet<>(); // } -//} \ No newline at end of file +//} + +//paper has this \ No newline at end of file diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/BlockPosMixin.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/BlockPosMixin.java new file mode 100644 index 0000000..62ce3ec --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/BlockPosMixin.java @@ -0,0 +1,127 @@ +package net.gensokyoreimagined.nitori.mixin.math.fast_blockops; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + + +@Mixin(BlockPos.class) +public abstract class BlockPosMixin extends Vec3i { + + public BlockPosMixin(int x, int y, int z) { + super(x, y, z); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Override + @Overwrite + public BlockPos above() { + return new BlockPos(this.getX(), this.getY() + 1, this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Override + @Overwrite + public BlockPos above(int distance) { + return new BlockPos(this.getX(), this.getY() + distance, this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Override + @Overwrite + public BlockPos below() { + return new BlockPos(this.getX(), this.getY() - 1, this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Override + @Overwrite + public BlockPos below(int distance) { + return new BlockPos(this.getX(), this.getY() - distance, this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos north() { + return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos north(int distance) { + return new BlockPos(this.getX(), this.getY(), this.getZ() - distance); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos south() { + return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos south(int distance) { + return new BlockPos(this.getX(), this.getY(), this.getZ() + distance); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos west() { + return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos west(int distance) { + return new BlockPos(this.getX() - distance, this.getY(), this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos east() { + return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); + } + + /** + * @author JellySquid + * @reason Simplify and inline + */ + @Overwrite + public BlockPos east(int distance) { + return new BlockPos(this.getX() + distance, this.getY(), this.getZ()); + } +} \ No newline at end of file diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/DirectionMixin.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/DirectionMixin.java new file mode 100644 index 0000000..6f41cff --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/math/fast_blockops/DirectionMixin.java @@ -0,0 +1,54 @@ +package net.gensokyoreimagined.nitori.mixin.math.fast_blockops; + +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * The vector of each Direction is usually stored inside another object, which introduces indirection and makes things + * harder for the JVM to optimize. This patch simply hoists the offset fields to the Direction enum itself. + */ +@Mixin(Direction.class) +public class DirectionMixin { + @Unique + private int nitori$getStepX, nitori$getStepY, nitori$getStepZ; + + @Inject(method = "", at = @At("RETURN")) + private void reinit(String enumName, int ordinal, int id, int idOpposite, int idHorizontal, String name, Direction.AxisDirection direction, Direction.Axis axis, Vec3i vector, CallbackInfo ci) { + this.nitori$getStepX = vector.getX(); + this.nitori$getStepY = vector.getY(); + this.nitori$getStepZ = vector.getZ(); + } + + /** + * @reason Avoid indirection to aid inlining + * @author JellySquid + */ + @Overwrite + public int getStepX() { + return this.nitori$getStepX; + } + + /** + * @reason Avoid indirection to aid inlining + * @author JellySquid + */ + @Overwrite + public int getStepY() { + return this.nitori$getStepY; + } + + /** + * @reason Avoid indirection to aid inlining + * @author JellySquid + */ + @Overwrite + public int getStepZ() { + return this.nitori$getStepZ; + } +} \ No newline at end of file diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldChunkMixin.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldChunkMixin.java new file mode 100644 index 0000000..b4c20f9 --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldChunkMixin.java @@ -0,0 +1,62 @@ +package net.gensokyoreimagined.nitori.mixin.world.inline_height; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.chunk.LevelChunk; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(LevelChunk.class) +public abstract class WorldChunkMixin implements LevelHeightAccessor { + + @Shadow + @Final + Level level; + + @Override + public int getMaxBuildHeight() { + return this.level.getMaxBuildHeight(); + } + + @Override + public int getSectionsCount() { + return this.level.getSectionsCount(); + } + + @Override + public int getMinSection() { + return this.level.getMinSection(); + } + + @Override + public int getMaxSection() { + return this.level.getMaxSection(); + } + + @Override + public boolean isOutsideBuildHeight(BlockPos pos) { + return this.level.isOutsideBuildHeight(pos); + } + + @Override + public boolean isOutsideBuildHeight(int y) { + return this.level.isOutsideBuildHeight(y); + } + + @Override + public int getSectionIndex(int y) { + return this.level.getSectionIndex(y); + } + + @Override + public int getSectionIndexFromSectionY(int coord) { + return this.level.getSectionIndexFromSectionY(coord); + } + + @Override + public int getSectionYFromSectionIndex(int index) { + return this.level.getSectionYFromSectionIndex(index); + } +} \ No newline at end of file diff --git a/src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldMixin.java b/src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldMixin.java new file mode 100644 index 0000000..b7c6484 --- /dev/null +++ b/src/main/java/net/gensokyoreimagined/nitori/mixin/world/inline_height/WorldMixin.java @@ -0,0 +1,99 @@ +//package net.gensokyoreimagined.nitori.mixin.world.inline_height; +// +//import net.minecraft.core.RegistryAccess; +//import net.minecraft.resources.ResourceKey; +//import net.minecraft.core.Holder; +//import net.minecraft.core.BlockPos; +//import net.minecraft.world.level.LevelHeightAccessor; +//import net.minecraft.world.level.storage.WritableLevelData; +//import net.minecraft.world.level.Level; +//import net.minecraft.world.level.dimension.DimensionType; +//import org.spongepowered.asm.mixin.Mixin; +//import org.spongepowered.asm.mixin.Unique; +//import org.spongepowered.asm.mixin.injection.At; +//import org.spongepowered.asm.mixin.injection.Inject; +//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +// +//import java.util.function.Supplier; +// +///** +// * Implement world height related methods directly instead of going through WorldView and Dimension +// */ +//@Mixin(Level.class) +//public abstract class WorldMixin implements LevelHeightAccessor { +// @Unique +// private int nitori$getMinBuildHeight; +// @Unique +// private int nitori$getHeight; +// @Unique +// private int nitori$getSectionsCount; +// +// @Inject( +// method = "", +// at = @At("RETURN") +// ) +// private void initHeightCache(WritableLevelData properties, ResourceKey registryRef, RegistryAccess registryManager, Holder dimensionEntry, Supplier profiler, boolean isClient, boolean debugWorld, long biomeAccess, int maxChainedNeighborUpdates, CallbackInfo ci) { +// this.nitori$getHeight = dimensionEntry.value().height(); +// this.nitori$getMinBuildHeight = dimensionEntry.value().minY(); +// this.nitori$getSectionsCount = this.nitori$getMinBuildHeight + this.nitori$getHeight - 1; +// } +// +// @Override +// public int getHeight() { +// return this.nitori$getHeight; +// } +// +// @Override +// public int getMinBuildHeight() { +// return this.nitori$getMinBuildHeight; +// } +// +// @Override +// public int getSectionsCount() { +// return ((this.nitori$getSectionsCount >> 4) + 1) - (this.nitori$getMinBuildHeight >> 4); +// } +// +// @Override +// public int getMinSection() { +// return this.nitori$getMinBuildHeight >> 4; +// } +// +// @Override +// public int getMaxSection() { +// return (this.nitori$getSectionsCount >> 4) + 1; +// } +// +// @Override +// public boolean isOutsideBuildHeight(BlockPos pos) { +// int y = pos.getY(); +// return (y < this.nitori$getMinBuildHeight) || (y > this.nitori$getSectionsCount); +// } +// +// @Override +// public boolean isOutsideBuildHeight(int y) { +// return (y < this.nitori$getMinBuildHeight) || (y > this.nitori$getSectionsCount); +// } +// +// @Override +// public int getSectionIndex(int y) { +// return (y >> 4) - (this.nitori$getMinBuildHeight >> 4); +// } +// +// @Override +// public int getSectionIndexFromSectionY(int coord) { +// return coord - (this.nitori$getMinBuildHeight >> 4); +// +// } +// +// @Override +// public int getSectionYFromSectionIndex(int index) { +// return index + (this.nitori$getMinBuildHeight >> 4); +// } +// +// @Override +// public int getMaxBuildHeight() { +// return this.nitori$getSectionsCount + 1; +// } +//} + +//im stupid, couldn't figure out why initHeightCache is dying \ No newline at end of file diff --git a/src/main/resources/mixins.core.json b/src/main/resources/mixins.core.json index b18f9c8..e283bfa 100755 --- a/src/main/resources/mixins.core.json +++ b/src/main/resources/mixins.core.json @@ -34,6 +34,9 @@ "alloc.blockstate.StateMixin", "util.MixinLevelBlockEntityRetrieval", "cached_hashcode.BlockNeighborGroupMixin", - "shapes.blockstate_cache.BlockMixin" + "shapes.blockstate_cache.BlockMixin", + "world.inline_height.WorldChunkMixin", + "math.fast_blockops.DirectionMixin", + "math.fast_blockops.BlockPosMixin" ] }