Path: blob/master/src/hotspot/share/prims/jvmtiExtensions.cpp
41145 views
/*1* Copyright (c) 2003, 2019, 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.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "prims/jvmtiExport.hpp"26#include "prims/jvmtiExtensions.hpp"2728// the list of extension functions29GrowableArray<jvmtiExtensionFunctionInfo*>* JvmtiExtensions::_ext_functions;3031// the list of extension events32GrowableArray<jvmtiExtensionEventInfo*>* JvmtiExtensions::_ext_events;333435// extension function36static jvmtiError JNICALL IsClassUnloadingEnabled(const jvmtiEnv* env, ...) {37jboolean* enabled = NULL;38va_list ap;3940va_start(ap, env);41enabled = va_arg(ap, jboolean *);42va_end(ap);4344if (enabled == NULL) {45return JVMTI_ERROR_NULL_POINTER;46}47*enabled = (jboolean)ClassUnloading;48return JVMTI_ERROR_NONE;49}5051// register extension functions and events. In this implementation we52// have a single extension function (to prove the API) that tests if class53// unloading is enabled or disabled. We also have a single extension event54// EXT_EVENT_CLASS_UNLOAD which is used to provide the JVMDI_EVENT_CLASS_UNLOAD55// event. The function and the event are registered here.56//57void JvmtiExtensions::register_extensions() {58_ext_functions = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiExtensionFunctionInfo*>(1, mtServiceability);59_ext_events = new (ResourceObj::C_HEAP, mtServiceability) GrowableArray<jvmtiExtensionEventInfo*>(1, mtServiceability);6061// register our extension function62static jvmtiParamInfo func_params[] = {63{ (char*)"IsClassUnloadingEnabled", JVMTI_KIND_OUT, JVMTI_TYPE_JBOOLEAN, JNI_FALSE }64};65static jvmtiExtensionFunctionInfo ext_func = {66(jvmtiExtensionFunction)IsClassUnloadingEnabled,67(char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled",68(char*)"Tell if class unloading is enabled (-noclassgc)",69sizeof(func_params)/sizeof(func_params[0]),70func_params,710, // no non-universal errors72NULL73};74_ext_functions->append(&ext_func);7576// register our extension event7778static jvmtiParamInfo event_params[] = {79{ (char*)"JNI Environment", JVMTI_KIND_IN_PTR, JVMTI_TYPE_JNIENV, JNI_FALSE },80{ (char*)"Class", JVMTI_KIND_IN_PTR, JVMTI_TYPE_CCHAR, JNI_FALSE }81};82static jvmtiExtensionEventInfo ext_event = {83EXT_EVENT_CLASS_UNLOAD,84(char*)"com.sun.hotspot.events.ClassUnload",85(char*)"CLASS_UNLOAD event",86sizeof(event_params)/sizeof(event_params[0]),87event_params88};89_ext_events->append(&ext_event);90}919293// return the list of extension functions9495jvmtiError JvmtiExtensions::get_functions(JvmtiEnv* env,96jint* extension_count_ptr,97jvmtiExtensionFunctionInfo** extensions)98{99guarantee(_ext_functions != NULL, "registration not done");100101ResourceTracker rt(env);102103jvmtiExtensionFunctionInfo* ext_funcs;104jvmtiError err = rt.allocate(_ext_functions->length() *105sizeof(jvmtiExtensionFunctionInfo),106(unsigned char**)&ext_funcs);107if (err != JVMTI_ERROR_NONE) {108return err;109}110111for (int i=0; i<_ext_functions->length(); i++ ) {112ext_funcs[i].func = _ext_functions->at(i)->func;113114char *id = _ext_functions->at(i)->id;115err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_funcs[i].id));116if (err != JVMTI_ERROR_NONE) {117return err;118}119strcpy(ext_funcs[i].id, id);120121char *desc = _ext_functions->at(i)->short_description;122err = rt.allocate(strlen(desc)+1,123(unsigned char**)&(ext_funcs[i].short_description));124if (err != JVMTI_ERROR_NONE) {125return err;126}127strcpy(ext_funcs[i].short_description, desc);128129// params130131jint param_count = _ext_functions->at(i)->param_count;132133ext_funcs[i].param_count = param_count;134if (param_count == 0) {135ext_funcs[i].params = NULL;136} else {137err = rt.allocate(param_count*sizeof(jvmtiParamInfo),138(unsigned char**)&(ext_funcs[i].params));139if (err != JVMTI_ERROR_NONE) {140return err;141}142jvmtiParamInfo* src_params = _ext_functions->at(i)->params;143jvmtiParamInfo* dst_params = ext_funcs[i].params;144145for (int j=0; j<param_count; j++) {146err = rt.allocate(strlen(src_params[j].name)+1,147(unsigned char**)&(dst_params[j].name));148if (err != JVMTI_ERROR_NONE) {149return err;150}151strcpy(dst_params[j].name, src_params[j].name);152153dst_params[j].kind = src_params[j].kind;154dst_params[j].base_type = src_params[j].base_type;155dst_params[j].null_ok = src_params[j].null_ok;156}157}158159// errors160161jint error_count = _ext_functions->at(i)->error_count;162ext_funcs[i].error_count = error_count;163if (error_count == 0) {164ext_funcs[i].errors = NULL;165} else {166err = rt.allocate(error_count*sizeof(jvmtiError),167(unsigned char**)&(ext_funcs[i].errors));168if (err != JVMTI_ERROR_NONE) {169return err;170}171memcpy(ext_funcs[i].errors, _ext_functions->at(i)->errors,172error_count*sizeof(jvmtiError));173}174}175176*extension_count_ptr = _ext_functions->length();177*extensions = ext_funcs;178return JVMTI_ERROR_NONE;179}180181182// return the list of extension events183184jvmtiError JvmtiExtensions::get_events(JvmtiEnv* env,185jint* extension_count_ptr,186jvmtiExtensionEventInfo** extensions)187{188guarantee(_ext_events != NULL, "registration not done");189190ResourceTracker rt(env);191192jvmtiExtensionEventInfo* ext_events;193jvmtiError err = rt.allocate(_ext_events->length() * sizeof(jvmtiExtensionEventInfo),194(unsigned char**)&ext_events);195if (err != JVMTI_ERROR_NONE) {196return err;197}198199for (int i=0; i<_ext_events->length(); i++ ) {200ext_events[i].extension_event_index = _ext_events->at(i)->extension_event_index;201202char *id = _ext_events->at(i)->id;203err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_events[i].id));204if (err != JVMTI_ERROR_NONE) {205return err;206}207strcpy(ext_events[i].id, id);208209char *desc = _ext_events->at(i)->short_description;210err = rt.allocate(strlen(desc)+1,211(unsigned char**)&(ext_events[i].short_description));212if (err != JVMTI_ERROR_NONE) {213return err;214}215strcpy(ext_events[i].short_description, desc);216217// params218219jint param_count = _ext_events->at(i)->param_count;220221ext_events[i].param_count = param_count;222if (param_count == 0) {223ext_events[i].params = NULL;224} else {225err = rt.allocate(param_count*sizeof(jvmtiParamInfo),226(unsigned char**)&(ext_events[i].params));227if (err != JVMTI_ERROR_NONE) {228return err;229}230jvmtiParamInfo* src_params = _ext_events->at(i)->params;231jvmtiParamInfo* dst_params = ext_events[i].params;232233for (int j=0; j<param_count; j++) {234err = rt.allocate(strlen(src_params[j].name)+1,235(unsigned char**)&(dst_params[j].name));236if (err != JVMTI_ERROR_NONE) {237return err;238}239strcpy(dst_params[j].name, src_params[j].name);240241dst_params[j].kind = src_params[j].kind;242dst_params[j].base_type = src_params[j].base_type;243dst_params[j].null_ok = src_params[j].null_ok;244}245}246}247248*extension_count_ptr = _ext_events->length();249*extensions = ext_events;250return JVMTI_ERROR_NONE;251}252253// set callback for an extension event and enable/disable it.254255jvmtiError JvmtiExtensions::set_event_callback(JvmtiEnv* env,256jint extension_event_index,257jvmtiExtensionEvent callback)258{259guarantee(_ext_events != NULL, "registration not done");260261jvmtiExtensionEventInfo* event = NULL;262263// if there are extension events registered then validate that the264// extension_event_index matches one of the registered events.265if (_ext_events != NULL) {266for (int i=0; i<_ext_events->length(); i++ ) {267if (_ext_events->at(i)->extension_event_index == extension_event_index) {268event = _ext_events->at(i);269break;270}271}272}273274// invalid event index275if (event == NULL) {276return JVMTI_ERROR_ILLEGAL_ARGUMENT;277}278279JvmtiEventController::set_extension_event_callback(env, extension_event_index,280callback);281282return JVMTI_ERROR_NONE;283}284285286