From 433f6d8a0643b59663bf76c0f3a2af27a6cc56b7 Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Wed, 4 Sep 2024 16:46:44 +0000 Subject: [PATCH] 8339492: StackMapDecoder::writeFrames makes lots of allocations Reviewed-by: liach, redestad, jwaters, asotona --- .../classfile/impl/StackMapDecoder.java | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java index 609333048d0..bdee788c9da 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java @@ -35,9 +35,10 @@ import java.lang.classfile.constantpool.ClassEntry; import java.lang.constant.ConstantDescs; import java.lang.constant.MethodTypeDesc; import java.lang.reflect.AccessFlag; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.Objects; -import java.util.TreeMap; import static java.lang.classfile.ClassFile.*; @@ -46,6 +47,7 @@ public class StackMapDecoder { private static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247, SAME_EXTENDED = 251; + private static final StackMapFrameInfo[] NO_STACK_FRAME_INFOS = new StackMapFrameInfo[0]; private final ClassReader classReader; private final int pos; @@ -103,15 +105,20 @@ public class StackMapDecoder { mi.methodTypeSymbol(), (mi.methodFlags() & ACC_STATIC) != 0); int prevOffset = -1; - var map = new TreeMap(); + // avoid using method handles due to early bootstrap + StackMapFrameInfo[] infos = entries.toArray(NO_STACK_FRAME_INFOS); //sort by resolved label offsets first to allow unordered entries - for (var fr : entries) { - map.put(dcb.labelToBci(fr.target()), fr); - } - b.writeU2(map.size()); - for (var me : map.entrySet()) { - int offset = me.getKey(); - var fr = me.getValue(); + Arrays.sort(infos, new Comparator() { + public int compare(final StackMapFrameInfo o1, final StackMapFrameInfo o2) { + return Integer.compare(dcb.labelToBci(o1.target()), dcb.labelToBci(o2.target())); + } + }); + b.writeU2(infos.length); + for (var fr : infos) { + int offset = dcb.labelToBci(fr.target()); + if (offset == prevOffset) { + throw new IllegalArgumentException("Duplicated stack frame bytecode index: " + offset); + } writeFrame(buf, offset - prevOffset - 1, prevLocals, fr); prevOffset = offset; prevLocals = fr.locals();