Skip to content

Commit e9acfce

Browse files
Alexey PavlyutkinYuri Nesterenko
authored andcommitted
8295322: Tests for JDK-8271459 were not backported to 11u
Reviewed-by: phh Backport-of: 70ddb1b025ce3b8eed4d8ad5af1b1fa4d0e0b015
1 parent 7eb2803 commit e9acfce

File tree

1 file changed

+186
-0
lines changed

1 file changed

+186
-0
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import org.testng.Assert;
25+
import org.testng.annotations.Test;
26+
27+
/*
28+
* @test
29+
* @bug 8271459
30+
* @summary C2 applies string opts to StringBuilder object created with a negative size and misses the NegativeArraySizeException.
31+
* @run testng TestNegativeStringBuilderCapacity
32+
*/
33+
public class TestNegativeStringBuilderCapacity {
34+
35+
static final int pass_count = 10000;
36+
37+
static final String doIdenticalPositiveConst() throws Throwable {
38+
// C2 knows that argument is 5 and applies string opts without runtime check.
39+
StringBuilder sb = new StringBuilder(5); // StringBuilder object optimized away by string opts.
40+
return sb.toString(); // Call optimized away by string opts.
41+
}
42+
43+
@Test
44+
public static final void testIdenticalPositiveConst() {
45+
int throw_count = 0;
46+
for ( int pass = 0; pass < pass_count; pass++ ) {
47+
try {
48+
String s = doIdenticalPositiveConst();
49+
} catch (NegativeArraySizeException e) {
50+
throw_count++;
51+
} catch (Throwable e) {
52+
Assert.fail("Unexpected exception thrown");
53+
}
54+
}
55+
Assert.assertEquals( throw_count, 0, String.format("%d exception were thrown, 0 expected", throw_count));
56+
}
57+
58+
static final String doIdenticalNegativeConst() throws Throwable {
59+
// C2 knows that we always have a negative int -> bail out of string opts
60+
StringBuilder sb = new StringBuilder(-5);
61+
return sb.toString(); // Call stays due to bailout.
62+
}
63+
64+
@Test
65+
public static final void testIdenticalNegativeConst() {
66+
int throw_count = 0;
67+
for ( int pass = 0; pass < pass_count; pass++ ) {
68+
try {
69+
String s = doIdenticalNegativeConst();
70+
} catch (NegativeArraySizeException e) {
71+
throw_count++;
72+
} catch (Throwable e) {
73+
Assert.fail("Unexpected exception thrown");
74+
}
75+
}
76+
Assert.assertEquals( throw_count, pass_count, String.format("%d exception were thrown, %d expected", throw_count, pass_count));
77+
}
78+
79+
static int aField;
80+
81+
static final String doField() throws Throwable {
82+
// C2 does not know if iFld is positive or negative. It applies string opts but inserts a runtime check to
83+
// bail out to interpreter
84+
StringBuilder sb = new StringBuilder(aField);
85+
return sb.toString();
86+
}
87+
88+
@Test
89+
public static final void testPositiveField() {
90+
aField = 4;
91+
int throw_count = 0;
92+
for ( int pass = 0; pass < pass_count; pass++ ) {
93+
try {
94+
String s = doField();
95+
} catch (NegativeArraySizeException e) {
96+
throw_count++;
97+
} catch (Throwable e) {
98+
Assert.fail("Unexpected exception thrown");
99+
}
100+
}
101+
Assert.assertEquals( throw_count, 0, String.format("%d exception were thrown, 0 expected", throw_count));
102+
}
103+
104+
@Test
105+
public static final void testNegativeField() {
106+
aField = -4;
107+
int throw_count = 0;
108+
for ( int pass = 0; pass < pass_count; pass++ ) {
109+
try {
110+
String s = doField();
111+
} catch (NegativeArraySizeException e) {
112+
throw_count++;
113+
} catch (Throwable e) {
114+
Assert.fail("Unexpected exception thrown");
115+
}
116+
}
117+
Assert.assertEquals( throw_count, pass_count, String.format("%d exception were thrown, %d expected", throw_count, pass_count));
118+
}
119+
120+
static final String doPossiblyNegativeConst(boolean flag) throws Throwable {
121+
// C2 knows that cap is between -5 and 5. It applies string opts but inserts a runtime check to
122+
// bail out to interpreter. This path is sometimes taken and sometimes not.
123+
final int capacity = flag ? 5 : -5;
124+
StringBuilder sb = new StringBuilder(capacity);
125+
return sb.toString();
126+
}
127+
128+
@Test
129+
public static final void testPossiblyNegativeConst() {
130+
int throw_count = 0;
131+
for ( int pass = 0; pass < pass_count; pass++ ) {
132+
try {
133+
String s = doPossiblyNegativeConst((pass % 2) == 0);
134+
} catch (NegativeArraySizeException e) {
135+
throw_count++;
136+
} catch (Throwable e) {
137+
Assert.fail("Unexpected exception thrown");
138+
}
139+
}
140+
Assert.assertEquals( throw_count, pass_count/2, String.format("%d exception were thrown, %d expected", throw_count, pass_count/2));
141+
}
142+
143+
static final String doPositiveConst(boolean flag) throws Throwable {
144+
// C2 knows that cap is between 1 and 100 and applies string opts without runtime check.
145+
final int capacity = flag ? 1 : 100;
146+
StringBuilder sb = new StringBuilder(capacity);
147+
return sb.toString();
148+
}
149+
150+
@Test
151+
public static final void testPositiveConst() {
152+
int throw_count = 0;
153+
for ( int pass = 0; pass < pass_count; pass++ ) {
154+
try {
155+
String s = doPositiveConst((pass % 2) == 0);
156+
} catch (NegativeArraySizeException e) {
157+
throw_count++;
158+
} catch (Throwable e) {
159+
Assert.fail("Unexpected exception thrown");
160+
}
161+
}
162+
Assert.assertEquals( throw_count, 0, String.format("%d exception were thrown, 0 expected", throw_count));
163+
}
164+
165+
static final String doArg(int capacity) throws Throwable {
166+
// C2 does not know if cap is positive or negative. It applies string opts but inserts a runtime check to
167+
// bail out to interpreter. This path is always taken because cap is always negative.
168+
StringBuilder sb = new StringBuilder(capacity);
169+
return sb.toString();
170+
}
171+
172+
@Test
173+
public static final void testArg() {
174+
int throw_count = 0;
175+
for ( int pass = 0; pass < pass_count; pass++ ) {
176+
try {
177+
String s = doArg((pass % 2) == 0 ? 3 : -3 );
178+
} catch (NegativeArraySizeException e) {
179+
throw_count++;
180+
} catch (Throwable e) {
181+
Assert.fail("Unexpected exception thrown");
182+
}
183+
}
184+
Assert.assertEquals( throw_count, pass_count/2, String.format("%d exception were thrown, %d expected", throw_count, pass_count/2));
185+
}
186+
}

0 commit comments

Comments
 (0)