From 5e987f1f61122af6b77370715d6b8a48f54debe3 Mon Sep 17 00:00:00 2001 From: Graham Date: Fri, 1 May 2020 20:20:41 +0100 Subject: [PATCH] Remove memory allocation delay during client startup Signed-off-by: Graham --- .../java/dev/openrs2/bundler/BundlerModule.kt | 2 + .../transform/MemoryAllocationTransformer.kt | 64 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 bundler/src/main/java/dev/openrs2/bundler/transform/MemoryAllocationTransformer.kt diff --git a/bundler/src/main/java/dev/openrs2/bundler/BundlerModule.kt b/bundler/src/main/java/dev/openrs2/bundler/BundlerModule.kt index c5e7704d..299975cc 100644 --- a/bundler/src/main/java/dev/openrs2/bundler/BundlerModule.kt +++ b/bundler/src/main/java/dev/openrs2/bundler/BundlerModule.kt @@ -9,6 +9,7 @@ import dev.openrs2.bundler.transform.DomainTransformer import dev.openrs2.bundler.transform.HostCheckTransformer import dev.openrs2.bundler.transform.LoadLibraryTransformer import dev.openrs2.bundler.transform.MacResizeTransformer +import dev.openrs2.bundler.transform.MemoryAllocationTransformer import dev.openrs2.bundler.transform.NameTransformer import dev.openrs2.bundler.transform.PlatformDetectionTransformer import dev.openrs2.bundler.transform.PublicKeyTransformer @@ -29,6 +30,7 @@ object BundlerModule : AbstractModule() { binder.addBinding().to(DomainTransformer::class.java) binder.addBinding().to(LoadLibraryTransformer::class.java) binder.addBinding().to(MacResizeTransformer::class.java) + binder.addBinding().to(MemoryAllocationTransformer::class.java) binder.addBinding().to(NameTransformer::class.java) binder.addBinding().to(PlatformDetectionTransformer::class.java) binder.addBinding().to(PublicKeyTransformer::class.java) diff --git a/bundler/src/main/java/dev/openrs2/bundler/transform/MemoryAllocationTransformer.kt b/bundler/src/main/java/dev/openrs2/bundler/transform/MemoryAllocationTransformer.kt new file mode 100644 index 00000000..50116b08 --- /dev/null +++ b/bundler/src/main/java/dev/openrs2/bundler/transform/MemoryAllocationTransformer.kt @@ -0,0 +1,64 @@ +package dev.openrs2.bundler.transform + +import com.github.michaelbull.logging.InlineLogger +import dev.openrs2.asm.InsnMatcher +import dev.openrs2.asm.classpath.ClassPath +import dev.openrs2.asm.classpath.Library +import dev.openrs2.asm.replaceExpression +import dev.openrs2.asm.transform.Transformer +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.InsnNode +import org.objectweb.asm.tree.MethodInsnNode +import org.objectweb.asm.tree.MethodNode +import org.objectweb.asm.tree.VarInsnNode +import javax.inject.Singleton + +@Singleton +class MemoryAllocationTransformer : Transformer() { + private var usedMemoryExprsZeroed = 0 + + override fun preTransform(classPath: ClassPath) { + usedMemoryExprsZeroed = 0 + } + + override fun transformCode(classPath: ClassPath, library: Library, clazz: ClassNode, method: MethodNode): Boolean { + if ((method.access and Opcodes.ACC_STATIC) != 0) { + return false + } + + for (match in USED_MEMORY_MATCHER.match(method)) { + val load1 = match[0] as VarInsnNode + val load2 = match[2] as VarInsnNode + if (load1.`var` != load2.`var`) { + continue + } + + val invoke1 = match[1] as MethodInsnNode + if (invoke1.owner != "java/lang/Runtime" || invoke1.name != "totalMemory" || invoke1.desc != "()J") { + continue + } + + val invoke2 = match[3] as MethodInsnNode + if (invoke2.owner != "java/lang/Runtime" || invoke2.name != "freeMemory" || invoke2.desc != "()J") { + continue + } + + if (method.instructions.replaceExpression(match[4], InsnNode(Opcodes.LCONST_0))) { + usedMemoryExprsZeroed++ + } + } + + return false + } + + override fun postTransform(classPath: ClassPath) { + logger.info { "Zeroed $usedMemoryExprsZeroed used memory expressions" } + } + + companion object { + private val logger = InlineLogger() + + private val USED_MEMORY_MATCHER = InsnMatcher.compile("ALOAD INVOKEVIRTUAL ALOAD INVOKEVIRTUAL LSUB") + } +}