Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/serviceability/jvmti/ModuleAwareAgents/ClassLoadPrepare/libMAAClassLoadPrepare.c
41159 views
1
/*
2
* Copyright (c) 2016, 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
#include <stdio.h>
25
#include <string.h>
26
#include "jvmti.h"
27
28
#ifdef __cplusplus
29
extern "C" {
30
#endif
31
32
#ifndef JNI_ENV_ARG
33
34
#ifdef __cplusplus
35
#define JNI_ENV_ARG(x, y) y
36
#define JNI_ENV_PTR(x) x
37
#else
38
#define JNI_ENV_ARG(x,y) x, y
39
#define JNI_ENV_PTR(x) (*x)
40
#endif
41
42
#endif
43
44
#define TranslateError(err) "JVMTI error"
45
46
#define PASSED 0
47
#define FAILED 2
48
49
static const char *EXPECTED_SIGNATURE = "Ljava/util/Collections;";
50
static const char *EXC_CNAME = "java/lang/Exception";
51
52
static jvmtiEnv *jvmti = NULL;
53
static jint result = PASSED;
54
static jboolean printdump = JNI_FALSE;
55
56
static jboolean with_early_vm_start_capability = JNI_FALSE;
57
58
static jboolean class_in_class_load_events_vm_start = JNI_FALSE;
59
static jboolean class_in_class_load_events_vm_live = JNI_FALSE;
60
static jboolean class_in_class_prepare_events_vm_start = JNI_FALSE;
61
static jboolean class_in_class_prepare_events_vm_live = JNI_FALSE;
62
63
static int class_load_events_vm_start_count = 0;
64
static int class_prepare_events_vm_start_count = 0;
65
66
static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
67
68
JNIEXPORT
69
jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
70
return Agent_Initialize(jvm, options, reserved);
71
}
72
73
JNIEXPORT
74
jint JNICALL Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
75
return Agent_Initialize(jvm, options, reserved);
76
}
77
78
JNIEXPORT
79
jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
80
return JNI_VERSION_9;
81
}
82
83
static
84
jint throw_exc(JNIEnv *env, char *msg) {
85
jclass exc_class = JNI_ENV_PTR(env)->FindClass(JNI_ENV_ARG(env, EXC_CNAME));
86
87
if (exc_class == NULL) {
88
printf("throw_exc: Error in FindClass(env, %s)\n", EXC_CNAME);
89
return -1;
90
}
91
return JNI_ENV_PTR(env)->ThrowNew(JNI_ENV_ARG(env, exc_class), msg);
92
}
93
94
static void JNICALL
95
Callback_ClassFileLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
96
jvmtiPhase phase;
97
char *sig, *generic;
98
jvmtiError err;
99
100
err = (*jvmti)->GetPhase(jvmti_env,&phase);
101
if (err != JVMTI_ERROR_NONE) {
102
printf("ClassLoad event: GetPhase error: %s (%d)\n", TranslateError(err), err);
103
result = FAILED;
104
return;
105
}
106
107
if (phase == JVMTI_PHASE_START || phase == JVMTI_PHASE_LIVE) {
108
109
err = (*jvmti)->GetClassSignature(jvmti_env, klass, &sig, &generic);
110
111
if (err != JVMTI_ERROR_NONE) {
112
printf("ClassLoad event: GetClassSignature error: %s (%d)\n", TranslateError(err), err);
113
result = FAILED;
114
return;
115
}
116
117
if (phase == JVMTI_PHASE_START) {
118
class_load_events_vm_start_count++;
119
if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {
120
class_in_class_load_events_vm_start = JNI_TRUE;
121
}
122
} else {
123
if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {
124
class_in_class_load_events_vm_live = JNI_TRUE;
125
}
126
}
127
128
if (printdump == JNI_TRUE) {
129
printf(">>> ClassLoad event: phase(%d), class signature %s\n", phase, sig == NULL ? "null": sig);
130
}
131
} else {
132
printf("ClassLoad event: get event in unexpected phase(%d)\n", phase);
133
result = FAILED;
134
}
135
}
136
137
static void JNICALL
138
Callback_ClassFilePrepare(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
139
jvmtiPhase phase;
140
char *sig, *generic;
141
jvmtiError err;
142
143
err = (*jvmti)->GetPhase(jvmti_env,&phase);
144
if (err != JVMTI_ERROR_NONE) {
145
printf("ClassPrepare event: GetPhase error: %s (%d)\n", TranslateError(err), err);
146
result = FAILED;
147
return;
148
}
149
150
if (phase == JVMTI_PHASE_START || phase == JVMTI_PHASE_LIVE) {
151
152
err = (*jvmti)->GetClassSignature(jvmti_env, klass, &sig, &generic);
153
154
if (err != JVMTI_ERROR_NONE) {
155
printf("ClassPrepare event: GetClassSignature error: %s (%d)\n", TranslateError(err), err);
156
result = FAILED;
157
return;
158
}
159
160
if (phase == JVMTI_PHASE_START) {
161
class_prepare_events_vm_start_count++;
162
if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {
163
class_in_class_prepare_events_vm_start = JNI_TRUE;
164
}
165
} else {
166
if(strcmp(sig, EXPECTED_SIGNATURE) == 0) {
167
class_in_class_prepare_events_vm_live = JNI_TRUE;
168
}
169
}
170
171
if (printdump == JNI_TRUE) {
172
printf(">>> ClassPrepare event: phase(%d), class signature %s\n", phase, sig == NULL ? "null": sig);
173
}
174
} else {
175
printf("ClassPrepare event: get event in unexpected phase(%d)\n", phase);
176
result = FAILED;
177
}
178
}
179
180
static
181
jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
182
jint res, size;
183
jvmtiCapabilities caps;
184
jvmtiEventCallbacks callbacks;
185
jvmtiError err;
186
187
if (options != NULL) {
188
if (strstr(options, "with_early_vmstart") != NULL) {
189
with_early_vm_start_capability = JNI_TRUE;
190
}
191
if (strstr(options, "printdump") != NULL) {
192
printdump = JNI_TRUE;
193
}
194
}
195
196
res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
197
JVMTI_VERSION_9);
198
if (res != JNI_OK || jvmti == NULL) {
199
printf(" Error: wrong result of a valid call to GetEnv!\n");
200
return JNI_ERR;
201
}
202
203
if (with_early_vm_start_capability == JNI_TRUE) {
204
printf("Enabling following capability: can_generate_early_vmstart\n");
205
memset(&caps, 0, sizeof(caps));
206
caps.can_generate_early_vmstart = 1;
207
208
err = (*jvmti)->AddCapabilities(jvmti, &caps);
209
if (err != JVMTI_ERROR_NONE) {
210
printf(" Error in AddCapabilites: %s (%d)\n", TranslateError(err), err);
211
return JNI_ERR;
212
}
213
}
214
215
size = (jint)sizeof(callbacks);
216
217
memset(&callbacks, 0, sizeof(callbacks));
218
callbacks.ClassLoad = Callback_ClassFileLoad;
219
callbacks.ClassPrepare = Callback_ClassFilePrepare;
220
221
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, size);
222
if (err != JVMTI_ERROR_NONE) {
223
printf(" Error in SetEventCallbacks: %s (%d)\n", TranslateError(err), err);
224
return JNI_ERR;
225
}
226
227
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL);
228
if (err != JVMTI_ERROR_NONE) {
229
printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err);
230
return JNI_ERR;
231
}
232
233
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);
234
235
if (err != JVMTI_ERROR_NONE) {
236
printf(" Error in SetEventNotificationMode: %s (%d)\n", TranslateError(err), err);
237
return JNI_ERR;
238
}
239
240
return JNI_OK;
241
}
242
243
JNIEXPORT jint JNICALL
244
Java_MAAClassLoadPrepare_check(JNIEnv *env, jclass cls) {
245
jobject loader = NULL;
246
247
if (jvmti == NULL) {
248
throw_exc(env, "JVMTI client was not properly loaded!\n");
249
return FAILED;
250
}
251
252
if (with_early_vm_start_capability == JNI_TRUE) {
253
/*
254
* Expecting that "java/util/Collections" class from java.base module is present in the
255
* ClassLoad and ClassPrepare events during VM Start phase when can_generate_early_vmstart
256
* capability is enabled.
257
* Expecting that ClassLoad and ClassPrepare events are sent in the VM early start phase
258
* when can_generate_early_vmstart is enabled(JDK-8165681).
259
*/
260
if (class_load_events_vm_start_count == 0) {
261
throw_exc(env, "Didn't get ClassLoad events in start phase!\n");
262
return FAILED;
263
}
264
265
printf("Expecting to find '%s' class in ClassLoad events during VM early start phase.\n", EXPECTED_SIGNATURE);
266
if (class_in_class_load_events_vm_start == JNI_FALSE) {
267
throw_exc(env, "Unable to find expected class in ClassLoad events during early start phase!\n");
268
return FAILED;
269
}
270
271
if (class_prepare_events_vm_start_count == 0) {
272
throw_exc(env, "Didn't get ClassPrepare events in start phase!\n");
273
return FAILED;
274
}
275
276
printf("Expecting to find '%s' class in ClassPrepare events during VM early start phase.\n", EXPECTED_SIGNATURE);
277
if (class_in_class_prepare_events_vm_start == JNI_FALSE) {
278
throw_exc(env, "Unable to find expected class in ClassPrepare events during early start phase!\n");
279
return FAILED;
280
}
281
} else {
282
/*
283
* Expecting that "java/util/Collections" class from java.base module is not present in the
284
* ClassLoad and ClassPrepare events during VM Start phase when can_generate_early_vmstart
285
* capability is disabled.
286
*/
287
printf("Expecting that '%s' class is absent in ClassLoad events during normal VM start phase.\n", EXPECTED_SIGNATURE);
288
if (class_in_class_prepare_events_vm_start == JNI_TRUE) {
289
throw_exc(env, "Class is found in ClassLoad events during normal VM start phase!\n");
290
return FAILED;
291
}
292
293
printf("Expecting that '%s' class is absent in ClassPrepare events during normal VM start phase.\n", EXPECTED_SIGNATURE);
294
if (class_in_class_prepare_events_vm_start == JNI_TRUE) {
295
throw_exc(env, "Class is found in ClassPrepare events during normal VM start phase!\n");
296
return FAILED;
297
}
298
}
299
300
/*
301
* In any case, we not expect to see "java/util/Collections" class from java.base module
302
* in the ClassLoad and ClassPrepare events during VM Live phase.
303
*/
304
if (class_in_class_prepare_events_vm_live == JNI_TRUE) {
305
throw_exc(env, "Class is found in ClassLoad events during VM Live phase!\n");
306
return FAILED;
307
}
308
309
if (class_in_class_prepare_events_vm_live == JNI_TRUE) {
310
throw_exc(env, "Class is found in ClassPrepare events during VM Live phase!\n");
311
return FAILED;
312
}
313
314
return result;
315
}
316
317
#ifdef __cplusplus
318
}
319
#endif
320
321