Skip to content

Commit

Permalink
Various Optimizations (#455)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchej123 authored Dec 27, 2024
1 parent e90ecf2 commit 16ed4e0
Show file tree
Hide file tree
Showing 29 changed files with 1,154 additions and 5 deletions.
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ dependencies {
transformedModCompileOnly(deobf("https://forum.industrial-craft.net/core/attachment/4316-advancedsolarpanel-1-7-10-3-5-1-jar/"))
transformedModCompileOnly(rfg.deobf("curse.maven:candycraft-251118:2330488"))

runtimeOnly(deobf("https://github.com/makamys/CoreTweaks/releases/download/0.3.3.2/CoreTweaks-1.7.10-0.3.3.2+nomixin.jar"))
devOnlyNonPublishable(deobf("https://github.com/makamys/CoreTweaks/releases/download/0.3.3.2/CoreTweaks-1.7.10-0.3.3.2+nomixin.jar"))
}

// Replace when RFG support deobfuscation from notch mappings
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/com/mitchej123/hodgepodge/asm/AsmTransformers.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Set;
import java.util.function.Supplier;

import com.google.common.collect.ImmutableList;
import com.gtnewhorizon.gtnhmixins.core.GTNHMixinsCore;
import com.mitchej123.hodgepodge.Common;
import com.mitchej123.hodgepodge.config.ASMConfig;
Expand All @@ -32,10 +33,17 @@ public enum AsmTransformers {
SPEEDUP_LONG_INT_HASHMAP(
"Speed up LongHashMap & IntHashMap",
() -> ASMConfig.speedupLongIntHashMap,
Side.CLIENT,
Side.BOTH,
null,
Collections.singletonList(TargetedMod.FASTCRAFT),
ImmutableList.of(TargetedMod.FASTCRAFT, TargetedMod.BUKKIT),
"com.mitchej123.hodgepodge.asm.transformers.mc.SpeedupLongIntHashMapTransformer"),
SPEEDUP_NBT_TAG_COMPOUND_COPY(
"Speed up NBTTagCompound.copy()",
() -> ASMConfig.speedupNBTTagCompoundCopy,
Side.BOTH,
null,
ImmutableList.of(TargetedMod.FASTCRAFT, TargetedMod.BUKKIT),
"com.mitchej123.hodgepodge.asm.transformers.mc.NBTTagCompoundHashMapTransformer"),
FIX_BOGUS_INTEGRATED_SERVER_NPE(
"Fix bogus FMLProxyPacket NPEs on integrated server crashes",
() -> FixesConfig.fixBogusIntegratedServerNPEs,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.mitchej123.hodgepodge.asm.transformers.mc;

import net.minecraft.launchwrapper.IClassTransformer;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;

@SuppressWarnings("unused")
public class NBTTagCompoundHashMapTransformer implements IClassTransformer {

private static final Logger LOGGER = LogManager.getLogger("NBTTagCompoundHashMapTransformerTransformer");
public static final String INIT = "<init>";
public static final String EMPTY_DESC = "()V";
public static final String HASHMAP = "java/util/HashMap";
public static final String FASTUTIL_HASHMAP = "it/unimi/dsi/fastutil/objects/Object2ObjectOpenHashMap";
public static final String NBT_TAG_COMPOUND = "net.minecraft.nbt.NBTTagCompound";

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
if (basicClass == null) return null;
if (!transformedName.equals(NBT_TAG_COMPOUND)) {
return basicClass;
}

final ClassReader cr = new ClassReader(basicClass);
final ClassNode cn = new ClassNode();
cr.accept(cn, 0);
final boolean changed = transformClassNode(transformedName, cn);
if (changed) {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cn.accept(cw);
return cw.toByteArray();
}
return basicClass;
}

/** @return Was the class changed? */
public boolean transformClassNode(String transformedName, ClassNode cn) {
if (cn == null) {
return false;
}

boolean changed = false;
for (MethodNode mn : cn.methods) {
if (mn.name.equals(INIT) && mn.desc.equals(EMPTY_DESC)) {
for (AbstractInsnNode node : mn.instructions.toArray()) {
if (node.getOpcode() == Opcodes.NEW && node instanceof TypeInsnNode tNode) {
if (tNode.desc.equals(HASHMAP)) {
LOGGER.info("Found HashMap instantiation in NBTTagCompound.<init>");
mn.instructions.insertBefore(tNode, new TypeInsnNode(Opcodes.NEW, FASTUTIL_HASHMAP));
mn.instructions.remove(tNode);
changed = true;
}
} else if (node.getOpcode() == Opcodes.INVOKESPECIAL && node instanceof MethodInsnNode mNode) {
if (mNode.name.equals(INIT) && mNode.desc.equals(EMPTY_DESC) && mNode.owner.equals(HASHMAP)) {
LOGGER.info("Found HashMap constructor call in NBTTagCompound.<init>");
mn.instructions.insertBefore(
mNode,
new MethodInsnNode(
Opcodes.INVOKESPECIAL,
FASTUTIL_HASHMAP,
INIT,
EMPTY_DESC,
false));
mn.instructions.remove(mNode);
changed = true;
}
}
}
}
}

return changed;
}
}
3 changes: 3 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/config/ASMConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ public class ASMConfig {
@Config.DefaultString("org.bukkit.craftbukkit.v1_7_R4.CraftServer")
public static String thermosCraftServerClass;

@Config.Comment("Speedup NBTTagCompound copy")
@Config.DefaultBoolean(true)
public static boolean speedupNBTTagCompoundCopy;
}
14 changes: 14 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/config/SpeedupsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ public class SpeedupsConfig {
@Config.RangeInt(min = 100)
public static int maxUnloadSpeed;

@Config.Comment("Speed up NBT copying")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean speedupNBTCopy;

@Config.Comment("Optimize mob spawning")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean optimizeMobSpawning;

@Config.Comment("Limit mob spawning to the view distance")
@Config.DefaultBoolean(true)
public static boolean limitMobSpawningToViewDistance;

// Biomes O' Plenty

@Config.Comment("Speedup biome fog rendering in BiomesOPlenty")
Expand Down
35 changes: 35 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/config/TweaksConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,40 @@ public class TweaksConfig {
@Config.DefaultBoolean(false)
public static boolean useLighterWater;

// NBT String Pooling

@Config.Comment("Enable string pooling for NBT TagCompound Keys")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean enableTagCompoundStringPooling;

@Config.Comment("Enable string pooling for NBT Strings - trades performance for memory")
@Config.DefaultBoolean(false)
@Config.RequiresMcRestart
public static boolean enableNBTStringPooling;

@Config.Comment("String pooling mode (0 = Java intern, 1 = Guava strong interner, 2 = Guava weak interner)")
@Config.RangeInt(min = 0, max = 2)
@Config.DefaultInt(1)
@Config.RequiresMcRestart
public static int stringPoolMode;

// Threaded WorldData Saving
@Config.Comment("Enable threaded saving for WorldData")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean threadedWorldDataSaving;

@Config.Comment("Don't sleep on threaded IO")
@Config.DefaultBoolean(true)
@Config.RequiresMcRestart
public static boolean dontSleepOnThreadedIO;

@Config.Comment({ "Save Mineshaft data (Requires threadedWorldDataSaving for changes to take effect)",
"Might cause small worldgen issues if disabled; equivalent to removing the file on each boot if disabled" })
@Config.DefaultBoolean(true)
public static boolean saveMineshaftData;

// affecting multiple mods

@Config.Comment("Unbinds keybinds of certain ARR mods to avoid keybinds conflicts")
Expand Down Expand Up @@ -272,4 +306,5 @@ public class TweaksConfig {
@Config.Comment("Avoids droping items on container close, and instead places them in the player inventory. (Inspired from EFR)")
@Config.DefaultBoolean(true)
public static boolean avoidDroppingItemsWhenClosing;

}
19 changes: 19 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/core/CoreCompat.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.mitchej123.hodgepodge.core;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.mitchej123.hodgepodge.config.TweaksConfig;

public class CoreCompat {

private static final Logger LOOGGER = LogManager.getLogger("HodgepodgeCoreCompat");

public static void disableCoretweaksConflictingMixins() {
if (TweaksConfig.threadedWorldDataSaving) {
LOOGGER.info("Disabled CoreTweaks conflicting mixin: enhanceMapStorageErrors");
makamys.coretweaks.Config.enhanceMapStorageErrors.disable();
}
}

}
28 changes: 28 additions & 0 deletions src/main/java/com/mitchej123/hodgepodge/core/HodgepodgeCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import java.util.Map;
import java.util.Set;

import net.minecraft.nbt.NBTTagCompound;

import com.gtnewhorizon.gtnhlib.config.ConfigException;
import com.gtnewhorizon.gtnhlib.config.ConfigurationManager;
import com.gtnewhorizon.gtnhmixins.IEarlyMixinLoader;
Expand All @@ -16,7 +18,9 @@
import com.mitchej123.hodgepodge.config.SpeedupsConfig;
import com.mitchej123.hodgepodge.config.TweaksConfig;
import com.mitchej123.hodgepodge.mixins.Mixins;
import com.mitchej123.hodgepodge.util.StringPooler;
import com.mitchej123.hodgepodge.util.VoxelMapCacheMover;
import com.mitchej123.hodgepodge.util.WorldDataSaver;

import cpw.mods.fml.relauncher.IFMLLoadingPlugin;

Expand All @@ -33,11 +37,29 @@ public class HodgepodgeCore implements IFMLLoadingPlugin, IEarlyMixinLoader {
ConfigurationManager.registerConfig(GeneralConfig.class);
ConfigurationManager.registerConfig(SpeedupsConfig.class);
ConfigurationManager.registerConfig(TweaksConfig.class);
if (TweaksConfig.enableTagCompoundStringPooling || TweaksConfig.enableNBTStringPooling)
StringPooler.setupPooler();
} catch (ConfigException e) {
throw new RuntimeException(e);
}
}

public static void saveWorldData(File file, NBTTagCompound tag) {
WorldDataSaver.INSTANCE.saveData(file, tag, true, false);
}

public static void saveWorldDataUncompressed(File file, NBTTagCompound tag) {
WorldDataSaver.INSTANCE.saveData(file, tag, false, false);
}

public static void saveWorldDataBackup(File file, NBTTagCompound tag) {
WorldDataSaver.INSTANCE.saveData(file, tag, true, true);
}

public static void savfeWorldDataUncompressedBackup(File file, NBTTagCompound tag) {
WorldDataSaver.INSTANCE.saveData(file, tag, false, true);
}

private String[] transformerClasses;

@Override
Expand Down Expand Up @@ -75,6 +97,12 @@ public void injectData(Map<String, Object> data) {

@Override
public String getAccessTransformerClass() {
try {
final Class<?> clazz = Class.forName("makamys.coretweaks.Config");
CoreCompat.disableCoretweaksConflictingMixins();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return null;
}
}
38 changes: 36 additions & 2 deletions src/main/java/com/mitchej123/hodgepodge/mixins/Mixins.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public enum Mixins {
.addMixinClasses(
"minecraft.MixinChunkCoordIntPair",
"minecraft.MixinWorld_FixAllocations",
"minecraft.MixinWorldClient_FixAllocations")
"minecraft.MixinWorldClient_FixAllocations",
"minecraft.MixinAnvilChunkLoader_FixAllocations")
.setApplyIf(() -> FixesConfig.fixTooManyAllocationsChunkPositionIntPair)),
FIX_TOO_MANY_ALLOCATIONS_CHUNK_POSITION_INT_PAIR_OPTIFINE_INCOMPAT(
new Builder("Stops MC from allocating too many ChunkPositionIntPair objects")
Expand Down Expand Up @@ -286,8 +287,38 @@ public enum Mixins {
CHUNK_SAVE_CME_DEBUG(new Builder("Add debugging code to Chunk Save CME").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses("minecraft.MixinNBTTagCompound").setApplyIf(() -> DebugConfig.chunkSaveCMEDebug)
.addTargetedMod(TargetedMod.VANILLA)),
SPEEDUP_NBT_COPY(new Builder("Speed up NBT copy").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses("minecraft.MixinNBTTagCompound_speedup", "minecraft.MixinNBTTagList_speedup")
.setApplyIf(() -> ASMConfig.speedupNBTTagCompoundCopy).addTargetedMod(TargetedMod.VANILLA)
.addExcludedMod(TargetedMod.BUKKIT)),
STRING_POOLER_NBT_TAG(new Builder("Pool NBT Strings").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses("minecraft.MixinNBTTagCompound_stringPooler")
.setApplyIf(() -> TweaksConfig.enableTagCompoundStringPooling).addTargetedMod(TargetedMod.VANILLA)),
STRING_POOLER_NBT_STRING(new Builder("Pool NBT Strings").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses("minecraft.MixinNBTTagString_stringPooler")
.setApplyIf(() -> TweaksConfig.enableNBTStringPooling).addTargetedMod(TargetedMod.VANILLA)),
THREADED_WORLDDATA_SAVING(new Builder("Threaded WorldData Saving").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses(
"minecraft.MixinMapStorage_threadedIO",
"minecraft.MixinSaveHandler_threadedIO",
"minecraft.MixinScoreboardSaveData_threadedIO",
"minecraft.MixinVillageCollection_threadedIO",
"minecraft.MixinMapData_threadedIO",
"forge.MixinForgeChunkManager_threadedIO")
.setApplyIf(() -> TweaksConfig.threadedWorldDataSaving).addTargetedMod(TargetedMod.VANILLA)),
DONT_SLEEP_ON_THREADED_IO(new Builder("Don't sleep on threaded IO").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses("minecraft.MixinThreadedFileIOBase_noSleep")
.setApplyIf(() -> TweaksConfig.dontSleepOnThreadedIO).addTargetedMod(TargetedMod.VANILLA)),
OPTIMIZE_MOB_SPAWNING(new Builder("Optimize Mob Spawning").setPhase(Phase.EARLY).setSide(Side.BOTH)
.addMixinClasses(
"minecraft.MixinSpawnerAnimals_optimizeSpawning",
"minecraft.MixinSpawnListEntry_optimizeSpawning")
.setApplyIf(() -> SpeedupsConfig.optimizeMobSpawning).addTargetedMod(TargetedMod.VANILLA)
.addExcludedMod(TargetedMod.BUKKIT)),

RENDER_DEBUG(new Builder("Render Debug").setPhase(Phase.EARLY).addMixinClasses("minecraft.MixinRenderGlobal")
.setSide(Side.CLIENT).setApplyIf(() -> DebugConfig.renderDebug).addTargetedMod(TargetedMod.VANILLA)),
.setSide(Side.CLIENT).setApplyIf(() -> DebugConfig.renderDebug).addTargetedMod(TargetedMod.VANILLA)
.addExcludedMod(TargetedMod.BUKKIT)),
STATIC_LAN_PORT(new Builder("Static Lan Port").setPhase(Phase.EARLY)
.addMixinClasses("minecraft.server.MixinHttpUtil").setSide(Side.CLIENT)
.setApplyIf(() -> TweaksConfig.enableDefaultLanPort).addTargetedMod(TargetedMod.VANILLA)),
Expand Down Expand Up @@ -557,6 +588,9 @@ public enum Mixins {
.addTargetedMod(TargetedMod.HARVESTCRAFT)),

// Thaumcraft
THREADED_THAUMCRAFT_MAZE_SAVING(new Builder("Threaded Thaumcraft Maze Saving").setPhase(Phase.LATE)
.setSide(Side.BOTH).addMixinClasses("thaumcraft.MixinMazeHandler_threadedIO")
.setApplyIf(() -> TweaksConfig.threadedWorldDataSaving).addTargetedMod(TargetedMod.THAUMCRAFT)),
ADD_CV_SUPPORT_TO_WAND_PEDESTAL(new Builder("CV Support for Wand Pedestal").setPhase(Phase.LATE).setSide(Side.BOTH)
.addMixinClasses("thaumcraft.MixinTileWandPedestal")
.setApplyIf(() -> TweaksConfig.addCVSupportToWandPedestal).addTargetedMod(TargetedMod.THAUMCRAFT)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.mitchej123.hodgepodge.mixins.early.forge;

import java.io.File;
import java.io.IOException;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.ForgeChunkManager;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import com.mitchej123.hodgepodge.core.HodgepodgeCore;

@Mixin(ForgeChunkManager.class)
public class MixinForgeChunkManager_threadedIO {

@Redirect(
method = "saveWorld",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/nbt/CompressedStreamTools;write(Lnet/minecraft/nbt/NBTTagCompound;Ljava/io/File;)V"))
private static void redirectWrite(NBTTagCompound forcedChunkNBTData, File chunkLoaderFile) throws IOException {
HodgepodgeCore.saveWorldDataUncompressed(chunkLoaderFile, forcedChunkNBTData);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.mitchej123.hodgepodge.mixins.early.minecraft;

import java.util.Set;

import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.chunk.storage.AnvilChunkLoader;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;

import com.mitchej123.hodgepodge.hax.LongChunkCoordIntPairSet;
import com.mitchej123.hodgepodge.mixins.interfaces.MutableChunkCoordIntPair;

@Mixin(AnvilChunkLoader.class)
public class MixinAnvilChunkLoader_FixAllocations {

@Shadow
private Set<ChunkCoordIntPair> pendingAnvilChunksCoordinates = new LongChunkCoordIntPairSet();

private final MutableChunkCoordIntPair reusableCCIP = (MutableChunkCoordIntPair) new ChunkCoordIntPair(0, 0);

@Redirect(method = "chunkExists", at = @At(value = "NEW", target = "Lnet/minecraft/world/ChunkCoordIntPair;"))
private ChunkCoordIntPair chunkExistsReusable(int i, int j) {
return (ChunkCoordIntPair) reusableCCIP.setChunkPos(i, j);
}
}
Loading

0 comments on commit 16ed4e0

Please sign in to comment.