From 7b9ff9b77dc6c788f8c23c9d791ceade5a25ead4 Mon Sep 17 00:00:00 2001 From: LlamaLad7 Date: Mon, 17 Feb 2025 12:55:11 +0000 Subject: [PATCH] Avoid unnecessary linked list traversals in MethodLinker. (#133) The chains themselves are assumed to be an implementation detail of this class, in which case it's fine to flatten them at any time. --- .../java/proguard/classfile/util/MethodLinker.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/base/src/main/java/proguard/classfile/util/MethodLinker.java b/base/src/main/java/proguard/classfile/util/MethodLinker.java index 89bd70def..9cfec7962 100644 --- a/base/src/main/java/proguard/classfile/util/MethodLinker.java +++ b/base/src/main/java/proguard/classfile/util/MethodLinker.java @@ -19,7 +19,9 @@ import static proguard.classfile.instruction.Instruction.OP_INVOKESTATIC; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import proguard.classfile.AccessConstants; import proguard.classfile.Clazz; @@ -132,12 +134,19 @@ private static void link(Member member1, Member member2) { * @return The last method in the linked list. */ public static Member lastMember(Member member) { + List chain = new ArrayList<>(); Member lastMember = member; while (lastMember.getProcessingInfo() != null && lastMember.getProcessingInfo() instanceof Member) { + chain.add(lastMember); lastMember = (Member) lastMember.getProcessingInfo(); } + // Point every member in the chain directly to the last element to save time in the future + for (Member relatedMember : chain) { + relatedMember.setProcessingInfo(lastMember); + } + return lastMember; } @@ -149,6 +158,9 @@ public static Member lastMember(Member member) { */ public static Processable lastProcessable(Processable processable) { Processable lastProcessable = processable; + if (lastProcessable instanceof Member) { + lastProcessable = lastMember((Member) lastProcessable); + } while (lastProcessable.getProcessingInfo() != null && lastProcessable.getProcessingInfo() instanceof Processable) { lastProcessable = (Processable) lastProcessable.getProcessingInfo();