Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/tracing/dtrace/JVM.c
38918 views
1
/*
2
* Copyright (c) 2008, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include <stdlib.h>
27
28
#include "jvm.h"
29
#include "jni.h"
30
#include "jni_util.h"
31
32
#include "jvm_symbols.h"
33
#include "sun_tracing_dtrace_JVM.h"
34
35
#ifdef __cplusplus
36
extern "C" {
37
#endif
38
39
static JvmSymbols* jvm_symbols = NULL;
40
41
static void initialize() {
42
static int initialized = 0;
43
if (initialized == 0) {
44
jvm_symbols = lookupJvmSymbols();
45
initialized = 1;
46
}
47
}
48
49
/*
50
* Class: sun_tracing_dtrace_JVM
51
* Method: isSupported0
52
* Signature: ()I
53
*/
54
JNIEXPORT jboolean JNICALL Java_sun_tracing_dtrace_JVM_isSupported0(
55
JNIEnv* env, jclass cls) {
56
initialize();
57
if (jvm_symbols != NULL) {
58
return jvm_symbols->IsSupported(env) ? JNI_TRUE : JNI_FALSE;
59
} else {
60
return JNI_FALSE;
61
}
62
}
63
64
// Macros that cause an immediate return if we detect an exception
65
#define CHECK if ((*env)->ExceptionOccurred(env)) { return; }
66
#define CHECK_(x) if ((*env)->ExceptionOccurred(env)) { return x; }
67
68
static void readProbeData (
69
JNIEnv* env, jobject probe, JVM_DTraceProbe* jvm_probe) {
70
jclass clazz;
71
jmethodID mid;
72
jobject method;
73
74
if (jvm_probe == NULL) {
75
return; // just in case
76
}
77
78
clazz = (*env)->GetObjectClass(env, probe); CHECK
79
80
mid = (*env)->GetMethodID(
81
env, clazz, "getFunctionName", "()Ljava/lang/String;"); CHECK
82
jvm_probe->function = (jstring)(*env)->CallObjectMethod(
83
env, probe, mid); CHECK
84
85
mid = (*env)->GetMethodID(
86
env, clazz, "getProbeName", "()Ljava/lang/String;"); CHECK
87
jvm_probe->name = (jstring)(*env)->CallObjectMethod(env, probe, mid); CHECK
88
89
mid = (*env)->GetMethodID(
90
env, clazz, "getMethod", "()Ljava/lang/reflect/Method;"); CHECK
91
method = (*env)->CallObjectMethod(env, probe, mid); CHECK
92
jvm_probe->method = (*env)->FromReflectedMethod(env, method); CHECK
93
}
94
95
static void readFieldInterfaceAttributes(
96
char* annotationName, JNIEnv* env, jobject provider,
97
JVM_DTraceInterfaceAttributes* attrs) {
98
jobject result;
99
jobject result_clazz;
100
jclass provider_clazz;
101
jclass annotation_clazz;
102
jmethodID get;
103
jmethodID enc;
104
105
provider_clazz = (*env)->GetObjectClass(env, provider); CHECK
106
annotation_clazz = (*env)->FindClass(env, annotationName); CHECK
107
108
get = (*env)->GetMethodID(env, provider_clazz, "getNameStabilityFor",
109
"(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/StabilityLevel;"); CHECK
110
result = (*env)->CallObjectMethod(
111
env, provider, get, annotation_clazz); CHECK
112
result_clazz = (*env)->GetObjectClass(env, result); CHECK
113
enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK
114
attrs->nameStability = (*env)->CallIntMethod(env, result, enc); CHECK
115
116
get = (*env)->GetMethodID(env, provider_clazz, "getDataStabilityFor",
117
"(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/StabilityLevel;"); CHECK
118
result = (*env)->CallObjectMethod(
119
env, provider, get, annotation_clazz); CHECK
120
result_clazz = (*env)->GetObjectClass(env, result); CHECK
121
enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK
122
attrs->dataStability = (*env)->CallIntMethod(env, result, enc); CHECK
123
124
get = (*env)->GetMethodID(env, provider_clazz, "getDependencyClassFor",
125
"(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/DependencyClass;"); CHECK
126
result = (*env)->CallObjectMethod(
127
env, provider, get, annotation_clazz); CHECK
128
result_clazz = (*env)->GetObjectClass(env, result); CHECK
129
enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK
130
attrs->dependencyClass = (*env)->CallIntMethod(env, result, enc); CHECK
131
}
132
133
static void readInterfaceAttributes(
134
JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) {
135
readFieldInterfaceAttributes("com/sun/tracing/dtrace/ProviderAttributes",
136
env, provider, &(jvm_provider->providerAttributes));
137
readFieldInterfaceAttributes("com/sun/tracing/dtrace/ModuleAttributes",
138
env, provider, &(jvm_provider->moduleAttributes));
139
readFieldInterfaceAttributes("com/sun/tracing/dtrace/FunctionAttributes",
140
env, provider, &(jvm_provider->functionAttributes));
141
readFieldInterfaceAttributes("com/sun/tracing/dtrace/NameAttributes",
142
env, provider, &(jvm_provider->nameAttributes));
143
readFieldInterfaceAttributes("com/sun/tracing/dtrace/ArgsAttributes",
144
env, provider, &(jvm_provider->argsAttributes));
145
}
146
147
static int readProviderData(
148
JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) {
149
jmethodID mid;
150
jobjectArray probes;
151
jsize i;
152
jclass clazz = (*env)->GetObjectClass(env, provider); CHECK_(0)
153
mid = (*env)->GetMethodID(
154
env, clazz, "getProbes", "()[Lsun/tracing/dtrace/DTraceProbe;"); CHECK_(0)
155
probes = (jobjectArray)(*env)->CallObjectMethod(
156
env, provider, mid); CHECK_(0)
157
158
// Fill JVM structure, describing provider
159
jvm_provider->probe_count = (*env)->GetArrayLength(env, probes); CHECK_(0)
160
jvm_provider->probes = (JVM_DTraceProbe*)calloc(
161
jvm_provider->probe_count, sizeof(*jvm_provider->probes));
162
mid = (*env)->GetMethodID(
163
env, clazz, "getProviderName", "()Ljava/lang/String;"); CHECK_(0)
164
jvm_provider->name = (jstring)(*env)->CallObjectMethod(
165
env, provider, mid); CHECK_(0)
166
167
readInterfaceAttributes(env, provider, jvm_provider); CHECK_(0)
168
169
for (i = 0; i < jvm_provider->probe_count; ++i) {
170
jobject probe = (*env)->GetObjectArrayElement(env, probes, i); CHECK_(0)
171
readProbeData(env, probe, &jvm_provider->probes[i]); CHECK_(0)
172
}
173
174
return 1;
175
}
176
177
/*
178
* Class: sun_tracing_dtrace_JVM
179
* Method: activate0
180
* Signature: ()J
181
*/
182
JNIEXPORT jlong JNICALL Java_sun_tracing_dtrace_JVM_activate0(
183
JNIEnv* env, jclass cls, jstring moduleName, jobjectArray providers) {
184
jlong handle = 0;
185
jsize num_providers;
186
jsize i;
187
jsize count = 0;
188
JVM_DTraceProvider* jvm_providers;
189
190
initialize();
191
192
if (jvm_symbols == NULL) {
193
return 0;
194
}
195
196
num_providers = (*env)->GetArrayLength(env, providers); CHECK_(0L)
197
198
jvm_providers = (JVM_DTraceProvider*)calloc(
199
num_providers, sizeof(*jvm_providers));
200
201
for (; count < num_providers; ++count) {
202
JVM_DTraceProvider* p = &(jvm_providers[count]);
203
jobject provider = (*env)->GetObjectArrayElement(
204
env, providers, count);
205
if ((*env)->ExceptionOccurred(env) ||
206
! readProviderData(env, provider, p)) {
207
// got an error, bail out!
208
break;
209
}
210
}
211
212
if (count == num_providers) {
213
// all providers successfully loaded - get the handle
214
handle = jvm_symbols->Activate(
215
env, JVM_TRACING_DTRACE_VERSION, moduleName,
216
num_providers, jvm_providers);
217
}
218
219
for (i = 0; i < num_providers; ++i) {
220
JVM_DTraceProvider* p = &(jvm_providers[i]);
221
free(p->probes);
222
}
223
free(jvm_providers);
224
225
return handle;
226
}
227
228
/*
229
* Class: sun_tracing_dtrace_JVM
230
* Method: dispose0
231
* Signature: (J)V
232
*/
233
JNIEXPORT void JNICALL Java_sun_tracing_dtrace_JVM_dispose0(
234
JNIEnv* env, jclass cls, jlong handle) {
235
if (jvm_symbols != NULL && handle != 0) {
236
jvm_symbols->Dispose(env, handle);
237
}
238
}
239
240
/*
241
* Class: sun_tracing_dtrace_JVM
242
* Method: isEnabled0
243
* Signature: (Ljava/lang/String;Ljava/lang/String;)Z
244
*/
245
JNIEXPORT jboolean JNICALL Java_sun_tracing_dtrace_JVM_isEnabled0(
246
JNIEnv* env, jclass cls, jobject method) {
247
jmethodID mid;
248
if (jvm_symbols != NULL && method != NULL) {
249
mid = (*env)->FromReflectedMethod(env, method);
250
return jvm_symbols->IsProbeEnabled(env, mid);
251
}
252
return JNI_FALSE;
253
}
254
255
/*
256
* Class: sun_tracing_dtrace_JVM
257
* Method: defineClass0
258
* Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BII)Ljava/lang/Class;
259
*
260
* The implementation of this native static method is a copy of that of
261
* the native instance method Java_java_lang_ClassLoader_defineClass0()
262
* with the implicit "this" parameter becoming the "loader" parameter.
263
*
264
* This code was cloned and modified from java_lang_reflect_Proxy
265
*/
266
JNIEXPORT jclass JNICALL
267
Java_sun_tracing_dtrace_JVM_defineClass0(
268
JNIEnv *env, jclass ignore, jobject loader, jstring name, jbyteArray data,
269
jint offset, jint length)
270
{
271
jbyte *body;
272
char *utfName;
273
jclass result = 0;
274
char buf[128];
275
276
if (data == NULL) {
277
return 0;
278
}
279
280
/* Work around 4153825. malloc crashes on Solaris when passed a
281
* negative size.
282
*/
283
if (length < 0) {
284
return 0;
285
}
286
287
body = (jbyte *)malloc(length);
288
289
if (body == 0) {
290
return 0;
291
}
292
293
(*env)->GetByteArrayRegion(env, data, offset, length, body);
294
295
if ((*env)->ExceptionOccurred(env))
296
goto free_body;
297
298
if (name != NULL) {
299
int i;
300
int len = (*env)->GetStringUTFLength(env, name);
301
int unicode_len = (*env)->GetStringLength(env, name);
302
if (len >= sizeof(buf)) {
303
utfName = malloc(len + 1);
304
if (utfName == NULL) {
305
goto free_body;
306
}
307
} else {
308
utfName = buf;
309
}
310
(*env)->GetStringUTFRegion(env, name, 0, unicode_len, utfName);
311
312
// Convert '.' to '/' in the package name
313
for (i = 0; i < unicode_len; ++i) {
314
if (utfName[i] == '.') {
315
utfName[i] = '/';
316
}
317
}
318
} else {
319
utfName = NULL;
320
}
321
322
result = (*env)->DefineClass(env, utfName, loader, body, length);
323
324
if (utfName && utfName != buf)
325
free(utfName);
326
327
free_body:
328
free(body);
329
return result;
330
}
331
332
#ifdef __cplusplus
333
}
334
#endif
335
336