Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/lang/invoke/CallStaticInitOrder.java
47209 views
1
/*
2
* Copyright (c) 2013, 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
/**
26
* @test
27
* @summary static initializer invocation order
28
*
29
* @build indify.Indify
30
* @compile CallStaticInitOrder.java
31
* @run main/othervm
32
* indify.Indify
33
* --expand-properties --classpath ${test.classes}
34
* --java test.java.lang.invoke.CallStaticInitOrder
35
*/
36
37
package test.java.lang.invoke;
38
39
import java.io.*;
40
41
import java.lang.invoke.*;
42
import static java.lang.invoke.MethodHandles.*;
43
import static java.lang.invoke.MethodType.*;
44
45
public class CallStaticInitOrder {
46
private static int TICK;
47
private static synchronized int tick(String event) {
48
int n = ++TICK;
49
System.out.println("event #"+n+" = "+event);
50
return n;
51
}
52
53
static int Init1Tick;
54
private static class Init1 {
55
static { Init1Tick = tick("foo -> Init1.<clinit>"); }
56
static int foo() { return Init1Tick; }
57
}
58
59
static int Init2Tick;
60
private static class Init2 {
61
static { Init2Tick = tick("bar -> Init2.<clinit>"); }
62
static int bar() { return Init2Tick; }
63
}
64
65
static int Init3Tick;
66
private static class Init3 {
67
static { Init3Tick = tick("baz -> Init3.<clinit>"); }
68
static int baz() { return Init3Tick; }
69
}
70
71
static int Init4Tick;
72
private static class Init4 {
73
static { Init4Tick = tick("bat -> Init4.<clinit>"); }
74
static int bat() { return Init4Tick; }
75
}
76
77
static int Init5Tick;
78
private static class Init5 {
79
static { Init5Tick = tick("read bang -> Init5.<clinit>"); }
80
static int bang = Init5Tick;
81
}
82
83
static int Init6Tick;
84
private static class Init6 {
85
static { Init6Tick = tick("write pong -> Init6.<clinit>"); }
86
static int pong;
87
}
88
89
private static final MutableCallSite CONSTANT_CS_baz;
90
private static MethodHandle MH_foo() throws ReflectiveOperationException {
91
return lookup().findStatic(Init1.class, "foo", methodType(int.class));
92
}
93
private static final MethodHandle CONSTANT_MH_bar;
94
private static MethodHandle MH_baz() throws ReflectiveOperationException {
95
return lookup().findStatic(Init3.class, "baz", methodType(int.class));
96
}
97
private static final MethodHandle CONSTANT_MH_bat;
98
private static final MethodHandle CONSTANT_MH_bangGetter;
99
private static final MethodHandle CONSTANT_MH_pongSetter;
100
static {
101
try {
102
int t1 = tick("CallStaticInitOrder.<clinit>");
103
{
104
CONSTANT_CS_baz = new MutableCallSite(methodType(int.class));
105
// MH_foo() := lookup().findStatic(Init1.class, "foo", methodType(int.class));
106
CONSTANT_MH_bar = lookup().findStatic(Init2.class, "bar", methodType(int.class));
107
// MH_baz() := lookup().findStatic(Init3.class, "baz", methodType(int.class));
108
CONSTANT_MH_bat = lookup().unreflect(Init4.class.getDeclaredMethod("bat"));
109
CONSTANT_MH_bangGetter = lookup().findStaticGetter(Init5.class, "bang", int.class);
110
MethodHandle pongSetter = lookup().findStaticSetter(Init6.class, "pong", int.class);
111
MethodHandle tickGetter = lookup().findStaticGetter(CallStaticInitOrder.class, "Init6Tick", int.class);
112
CONSTANT_MH_pongSetter = filterReturnValue(insertArguments(pongSetter, 0, -99), tickGetter);
113
}
114
int t2 = tick("CallStaticInitOrder.<clinit> done");
115
assertEquals(t1+1, t2); // no ticks in between
116
} catch (Exception ex) {
117
throw new InternalError(ex.toString());
118
}
119
}
120
121
public static void main(String... av) throws Throwable {
122
testInit();
123
if (LAST_LOSER != null) throw LAST_LOSER;
124
}
125
126
private static Throwable LAST_LOSER;
127
128
private static void assertEquals(int expected, int actual) {
129
if (expected != actual) {
130
Throwable loser = new AssertionError("expected: " + expected + ", actual: " + actual);
131
if (LAST_LOSER != null)
132
LAST_LOSER.printStackTrace(System.out);
133
LAST_LOSER = loser;
134
}
135
}
136
137
private static void testInit() throws Throwable {
138
System.out.println("runFoo = "+runFoo());
139
System.out.println("runBar = "+runBar());
140
try {
141
runBaz();
142
} catch (IllegalStateException ex) {
143
tick("runBaz throw/catch");
144
}
145
CONSTANT_CS_baz.setTarget(MH_baz());
146
System.out.println("runBaz = "+runBaz());
147
System.out.println("runBat = "+runBat());
148
System.out.println("runBang = "+runBang());
149
System.out.println("runPong = "+runPong());
150
}
151
152
private static int runFoo() throws Throwable {
153
assertEquals(Init1Tick, 0); // Init1 not initialized yet
154
int t1 = tick("runFoo");
155
int t2 = (int) INDY_foo().invokeExact();
156
int t3 = tick("runFoo done");
157
assertEquals(Init1Tick, t2); // when Init1 was initialized
158
assertEquals(t1+2, t3); // exactly two ticks in between
159
assertEquals(t1+1, t2); // init happened inside
160
return t2;
161
}
162
private static MethodHandle INDY_foo() throws Throwable {
163
shouldNotCallThis();
164
return ((CallSite) MH_bsm().invoke(lookup(), "foo", methodType(int.class))).dynamicInvoker();
165
}
166
167
private static int runBar() throws Throwable {
168
assertEquals(Init2Tick, 0); // Init2 not initialized yet
169
int t1 = tick("runBar");
170
int t2 = (int) INDY_bar().invokeExact();
171
int t3 = tick("runBar done");
172
assertEquals(Init2Tick, t2); // when Init2 was initialized
173
assertEquals(t1+2, t3); // exactly two ticks in between
174
assertEquals(t1+1, t2); // init happened inside
175
return t2;
176
}
177
private static MethodHandle INDY_bar() throws Throwable {
178
shouldNotCallThis();
179
return ((CallSite) MH_bsm().invoke(lookup(), "bar", methodType(int.class))).dynamicInvoker();
180
}
181
182
private static int runBaz() throws Throwable {
183
assertEquals(Init3Tick, 0); // Init3 not initialized yet
184
int t1 = tick("runBaz");
185
int t2 = (int) INDY_baz().invokeExact();
186
int t3 = tick("runBaz done");
187
assertEquals(Init3Tick, t2); // when Init3 was initialized
188
assertEquals(t1+2, t3); // exactly two ticks in between
189
assertEquals(t1+1, t2); // init happened inside
190
return t2;
191
}
192
private static MethodHandle INDY_baz() throws Throwable {
193
shouldNotCallThis();
194
return ((CallSite) MH_bsm().invoke(lookup(), "baz", methodType(int.class))).dynamicInvoker();
195
}
196
197
private static int runBat() throws Throwable {
198
assertEquals(Init4Tick, 0); // Init4 not initialized yet
199
int t1 = tick("runBat");
200
int t2 = (int) INDY_bat().invokeExact();
201
int t3 = tick("runBat done");
202
assertEquals(Init4Tick, t2); // when Init4 was initialized
203
assertEquals(t1+2, t3); // exactly two ticks in between
204
assertEquals(t1+1, t2); // init happened inside
205
return t2;
206
}
207
private static MethodHandle INDY_bat() throws Throwable {
208
shouldNotCallThis();
209
return ((CallSite) MH_bsm().invoke(lookup(), "bat", methodType(int.class))).dynamicInvoker();
210
}
211
212
private static int runBang() throws Throwable {
213
assertEquals(Init5Tick, 0); // Init5 not initialized yet
214
int t1 = tick("runBang");
215
int t2 = (int) INDY_bang().invokeExact();
216
int t3 = tick("runBang done");
217
assertEquals(Init5Tick, t2); // when Init5 was initialized
218
assertEquals(t1+2, t3); // exactly two ticks in between
219
assertEquals(t1+1, t2); // init happened inside
220
return t2;
221
}
222
private static MethodHandle INDY_bang() throws Throwable {
223
shouldNotCallThis();
224
return ((CallSite) MH_bsm().invoke(lookup(), "bang", methodType(int.class))).dynamicInvoker();
225
}
226
227
private static int runPong() throws Throwable {
228
assertEquals(Init6Tick, 0); // Init6 not initialized yet
229
int t1 = tick("runPong");
230
int t2 = (int) INDY_pong().invokeExact();
231
int t3 = tick("runPong done");
232
assertEquals(Init6Tick, t2); // when Init6 was initialized
233
assertEquals(t1+2, t3); // exactly two ticks in between
234
assertEquals(t1+1, t2); // init happened inside
235
return t2;
236
}
237
private static MethodHandle INDY_pong() throws Throwable {
238
shouldNotCallThis();
239
return ((CallSite) MH_bsm().invoke(lookup(), "pong", methodType(int.class))).dynamicInvoker();
240
}
241
242
private static CallSite bsm(Lookup caller, String name, MethodType type) throws ReflectiveOperationException {
243
System.out.println("bsm "+name+type);
244
CallSite res;
245
switch (name) {
246
case "foo":
247
res = new ConstantCallSite(MH_foo()); break;
248
case "bar":
249
res = new ConstantCallSite(CONSTANT_MH_bar); break;
250
case "baz":
251
res = CONSTANT_CS_baz; break;
252
case "bat":
253
res = new ConstantCallSite(CONSTANT_MH_bat); break;
254
case "bang":
255
res = new ConstantCallSite(CONSTANT_MH_bangGetter); break;
256
case "pong":
257
res = new ConstantCallSite(CONSTANT_MH_pongSetter); break;
258
default:
259
res = null;
260
}
261
if (res == null || !res.type().equals(type)) {
262
throw new AssertionError(String.valueOf(res));
263
}
264
return res;
265
}
266
private static MethodHandle MH_bsm() throws ReflectiveOperationException {
267
shouldNotCallThis();
268
return lookup().findStatic(lookup().lookupClass(), "bsm",
269
methodType(CallSite.class, Lookup.class, String.class, MethodType.class));
270
}
271
private static void shouldNotCallThis() {
272
// if this gets called, the transformation has not taken place
273
throw new AssertionError("this code should be statically transformed away by Indify");
274
}
275
}
276
277