Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/jvmti/ClassPrepare/classprep001/classprep001.cpp
40951 views
1
/*
2
* Copyright (c) 2003, 2021, 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 <inttypes.h>
27
#include "jvmti.h"
28
#include "agent_common.h"
29
#include "JVMTITools.h"
30
31
extern "C" {
32
33
34
#define PASSED 0
35
#define STATUS_FAILED 2
36
37
#define EXP_STATUS (JVMTI_CLASS_STATUS_VERIFIED | JVMTI_CLASS_STATUS_PREPARED)
38
39
typedef struct {
40
char *sig;
41
jint status;
42
jint mcount;
43
jint fcount;
44
jint icount;
45
} writable_class_info;
46
47
typedef struct {
48
const char *sig;
49
jint status;
50
jint mcount;
51
jint fcount;
52
jint icount;
53
} class_info;
54
55
static jvmtiEnv *jvmti = NULL;
56
static jvmtiEventCallbacks callbacks;
57
static jint result = PASSED;
58
static jboolean printdump = JNI_FALSE;
59
static size_t eventsCount = 0;
60
static size_t eventsExpected = 0;
61
static class_info classes[] = {
62
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestInterface;", EXP_STATUS, 2, 1, 0 },
63
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestClass;", EXP_STATUS, 3, 2, 1 }
64
};
65
// These classes are loaded on a different thread.
66
// We should not get ClassPrepare events for them.
67
static const class_info unexpectedClasses[] = {
68
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestInterface2;", 0, 0, 0, 0 },
69
{ "Lnsk/jvmti/ClassPrepare/classprep001$TestClass2;", 0, 0, 0, 0}
70
};
71
72
void printStatus(jint status) {
73
int flags = 0;
74
if ((status & JVMTI_CLASS_STATUS_VERIFIED) != 0) {
75
printf("JVMTI_CLASS_STATUS_VERIFIED");
76
flags++;
77
}
78
if ((status & JVMTI_CLASS_STATUS_PREPARED) != 0) {
79
if (flags > 0) printf(" | ");
80
printf("JVMTI_CLASS_STATUS_PREPARED");
81
flags++;
82
}
83
if ((status & JVMTI_CLASS_STATUS_INITIALIZED) != 0) {
84
if (flags > 0) printf(" | ");
85
printf("JVMTI_CLASS_STATUS_INITIALIZED");
86
flags++;
87
}
88
if ((status & JVMTI_CLASS_STATUS_ERROR) != 0) {
89
if (flags > 0) printf(" | ");
90
printf("JVMTI_CLASS_STATUS_ERROR");
91
flags++;
92
}
93
printf(" (0x%x)\n", status);
94
}
95
96
const size_t NOT_FOUND = (size_t)(-1);
97
98
size_t findClass(const char *classSig, const class_info *arr, int size) {
99
for (int i = 0; i < size; i++) {
100
if (strcmp(classSig, arr[i].sig) == 0) {
101
return i;
102
}
103
}
104
return NOT_FOUND;
105
}
106
107
void JNICALL ClassPrepare(jvmtiEnv *jvmti_env, JNIEnv *env,
108
jthread thr, jclass cls) {
109
jvmtiError err;
110
writable_class_info inf;
111
jmethodID *methods;
112
jfieldID *fields;
113
jclass *interfaces;
114
char *name, *sig, *generic;
115
int i;
116
117
err = jvmti_env->GetClassSignature(cls, &inf.sig, &generic);
118
if (err != JVMTI_ERROR_NONE) {
119
printf("(GetClassSignature#%" PRIuPTR ") unexpected error: %s (%d)\n",
120
eventsCount, TranslateError(err), err);
121
result = STATUS_FAILED;
122
return;
123
}
124
err = jvmti_env->GetClassStatus(cls, &inf.status);
125
if (err != JVMTI_ERROR_NONE) {
126
printf("(GetClassStatus#%" PRIuPTR ") unexpected error: %s (%d)\n",
127
eventsCount, TranslateError(err), err);
128
result = STATUS_FAILED;
129
}
130
err = jvmti_env->GetClassMethods(cls, &inf.mcount, &methods);
131
if (err != JVMTI_ERROR_NONE) {
132
printf("(GetClassMethods#%" PRIuPTR ") unexpected error: %s (%d)\n",
133
eventsCount, TranslateError(err), err);
134
result = STATUS_FAILED;
135
return;
136
}
137
err = jvmti_env->GetClassFields(cls, &inf.fcount, &fields);
138
if (err != JVMTI_ERROR_NONE) {
139
printf("(GetClassMethods#%" PRIuPTR ") unexpected error: %s (%d)\n",
140
eventsCount, TranslateError(err), err);
141
result = STATUS_FAILED;
142
return;
143
}
144
err = jvmti_env->GetImplementedInterfaces(cls,
145
&inf.icount, &interfaces);
146
if (err != JVMTI_ERROR_NONE) {
147
printf("(GetImplementedInterfaces#%" PRIuPTR ") unexpected error: %s (%d)\n",
148
eventsCount, TranslateError(err), err);
149
result = STATUS_FAILED;
150
return;
151
}
152
153
if (printdump == JNI_TRUE) {
154
printf(">>> [class prepare event #%" PRIuPTR "]", eventsCount);
155
printf(" \"%s\"\n", inf.sig);
156
printf(">>> status: ");
157
printStatus(inf.status);
158
printf(">>> %d methods:", inf.mcount);
159
for (i = 0; i < inf.mcount; i++) {
160
if (i > 0) printf(",");
161
if (methods[i] == NULL) {
162
printf(" null");
163
} else {
164
err = jvmti_env->GetMethodName(methods[i],
165
&name, &sig, &generic);
166
if (err == JVMTI_ERROR_NONE) {
167
printf(" \"%s%s\"", name, sig);
168
} else {
169
printf(" ???");
170
}
171
}
172
}
173
printf("\n");
174
printf(">>> %d fields:", inf.fcount);
175
for (i = 0; i < inf.fcount; i++) {
176
if (i > 0) printf(",");
177
if (fields[i] == NULL) {
178
printf(" null");
179
} else {
180
err = jvmti_env->GetFieldName(cls, fields[i],
181
&name, &sig, &generic);
182
if (err == JVMTI_ERROR_NONE) {
183
printf(" \"%s, %s\"", name, sig);
184
} else {
185
printf(" ???");
186
}
187
}
188
}
189
printf("\n");
190
printf(">>> %d interfaces:", inf.icount);
191
for (i = 0; i < inf.icount; i++) {
192
if (i > 0) printf(",");
193
if (interfaces[i] == NULL) {
194
printf(" null");
195
} else {
196
err = jvmti_env->GetClassSignature(
197
interfaces[i], &sig, &generic);
198
if (err == JVMTI_ERROR_NONE) {
199
printf(" \"%s\"", sig);
200
} else {
201
printf(" ???");
202
}
203
}
204
}
205
printf("\n");
206
}
207
208
size_t expectedClassIdx = findClass(inf.sig, classes, sizeof(classes)/sizeof(class_info));
209
// Test classes loading may cause system classes loading - skip them.
210
if (expectedClassIdx == NOT_FOUND) {
211
size_t unexpectedClassIdx = findClass(inf.sig, unexpectedClasses,
212
sizeof(unexpectedClasses)/sizeof(class_info));
213
if (unexpectedClassIdx != NOT_FOUND) {
214
printf("# wrong class: \"%s\"\n", inf.sig);
215
result = STATUS_FAILED;
216
}
217
return;
218
}
219
220
if (eventsCount != expectedClassIdx) {
221
printf("(#%" PRIuPTR ") unexpected order: %" PRIuPTR ", expected: %" PRIuPTR "\n",
222
eventsCount, expectedClassIdx, eventsCount);
223
result = STATUS_FAILED;
224
return;
225
}
226
227
if (inf.status != classes[eventsCount].status) {
228
printf("(#%" PRIuPTR ") wrong status: ", eventsCount);
229
printStatus(inf.status);
230
printf(" expected: ");
231
printStatus(classes[eventsCount].status);
232
result = STATUS_FAILED;
233
}
234
if (inf.mcount != classes[eventsCount].mcount) {
235
printf("(#%" PRIuPTR ") wrong number of methods: 0x%x",
236
eventsCount, inf.mcount);
237
printf(", expected: 0x%x\n", classes[eventsCount].mcount);
238
result = STATUS_FAILED;
239
}
240
if (inf.fcount != classes[eventsCount].fcount) {
241
printf("(#%" PRIuPTR ") wrong number of fields: 0x%x",
242
eventsCount, inf.fcount);
243
printf(", expected: 0x%x\n", classes[eventsCount].fcount);
244
result = STATUS_FAILED;
245
}
246
if (inf.icount != classes[eventsCount].icount) {
247
printf("(#%" PRIuPTR ") wrong number of interfaces: 0x%x",
248
eventsCount, inf.icount);
249
printf(", expected: 0x%x\n", classes[eventsCount].icount);
250
result = STATUS_FAILED;
251
}
252
eventsCount++;
253
}
254
255
#ifdef STATIC_BUILD
256
JNIEXPORT jint JNICALL Agent_OnLoad_classprep001(JavaVM *jvm, char *options, void *reserved) {
257
return Agent_Initialize(jvm, options, reserved);
258
}
259
JNIEXPORT jint JNICALL Agent_OnAttach_classprep001(JavaVM *jvm, char *options, void *reserved) {
260
return Agent_Initialize(jvm, options, reserved);
261
}
262
JNIEXPORT jint JNI_OnLoad_classprep001(JavaVM *jvm, char *options, void *reserved) {
263
return JNI_VERSION_1_8;
264
}
265
#endif
266
jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
267
jvmtiError err;
268
jint res;
269
270
if (options != NULL && strcmp(options, "printdump") == 0) {
271
printdump = JNI_TRUE;
272
}
273
274
res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
275
if (res != JNI_OK || jvmti == NULL) {
276
printf("Wrong result of a valid call to GetEnv!\n");
277
return JNI_ERR;
278
}
279
280
callbacks.ClassPrepare = &ClassPrepare;
281
err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
282
if (err != JVMTI_ERROR_NONE) {
283
printf("(SetEventCallbacks) unexpected error: %s (%d)\n",
284
TranslateError(err), err);
285
return JNI_ERR;
286
}
287
288
return JNI_OK;
289
}
290
291
JNIEXPORT void JNICALL
292
Java_nsk_jvmti_ClassPrepare_classprep001_getReady(JNIEnv *env, jclass cls, jthread thread) {
293
jvmtiError err;
294
295
if (jvmti == NULL) {
296
printf("JVMTI client was not properly loaded!\n");
297
return;
298
}
299
300
err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
301
JVMTI_EVENT_CLASS_PREPARE, thread);
302
if (err == JVMTI_ERROR_NONE) {
303
eventsExpected = sizeof(classes)/sizeof(class_info);
304
} else {
305
printf("Failed to enable JVMTI_EVENT_CLASS_PREPARE: %s (%d)\n",
306
TranslateError(err), err);
307
result = STATUS_FAILED;
308
}
309
}
310
311
JNIEXPORT jint JNICALL
312
Java_nsk_jvmti_ClassPrepare_classprep001_check(JNIEnv *env, jclass cls, jthread thread) {
313
jvmtiError err;
314
315
if (jvmti == NULL) {
316
printf("JVMTI client was not properly loaded!\n");
317
return STATUS_FAILED;
318
}
319
320
err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,
321
JVMTI_EVENT_CLASS_PREPARE, thread);
322
if (err != JVMTI_ERROR_NONE) {
323
printf("Failed to disable JVMTI_EVENT_CLASS_PREPARE: %s (%d)\n",
324
TranslateError(err), err);
325
result = STATUS_FAILED;
326
}
327
328
if (eventsCount != eventsExpected) {
329
printf("Wrong number of class prepare events: %" PRIuPTR ", expected: %" PRIuPTR "\n",
330
eventsCount, eventsExpected);
331
result = STATUS_FAILED;
332
}
333
return result;
334
}
335
336
}
337
338