Skip to content

Commit 2193aa1

Browse files
committed
Add some relatively safe allocation optimizations for worldgen
1 parent 1ec9aad commit 2193aa1

File tree

10 files changed

+204
-5
lines changed

10 files changed

+204
-5
lines changed

annotation-processor/src/main/java/org/fury_phoenix/mixinAp/annotation/MixinProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import javax.lang.model.SourceVersion;
2020
import javax.lang.model.element.Element;
2121
import javax.lang.model.element.TypeElement;
22+
import javax.lang.model.util.Elements;
2223
import javax.tools.Diagnostic;
2324

2425
import org.fury_phoenix.mixinAp.config.MixinConfig;
@@ -80,7 +81,7 @@ private void processMixins(Set<? extends TypeElement> annotations, RoundEnvironm
8081
List<String> mixins =
8182
annotatedMixins.stream()
8283
.map(TypeElement.class::cast)
83-
.map(TypeElement::toString)
84+
.map(e -> processingEnv.getElementUtils().getBinaryName(e).toString())
8485
.collect(Collectors.toList());
8586

8687
mixinConfigList.putIfAbsent(aliases.get(annotation.getSimpleName().toString()), mixins);

annotation-processor/src/main/java/org/fury_phoenix/mixinAp/config/MixinConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ public record MixinConfig(
1717
@SerializedName("package")
1818
String packageName,
1919
String plugin,
20-
String compatabilityLevel,
20+
String compatibilityLevel,
2121
@SerializedName("mixins")
2222
List<String> commonMixins,
2323
@SerializedName("client")
2424
List<String> clientMixins,
2525
InjectorOptions injectors, OverwriteOptions overwrites
2626
) {
2727
public MixinConfig(String packageName, List<String> commonMixins, List<String> clientMixins) {
28-
this(true, "0.8", packageName, "org.embeddedt.modernfix.core.ModernFixMixinPlugin", "JAVA_8",
28+
this(true, "0.8", packageName, "org.embeddedt.modernfix.core.ModernFixMixinPlugin", "JAVA_17",
2929
commonMixins, clientMixins, InjectorOptions.DEFAULT, OverwriteOptions.DEFAULT);
3030
}
3131
public record InjectorOptions(int defaultRequire) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import net.minecraft.world.level.block.state.BlockState;
4+
import net.minecraft.world.level.levelgen.DensityFunction;
5+
import net.minecraft.world.level.levelgen.NoiseChunk;
6+
import net.minecraft.world.level.levelgen.material.MaterialRuleList;
7+
import org.jetbrains.annotations.Nullable;
8+
import org.spongepowered.asm.mixin.Final;
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.Overwrite;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
13+
import java.util.List;
14+
15+
@Mixin(value = MaterialRuleList.class, priority = 100)
16+
public class MaterialRuleListMixin {
17+
@Shadow @Final private List<NoiseChunk.BlockStateFiller> materialRuleList;
18+
19+
/**
20+
* @author embeddedt
21+
* @reason Avoid iterator allocation
22+
*/
23+
@Overwrite
24+
@Nullable
25+
public BlockState calculate(DensityFunction.FunctionContext arg) {
26+
BlockState state = null;
27+
int s = this.materialRuleList.size();
28+
for(int i = 0; state == null && i < s; i++) {
29+
NoiseChunk.BlockStateFiller blockStateFiller = this.materialRuleList.get(i);
30+
state = blockStateFiller.calculate(arg);
31+
}
32+
return state;
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
4+
import net.minecraft.world.level.levelgen.DensityFunction;
5+
import net.minecraft.world.level.levelgen.NoiseChunk;
6+
import org.spongepowered.asm.mixin.Final;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.Mutable;
9+
import org.spongepowered.asm.mixin.Overwrite;
10+
import org.spongepowered.asm.mixin.Shadow;
11+
12+
import java.util.Map;
13+
14+
@Mixin(value = NoiseChunk.class, priority = 100)
15+
public abstract class NoiseChunkMixin {
16+
@Shadow @Final @Mutable
17+
private Map<DensityFunction, DensityFunction> wrapped = new Object2ObjectOpenHashMap<>();
18+
19+
@Shadow protected abstract DensityFunction wrapNew(DensityFunction densityFunction);
20+
21+
/**
22+
* @author embeddedt
23+
* @reason Avoid lambda allocation
24+
*/
25+
@Overwrite
26+
protected DensityFunction wrap(DensityFunction unwrapped) {
27+
DensityFunction func = this.wrapped.get(unwrapped);
28+
if (func == null) {
29+
func = this.wrapNew(unwrapped);
30+
this.wrapped.put(unwrapped, func);
31+
}
32+
return func;
33+
}
34+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import net.minecraft.world.level.block.state.BlockState;
4+
import net.minecraft.world.level.levelgen.SurfaceRules;
5+
import org.spongepowered.asm.mixin.Final;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.Overwrite;
8+
import org.spongepowered.asm.mixin.Shadow;
9+
10+
import java.util.List;
11+
12+
@Mixin(value = SurfaceRules.SequenceRule.class, priority = 100)
13+
public class SequenceRuleMixin {
14+
@Shadow @Final private List<SurfaceRules.SurfaceRule> rules;
15+
16+
/**
17+
* @author embeddedt
18+
* @reason Avoid iterator allocation
19+
*/
20+
@Overwrite
21+
public BlockState tryApply(int x, int y, int z) {
22+
int s = this.rules.size();
23+
//noinspection ForLoopReplaceableByForEach
24+
for(int i = 0; i < s; i++) {
25+
BlockState state = this.rules.get(i).tryApply(x, y, z);
26+
if(state != null) {
27+
return state;
28+
}
29+
}
30+
return null;
31+
}
32+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Holder;
5+
import net.minecraft.world.level.biome.Biome;
6+
import org.embeddedt.modernfix.world.gen.PositionalBiomeGetter;
7+
import org.spongepowered.asm.mixin.Final;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Overwrite;
10+
import org.spongepowered.asm.mixin.Shadow;
11+
12+
import java.util.function.Function;
13+
import java.util.function.Supplier;
14+
15+
@Mixin(targets = {"net/minecraft/world/level/levelgen/SurfaceRules$Context"}, priority = 100)
16+
public class SurfaceRulesContextMixin {
17+
@Shadow private long lastUpdateY;
18+
19+
@Shadow private int blockY;
20+
21+
@Shadow private int waterHeight;
22+
23+
@Shadow private int stoneDepthBelow;
24+
25+
@Shadow private int stoneDepthAbove;
26+
27+
@Shadow private Supplier<Holder<Biome>> biome;
28+
29+
@Shadow @Final private Function<BlockPos, Holder<Biome>> biomeGetter;
30+
31+
@Shadow @Final private BlockPos.MutableBlockPos pos;
32+
33+
/**
34+
* @author embeddedt
35+
* @reason Reuse supplier object instead of creating new ones every time
36+
*/
37+
@Overwrite
38+
protected void updateY(int stoneDepthAbove, int stoneDepthBelow, int waterHeight, int blockX, int blockY, int blockZ) {
39+
++this.lastUpdateY;
40+
var getter = this.biome;
41+
if(getter == null) {
42+
this.biome = getter = new PositionalBiomeGetter(this.biomeGetter, this.pos);
43+
}
44+
((PositionalBiomeGetter)getter).update(blockX, blockY, blockZ);
45+
this.blockY = blockY;
46+
this.waterHeight = waterHeight;
47+
this.stoneDepthBelow = stoneDepthBelow;
48+
this.stoneDepthAbove = stoneDepthAbove;
49+
}
50+
}

common/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ else if(isClientOnly && !ModernFixPlatformHooks.INSTANCE.isClient())
139139
mixinOptions.add(mixinCategoryName);
140140
}
141141
} catch(IOException e) {
142-
ModernFix.LOGGER.error("Error scanning file " + mixinPath, e);
142+
LOGGER.error("Error scanning file " + mixinPath, e);
143143
}
144144
}
145145
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.embeddedt.modernfix.world.gen;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.Holder;
5+
import net.minecraft.world.level.biome.Biome;
6+
7+
import java.util.function.Function;
8+
import java.util.function.Supplier;
9+
10+
public class PositionalBiomeGetter implements Supplier<Holder<Biome>> {
11+
private final Function<BlockPos, Holder<Biome>> biomeGetter;
12+
private final BlockPos.MutableBlockPos pos;
13+
private int nextX, nextY, nextZ;
14+
private volatile Holder<Biome> curBiome;
15+
16+
public PositionalBiomeGetter(Function<BlockPos, Holder<Biome>> biomeGetter, BlockPos.MutableBlockPos pos) {
17+
this.biomeGetter = biomeGetter;
18+
this.pos = pos;
19+
}
20+
21+
public void update(int nextX, int nextY, int nextZ) {
22+
this.nextX = nextX;
23+
this.nextY = nextY;
24+
this.nextZ = nextZ;
25+
this.curBiome = null;
26+
}
27+
28+
@Override
29+
public Holder<Biome> get() {
30+
var biome = curBiome;
31+
if(biome == null) {
32+
curBiome = biome = biomeGetter.apply(pos.set(nextX, nextY, nextZ));
33+
}
34+
return biome;
35+
}
36+
}

common/src/main/resources/modernfix.accesswidener

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@ accessible field net/minecraft/world/level/Level blockEntityTickers Ljava/util/L
1111
accessible class net/minecraft/client/renderer/RenderType$CompositeRenderType
1212
accessible method net/minecraft/nbt/CompoundTag <init> (Ljava/util/Map;)V
1313

14+
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRule
15+
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SurfaceRule
16+
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Marker
17+
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Marker$Type
18+
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
19+
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Mapped
20+
accessible class net/minecraft/world/level/levelgen/DensityFunctions$Mapped$Type
21+
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
22+
accessible class net/minecraft/world/level/levelgen/DensityFunctions$MulOrAdd
23+
accessible class net/minecraft/world/level/levelgen/DensityFunctions$MulOrAdd$Type
24+
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
25+
1426
accessible class net/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase$Cache
1527
accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
1628
accessible field net/minecraft/world/level/block/state/BlockBehaviour properties Lnet/minecraft/world/level/block/state/BlockBehaviour$Properties;

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ diagonal_fences_version=4558828
2727

2828
spark_version=4587310
2929

30-
use_fabric_api_at_runtime=true
30+
use_fabric_api_at_runtime=false
3131

3232
# Look up maven coordinates when changing shadow_version
3333
shadow_version=7.1.2

0 commit comments

Comments
 (0)