Skip to content

Commit 2f60d36

Browse files
committed
8335475: ClassBuilder incorrectly calculates max_locals in some cases
Reviewed-by: asotona Backport-of: 1ef34c1
1 parent b415b98 commit 2f60d36

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ private void setLocalRawInternal(int index, Type type) {
10471047
void setLocalsFromArg(String name, MethodTypeDesc methodDesc, boolean isStatic, Type thisKlass) {
10481048
int localsSize = 0;
10491049
// Pre-emptively create a locals array that encompass all parameter slots
1050-
checkLocal(methodDesc.parameterCount() + (isStatic ? 0 : -1));
1050+
checkLocal(methodDesc.parameterCount() + (isStatic ? -1 : 0));
10511051
if (!isStatic) {
10521052
localsSize++;
10531053
if (OBJECT_INITIALIZER_NAME.equals(name) && !CD_Object.equals(thisKlass.sym)) {

test/jdk/jdk/classfile/StackMapsTest.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
2424
/*
2525
* @test
2626
* @summary Testing Classfile stack maps generator.
27-
* @bug 8305990 8320222 8320618
27+
* @bug 8305990 8320222 8320618 8335475
2828
* @build testdata.*
2929
* @run junit StackMapsTest
3030
*/
@@ -36,6 +36,10 @@
3636
import java.nio.file.FileSystems;
3737
import java.nio.file.Files;
3838
import org.junit.jupiter.api.Test;
39+
import org.junit.jupiter.params.ParameterizedTest;
40+
import org.junit.jupiter.params.provider.EnumSource;
41+
42+
import static java.lang.constant.ConstantDescs.MTD_void;
3943
import static org.junit.jupiter.api.Assertions.*;
4044
import static helpers.TestUtil.assertEmpty;
4145
import static java.lang.classfile.ClassFile.ACC_STATIC;
@@ -238,7 +242,7 @@ void testClassVersions() throws Exception {
238242
@Test
239243
void testInvalidAALOADStack() {
240244
ClassFile.of().build(ClassDesc.of("Test"), clb
241-
-> clb.withMethodBody("test", ConstantDescs.MTD_void, 0, cob
245+
-> clb.withMethodBody("test", MTD_void, 0, cob
242246
-> cob.bipush(10)
243247
.anewarray(ConstantDescs.CD_Object)
244248
.lconst_1() //long on stack caused NPE, see 8320618
@@ -312,4 +316,28 @@ void testInvalidStack() throws Exception {
312316
cb.pop();
313317
})));
314318
}
319+
320+
@ParameterizedTest
321+
@EnumSource(ClassFile.StackMapsOption.class)
322+
void testEmptyCounters(ClassFile.StackMapsOption option) {
323+
var cf = ClassFile.of(option);
324+
var bytes = cf.build(ClassDesc.of("Test"), clb -> clb
325+
.withMethodBody("a", MTD_void, ACC_STATIC, CodeBuilder::return_)
326+
.withMethodBody("b", MTD_void, 0, CodeBuilder::return_)
327+
);
328+
329+
var cm = ClassFile.of().parse(bytes);
330+
for (var method : cm.methods()) {
331+
var name = method.methodName();
332+
var code = method.code().orElseThrow();
333+
if (name.equalsString("a")) {
334+
assertEquals(0, code.maxLocals()); // static method
335+
assertEquals(0, code.maxStack());
336+
} else {
337+
assertTrue(name.equalsString("b"));
338+
assertEquals(1, code.maxLocals()); // instance method
339+
assertEquals(0, code.maxStack());
340+
}
341+
}
342+
}
315343
}

0 commit comments

Comments
 (0)