1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/jvmtiExtensions.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,278 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "prims/jvmtiExport.hpp" 1.30 +#include "prims/jvmtiExtensions.hpp" 1.31 + 1.32 +// the list of extension functions 1.33 +GrowableArray<jvmtiExtensionFunctionInfo*>* JvmtiExtensions::_ext_functions; 1.34 + 1.35 +// the list of extension events 1.36 +GrowableArray<jvmtiExtensionEventInfo*>* JvmtiExtensions::_ext_events; 1.37 + 1.38 + 1.39 +// extension function 1.40 +static jvmtiError JNICALL IsClassUnloadingEnabled(const jvmtiEnv* env, jboolean* enabled, ...) { 1.41 + if (enabled == NULL) { 1.42 + return JVMTI_ERROR_NULL_POINTER; 1.43 + } 1.44 + *enabled = (jboolean)ClassUnloading; 1.45 + return JVMTI_ERROR_NONE; 1.46 +} 1.47 + 1.48 +// register extension functions and events. In this implementation we 1.49 +// have a single extension function (to prove the API) that tests if class 1.50 +// unloading is enabled or disabled. We also have a single extension event 1.51 +// EXT_EVENT_CLASS_UNLOAD which is used to provide the JVMDI_EVENT_CLASS_UNLOAD 1.52 +// event. The function and the event are registered here. 1.53 +// 1.54 +void JvmtiExtensions::register_extensions() { 1.55 + _ext_functions = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiExtensionFunctionInfo*>(1,true); 1.56 + _ext_events = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiExtensionEventInfo*>(1,true); 1.57 + 1.58 + // register our extension function 1.59 + static jvmtiParamInfo func_params[] = { 1.60 + { (char*)"IsClassUnloadingEnabled", JVMTI_KIND_OUT, JVMTI_TYPE_JBOOLEAN, JNI_FALSE } 1.61 + }; 1.62 + static jvmtiExtensionFunctionInfo ext_func = { 1.63 + (jvmtiExtensionFunction)IsClassUnloadingEnabled, 1.64 + (char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled", 1.65 + (char*)"Tell if class unloading is enabled (-noclassgc)", 1.66 + sizeof(func_params)/sizeof(func_params[0]), 1.67 + func_params, 1.68 + 0, // no non-universal errors 1.69 + NULL 1.70 + }; 1.71 + _ext_functions->append(&ext_func); 1.72 + 1.73 + // register our extension event 1.74 + 1.75 + static jvmtiParamInfo event_params[] = { 1.76 + { (char*)"JNI Environment", JVMTI_KIND_IN, JVMTI_TYPE_JNIENV, JNI_FALSE }, 1.77 + { (char*)"Thread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE }, 1.78 + { (char*)"Class", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, JNI_FALSE } 1.79 + }; 1.80 + static jvmtiExtensionEventInfo ext_event = { 1.81 + EXT_EVENT_CLASS_UNLOAD, 1.82 + (char*)"com.sun.hotspot.events.ClassUnload", 1.83 + (char*)"CLASS_UNLOAD event", 1.84 + sizeof(event_params)/sizeof(event_params[0]), 1.85 + event_params 1.86 + }; 1.87 + _ext_events->append(&ext_event); 1.88 +} 1.89 + 1.90 + 1.91 +// return the list of extension functions 1.92 + 1.93 +jvmtiError JvmtiExtensions::get_functions(JvmtiEnv* env, 1.94 + jint* extension_count_ptr, 1.95 + jvmtiExtensionFunctionInfo** extensions) 1.96 +{ 1.97 + guarantee(_ext_functions != NULL, "registration not done"); 1.98 + 1.99 + ResourceTracker rt(env); 1.100 + 1.101 + jvmtiExtensionFunctionInfo* ext_funcs; 1.102 + jvmtiError err = rt.allocate(_ext_functions->length() * 1.103 + sizeof(jvmtiExtensionFunctionInfo), 1.104 + (unsigned char**)&ext_funcs); 1.105 + if (err != JVMTI_ERROR_NONE) { 1.106 + return err; 1.107 + } 1.108 + 1.109 + for (int i=0; i<_ext_functions->length(); i++ ) { 1.110 + ext_funcs[i].func = _ext_functions->at(i)->func; 1.111 + 1.112 + char *id = _ext_functions->at(i)->id; 1.113 + err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_funcs[i].id)); 1.114 + if (err != JVMTI_ERROR_NONE) { 1.115 + return err; 1.116 + } 1.117 + strcpy(ext_funcs[i].id, id); 1.118 + 1.119 + char *desc = _ext_functions->at(i)->short_description; 1.120 + err = rt.allocate(strlen(desc)+1, 1.121 + (unsigned char**)&(ext_funcs[i].short_description)); 1.122 + if (err != JVMTI_ERROR_NONE) { 1.123 + return err; 1.124 + } 1.125 + strcpy(ext_funcs[i].short_description, desc); 1.126 + 1.127 + // params 1.128 + 1.129 + jint param_count = _ext_functions->at(i)->param_count; 1.130 + 1.131 + ext_funcs[i].param_count = param_count; 1.132 + if (param_count == 0) { 1.133 + ext_funcs[i].params = NULL; 1.134 + } else { 1.135 + err = rt.allocate(param_count*sizeof(jvmtiParamInfo), 1.136 + (unsigned char**)&(ext_funcs[i].params)); 1.137 + if (err != JVMTI_ERROR_NONE) { 1.138 + return err; 1.139 + } 1.140 + jvmtiParamInfo* src_params = _ext_functions->at(i)->params; 1.141 + jvmtiParamInfo* dst_params = ext_funcs[i].params; 1.142 + 1.143 + for (int j=0; j<param_count; j++) { 1.144 + err = rt.allocate(strlen(src_params[j].name)+1, 1.145 + (unsigned char**)&(dst_params[j].name)); 1.146 + if (err != JVMTI_ERROR_NONE) { 1.147 + return err; 1.148 + } 1.149 + strcpy(dst_params[j].name, src_params[j].name); 1.150 + 1.151 + dst_params[j].kind = src_params[j].kind; 1.152 + dst_params[j].base_type = src_params[j].base_type; 1.153 + dst_params[j].null_ok = src_params[j].null_ok; 1.154 + } 1.155 + } 1.156 + 1.157 + // errors 1.158 + 1.159 + jint error_count = _ext_functions->at(i)->error_count; 1.160 + ext_funcs[i].error_count = error_count; 1.161 + if (error_count == 0) { 1.162 + ext_funcs[i].errors = NULL; 1.163 + } else { 1.164 + err = rt.allocate(error_count*sizeof(jvmtiError), 1.165 + (unsigned char**)&(ext_funcs[i].errors)); 1.166 + if (err != JVMTI_ERROR_NONE) { 1.167 + return err; 1.168 + } 1.169 + memcpy(ext_funcs[i].errors, _ext_functions->at(i)->errors, 1.170 + error_count*sizeof(jvmtiError)); 1.171 + } 1.172 + } 1.173 + 1.174 + *extension_count_ptr = _ext_functions->length(); 1.175 + *extensions = ext_funcs; 1.176 + return JVMTI_ERROR_NONE; 1.177 +} 1.178 + 1.179 + 1.180 +// return the list of extension events 1.181 + 1.182 +jvmtiError JvmtiExtensions::get_events(JvmtiEnv* env, 1.183 + jint* extension_count_ptr, 1.184 + jvmtiExtensionEventInfo** extensions) 1.185 +{ 1.186 + guarantee(_ext_events != NULL, "registration not done"); 1.187 + 1.188 + ResourceTracker rt(env); 1.189 + 1.190 + jvmtiExtensionEventInfo* ext_events; 1.191 + jvmtiError err = rt.allocate(_ext_events->length() * sizeof(jvmtiExtensionEventInfo), 1.192 + (unsigned char**)&ext_events); 1.193 + if (err != JVMTI_ERROR_NONE) { 1.194 + return err; 1.195 + } 1.196 + 1.197 + for (int i=0; i<_ext_events->length(); i++ ) { 1.198 + ext_events[i].extension_event_index = _ext_events->at(i)->extension_event_index; 1.199 + 1.200 + char *id = _ext_events->at(i)->id; 1.201 + err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_events[i].id)); 1.202 + if (err != JVMTI_ERROR_NONE) { 1.203 + return err; 1.204 + } 1.205 + strcpy(ext_events[i].id, id); 1.206 + 1.207 + char *desc = _ext_events->at(i)->short_description; 1.208 + err = rt.allocate(strlen(desc)+1, 1.209 + (unsigned char**)&(ext_events[i].short_description)); 1.210 + if (err != JVMTI_ERROR_NONE) { 1.211 + return err; 1.212 + } 1.213 + strcpy(ext_events[i].short_description, desc); 1.214 + 1.215 + // params 1.216 + 1.217 + jint param_count = _ext_events->at(i)->param_count; 1.218 + 1.219 + ext_events[i].param_count = param_count; 1.220 + if (param_count == 0) { 1.221 + ext_events[i].params = NULL; 1.222 + } else { 1.223 + err = rt.allocate(param_count*sizeof(jvmtiParamInfo), 1.224 + (unsigned char**)&(ext_events[i].params)); 1.225 + if (err != JVMTI_ERROR_NONE) { 1.226 + return err; 1.227 + } 1.228 + jvmtiParamInfo* src_params = _ext_events->at(i)->params; 1.229 + jvmtiParamInfo* dst_params = ext_events[i].params; 1.230 + 1.231 + for (int j=0; j<param_count; j++) { 1.232 + err = rt.allocate(strlen(src_params[j].name)+1, 1.233 + (unsigned char**)&(dst_params[j].name)); 1.234 + if (err != JVMTI_ERROR_NONE) { 1.235 + return err; 1.236 + } 1.237 + strcpy(dst_params[j].name, src_params[j].name); 1.238 + 1.239 + dst_params[j].kind = src_params[j].kind; 1.240 + dst_params[j].base_type = src_params[j].base_type; 1.241 + dst_params[j].null_ok = src_params[j].null_ok; 1.242 + } 1.243 + } 1.244 + } 1.245 + 1.246 + *extension_count_ptr = _ext_events->length(); 1.247 + *extensions = ext_events; 1.248 + return JVMTI_ERROR_NONE; 1.249 +} 1.250 + 1.251 +// set callback for an extension event and enable/disable it. 1.252 + 1.253 +jvmtiError JvmtiExtensions::set_event_callback(JvmtiEnv* env, 1.254 + jint extension_event_index, 1.255 + jvmtiExtensionEvent callback) 1.256 +{ 1.257 + guarantee(_ext_events != NULL, "registration not done"); 1.258 + 1.259 + jvmtiExtensionEventInfo* event = NULL; 1.260 + 1.261 + // if there are extension events registered then validate that the 1.262 + // extension_event_index matches one of the registered events. 1.263 + if (_ext_events != NULL) { 1.264 + for (int i=0; i<_ext_events->length(); i++ ) { 1.265 + if (_ext_events->at(i)->extension_event_index == extension_event_index) { 1.266 + event = _ext_events->at(i); 1.267 + break; 1.268 + } 1.269 + } 1.270 + } 1.271 + 1.272 + // invalid event index 1.273 + if (event == NULL) { 1.274 + return JVMTI_ERROR_ILLEGAL_ARGUMENT; 1.275 + } 1.276 + 1.277 + JvmtiEventController::set_extension_event_callback(env, extension_event_index, 1.278 + callback); 1.279 + 1.280 + return JVMTI_ERROR_NONE; 1.281 +}