Skip to content

Commit 433f6d8

Browse files
dmlloydliach
authored andcommittedSep 4, 2024
8339492: StackMapDecoder::writeFrames makes lots of allocations
Reviewed-by: liach, redestad, jwaters, asotona
1 parent ef96a7b commit 433f6d8

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed
 

‎src/java.base/share/classes/jdk/internal/classfile/impl/StackMapDecoder.java

+16-9
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@
3535
import java.lang.constant.ConstantDescs;
3636
import java.lang.constant.MethodTypeDesc;
3737
import java.lang.reflect.AccessFlag;
38+
import java.util.Arrays;
39+
import java.util.Comparator;
3840
import java.util.List;
3941
import java.util.Objects;
40-
import java.util.TreeMap;
4142

4243
import static java.lang.classfile.ClassFile.*;
4344

@@ -46,6 +47,7 @@ public class StackMapDecoder {
4647
private static final int
4748
SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247,
4849
SAME_EXTENDED = 251;
50+
private static final StackMapFrameInfo[] NO_STACK_FRAME_INFOS = new StackMapFrameInfo[0];
4951

5052
private final ClassReader classReader;
5153
private final int pos;
@@ -103,15 +105,20 @@ public static void writeFrames(BufWriter b, List<StackMapFrameInfo> entries) {
103105
mi.methodTypeSymbol(),
104106
(mi.methodFlags() & ACC_STATIC) != 0);
105107
int prevOffset = -1;
106-
var map = new TreeMap<Integer, StackMapFrameInfo>();
108+
// avoid using method handles due to early bootstrap
109+
StackMapFrameInfo[] infos = entries.toArray(NO_STACK_FRAME_INFOS);
107110
//sort by resolved label offsets first to allow unordered entries
108-
for (var fr : entries) {
109-
map.put(dcb.labelToBci(fr.target()), fr);
110-
}
111-
b.writeU2(map.size());
112-
for (var me : map.entrySet()) {
113-
int offset = me.getKey();
114-
var fr = me.getValue();
111+
Arrays.sort(infos, new Comparator<StackMapFrameInfo>() {
112+
public int compare(final StackMapFrameInfo o1, final StackMapFrameInfo o2) {
113+
return Integer.compare(dcb.labelToBci(o1.target()), dcb.labelToBci(o2.target()));
114+
}
115+
});
116+
b.writeU2(infos.length);
117+
for (var fr : infos) {
118+
int offset = dcb.labelToBci(fr.target());
119+
if (offset == prevOffset) {
120+
throw new IllegalArgumentException("Duplicated stack frame bytecode index: " + offset);
121+
}
115122
writeFrame(buf, offset - prevOffset - 1, prevLocals, fr);
116123
prevOffset = offset;
117124
prevLocals = fr.locals();

0 commit comments

Comments
 (0)
Please sign in to comment.