jdk/src/java.management/share/native/libmanagement/GcInfoBuilder.c
changeset 30355 e37c7eba132f
parent 30354 ca83b4cae363
child 30356 a56e57aad51f
equal deleted inserted replaced
30354:ca83b4cae363 30355:e37c7eba132f
     1 /*
       
     2  * Copyright (c) 2003, 2004, 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 #include <stdio.h>
       
    28 #include <jni.h>
       
    29 #include "management.h"
       
    30 #include "sun_management_GcInfoBuilder.h"
       
    31 
       
    32 JNIEXPORT jint JNICALL Java_sun_management_GcInfoBuilder_getNumGcExtAttributes
       
    33   (JNIEnv *env, jobject dummy, jobject gc) {
       
    34     jlong value;
       
    35 
       
    36     if (gc == NULL) {
       
    37         JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
       
    38         return 0;
       
    39     }
       
    40     value = jmm_interface->GetLongAttribute(env, gc,
       
    41                                             JMM_GC_EXT_ATTRIBUTE_INFO_SIZE);
       
    42     return (jint) value;
       
    43 }
       
    44 
       
    45 JNIEXPORT void JNICALL Java_sun_management_GcInfoBuilder_fillGcAttributeInfo
       
    46   (JNIEnv *env, jobject dummy, jobject gc,
       
    47    jint num_attributes, jobjectArray attributeNames,
       
    48    jcharArray types, jobjectArray descriptions) {
       
    49 
       
    50     jmmExtAttributeInfo* ext_att_info;
       
    51     jchar* nativeTypes;
       
    52     jstring attName = NULL;
       
    53     jstring desc = NULL;
       
    54     jint ret = 0;
       
    55     jint i;
       
    56 
       
    57     if (gc == NULL) {
       
    58         JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
       
    59         return;
       
    60     }
       
    61 
       
    62     if (num_attributes <= 0) {
       
    63         JNU_ThrowIllegalArgumentException(env, "Invalid num_attributes");
       
    64         return;
       
    65     }
       
    66 
       
    67     ext_att_info = (jmmExtAttributeInfo*) malloc((size_t)num_attributes *
       
    68                                                  sizeof(jmmExtAttributeInfo));
       
    69     if (ext_att_info == NULL) {
       
    70         JNU_ThrowOutOfMemoryError(env, 0);
       
    71         return;
       
    72     }
       
    73     ret = jmm_interface->GetGCExtAttributeInfo(env, gc,
       
    74                                                ext_att_info, num_attributes);
       
    75     if (ret != num_attributes) {
       
    76         JNU_ThrowInternalError(env, "Unexpected num_attributes");
       
    77         free(ext_att_info);
       
    78         return;
       
    79     }
       
    80 
       
    81     nativeTypes = (jchar*) malloc((size_t)num_attributes * sizeof(jchar));
       
    82     if (nativeTypes == NULL) {
       
    83         free(ext_att_info);
       
    84         JNU_ThrowOutOfMemoryError(env, 0);
       
    85         return;
       
    86     }
       
    87     for (i = 0; i < num_attributes; i++) {
       
    88         nativeTypes[i] = ext_att_info[i].type;
       
    89         attName = (*env)->NewStringUTF(env, ext_att_info[i].name);
       
    90         desc = (*env)->NewStringUTF(env, ext_att_info[i].description);
       
    91         (*env)->SetObjectArrayElement(env, attributeNames, i, attName);
       
    92         (*env)->SetObjectArrayElement(env, descriptions, i, desc);
       
    93     }
       
    94     (*env)->SetCharArrayRegion(env, types, 0, num_attributes, nativeTypes);
       
    95 
       
    96     if (ext_att_info != NULL) {
       
    97         free(ext_att_info);
       
    98     }
       
    99     if (nativeTypes != NULL) {
       
   100         free(nativeTypes);
       
   101     }
       
   102 }
       
   103 
       
   104 static void setLongValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   105                                       jsize index, jlong value) {
       
   106     static const char* class_name = "java/lang/Long";
       
   107     static const char* signature = "(J)V";
       
   108     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   109 
       
   110     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   111 }
       
   112 
       
   113 static void setBooleanValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   114                                          jsize index, jboolean value) {
       
   115     static const char* class_name = "java/lang/Boolean";
       
   116     static const char* signature = "(Z)V";
       
   117     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   118 
       
   119     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   120 }
       
   121 
       
   122 static void setByteValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   123                                       jsize index, jbyte value) {
       
   124     static const char* class_name = "java/lang/Byte";
       
   125     static const char* signature = "(B)V";
       
   126     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   127 
       
   128     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   129 }
       
   130 
       
   131 static void setIntValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   132                                      jsize index, jint value) {
       
   133     static const char* class_name = "java/lang/Integer";
       
   134     static const char* signature = "(I)V";
       
   135     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   136 
       
   137     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   138 }
       
   139 
       
   140 static void setShortValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   141                                        jsize index, jshort value) {
       
   142     static const char* class_name = "java/lang/Short";
       
   143     static const char* signature = "(S)V";
       
   144     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   145 
       
   146     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   147 }
       
   148 
       
   149 static void setDoubleValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   150                                         jsize index, jdouble value) {
       
   151     static const char* class_name = "java/lang/Double";
       
   152     static const char* signature = "(D)V";
       
   153     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   154 
       
   155     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   156 }
       
   157 
       
   158 static void setFloatValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   159                                        jsize index, jfloat value) {
       
   160     static const char* class_name = "java/lang/Float";
       
   161     static const char* signature = "(D)V";
       
   162     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   163 
       
   164     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   165 }
       
   166 
       
   167 static void setCharValueAtObjectArray(JNIEnv *env, jobjectArray array,
       
   168                                       jsize index, jchar value) {
       
   169     static const char* class_name = "java/lang/Character";
       
   170     static const char* signature = "(C)V";
       
   171     jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
       
   172 
       
   173     (*env)->SetObjectArrayElement(env, array, index, obj);
       
   174 }
       
   175 
       
   176 JNIEXPORT jobject JNICALL Java_sun_management_GcInfoBuilder_getLastGcInfo0
       
   177   (JNIEnv *env, jobject builder, jobject gc,
       
   178    jint ext_att_count, jobjectArray ext_att_values, jcharArray ext_att_types,
       
   179    jobjectArray usageBeforeGC, jobjectArray usageAfterGC) {
       
   180 
       
   181     jmmGCStat   gc_stat;
       
   182     jchar*      nativeTypes;
       
   183     jsize       i;
       
   184     jvalue      v;
       
   185 
       
   186     if (gc == NULL) {
       
   187         JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
       
   188         return 0;
       
   189     }
       
   190 
       
   191     if (ext_att_count <= 0) {
       
   192         JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count");
       
   193         return 0;
       
   194     }
       
   195 
       
   196     gc_stat.usage_before_gc = usageBeforeGC;
       
   197     gc_stat.usage_after_gc = usageAfterGC;
       
   198     gc_stat.gc_ext_attribute_values_size = ext_att_count;
       
   199     if (ext_att_count > 0) {
       
   200         gc_stat.gc_ext_attribute_values = (jvalue*) malloc((size_t)ext_att_count *
       
   201                                                            sizeof(jvalue));
       
   202         if (gc_stat.gc_ext_attribute_values == NULL) {
       
   203             JNU_ThrowOutOfMemoryError(env, 0);
       
   204             return 0;
       
   205         }
       
   206     } else {
       
   207         gc_stat.gc_ext_attribute_values = NULL;
       
   208     }
       
   209 
       
   210 
       
   211     jmm_interface->GetLastGCStat(env, gc, &gc_stat);
       
   212     if (gc_stat.gc_index == 0) {
       
   213         if (gc_stat.gc_ext_attribute_values != NULL) {
       
   214             free(gc_stat.gc_ext_attribute_values);
       
   215         }
       
   216         return 0;
       
   217     }
       
   218 
       
   219     // convert the ext_att_types to native types
       
   220     nativeTypes = (jchar*) malloc((size_t)ext_att_count * sizeof(jchar));
       
   221     if (nativeTypes == NULL) {
       
   222         if (gc_stat.gc_ext_attribute_values != NULL) {
       
   223             free(gc_stat.gc_ext_attribute_values);
       
   224         }
       
   225         JNU_ThrowOutOfMemoryError(env, 0);
       
   226         return 0;
       
   227     }
       
   228     (*env)->GetCharArrayRegion(env, ext_att_types, 0, ext_att_count, nativeTypes);
       
   229     for (i = 0; i < ext_att_count; i++) {
       
   230        v = gc_stat.gc_ext_attribute_values[i];
       
   231        switch (nativeTypes[i]) {
       
   232             case 'Z':
       
   233                 setBooleanValueAtObjectArray(env, ext_att_values, i, v.z);
       
   234                 break;
       
   235             case 'B':
       
   236                 setByteValueAtObjectArray(env, ext_att_values, i, v.b);
       
   237                 break;
       
   238             case 'C':
       
   239                 setCharValueAtObjectArray(env, ext_att_values, i, v.c);
       
   240                 break;
       
   241             case 'S':
       
   242                 setShortValueAtObjectArray(env, ext_att_values, i, v.s);
       
   243                 break;
       
   244             case 'I':
       
   245                 setIntValueAtObjectArray(env, ext_att_values, i, v.i);
       
   246                 break;
       
   247             case 'J':
       
   248                 setLongValueAtObjectArray(env, ext_att_values, i, v.j);
       
   249                 break;
       
   250             case 'F':
       
   251                 setFloatValueAtObjectArray(env, ext_att_values, i, v.f);
       
   252                 break;
       
   253             case 'D':
       
   254                 setDoubleValueAtObjectArray(env, ext_att_values, i, v.d);
       
   255                 break;
       
   256             default:
       
   257                 if (gc_stat.gc_ext_attribute_values != NULL) {
       
   258                     free(gc_stat.gc_ext_attribute_values);
       
   259                 }
       
   260                 if (nativeTypes != NULL) {
       
   261                     free(nativeTypes);
       
   262                 }
       
   263                 JNU_ThrowInternalError(env, "Unsupported attribute type");
       
   264                 return 0;
       
   265        }
       
   266     }
       
   267     if (gc_stat.gc_ext_attribute_values != NULL) {
       
   268         free(gc_stat.gc_ext_attribute_values);
       
   269     }
       
   270     if (nativeTypes != NULL) {
       
   271         free(nativeTypes);
       
   272     }
       
   273 
       
   274     return JNU_NewObjectByName(env,
       
   275        "com/sun/management/GcInfo",
       
   276        "(Lsun/management/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V",
       
   277        builder,
       
   278        gc_stat.gc_index,
       
   279        gc_stat.start_time,
       
   280        gc_stat.end_time,
       
   281        usageBeforeGC,
       
   282        usageAfterGC,
       
   283        ext_att_values);
       
   284 }