/*
* Copyright ( c ) 2020 , 2021 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
/**
* @ test
* @ key stress randomness
* @ bug 8229855 8238812
* @ summary Test jump table with key value that gets out of bounds after loop unrolling .
* @ requires vm . compiler2 . enabled
*
* @ run main / othervm - XX : CompileCommand = dontinline , compiler . c2 . TestJumpTable : : test *
* - Xbatch - XX : + UnlockDiagnosticVMOptions - XX : - TieredCompilation - XX : - UseSwitchProfiling
* compiler . c2 . TestJumpTable
* @ run main / othervm - XX : CompileCommand = dontinline , compiler . c2 . TestJumpTable : : test *
* - Xbatch - XX : - TieredCompilation - XX : - UseOnStackReplacement
* compiler . c2 . TestJumpTable
* @ run main / othervm - XX : CompileCommand = dontinline , compiler . c2 . TestJumpTable : : test *
* - Xbatch - XX : + UnlockDiagnosticVMOptions - XX : - TieredCompilation - XX : + StressIGVN
* compiler . c2 . TestJumpTable
*/
package compiler.c2;
public class TestJumpTable {
public static int test0() {
int res = 0 ;
for (int i = 10 ; i < 50 ; ++i) {
switch (i * 5 ) {
case 15 :
case 25 :
case 40 :
case 101 :
return 42 ;
case 45 :
case 51 :
case 60 :
res++;
break ;
}
}
return res;
}
static int field;
// Original (slightly simplified) fuzzer generated test
public static void test1() {
int i4, i5 = 99 , i6, i9 = 89 ;
for (i4 = 12 ; i4 < 365 ; i4++) {
for (i6 = 5 ; i6 > 1 ; i6--) {
switch ((i6 * 5 ) + 11 ) {
case 13 :
case 19 :
case 26 :
case 31 :
case 35 :
case 41 :
case 43 :
case 61 :
case 71 :
case 83 :
case 314 :
i9 = i5;
break ;
}
}
}
}
// This generates the following subgraph:
/*
// i: -10..4
if ( ( i + min_jint ) u < = max_jint ) { < - This is always true but not folded by C2
. . .
} else {
. . .
CastII ( i - 5 , 0 . . 45 ) < - Replaced by TOP because i - 5 range is - 15 . . - 1 but still considered reachable by C2 although it is dead code
. . .
}
*/
public static void test2() {
for (int i = 5 ; i > -10 ; i--) {
switch (i) {
case 0 :
case 4 :
case 10 :
case 20 :
case 30 :
case 40 :
case 50 :
case 100 :
field = 42 ;
break ;
}
}
}
// This generates the following subgraph:
/*
// i: -20..0
if ( i ! = 0 ) {
// i: -20..-1
if ( i < 0 ) { < - This is always true but not folded by C2
// Fall through
} else {
. . .
CastII ( i - 1 , 0 . . 4 ) < - Replaced by TOP because i - 1 range is - 21 . . - 1 but still considered reachable by C2 although it is dead code
. . .
}
} else {
StoreI < - Due to this additional store on , IfNode : : has_shared_region returns false and the fold compares optimization does not kick in
}
*/
public static void test3() {
for (int i = 5 ; i > -20 ; i -= 5 ) {
switch (i) {
case 0 :
case 10 :
case 20 :
case 30 :
case 40 :
case 50 :
case 60 :
case 100 :
field = 42 ;
break ;
}
}
}
// This generates the following subgraph:
/*
// i: -20..0
if ( i ! = 0 ) {
// i: -20..-1
if ( i u < 101 ) { < - This is always false but not folded by C2 because CmpU is not handled
CastII ( i - 1 , 0 . . 49 ) < - Replaced by TOP because i - 1 range is - 21 . . - 1 but still considered reachable by C2 although it is dead code
} else {
. . .
}
} else {
. . .
}
*/
public static void test4() {
int local = 0 ;
for (int i = 5 ; i > -20 ; i -= 5 ) {
switch (i) {
case 0 :
case 10 :
case 20 :
case 30 :
case 40 :
case 50 :
case 100 :
local = 42 ;
break ;
}
}
}
// This generates the following subgraph:
/*
// i: 0..20
if ( i ! = 20 ) {
// i: 0..19
if ( ( i - 20 ) u < 281 ) { < - This is always false but not folded by C2 because the two ifs compare different values
CastII ( i - 21 , 0 . . 49 ) < - Replaced by TOP because i - 21 range is - 21 . . - 1 but still considered reachable by C2 although it is dead code
} else {
. . .
}
} else {
. . .
}
*/
public static void test5() {
int local;
for (int i = 25 ; i > 0 ; i -= 5 ) {
switch (i) {
case 20 :
case 30 :
case 40 :
case 50 :
case 60 :
case 70 :
case 300 :
local = 42 ;
break ;
}
}
}
// This generates the following subgraph:
/*
// i: 0..20
if ( ( i + 10 ) ! = 30 ) {
// i: 0..19
if ( ( i - 20 ) u < 271 ) { < - This is always false but not folded by C2 because the two ifs compare different values
CastII ( i - 21 , 0 . . 4 ) < - Replaced by TOP because i - 21 range is - 21 . . - 1 but still considered reachable by C2 although it is dead code
} else {
. . .
}
} else {
. . .
}
*/
public static void test6() {
int local;
for (int i = 25 ; i > 0 ; i -= 5 ) {
switch (i + 10 ) {
case 30 :
case 40 :
case 50 :
case 60 :
case 70 :
case 80 :
case 300 :
local = 42 ;
break ;
}
}
}
public static void main(String[] args) {
for (int i = 0 ; i < 50 _000 ; ++i) {
test0();
test1();
test2();
test3();
test4();
test5();
test6();
}
}
}
Messung V0.5 in Prozent C=85 H=83 G=83
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland