1 /*
   2  * Copyright (c) 2003, 2015, 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 <string.h>
  29 #include <jni.h>
  30 #include "management_ext.h"
  31 #include "com_sun_management_internal_Flag.h"
  32 
  33 static jobject default_origin = NULL;
  34 static jobject vm_creation_origin = NULL;
  35 static jobject mgmt_origin = NULL;
  36 static jobject envvar_origin = NULL;
  37 static jobject config_file_origin = NULL;
  38 static jobject ergo_origin = NULL;
  39 static jobject attach_origin = NULL;
  40 static jobject other_origin = NULL;
  41 
  42 JNIEXPORT jint JNICALL
  43 Java_com_sun_management_internal_Flag_getInternalFlagCount
  44   (JNIEnv *env, jclass cls)
  45 {
  46     jlong count = jmm_interface->GetLongAttribute(env, NULL,
  47                                                   JMM_VM_GLOBAL_COUNT);
  48     return (jint) count;
  49 }
  50 
  51 JNIEXPORT jobjectArray JNICALL
  52   Java_com_sun_management_internal_Flag_getAllFlagNames
  53 (JNIEnv *env, jclass cls)
  54 {
  55   return jmm_interface->GetVMGlobalNames(env);
  56 }
  57 
  58 static jobject find_origin_constant(JNIEnv* env, const char* enum_name) {
  59     jvalue field;
  60     field = JNU_GetStaticFieldByName(env,
  61                                      NULL,
  62                                      "com/sun/management/VMOption$Origin",
  63                                      enum_name,
  64                                      "Lcom/sun/management/VMOption$Origin;");
  65     return (*env)->NewGlobalRef(env, field.l);
  66 }
  67 
  68 JNIEXPORT void JNICALL
  69 Java_com_sun_management_internal_Flag_initialize
  70   (JNIEnv *env, jclass cls)
  71 {
  72     default_origin = find_origin_constant(env, "DEFAULT");
  73     vm_creation_origin = find_origin_constant(env, "VM_CREATION");
  74     mgmt_origin = find_origin_constant(env, "MANAGEMENT");
  75     envvar_origin = find_origin_constant(env, "ENVIRON_VAR");
  76     config_file_origin = find_origin_constant(env, "CONFIG_FILE");
  77     ergo_origin = find_origin_constant(env, "ERGONOMIC");
  78     attach_origin = find_origin_constant(env, "ATTACH_ON_DEMAND");
  79     other_origin = find_origin_constant(env, "OTHER");
  80 }
  81 
  82 JNIEXPORT jint JNICALL
  83 Java_com_sun_management_internal_Flag_getFlags
  84   (JNIEnv *env, jclass cls, jobjectArray names, jobjectArray flags, jint count)
  85 {
  86     jint num_flags, i, index;
  87     jmmVMGlobal* globals;
  88     size_t gsize;
  89     const char* class_name = "com/sun/management/internal/Flag";
  90     const char* signature = "(Ljava/lang/String;Ljava/lang/Object;ZZLcom/sun/management/VMOption$Origin;)V";
  91     jobject origin;
  92     jobject valueObj;
  93     jobject flag;
  94 
  95     if (flags == NULL) {
  96         JNU_ThrowNullPointerException(env, 0);
  97         return 0;
  98     }
  99 
 100     if (count <= 0) {
 101         JNU_ThrowIllegalArgumentException(env, 0);
 102         return 0;
 103     }
 104 
 105     gsize = (size_t)count * sizeof(jmmVMGlobal);
 106     globals = (jmmVMGlobal*) malloc(gsize);
 107     if (globals == NULL) {
 108         JNU_ThrowOutOfMemoryError(env, 0);
 109         return 0;
 110     }
 111 
 112     memset(globals, 0, gsize);
 113     num_flags = jmm_interface->GetVMGlobals(env, names, globals, count);
 114     if (num_flags == 0) {
 115         free(globals);
 116         return 0;
 117     }
 118 
 119     index = 0;
 120     for (i = 0; i < count; i++) {
 121         if (globals[i].name == NULL) {
 122             continue;
 123         }
 124         switch (globals[i].type) {
 125         case JMM_VMGLOBAL_TYPE_JBOOLEAN:
 126             valueObj = JNU_NewObjectByName(env, "java/lang/Boolean", "(Z)V",
 127                                            globals[i].value.z);
 128             break;
 129         case JMM_VMGLOBAL_TYPE_JSTRING:
 130             valueObj = globals[i].value.l;
 131             break;
 132         case JMM_VMGLOBAL_TYPE_JLONG:
 133             valueObj = JNU_NewObjectByName(env, "java/lang/Long", "(J)V",
 134                                            globals[i].value.j);
 135             break;
 136         case JMM_VMGLOBAL_TYPE_JDOUBLE:
 137             valueObj = JNU_NewObjectByName(env, "java/lang/Double", "(D)V",
 138                                            globals[i].value.d);
 139             break;
 140         default:
 141             // ignore unsupported type
 142             continue;
 143         }
 144         switch (globals[i].origin) {
 145         case JMM_VMGLOBAL_ORIGIN_DEFAULT:
 146             origin = default_origin;
 147             break;
 148         case JMM_VMGLOBAL_ORIGIN_COMMAND_LINE:
 149             origin = vm_creation_origin;
 150             break;
 151         case JMM_VMGLOBAL_ORIGIN_MANAGEMENT:
 152             origin = mgmt_origin;
 153             break;
 154         case JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR:
 155             origin = envvar_origin;
 156             break;
 157         case JMM_VMGLOBAL_ORIGIN_CONFIG_FILE:
 158             origin = config_file_origin;
 159             break;
 160         case JMM_VMGLOBAL_ORIGIN_ERGONOMIC:
 161             origin = ergo_origin;
 162             break;
 163         case JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND:
 164             origin = attach_origin;
 165             break;
 166         case JMM_VMGLOBAL_ORIGIN_OTHER:
 167             origin = other_origin;
 168             break;
 169         default:
 170             // unknown origin
 171             origin = other_origin;
 172             break;
 173         }
 174         flag = JNU_NewObjectByName(env, class_name, signature, globals[i].name,
 175                                    valueObj, globals[i].writeable,
 176                                    globals[i].external, origin);
 177         if (flag == NULL) {
 178             free(globals);
 179             JNU_ThrowOutOfMemoryError(env, 0);
 180             return 0;
 181         }
 182         (*env)->SetObjectArrayElement(env, flags, index, flag);
 183         index++;
 184     }
 185 
 186     if (index != num_flags) {
 187         JNU_ThrowInternalError(env, "Number of Flag objects created unmatched");
 188         free(globals);
 189         return 0;
 190     }
 191 
 192     free(globals);
 193 
 194     /* return the number of Flag objects created */
 195     return num_flags;
 196 }
 197 
 198 JNIEXPORT void JNICALL
 199 Java_com_sun_management_internal_Flag_setLongValue
 200   (JNIEnv *env, jclass cls, jstring name, jlong value)
 201 {
 202    jvalue v;
 203    v.j = value;
 204 
 205    jmm_interface->SetVMGlobal(env, name, v);
 206 }
 207 
 208 JNIEXPORT void JNICALL
 209 Java_com_sun_management_internal_Flag_setDoubleValue
 210   (JNIEnv *env, jclass cls, jstring name, jdouble value)
 211 {
 212    jvalue v;
 213    v.d = value;
 214 
 215    jmm_interface->SetVMGlobal(env, name, v);
 216 }
 217 
 218 JNIEXPORT void JNICALL
 219 Java_com_sun_management_internal_Flag_setBooleanValue
 220   (JNIEnv *env, jclass cls, jstring name, jboolean value)
 221 {
 222    jvalue v;
 223    v.z = value;
 224 
 225    jmm_interface->SetVMGlobal(env, name, v);
 226 }
 227 
 228 JNIEXPORT void JNICALL
 229 Java_com_sun_management_internal_Flag_setStringValue
 230   (JNIEnv *env, jclass cls, jstring name, jstring value)
 231 {
 232    jvalue v;
 233    v.l = value;
 234 
 235    jmm_interface->SetVMGlobal(env, name, v);
 236 }