Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/tracing/dtrace/JVM.c
38918 views
/*1* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <stdlib.h>2627#include "jvm.h"28#include "jni.h"29#include "jni_util.h"3031#include "jvm_symbols.h"32#include "sun_tracing_dtrace_JVM.h"3334#ifdef __cplusplus35extern "C" {36#endif3738static JvmSymbols* jvm_symbols = NULL;3940static void initialize() {41static int initialized = 0;42if (initialized == 0) {43jvm_symbols = lookupJvmSymbols();44initialized = 1;45}46}4748/*49* Class: sun_tracing_dtrace_JVM50* Method: isSupported051* Signature: ()I52*/53JNIEXPORT jboolean JNICALL Java_sun_tracing_dtrace_JVM_isSupported0(54JNIEnv* env, jclass cls) {55initialize();56if (jvm_symbols != NULL) {57return jvm_symbols->IsSupported(env) ? JNI_TRUE : JNI_FALSE;58} else {59return JNI_FALSE;60}61}6263// Macros that cause an immediate return if we detect an exception64#define CHECK if ((*env)->ExceptionOccurred(env)) { return; }65#define CHECK_(x) if ((*env)->ExceptionOccurred(env)) { return x; }6667static void readProbeData (68JNIEnv* env, jobject probe, JVM_DTraceProbe* jvm_probe) {69jclass clazz;70jmethodID mid;71jobject method;7273if (jvm_probe == NULL) {74return; // just in case75}7677clazz = (*env)->GetObjectClass(env, probe); CHECK7879mid = (*env)->GetMethodID(80env, clazz, "getFunctionName", "()Ljava/lang/String;"); CHECK81jvm_probe->function = (jstring)(*env)->CallObjectMethod(82env, probe, mid); CHECK8384mid = (*env)->GetMethodID(85env, clazz, "getProbeName", "()Ljava/lang/String;"); CHECK86jvm_probe->name = (jstring)(*env)->CallObjectMethod(env, probe, mid); CHECK8788mid = (*env)->GetMethodID(89env, clazz, "getMethod", "()Ljava/lang/reflect/Method;"); CHECK90method = (*env)->CallObjectMethod(env, probe, mid); CHECK91jvm_probe->method = (*env)->FromReflectedMethod(env, method); CHECK92}9394static void readFieldInterfaceAttributes(95char* annotationName, JNIEnv* env, jobject provider,96JVM_DTraceInterfaceAttributes* attrs) {97jobject result;98jobject result_clazz;99jclass provider_clazz;100jclass annotation_clazz;101jmethodID get;102jmethodID enc;103104provider_clazz = (*env)->GetObjectClass(env, provider); CHECK105annotation_clazz = (*env)->FindClass(env, annotationName); CHECK106107get = (*env)->GetMethodID(env, provider_clazz, "getNameStabilityFor",108"(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/StabilityLevel;"); CHECK109result = (*env)->CallObjectMethod(110env, provider, get, annotation_clazz); CHECK111result_clazz = (*env)->GetObjectClass(env, result); CHECK112enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK113attrs->nameStability = (*env)->CallIntMethod(env, result, enc); CHECK114115get = (*env)->GetMethodID(env, provider_clazz, "getDataStabilityFor",116"(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/StabilityLevel;"); CHECK117result = (*env)->CallObjectMethod(118env, provider, get, annotation_clazz); CHECK119result_clazz = (*env)->GetObjectClass(env, result); CHECK120enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK121attrs->dataStability = (*env)->CallIntMethod(env, result, enc); CHECK122123get = (*env)->GetMethodID(env, provider_clazz, "getDependencyClassFor",124"(Ljava/lang/Class;)Lcom/sun/tracing/dtrace/DependencyClass;"); CHECK125result = (*env)->CallObjectMethod(126env, provider, get, annotation_clazz); CHECK127result_clazz = (*env)->GetObjectClass(env, result); CHECK128enc = (*env)->GetMethodID(env, result_clazz, "getEncoding", "()I"); CHECK129attrs->dependencyClass = (*env)->CallIntMethod(env, result, enc); CHECK130}131132static void readInterfaceAttributes(133JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) {134readFieldInterfaceAttributes("com/sun/tracing/dtrace/ProviderAttributes",135env, provider, &(jvm_provider->providerAttributes));136readFieldInterfaceAttributes("com/sun/tracing/dtrace/ModuleAttributes",137env, provider, &(jvm_provider->moduleAttributes));138readFieldInterfaceAttributes("com/sun/tracing/dtrace/FunctionAttributes",139env, provider, &(jvm_provider->functionAttributes));140readFieldInterfaceAttributes("com/sun/tracing/dtrace/NameAttributes",141env, provider, &(jvm_provider->nameAttributes));142readFieldInterfaceAttributes("com/sun/tracing/dtrace/ArgsAttributes",143env, provider, &(jvm_provider->argsAttributes));144}145146static int readProviderData(147JNIEnv* env, jobject provider, JVM_DTraceProvider* jvm_provider) {148jmethodID mid;149jobjectArray probes;150jsize i;151jclass clazz = (*env)->GetObjectClass(env, provider); CHECK_(0)152mid = (*env)->GetMethodID(153env, clazz, "getProbes", "()[Lsun/tracing/dtrace/DTraceProbe;"); CHECK_(0)154probes = (jobjectArray)(*env)->CallObjectMethod(155env, provider, mid); CHECK_(0)156157// Fill JVM structure, describing provider158jvm_provider->probe_count = (*env)->GetArrayLength(env, probes); CHECK_(0)159jvm_provider->probes = (JVM_DTraceProbe*)calloc(160jvm_provider->probe_count, sizeof(*jvm_provider->probes));161mid = (*env)->GetMethodID(162env, clazz, "getProviderName", "()Ljava/lang/String;"); CHECK_(0)163jvm_provider->name = (jstring)(*env)->CallObjectMethod(164env, provider, mid); CHECK_(0)165166readInterfaceAttributes(env, provider, jvm_provider); CHECK_(0)167168for (i = 0; i < jvm_provider->probe_count; ++i) {169jobject probe = (*env)->GetObjectArrayElement(env, probes, i); CHECK_(0)170readProbeData(env, probe, &jvm_provider->probes[i]); CHECK_(0)171}172173return 1;174}175176/*177* Class: sun_tracing_dtrace_JVM178* Method: activate0179* Signature: ()J180*/181JNIEXPORT jlong JNICALL Java_sun_tracing_dtrace_JVM_activate0(182JNIEnv* env, jclass cls, jstring moduleName, jobjectArray providers) {183jlong handle = 0;184jsize num_providers;185jsize i;186jsize count = 0;187JVM_DTraceProvider* jvm_providers;188189initialize();190191if (jvm_symbols == NULL) {192return 0;193}194195num_providers = (*env)->GetArrayLength(env, providers); CHECK_(0L)196197jvm_providers = (JVM_DTraceProvider*)calloc(198num_providers, sizeof(*jvm_providers));199200for (; count < num_providers; ++count) {201JVM_DTraceProvider* p = &(jvm_providers[count]);202jobject provider = (*env)->GetObjectArrayElement(203env, providers, count);204if ((*env)->ExceptionOccurred(env) ||205! readProviderData(env, provider, p)) {206// got an error, bail out!207break;208}209}210211if (count == num_providers) {212// all providers successfully loaded - get the handle213handle = jvm_symbols->Activate(214env, JVM_TRACING_DTRACE_VERSION, moduleName,215num_providers, jvm_providers);216}217218for (i = 0; i < num_providers; ++i) {219JVM_DTraceProvider* p = &(jvm_providers[i]);220free(p->probes);221}222free(jvm_providers);223224return handle;225}226227/*228* Class: sun_tracing_dtrace_JVM229* Method: dispose0230* Signature: (J)V231*/232JNIEXPORT void JNICALL Java_sun_tracing_dtrace_JVM_dispose0(233JNIEnv* env, jclass cls, jlong handle) {234if (jvm_symbols != NULL && handle != 0) {235jvm_symbols->Dispose(env, handle);236}237}238239/*240* Class: sun_tracing_dtrace_JVM241* Method: isEnabled0242* Signature: (Ljava/lang/String;Ljava/lang/String;)Z243*/244JNIEXPORT jboolean JNICALL Java_sun_tracing_dtrace_JVM_isEnabled0(245JNIEnv* env, jclass cls, jobject method) {246jmethodID mid;247if (jvm_symbols != NULL && method != NULL) {248mid = (*env)->FromReflectedMethod(env, method);249return jvm_symbols->IsProbeEnabled(env, mid);250}251return JNI_FALSE;252}253254/*255* Class: sun_tracing_dtrace_JVM256* Method: defineClass0257* Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BII)Ljava/lang/Class;258*259* The implementation of this native static method is a copy of that of260* the native instance method Java_java_lang_ClassLoader_defineClass0()261* with the implicit "this" parameter becoming the "loader" parameter.262*263* This code was cloned and modified from java_lang_reflect_Proxy264*/265JNIEXPORT jclass JNICALL266Java_sun_tracing_dtrace_JVM_defineClass0(267JNIEnv *env, jclass ignore, jobject loader, jstring name, jbyteArray data,268jint offset, jint length)269{270jbyte *body;271char *utfName;272jclass result = 0;273char buf[128];274275if (data == NULL) {276return 0;277}278279/* Work around 4153825. malloc crashes on Solaris when passed a280* negative size.281*/282if (length < 0) {283return 0;284}285286body = (jbyte *)malloc(length);287288if (body == 0) {289return 0;290}291292(*env)->GetByteArrayRegion(env, data, offset, length, body);293294if ((*env)->ExceptionOccurred(env))295goto free_body;296297if (name != NULL) {298int i;299int len = (*env)->GetStringUTFLength(env, name);300int unicode_len = (*env)->GetStringLength(env, name);301if (len >= sizeof(buf)) {302utfName = malloc(len + 1);303if (utfName == NULL) {304goto free_body;305}306} else {307utfName = buf;308}309(*env)->GetStringUTFRegion(env, name, 0, unicode_len, utfName);310311// Convert '.' to '/' in the package name312for (i = 0; i < unicode_len; ++i) {313if (utfName[i] == '.') {314utfName[i] = '/';315}316}317} else {318utfName = NULL;319}320321result = (*env)->DefineClass(env, utfName, loader, body, length);322323if (utfName && utfName != buf)324free(utfName);325326free_body:327free(body);328return result;329}330331#ifdef __cplusplus332}333#endif334335336