src/share/vm/prims/jvmtiExtensions.cpp

Wed, 11 Jan 2012 17:34:02 -0500

author
phh
date
Wed, 11 Jan 2012 17:34:02 -0500
changeset 3427
94ec88ca68e2
parent 2314
f95d63e2154a
child 3900
d2a62e0f25eb
permissions
-rw-r--r--

7115199: Add event tracing hooks and Java Flight Recorder infrastructure
Summary: Added a nop tracing infrastructure, JFR makefile changes and other infrastructure used only by JFR.
Reviewed-by: acorn, sspitsyn
Contributed-by: markus.gronlund@oracle.com

     1 /*
     2  * Copyright (c) 2003, 2010, 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  */
    25 #include "precompiled.hpp"
    26 #include "prims/jvmtiExport.hpp"
    27 #include "prims/jvmtiExtensions.hpp"
    29 // the list of extension functions
    30 GrowableArray<jvmtiExtensionFunctionInfo*>* JvmtiExtensions::_ext_functions;
    32 // the list of extension events
    33 GrowableArray<jvmtiExtensionEventInfo*>* JvmtiExtensions::_ext_events;
    36 // extension function
    37 static jvmtiError JNICALL IsClassUnloadingEnabled(const jvmtiEnv* env, jboolean* enabled, ...) {
    38   if (enabled == NULL) {
    39     return JVMTI_ERROR_NULL_POINTER;
    40   }
    41   *enabled = (jboolean)ClassUnloading;
    42   return JVMTI_ERROR_NONE;
    43 }
    45 // register extension functions and events. In this implementation we
    46 // have a single extension function (to prove the API) that tests if class
    47 // unloading is enabled or disabled. We also have a single extension event
    48 // EXT_EVENT_CLASS_UNLOAD which is used to provide the JVMDI_EVENT_CLASS_UNLOAD
    49 // event. The function and the event are registered here.
    50 //
    51 void JvmtiExtensions::register_extensions() {
    52   _ext_functions = new (ResourceObj::C_HEAP) GrowableArray<jvmtiExtensionFunctionInfo*>(1,true);
    53   _ext_events = new (ResourceObj::C_HEAP) GrowableArray<jvmtiExtensionEventInfo*>(1,true);
    55   // register our extension function
    56   static jvmtiParamInfo func_params[] = {
    57     { (char*)"IsClassUnloadingEnabled", JVMTI_KIND_OUT,  JVMTI_TYPE_JBOOLEAN, JNI_FALSE }
    58   };
    59   static jvmtiExtensionFunctionInfo ext_func = {
    60     (jvmtiExtensionFunction)IsClassUnloadingEnabled,
    61     (char*)"com.sun.hotspot.functions.IsClassUnloadingEnabled",
    62     (char*)"Tell if class unloading is enabled (-noclassgc)",
    63     sizeof(func_params)/sizeof(func_params[0]),
    64     func_params,
    65     0,              // no non-universal errors
    66     NULL
    67   };
    68   _ext_functions->append(&ext_func);
    70   // register our extension event
    72   static jvmtiParamInfo event_params[] = {
    73     { (char*)"JNI Environment", JVMTI_KIND_IN, JVMTI_TYPE_JNIENV, JNI_FALSE },
    74     { (char*)"Thread", JVMTI_KIND_IN, JVMTI_TYPE_JTHREAD, JNI_FALSE },
    75     { (char*)"Class", JVMTI_KIND_IN, JVMTI_TYPE_JCLASS, JNI_FALSE }
    76   };
    77   static jvmtiExtensionEventInfo ext_event = {
    78     EXT_EVENT_CLASS_UNLOAD,
    79     (char*)"com.sun.hotspot.events.ClassUnload",
    80     (char*)"CLASS_UNLOAD event",
    81     sizeof(event_params)/sizeof(event_params[0]),
    82     event_params
    83   };
    84   _ext_events->append(&ext_event);
    85 }
    88 // return the list of extension functions
    90 jvmtiError JvmtiExtensions::get_functions(JvmtiEnv* env,
    91                                           jint* extension_count_ptr,
    92                                           jvmtiExtensionFunctionInfo** extensions)
    93 {
    94   guarantee(_ext_functions != NULL, "registration not done");
    96   ResourceTracker rt(env);
    98   jvmtiExtensionFunctionInfo* ext_funcs;
    99   jvmtiError err = rt.allocate(_ext_functions->length() *
   100                                sizeof(jvmtiExtensionFunctionInfo),
   101                                (unsigned char**)&ext_funcs);
   102   if (err != JVMTI_ERROR_NONE) {
   103     return err;
   104   }
   106   for (int i=0; i<_ext_functions->length(); i++ ) {
   107     ext_funcs[i].func = _ext_functions->at(i)->func;
   109     char *id = _ext_functions->at(i)->id;
   110     err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_funcs[i].id));
   111     if (err != JVMTI_ERROR_NONE) {
   112       return err;
   113     }
   114     strcpy(ext_funcs[i].id, id);
   116     char *desc = _ext_functions->at(i)->short_description;
   117     err = rt.allocate(strlen(desc)+1,
   118                       (unsigned char**)&(ext_funcs[i].short_description));
   119     if (err != JVMTI_ERROR_NONE) {
   120       return err;
   121     }
   122     strcpy(ext_funcs[i].short_description, desc);
   124     // params
   126     jint param_count = _ext_functions->at(i)->param_count;
   128     ext_funcs[i].param_count = param_count;
   129     if (param_count == 0) {
   130       ext_funcs[i].params = NULL;
   131     } else {
   132       err = rt.allocate(param_count*sizeof(jvmtiParamInfo),
   133                         (unsigned char**)&(ext_funcs[i].params));
   134       if (err != JVMTI_ERROR_NONE) {
   135         return err;
   136       }
   137       jvmtiParamInfo* src_params = _ext_functions->at(i)->params;
   138       jvmtiParamInfo* dst_params = ext_funcs[i].params;
   140       for (int j=0; j<param_count; j++) {
   141         err = rt.allocate(strlen(src_params[j].name)+1,
   142                           (unsigned char**)&(dst_params[j].name));
   143         if (err != JVMTI_ERROR_NONE) {
   144           return err;
   145         }
   146         strcpy(dst_params[j].name, src_params[j].name);
   148         dst_params[j].kind = src_params[j].kind;
   149         dst_params[j].base_type = src_params[j].base_type;
   150         dst_params[j].null_ok = src_params[j].null_ok;
   151       }
   152     }
   154     // errors
   156     jint error_count = _ext_functions->at(i)->error_count;
   157     ext_funcs[i].error_count = error_count;
   158     if (error_count == 0) {
   159       ext_funcs[i].errors = NULL;
   160     } else {
   161       err = rt.allocate(error_count*sizeof(jvmtiError),
   162                         (unsigned char**)&(ext_funcs[i].errors));
   163       if (err != JVMTI_ERROR_NONE) {
   164         return err;
   165       }
   166       memcpy(ext_funcs[i].errors, _ext_functions->at(i)->errors,
   167              error_count*sizeof(jvmtiError));
   168     }
   169   }
   171   *extension_count_ptr = _ext_functions->length();
   172   *extensions = ext_funcs;
   173   return JVMTI_ERROR_NONE;
   174 }
   177 // return the list of extension events
   179 jvmtiError JvmtiExtensions::get_events(JvmtiEnv* env,
   180                                        jint* extension_count_ptr,
   181                                        jvmtiExtensionEventInfo** extensions)
   182 {
   183   guarantee(_ext_events != NULL, "registration not done");
   185   ResourceTracker rt(env);
   187   jvmtiExtensionEventInfo* ext_events;
   188   jvmtiError err = rt.allocate(_ext_events->length() * sizeof(jvmtiExtensionEventInfo),
   189                                (unsigned char**)&ext_events);
   190   if (err != JVMTI_ERROR_NONE) {
   191     return err;
   192   }
   194   for (int i=0; i<_ext_events->length(); i++ ) {
   195     ext_events[i].extension_event_index = _ext_events->at(i)->extension_event_index;
   197     char *id = _ext_events->at(i)->id;
   198     err = rt.allocate(strlen(id)+1, (unsigned char**)&(ext_events[i].id));
   199     if (err != JVMTI_ERROR_NONE) {
   200       return err;
   201     }
   202     strcpy(ext_events[i].id, id);
   204     char *desc = _ext_events->at(i)->short_description;
   205     err = rt.allocate(strlen(desc)+1,
   206                       (unsigned char**)&(ext_events[i].short_description));
   207     if (err != JVMTI_ERROR_NONE) {
   208       return err;
   209     }
   210     strcpy(ext_events[i].short_description, desc);
   212     // params
   214     jint param_count = _ext_events->at(i)->param_count;
   216     ext_events[i].param_count = param_count;
   217     if (param_count == 0) {
   218       ext_events[i].params = NULL;
   219     } else {
   220       err = rt.allocate(param_count*sizeof(jvmtiParamInfo),
   221                         (unsigned char**)&(ext_events[i].params));
   222       if (err != JVMTI_ERROR_NONE) {
   223         return err;
   224       }
   225       jvmtiParamInfo* src_params = _ext_events->at(i)->params;
   226       jvmtiParamInfo* dst_params = ext_events[i].params;
   228       for (int j=0; j<param_count; j++) {
   229         err = rt.allocate(strlen(src_params[j].name)+1,
   230                           (unsigned char**)&(dst_params[j].name));
   231         if (err != JVMTI_ERROR_NONE) {
   232           return err;
   233         }
   234         strcpy(dst_params[j].name, src_params[j].name);
   236         dst_params[j].kind = src_params[j].kind;
   237         dst_params[j].base_type = src_params[j].base_type;
   238         dst_params[j].null_ok = src_params[j].null_ok;
   239       }
   240     }
   241   }
   243   *extension_count_ptr = _ext_events->length();
   244   *extensions = ext_events;
   245   return JVMTI_ERROR_NONE;
   246 }
   248 // set callback for an extension event and enable/disable it.
   250 jvmtiError JvmtiExtensions::set_event_callback(JvmtiEnv* env,
   251                                                jint extension_event_index,
   252                                                jvmtiExtensionEvent callback)
   253 {
   254   guarantee(_ext_events != NULL, "registration not done");
   256   jvmtiExtensionEventInfo* event = NULL;
   258   // if there are extension events registered then validate that the
   259   // extension_event_index matches one of the registered events.
   260   if (_ext_events != NULL) {
   261     for (int i=0; i<_ext_events->length(); i++ ) {
   262       if (_ext_events->at(i)->extension_event_index == extension_event_index) {
   263          event = _ext_events->at(i);
   264          break;
   265       }
   266     }
   267   }
   269   // invalid event index
   270   if (event == NULL) {
   271     return JVMTI_ERROR_ILLEGAL_ARGUMENT;
   272   }
   274   JvmtiEventController::set_extension_event_callback(env, extension_event_index,
   275                                                      callback);
   277   return JVMTI_ERROR_NONE;
   278 }

mercurial