1 /*
2  * Copyright (c) 2008, 2020, 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 /*
25  * @test
26  *
27  * @summary converted from VM Testbase jit/deoptimization/test08.
28  * VM Testbase keywords: [jit, quick]
29  *
30  * @library /vmTestbase
31  *          /test/lib
32  * @build jit.deoptimization.test08.test08
33  * @run driver ExecDriver --java jit.deoptimization.test08.test08
34  */
35 
36 package jit.deoptimization.test08;
37 
38 import nsk.share.TestFailure;
39 
40 /*
41  *      Simple recursion that should causes hotspot to deoptimize
42  *      used_alot and A.foo and A.bar methods
43  *      Expected result for the test is: 0
44  *
45  *      run with the -XX:TraceDeoptimization to observ the result.
46  */
47 
48 class test08 {
main(String[] args)49   public static void main (String[] args) {
50     A obj = new A();
51     for (int index = 0; index < 1; index++) {
52       obj.used_alot();
53     }
54   }
55 }
56 
57 class A {
58         static int result = 0;
59 
foo(int index, int iter)60         synchronized public int foo(int index, int iter) {
61                 synchronized (A.a_ext) {
62                         if (index == 0)
63                                 return result;
64                         else if (iter <= sIteration / 2) {
65                                 result = bar(index) * foo(--index, iter);
66                         } else {
67                                 try {
68                                         // halfway through the max iterations
69                                         // create a B. This should cause the
70                                         // used_alot to be deoptimized
71                                         // Call b.frame for the remaining part of the recursion
72                                         if (b == null)
73                                                 b = Class.forName("jit.deoptimization.test08.B").newInstance();
74                                         result *= ((B)b).foo(index, iter);
75                                 } catch (Exception x) {
76                                                         throw new TestFailure("Class not found: B");
77                                 }
78                         }
79                 }
80                 return result;
81         }
82 
83         // Does nothing but it will let be over written in class C, See Below
bar(int index)84         synchronized public int bar(int index) {
85                 synchronized (a_ext) {
86                         for (int i=0; i<5; i++)
87                                 index--;
88                 }
89                 return 0;
90         }
91 
used_alot()92         synchronized public void used_alot() {
93                 int result = 1;
94 
95                 synchronized (a_ext) {
96                         for (int index = 1; index <= sIteration; index++) {
97                                 result *= foo(index, index);
98                         }
99                 }
100 
101                 if (result != 0) {
102                         System.err.println ("Result: " + result);
103                         System.exit (1);
104                 }
105         }
106 
107         protected Object b = null;
108         protected static final int sIteration = 1000;
109         protected static final Object a_ext = new Object();
110 }
111 
112 class B extends A {
113         //      Override foo in order to force deoptimization.
114         //      Also creates and instance of class C in the last
115         //      iteration in order to force A.foo to get deoptimized
116         //      otherwise just do something stupid.
foo(int index, int iter)117   synchronized public int foo(int index, int iter) {
118         synchronized (A.a_ext) {
119                 synchronized (B.b_ext) {
120                                 //      Make sure that this class was created at least
121                                 //      halfway through the iteration. Simple sanity check
122                         if (iter < sIteration /2) {
123                                 System.out.println ("class B create to early");
124                                 System.exit(1);
125                         }
126 
127                                 if (iter == sIteration) {
128                                         try {
129                                                 result = ((C)(Class.forName("jit.deoptimization.test08.C").newInstance())).foo(index,iter);
130                                                 result *= ((C)(Class.forName("jit.deoptimization.test08.C").newInstance())).bar(index);
131 
132                                         } catch (Exception x) {
133                                                                         throw new TestFailure("Class not found: C");
134                                         }
135                                 } else {
136                                         result = bar(index);
137                                         if (index != 0)
138                                                 result += foo(--index, iter);
139                                 }
140                         }
141                 }
142         return result;
143   }
144         protected static final Object b_ext = new Object();
145 }
146 
147 class C extends B {
foo(int index, int iter)148   synchronized public int foo(int index, int iter) {
149         synchronized (A.a_ext) {
150                 synchronized (B.b_ext) {
151                         synchronized (C.c_ext) {
152                                         for (int i=0; i<iter; i++) {
153                                                 result = bar(i);
154                                                 if (i == iter-2) {
155                                                         try {
156                                                                 result = ((D)(Class.forName("jit.deoptimization.test08.D").newInstance())).bar(index);
157                                                         } catch (Exception x) {
158                                                                                                         throw new TestFailure("Class not found: D");
159                                                         }
160                                                 }
161                                         }
162                                 }
163                         }
164                 }
165                 return result;
166         }
167         protected static final Object c_ext = new Object();
168 }
169 
170 class D extends C {
bar(int index)171   synchronized public int bar(int index) {
172                 return 1;
173         }
174 }
175