Add some relatively safe allocation optimizations for worldgen
This commit is contained in:
parent
1ec9aad47f
commit
2193aa11a4
|
|
@ -19,6 +19,7 @@ import javax.annotation.processing.SupportedOptions;
|
|||
import javax.lang.model.SourceVersion;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.util.Elements;
|
||||
import javax.tools.Diagnostic;
|
||||
|
||||
import org.fury_phoenix.mixinAp.config.MixinConfig;
|
||||
|
|
@ -80,7 +81,7 @@ public class MixinProcessor extends AbstractProcessor {
|
|||
List<String> mixins =
|
||||
annotatedMixins.stream()
|
||||
.map(TypeElement.class::cast)
|
||||
.map(TypeElement::toString)
|
||||
.map(e -> processingEnv.getElementUtils().getBinaryName(e).toString())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
mixinConfigList.putIfAbsent(aliases.get(annotation.getSimpleName().toString()), mixins);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public record MixinConfig(
|
|||
@SerializedName("package")
|
||||
String packageName,
|
||||
String plugin,
|
||||
String compatabilityLevel,
|
||||
String compatibilityLevel,
|
||||
@SerializedName("mixins")
|
||||
List<String> commonMixins,
|
||||
@SerializedName("client")
|
||||
|
|
@ -25,7 +25,7 @@ public record MixinConfig(
|
|||
InjectorOptions injectors, OverwriteOptions overwrites
|
||||
) {
|
||||
public MixinConfig(String packageName, List<String> commonMixins, List<String> clientMixins) {
|
||||
this(true, "0.8", packageName, "org.embeddedt.modernfix.core.ModernFixMixinPlugin", "JAVA_8",
|
||||
this(true, "0.8", packageName, "org.embeddedt.modernfix.core.ModernFixMixinPlugin", "JAVA_17",
|
||||
commonMixins, clientMixins, InjectorOptions.DEFAULT, OverwriteOptions.DEFAULT);
|
||||
}
|
||||
public record InjectorOptions(int defaultRequire) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
||||
import net.minecraft.world.level.levelgen.material.MaterialRuleList;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(value = MaterialRuleList.class, priority = 100)
|
||||
public class MaterialRuleListMixin {
|
||||
@Shadow @Final private List<NoiseChunk.BlockStateFiller> materialRuleList;
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason Avoid iterator allocation
|
||||
*/
|
||||
@Overwrite
|
||||
@Nullable
|
||||
public BlockState calculate(DensityFunction.FunctionContext arg) {
|
||||
BlockState state = null;
|
||||
int s = this.materialRuleList.size();
|
||||
for(int i = 0; state == null && i < s; i++) {
|
||||
NoiseChunk.BlockStateFiller blockStateFiller = this.materialRuleList.get(i);
|
||||
state = blockStateFiller.calculate(arg);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
import net.minecraft.world.level.levelgen.NoiseChunk;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(value = NoiseChunk.class, priority = 100)
|
||||
public abstract class NoiseChunkMixin {
|
||||
@Shadow @Final @Mutable
|
||||
private Map<DensityFunction, DensityFunction> wrapped = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
@Shadow protected abstract DensityFunction wrapNew(DensityFunction densityFunction);
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason Avoid lambda allocation
|
||||
*/
|
||||
@Overwrite
|
||||
protected DensityFunction wrap(DensityFunction unwrapped) {
|
||||
DensityFunction func = this.wrapped.get(unwrapped);
|
||||
if (func == null) {
|
||||
func = this.wrapNew(unwrapped);
|
||||
this.wrapped.put(unwrapped, func);
|
||||
}
|
||||
return func;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
|
||||
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.SurfaceRules;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(value = SurfaceRules.SequenceRule.class, priority = 100)
|
||||
public class SequenceRuleMixin {
|
||||
@Shadow @Final private List<SurfaceRules.SurfaceRule> rules;
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason Avoid iterator allocation
|
||||
*/
|
||||
@Overwrite
|
||||
public BlockState tryApply(int x, int y, int z) {
|
||||
int s = this.rules.size();
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for(int i = 0; i < s; i++) {
|
||||
BlockState state = this.rules.get(i).tryApply(x, y, z);
|
||||
if(state != null) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import org.embeddedt.modernfix.world.gen.PositionalBiomeGetter;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(targets = {"net/minecraft/world/level/levelgen/SurfaceRules$Context"}, priority = 100)
|
||||
public class SurfaceRulesContextMixin {
|
||||
@Shadow private long lastUpdateY;
|
||||
|
||||
@Shadow private int blockY;
|
||||
|
||||
@Shadow private int waterHeight;
|
||||
|
||||
@Shadow private int stoneDepthBelow;
|
||||
|
||||
@Shadow private int stoneDepthAbove;
|
||||
|
||||
@Shadow private Supplier<Holder<Biome>> biome;
|
||||
|
||||
@Shadow @Final private Function<BlockPos, Holder<Biome>> biomeGetter;
|
||||
|
||||
@Shadow @Final private BlockPos.MutableBlockPos pos;
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason Reuse supplier object instead of creating new ones every time
|
||||
*/
|
||||
@Overwrite
|
||||
protected void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockX, int blockY, int blockZ) {
|
||||
++this.lastUpdateY;
|
||||
var getter = this.biome;
|
||||
if(getter == null) {
|
||||
this.biome = getter = new PositionalBiomeGetter(this.biomeGetter, this.pos);
|
||||
}
|
||||
((PositionalBiomeGetter)getter).update(blockX, blockY, blockZ);
|
||||
this.blockY = blockY;
|
||||
this.waterHeight = waterHeight;
|
||||
this.stoneDepthBelow = stoneDepthBelow;
|
||||
this.stoneDepthAbove = stoneDepthAbove;
|
||||
}
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ public class ModernFixEarlyConfig {
|
|||
mixinOptions.add(mixinCategoryName);
|
||||
}
|
||||
} catch(IOException e) {
|
||||
ModernFix.LOGGER.error("Error scanning file " + mixinPath, e);
|
||||
LOGGER.error("Error scanning file " + mixinPath, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package org.embeddedt.modernfix.world.gen;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class PositionalBiomeGetter implements Supplier<Holder<Biome>> {
|
||||
private final Function<BlockPos, Holder<Biome>> biomeGetter;
|
||||
private final BlockPos.MutableBlockPos pos;
|
||||
private int nextX, nextY, nextZ;
|
||||
private volatile Holder<Biome> curBiome;
|
||||
|
||||
public PositionalBiomeGetter(Function<BlockPos, Holder<Biome>> biomeGetter, BlockPos.MutableBlockPos pos) {
|
||||
this.biomeGetter = biomeGetter;
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
public void update(int nextX, int nextY, int nextZ) {
|
||||
this.nextX = nextX;
|
||||
this.nextY = nextY;
|
||||
this.nextZ = nextZ;
|
||||
this.curBiome = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<Biome> get() {
|
||||
var biome = curBiome;
|
||||
if(biome == null) {
|
||||
curBiome = biome = biomeGetter.apply(pos.set(nextX, nextY, nextZ));
|
||||
}
|
||||
return biome;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,18 @@ accessible field net/minecraft/world/level/Level blockEntityTickers Ljava/util/L
|
|||
accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType
|
||||
accessible method net/minecraft/nbt/CompoundTag <init> (Ljava/util/Map;)V
|
||||
|
||||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRule
|
||||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SurfaceRule
|
||||
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Marker
|
||||
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Marker$Type
|
||||
accessible method net/minecraft/world/level/levelgen/DensityFunctions$Marker <init> (Lnet/minecraft/world/level/levelgen/DensityFunctions$Marker$Type;Lnet/minecraft/world/level/levelgen/DensityFunction;)V
|
||||
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Mapped
|
||||
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Mapped$Type
|
||||
accessible method net/minecraft/world/level/levelgen/DensityFunctions$Mapped <init> (Lnet/minecraft/world/level/levelgen/DensityFunctions$Mapped$Type;Lnet/minecraft/world/level/levelgen/DensityFunction;DD)V
|
||||
accessible class net/minecraft/world/level/levelgen/DensityFunctions$MulOrAdd
|
||||
accessible class net/minecraft/world/level/levelgen/DensityFunctions$MulOrAdd$Type
|
||||
accessible method net/minecraft/world/level/levelgen/DensityFunctions$MulOrAdd <init> (Lnet/minecraft/world/level/levelgen/DensityFunctions$MulOrAdd$Type;Lnet/minecraft/world/level/levelgen/DensityFunction;DDD)V
|
||||
|
||||
accessible class net/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache
|
||||
accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
|
||||
accessible field net/minecraft/world/level/block/state/BlockBehaviour properties Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ diagonal_fences_version=4558828
|
|||
|
||||
spark_version=4587310
|
||||
|
||||
use_fabric_api_at_runtime=true
|
||||
use_fabric_api_at_runtime=false
|
||||
|
||||
# Look up maven coordinates when changing shadow_version
|
||||
shadow_version=7.1.2
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user