src/share/vm/services/management.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/services/management.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,2375 @@
     1.4 +/*
     1.5 + * Copyright (c) 2003, 2014, 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 "classfile/systemDictionary.hpp"
    1.30 +#include "compiler/compileBroker.hpp"
    1.31 +#include "memory/iterator.hpp"
    1.32 +#include "memory/oopFactory.hpp"
    1.33 +#include "memory/resourceArea.hpp"
    1.34 +#include "oops/klass.hpp"
    1.35 +#include "oops/objArrayKlass.hpp"
    1.36 +#include "oops/oop.inline.hpp"
    1.37 +#include "runtime/arguments.hpp"
    1.38 +#include "runtime/globals.hpp"
    1.39 +#include "runtime/handles.inline.hpp"
    1.40 +#include "runtime/interfaceSupport.hpp"
    1.41 +#include "runtime/javaCalls.hpp"
    1.42 +#include "runtime/jniHandles.hpp"
    1.43 +#include "runtime/os.hpp"
    1.44 +#include "runtime/serviceThread.hpp"
    1.45 +#include "services/classLoadingService.hpp"
    1.46 +#include "services/diagnosticCommand.hpp"
    1.47 +#include "services/diagnosticFramework.hpp"
    1.48 +#include "services/heapDumper.hpp"
    1.49 +#include "services/jmm.h"
    1.50 +#include "services/lowMemoryDetector.hpp"
    1.51 +#include "services/gcNotifier.hpp"
    1.52 +#include "services/nmtDCmd.hpp"
    1.53 +#include "services/management.hpp"
    1.54 +#include "services/memoryManager.hpp"
    1.55 +#include "services/memoryPool.hpp"
    1.56 +#include "services/memoryService.hpp"
    1.57 +#include "services/runtimeService.hpp"
    1.58 +#include "services/threadService.hpp"
    1.59 +#include "utilities/macros.hpp"
    1.60 +
    1.61 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
    1.62 +
    1.63 +PerfVariable* Management::_begin_vm_creation_time = NULL;
    1.64 +PerfVariable* Management::_end_vm_creation_time = NULL;
    1.65 +PerfVariable* Management::_vm_init_done_time = NULL;
    1.66 +
    1.67 +Klass* Management::_sensor_klass = NULL;
    1.68 +Klass* Management::_threadInfo_klass = NULL;
    1.69 +Klass* Management::_memoryUsage_klass = NULL;
    1.70 +Klass* Management::_memoryPoolMXBean_klass = NULL;
    1.71 +Klass* Management::_memoryManagerMXBean_klass = NULL;
    1.72 +Klass* Management::_garbageCollectorMXBean_klass = NULL;
    1.73 +Klass* Management::_managementFactory_klass = NULL;
    1.74 +Klass* Management::_garbageCollectorImpl_klass = NULL;
    1.75 +Klass* Management::_gcInfo_klass = NULL;
    1.76 +Klass* Management::_diagnosticCommandImpl_klass = NULL;
    1.77 +Klass* Management::_managementFactoryHelper_klass = NULL;
    1.78 +
    1.79 +
    1.80 +jmmOptionalSupport Management::_optional_support = {0};
    1.81 +TimeStamp Management::_stamp;
    1.82 +
    1.83 +void management_init() {
    1.84 +#if INCLUDE_MANAGEMENT
    1.85 +  Management::init();
    1.86 +  ThreadService::init();
    1.87 +  RuntimeService::init();
    1.88 +  ClassLoadingService::init();
    1.89 +#else
    1.90 +  ThreadService::init();
    1.91 +  // Make sure the VM version is initialized
    1.92 +  // This is normally called by RuntimeService::init().
    1.93 +  // Since that is conditionalized out, we need to call it here.
    1.94 +  Abstract_VM_Version::initialize();
    1.95 +#endif // INCLUDE_MANAGEMENT
    1.96 +}
    1.97 +
    1.98 +#if INCLUDE_MANAGEMENT
    1.99 +
   1.100 +void Management::init() {
   1.101 +  EXCEPTION_MARK;
   1.102 +
   1.103 +  // These counters are for java.lang.management API support.
   1.104 +  // They are created even if -XX:-UsePerfData is set and in
   1.105 +  // that case, they will be allocated on C heap.
   1.106 +
   1.107 +  _begin_vm_creation_time =
   1.108 +            PerfDataManager::create_variable(SUN_RT, "createVmBeginTime",
   1.109 +                                             PerfData::U_None, CHECK);
   1.110 +
   1.111 +  _end_vm_creation_time =
   1.112 +            PerfDataManager::create_variable(SUN_RT, "createVmEndTime",
   1.113 +                                             PerfData::U_None, CHECK);
   1.114 +
   1.115 +  _vm_init_done_time =
   1.116 +            PerfDataManager::create_variable(SUN_RT, "vmInitDoneTime",
   1.117 +                                             PerfData::U_None, CHECK);
   1.118 +
   1.119 +  // Initialize optional support
   1.120 +  _optional_support.isLowMemoryDetectionSupported = 1;
   1.121 +  _optional_support.isCompilationTimeMonitoringSupported = 1;
   1.122 +  _optional_support.isThreadContentionMonitoringSupported = 1;
   1.123 +
   1.124 +  if (os::is_thread_cpu_time_supported()) {
   1.125 +    _optional_support.isCurrentThreadCpuTimeSupported = 1;
   1.126 +    _optional_support.isOtherThreadCpuTimeSupported = 1;
   1.127 +  } else {
   1.128 +    _optional_support.isCurrentThreadCpuTimeSupported = 0;
   1.129 +    _optional_support.isOtherThreadCpuTimeSupported = 0;
   1.130 +  }
   1.131 +
   1.132 +  _optional_support.isBootClassPathSupported = 1;
   1.133 +  _optional_support.isObjectMonitorUsageSupported = 1;
   1.134 +#if INCLUDE_SERVICES
   1.135 +  // This depends on the heap inspector
   1.136 +  _optional_support.isSynchronizerUsageSupported = 1;
   1.137 +#endif // INCLUDE_SERVICES
   1.138 +  _optional_support.isThreadAllocatedMemorySupported = 1;
   1.139 +  _optional_support.isRemoteDiagnosticCommandsSupported = 1;
   1.140 +
   1.141 +  // Registration of the diagnostic commands
   1.142 +  DCmdRegistrant::register_dcmds();
   1.143 +  DCmdRegistrant::register_dcmds_ext();
   1.144 +  uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI
   1.145 +                         | DCmd_Source_MBean;
   1.146 +  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<NMTDCmd>(full_export, true, false));
   1.147 +}
   1.148 +
   1.149 +void Management::initialize(TRAPS) {
   1.150 +  // Start the service thread
   1.151 +  ServiceThread::initialize();
   1.152 +
   1.153 +  if (ManagementServer) {
   1.154 +    ResourceMark rm(THREAD);
   1.155 +    HandleMark hm(THREAD);
   1.156 +
   1.157 +    // Load and initialize the sun.management.Agent class
   1.158 +    // invoke startAgent method to start the management server
   1.159 +    Handle loader = Handle(THREAD, SystemDictionary::java_system_loader());
   1.160 +    Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::sun_management_Agent(),
   1.161 +                                                   loader,
   1.162 +                                                   Handle(),
   1.163 +                                                   true,
   1.164 +                                                   CHECK);
   1.165 +    instanceKlassHandle ik (THREAD, k);
   1.166 +
   1.167 +    JavaValue result(T_VOID);
   1.168 +    JavaCalls::call_static(&result,
   1.169 +                           ik,
   1.170 +                           vmSymbols::startAgent_name(),
   1.171 +                           vmSymbols::void_method_signature(),
   1.172 +                           CHECK);
   1.173 +  }
   1.174 +}
   1.175 +
   1.176 +void Management::get_optional_support(jmmOptionalSupport* support) {
   1.177 +  memcpy(support, &_optional_support, sizeof(jmmOptionalSupport));
   1.178 +}
   1.179 +
   1.180 +Klass* Management::load_and_initialize_klass(Symbol* sh, TRAPS) {
   1.181 +  Klass* k = SystemDictionary::resolve_or_fail(sh, true, CHECK_NULL);
   1.182 +  instanceKlassHandle ik (THREAD, k);
   1.183 +  if (ik->should_be_initialized()) {
   1.184 +    ik->initialize(CHECK_NULL);
   1.185 +  }
   1.186 +  // If these classes change to not be owned by the boot loader, they need
   1.187 +  // to be walked to keep their class loader alive in oops_do.
   1.188 +  assert(ik->class_loader() == NULL, "need to follow in oops_do");
   1.189 +  return ik();
   1.190 +}
   1.191 +
   1.192 +void Management::record_vm_startup_time(jlong begin, jlong duration) {
   1.193 +  // if the performance counter is not initialized,
   1.194 +  // then vm initialization failed; simply return.
   1.195 +  if (_begin_vm_creation_time == NULL) return;
   1.196 +
   1.197 +  _begin_vm_creation_time->set_value(begin);
   1.198 +  _end_vm_creation_time->set_value(begin + duration);
   1.199 +  PerfMemory::set_accessible(true);
   1.200 +}
   1.201 +
   1.202 +jlong Management::timestamp() {
   1.203 +  TimeStamp t;
   1.204 +  t.update();
   1.205 +  return t.ticks() - _stamp.ticks();
   1.206 +}
   1.207 +
   1.208 +void Management::oops_do(OopClosure* f) {
   1.209 +  MemoryService::oops_do(f);
   1.210 +  ThreadService::oops_do(f);
   1.211 +}
   1.212 +
   1.213 +Klass* Management::java_lang_management_ThreadInfo_klass(TRAPS) {
   1.214 +  if (_threadInfo_klass == NULL) {
   1.215 +    _threadInfo_klass = load_and_initialize_klass(vmSymbols::java_lang_management_ThreadInfo(), CHECK_NULL);
   1.216 +  }
   1.217 +  return _threadInfo_klass;
   1.218 +}
   1.219 +
   1.220 +Klass* Management::java_lang_management_MemoryUsage_klass(TRAPS) {
   1.221 +  if (_memoryUsage_klass == NULL) {
   1.222 +    _memoryUsage_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryUsage(), CHECK_NULL);
   1.223 +  }
   1.224 +  return _memoryUsage_klass;
   1.225 +}
   1.226 +
   1.227 +Klass* Management::java_lang_management_MemoryPoolMXBean_klass(TRAPS) {
   1.228 +  if (_memoryPoolMXBean_klass == NULL) {
   1.229 +    _memoryPoolMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryPoolMXBean(), CHECK_NULL);
   1.230 +  }
   1.231 +  return _memoryPoolMXBean_klass;
   1.232 +}
   1.233 +
   1.234 +Klass* Management::java_lang_management_MemoryManagerMXBean_klass(TRAPS) {
   1.235 +  if (_memoryManagerMXBean_klass == NULL) {
   1.236 +    _memoryManagerMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_MemoryManagerMXBean(), CHECK_NULL);
   1.237 +  }
   1.238 +  return _memoryManagerMXBean_klass;
   1.239 +}
   1.240 +
   1.241 +Klass* Management::java_lang_management_GarbageCollectorMXBean_klass(TRAPS) {
   1.242 +  if (_garbageCollectorMXBean_klass == NULL) {
   1.243 +      _garbageCollectorMXBean_klass = load_and_initialize_klass(vmSymbols::java_lang_management_GarbageCollectorMXBean(), CHECK_NULL);
   1.244 +  }
   1.245 +  return _garbageCollectorMXBean_klass;
   1.246 +}
   1.247 +
   1.248 +Klass* Management::sun_management_Sensor_klass(TRAPS) {
   1.249 +  if (_sensor_klass == NULL) {
   1.250 +    _sensor_klass = load_and_initialize_klass(vmSymbols::sun_management_Sensor(), CHECK_NULL);
   1.251 +  }
   1.252 +  return _sensor_klass;
   1.253 +}
   1.254 +
   1.255 +Klass* Management::sun_management_ManagementFactory_klass(TRAPS) {
   1.256 +  if (_managementFactory_klass == NULL) {
   1.257 +    _managementFactory_klass = load_and_initialize_klass(vmSymbols::sun_management_ManagementFactory(), CHECK_NULL);
   1.258 +  }
   1.259 +  return _managementFactory_klass;
   1.260 +}
   1.261 +
   1.262 +Klass* Management::sun_management_GarbageCollectorImpl_klass(TRAPS) {
   1.263 +  if (_garbageCollectorImpl_klass == NULL) {
   1.264 +    _garbageCollectorImpl_klass = load_and_initialize_klass(vmSymbols::sun_management_GarbageCollectorImpl(), CHECK_NULL);
   1.265 +  }
   1.266 +  return _garbageCollectorImpl_klass;
   1.267 +}
   1.268 +
   1.269 +Klass* Management::com_sun_management_GcInfo_klass(TRAPS) {
   1.270 +  if (_gcInfo_klass == NULL) {
   1.271 +    _gcInfo_klass = load_and_initialize_klass(vmSymbols::com_sun_management_GcInfo(), CHECK_NULL);
   1.272 +  }
   1.273 +  return _gcInfo_klass;
   1.274 +}
   1.275 +
   1.276 +Klass* Management::sun_management_DiagnosticCommandImpl_klass(TRAPS) {
   1.277 +  if (_diagnosticCommandImpl_klass == NULL) {
   1.278 +    _diagnosticCommandImpl_klass = load_and_initialize_klass(vmSymbols::sun_management_DiagnosticCommandImpl(), CHECK_NULL);
   1.279 +  }
   1.280 +  return _diagnosticCommandImpl_klass;
   1.281 +}
   1.282 +
   1.283 +Klass* Management::sun_management_ManagementFactoryHelper_klass(TRAPS) {
   1.284 +  if (_managementFactoryHelper_klass == NULL) {
   1.285 +    _managementFactoryHelper_klass = load_and_initialize_klass(vmSymbols::sun_management_ManagementFactoryHelper(), CHECK_NULL);
   1.286 +  }
   1.287 +  return _managementFactoryHelper_klass;
   1.288 +}
   1.289 +
   1.290 +static void initialize_ThreadInfo_constructor_arguments(JavaCallArguments* args, ThreadSnapshot* snapshot, TRAPS) {
   1.291 +  Handle snapshot_thread(THREAD, snapshot->threadObj());
   1.292 +
   1.293 +  jlong contended_time;
   1.294 +  jlong waited_time;
   1.295 +  if (ThreadService::is_thread_monitoring_contention()) {
   1.296 +    contended_time = Management::ticks_to_ms(snapshot->contended_enter_ticks());
   1.297 +    waited_time = Management::ticks_to_ms(snapshot->monitor_wait_ticks() + snapshot->sleep_ticks());
   1.298 +  } else {
   1.299 +    // set them to -1 if thread contention monitoring is disabled.
   1.300 +    contended_time = max_julong;
   1.301 +    waited_time = max_julong;
   1.302 +  }
   1.303 +
   1.304 +  int thread_status = snapshot->thread_status();
   1.305 +  assert((thread_status & JMM_THREAD_STATE_FLAG_MASK) == 0, "Flags already set in thread_status in Thread object");
   1.306 +  if (snapshot->is_ext_suspended()) {
   1.307 +    thread_status |= JMM_THREAD_STATE_FLAG_SUSPENDED;
   1.308 +  }
   1.309 +  if (snapshot->is_in_native()) {
   1.310 +    thread_status |= JMM_THREAD_STATE_FLAG_NATIVE;
   1.311 +  }
   1.312 +
   1.313 +  ThreadStackTrace* st = snapshot->get_stack_trace();
   1.314 +  Handle stacktrace_h;
   1.315 +  if (st != NULL) {
   1.316 +    stacktrace_h = st->allocate_fill_stack_trace_element_array(CHECK);
   1.317 +  } else {
   1.318 +    stacktrace_h = Handle();
   1.319 +  }
   1.320 +
   1.321 +  args->push_oop(snapshot_thread);
   1.322 +  args->push_int(thread_status);
   1.323 +  args->push_oop(Handle(THREAD, snapshot->blocker_object()));
   1.324 +  args->push_oop(Handle(THREAD, snapshot->blocker_object_owner()));
   1.325 +  args->push_long(snapshot->contended_enter_count());
   1.326 +  args->push_long(contended_time);
   1.327 +  args->push_long(snapshot->monitor_wait_count() + snapshot->sleep_count());
   1.328 +  args->push_long(waited_time);
   1.329 +  args->push_oop(stacktrace_h);
   1.330 +}
   1.331 +
   1.332 +// Helper function to construct a ThreadInfo object
   1.333 +instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot, TRAPS) {
   1.334 +  Klass* k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
   1.335 +  instanceKlassHandle ik (THREAD, k);
   1.336 +
   1.337 +  JavaValue result(T_VOID);
   1.338 +  JavaCallArguments args(14);
   1.339 +
   1.340 +  // First allocate a ThreadObj object and
   1.341 +  // push the receiver as the first argument
   1.342 +  Handle element = ik->allocate_instance_handle(CHECK_NULL);
   1.343 +  args.push_oop(element);
   1.344 +
   1.345 +  // initialize the arguments for the ThreadInfo constructor
   1.346 +  initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
   1.347 +
   1.348 +  // Call ThreadInfo constructor with no locked monitors and synchronizers
   1.349 +  JavaCalls::call_special(&result,
   1.350 +                          ik,
   1.351 +                          vmSymbols::object_initializer_name(),
   1.352 +                          vmSymbols::java_lang_management_ThreadInfo_constructor_signature(),
   1.353 +                          &args,
   1.354 +                          CHECK_NULL);
   1.355 +
   1.356 +  return (instanceOop) element();
   1.357 +}
   1.358 +
   1.359 +instanceOop Management::create_thread_info_instance(ThreadSnapshot* snapshot,
   1.360 +                                                    objArrayHandle monitors_array,
   1.361 +                                                    typeArrayHandle depths_array,
   1.362 +                                                    objArrayHandle synchronizers_array,
   1.363 +                                                    TRAPS) {
   1.364 +  Klass* k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
   1.365 +  instanceKlassHandle ik (THREAD, k);
   1.366 +
   1.367 +  JavaValue result(T_VOID);
   1.368 +  JavaCallArguments args(17);
   1.369 +
   1.370 +  // First allocate a ThreadObj object and
   1.371 +  // push the receiver as the first argument
   1.372 +  Handle element = ik->allocate_instance_handle(CHECK_NULL);
   1.373 +  args.push_oop(element);
   1.374 +
   1.375 +  // initialize the arguments for the ThreadInfo constructor
   1.376 +  initialize_ThreadInfo_constructor_arguments(&args, snapshot, CHECK_NULL);
   1.377 +
   1.378 +  // push the locked monitors and synchronizers in the arguments
   1.379 +  args.push_oop(monitors_array);
   1.380 +  args.push_oop(depths_array);
   1.381 +  args.push_oop(synchronizers_array);
   1.382 +
   1.383 +  // Call ThreadInfo constructor with locked monitors and synchronizers
   1.384 +  JavaCalls::call_special(&result,
   1.385 +                          ik,
   1.386 +                          vmSymbols::object_initializer_name(),
   1.387 +                          vmSymbols::java_lang_management_ThreadInfo_with_locks_constructor_signature(),
   1.388 +                          &args,
   1.389 +                          CHECK_NULL);
   1.390 +
   1.391 +  return (instanceOop) element();
   1.392 +}
   1.393 +
   1.394 +// Helper functions
   1.395 +static JavaThread* find_java_thread_from_id(jlong thread_id) {
   1.396 +  assert(Threads_lock->owned_by_self(), "Must hold Threads_lock");
   1.397 +
   1.398 +  JavaThread* java_thread = NULL;
   1.399 +  // Sequential search for now.  Need to do better optimization later.
   1.400 +  for (JavaThread* thread = Threads::first(); thread != NULL; thread = thread->next()) {
   1.401 +    oop tobj = thread->threadObj();
   1.402 +    if (!thread->is_exiting() &&
   1.403 +        tobj != NULL &&
   1.404 +        thread_id == java_lang_Thread::thread_id(tobj)) {
   1.405 +      java_thread = thread;
   1.406 +      break;
   1.407 +    }
   1.408 +  }
   1.409 +  return java_thread;
   1.410 +}
   1.411 +
   1.412 +static GCMemoryManager* get_gc_memory_manager_from_jobject(jobject mgr, TRAPS) {
   1.413 +  if (mgr == NULL) {
   1.414 +    THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
   1.415 +  }
   1.416 +  oop mgr_obj = JNIHandles::resolve(mgr);
   1.417 +  instanceHandle h(THREAD, (instanceOop) mgr_obj);
   1.418 +
   1.419 +  Klass* k = Management::java_lang_management_GarbageCollectorMXBean_klass(CHECK_NULL);
   1.420 +  if (!h->is_a(k)) {
   1.421 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
   1.422 +               "the object is not an instance of java.lang.management.GarbageCollectorMXBean class",
   1.423 +               NULL);
   1.424 +  }
   1.425 +
   1.426 +  MemoryManager* gc = MemoryService::get_memory_manager(h);
   1.427 +  if (gc == NULL || !gc->is_gc_memory_manager()) {
   1.428 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
   1.429 +               "Invalid GC memory manager",
   1.430 +               NULL);
   1.431 +  }
   1.432 +  return (GCMemoryManager*) gc;
   1.433 +}
   1.434 +
   1.435 +static MemoryPool* get_memory_pool_from_jobject(jobject obj, TRAPS) {
   1.436 +  if (obj == NULL) {
   1.437 +    THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
   1.438 +  }
   1.439 +
   1.440 +  oop pool_obj = JNIHandles::resolve(obj);
   1.441 +  assert(pool_obj->is_instance(), "Should be an instanceOop");
   1.442 +  instanceHandle ph(THREAD, (instanceOop) pool_obj);
   1.443 +
   1.444 +  return MemoryService::get_memory_pool(ph);
   1.445 +}
   1.446 +
   1.447 +static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   1.448 +  int num_threads = ids_ah->length();
   1.449 +
   1.450 +  // Validate input thread IDs
   1.451 +  int i = 0;
   1.452 +  for (i = 0; i < num_threads; i++) {
   1.453 +    jlong tid = ids_ah->long_at(i);
   1.454 +    if (tid <= 0) {
   1.455 +      // throw exception if invalid thread id.
   1.456 +      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   1.457 +                "Invalid thread ID entry");
   1.458 +    }
   1.459 +  }
   1.460 +}
   1.461 +
   1.462 +static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
   1.463 +  // check if the element of infoArray is of type ThreadInfo class
   1.464 +  Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
   1.465 +  Klass* element_klass = ObjArrayKlass::cast(infoArray_h->klass())->element_klass();
   1.466 +  if (element_klass != threadinfo_klass) {
   1.467 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   1.468 +              "infoArray element type is not ThreadInfo class");
   1.469 +  }
   1.470 +}
   1.471 +
   1.472 +
   1.473 +static MemoryManager* get_memory_manager_from_jobject(jobject obj, TRAPS) {
   1.474 +  if (obj == NULL) {
   1.475 +    THROW_(vmSymbols::java_lang_NullPointerException(), NULL);
   1.476 +  }
   1.477 +
   1.478 +  oop mgr_obj = JNIHandles::resolve(obj);
   1.479 +  assert(mgr_obj->is_instance(), "Should be an instanceOop");
   1.480 +  instanceHandle mh(THREAD, (instanceOop) mgr_obj);
   1.481 +
   1.482 +  return MemoryService::get_memory_manager(mh);
   1.483 +}
   1.484 +
   1.485 +// Returns a version string and sets major and minor version if
   1.486 +// the input parameters are non-null.
   1.487 +JVM_LEAF(jint, jmm_GetVersion(JNIEnv *env))
   1.488 +  return JMM_VERSION;
   1.489 +JVM_END
   1.490 +
   1.491 +// Gets the list of VM monitoring and management optional supports
   1.492 +// Returns 0 if succeeded; otherwise returns non-zero.
   1.493 +JVM_LEAF(jint, jmm_GetOptionalSupport(JNIEnv *env, jmmOptionalSupport* support))
   1.494 +  if (support == NULL) {
   1.495 +    return -1;
   1.496 +  }
   1.497 +  Management::get_optional_support(support);
   1.498 +  return 0;
   1.499 +JVM_END
   1.500 +
   1.501 +// Returns a java.lang.String object containing the input arguments to the VM.
   1.502 +JVM_ENTRY(jobject, jmm_GetInputArguments(JNIEnv *env))
   1.503 +  ResourceMark rm(THREAD);
   1.504 +
   1.505 +  if (Arguments::num_jvm_args() == 0 && Arguments::num_jvm_flags() == 0) {
   1.506 +    return NULL;
   1.507 +  }
   1.508 +
   1.509 +  char** vm_flags = Arguments::jvm_flags_array();
   1.510 +  char** vm_args  = Arguments::jvm_args_array();
   1.511 +  int num_flags   = Arguments::num_jvm_flags();
   1.512 +  int num_args    = Arguments::num_jvm_args();
   1.513 +
   1.514 +  size_t length = 1; // null terminator
   1.515 +  int i;
   1.516 +  for (i = 0; i < num_flags; i++) {
   1.517 +    length += strlen(vm_flags[i]);
   1.518 +  }
   1.519 +  for (i = 0; i < num_args; i++) {
   1.520 +    length += strlen(vm_args[i]);
   1.521 +  }
   1.522 +  // add a space between each argument
   1.523 +  length += num_flags + num_args - 1;
   1.524 +
   1.525 +  // Return the list of input arguments passed to the VM
   1.526 +  // and preserve the order that the VM processes.
   1.527 +  char* args = NEW_RESOURCE_ARRAY(char, length);
   1.528 +  args[0] = '\0';
   1.529 +  // concatenate all jvm_flags
   1.530 +  if (num_flags > 0) {
   1.531 +    strcat(args, vm_flags[0]);
   1.532 +    for (i = 1; i < num_flags; i++) {
   1.533 +      strcat(args, " ");
   1.534 +      strcat(args, vm_flags[i]);
   1.535 +    }
   1.536 +  }
   1.537 +
   1.538 +  if (num_args > 0 && num_flags > 0) {
   1.539 +    // append a space if args already contains one or more jvm_flags
   1.540 +    strcat(args, " ");
   1.541 +  }
   1.542 +
   1.543 +  // concatenate all jvm_args
   1.544 +  if (num_args > 0) {
   1.545 +    strcat(args, vm_args[0]);
   1.546 +    for (i = 1; i < num_args; i++) {
   1.547 +      strcat(args, " ");
   1.548 +      strcat(args, vm_args[i]);
   1.549 +    }
   1.550 +  }
   1.551 +
   1.552 +  Handle hargs = java_lang_String::create_from_platform_dependent_str(args, CHECK_NULL);
   1.553 +  return JNIHandles::make_local(env, hargs());
   1.554 +JVM_END
   1.555 +
   1.556 +// Returns an array of java.lang.String object containing the input arguments to the VM.
   1.557 +JVM_ENTRY(jobjectArray, jmm_GetInputArgumentArray(JNIEnv *env))
   1.558 +  ResourceMark rm(THREAD);
   1.559 +
   1.560 +  if (Arguments::num_jvm_args() == 0 && Arguments::num_jvm_flags() == 0) {
   1.561 +    return NULL;
   1.562 +  }
   1.563 +
   1.564 +  char** vm_flags = Arguments::jvm_flags_array();
   1.565 +  char** vm_args = Arguments::jvm_args_array();
   1.566 +  int num_flags = Arguments::num_jvm_flags();
   1.567 +  int num_args = Arguments::num_jvm_args();
   1.568 +
   1.569 +  instanceKlassHandle ik (THREAD, SystemDictionary::String_klass());
   1.570 +  objArrayOop r = oopFactory::new_objArray(ik(), num_args + num_flags, CHECK_NULL);
   1.571 +  objArrayHandle result_h(THREAD, r);
   1.572 +
   1.573 +  int index = 0;
   1.574 +  for (int j = 0; j < num_flags; j++, index++) {
   1.575 +    Handle h = java_lang_String::create_from_platform_dependent_str(vm_flags[j], CHECK_NULL);
   1.576 +    result_h->obj_at_put(index, h());
   1.577 +  }
   1.578 +  for (int i = 0; i < num_args; i++, index++) {
   1.579 +    Handle h = java_lang_String::create_from_platform_dependent_str(vm_args[i], CHECK_NULL);
   1.580 +    result_h->obj_at_put(index, h());
   1.581 +  }
   1.582 +  return (jobjectArray) JNIHandles::make_local(env, result_h());
   1.583 +JVM_END
   1.584 +
   1.585 +// Returns an array of java/lang/management/MemoryPoolMXBean object
   1.586 +// one for each memory pool if obj == null; otherwise returns
   1.587 +// an array of memory pools for a given memory manager if
   1.588 +// it is a valid memory manager.
   1.589 +JVM_ENTRY(jobjectArray, jmm_GetMemoryPools(JNIEnv* env, jobject obj))
   1.590 +  ResourceMark rm(THREAD);
   1.591 +
   1.592 +  int num_memory_pools;
   1.593 +  MemoryManager* mgr = NULL;
   1.594 +  if (obj == NULL) {
   1.595 +    num_memory_pools = MemoryService::num_memory_pools();
   1.596 +  } else {
   1.597 +    mgr = get_memory_manager_from_jobject(obj, CHECK_NULL);
   1.598 +    if (mgr == NULL) {
   1.599 +      return NULL;
   1.600 +    }
   1.601 +    num_memory_pools = mgr->num_memory_pools();
   1.602 +  }
   1.603 +
   1.604 +  // Allocate the resulting MemoryPoolMXBean[] object
   1.605 +  Klass* k = Management::java_lang_management_MemoryPoolMXBean_klass(CHECK_NULL);
   1.606 +  instanceKlassHandle ik (THREAD, k);
   1.607 +  objArrayOop r = oopFactory::new_objArray(ik(), num_memory_pools, CHECK_NULL);
   1.608 +  objArrayHandle poolArray(THREAD, r);
   1.609 +
   1.610 +  if (mgr == NULL) {
   1.611 +    // Get all memory pools
   1.612 +    for (int i = 0; i < num_memory_pools; i++) {
   1.613 +      MemoryPool* pool = MemoryService::get_memory_pool(i);
   1.614 +      instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);
   1.615 +      instanceHandle ph(THREAD, p);
   1.616 +      poolArray->obj_at_put(i, ph());
   1.617 +    }
   1.618 +  } else {
   1.619 +    // Get memory pools managed by a given memory manager
   1.620 +    for (int i = 0; i < num_memory_pools; i++) {
   1.621 +      MemoryPool* pool = mgr->get_memory_pool(i);
   1.622 +      instanceOop p = pool->get_memory_pool_instance(CHECK_NULL);
   1.623 +      instanceHandle ph(THREAD, p);
   1.624 +      poolArray->obj_at_put(i, ph());
   1.625 +    }
   1.626 +  }
   1.627 +  return (jobjectArray) JNIHandles::make_local(env, poolArray());
   1.628 +JVM_END
   1.629 +
   1.630 +// Returns an array of java/lang/management/MemoryManagerMXBean object
   1.631 +// one for each memory manager if obj == null; otherwise returns
   1.632 +// an array of memory managers for a given memory pool if
   1.633 +// it is a valid memory pool.
   1.634 +JVM_ENTRY(jobjectArray, jmm_GetMemoryManagers(JNIEnv* env, jobject obj))
   1.635 +  ResourceMark rm(THREAD);
   1.636 +
   1.637 +  int num_mgrs;
   1.638 +  MemoryPool* pool = NULL;
   1.639 +  if (obj == NULL) {
   1.640 +    num_mgrs = MemoryService::num_memory_managers();
   1.641 +  } else {
   1.642 +    pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
   1.643 +    if (pool == NULL) {
   1.644 +      return NULL;
   1.645 +    }
   1.646 +    num_mgrs = pool->num_memory_managers();
   1.647 +  }
   1.648 +
   1.649 +  // Allocate the resulting MemoryManagerMXBean[] object
   1.650 +  Klass* k = Management::java_lang_management_MemoryManagerMXBean_klass(CHECK_NULL);
   1.651 +  instanceKlassHandle ik (THREAD, k);
   1.652 +  objArrayOop r = oopFactory::new_objArray(ik(), num_mgrs, CHECK_NULL);
   1.653 +  objArrayHandle mgrArray(THREAD, r);
   1.654 +
   1.655 +  if (pool == NULL) {
   1.656 +    // Get all memory managers
   1.657 +    for (int i = 0; i < num_mgrs; i++) {
   1.658 +      MemoryManager* mgr = MemoryService::get_memory_manager(i);
   1.659 +      instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);
   1.660 +      instanceHandle ph(THREAD, p);
   1.661 +      mgrArray->obj_at_put(i, ph());
   1.662 +    }
   1.663 +  } else {
   1.664 +    // Get memory managers for a given memory pool
   1.665 +    for (int i = 0; i < num_mgrs; i++) {
   1.666 +      MemoryManager* mgr = pool->get_memory_manager(i);
   1.667 +      instanceOop p = mgr->get_memory_manager_instance(CHECK_NULL);
   1.668 +      instanceHandle ph(THREAD, p);
   1.669 +      mgrArray->obj_at_put(i, ph());
   1.670 +    }
   1.671 +  }
   1.672 +  return (jobjectArray) JNIHandles::make_local(env, mgrArray());
   1.673 +JVM_END
   1.674 +
   1.675 +
   1.676 +// Returns a java/lang/management/MemoryUsage object containing the memory usage
   1.677 +// of a given memory pool.
   1.678 +JVM_ENTRY(jobject, jmm_GetMemoryPoolUsage(JNIEnv* env, jobject obj))
   1.679 +  ResourceMark rm(THREAD);
   1.680 +
   1.681 +  MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
   1.682 +  if (pool != NULL) {
   1.683 +    MemoryUsage usage = pool->get_memory_usage();
   1.684 +    Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
   1.685 +    return JNIHandles::make_local(env, h());
   1.686 +  } else {
   1.687 +    return NULL;
   1.688 +  }
   1.689 +JVM_END
   1.690 +
   1.691 +// Returns a java/lang/management/MemoryUsage object containing the memory usage
   1.692 +// of a given memory pool.
   1.693 +JVM_ENTRY(jobject, jmm_GetPeakMemoryPoolUsage(JNIEnv* env, jobject obj))
   1.694 +  ResourceMark rm(THREAD);
   1.695 +
   1.696 +  MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
   1.697 +  if (pool != NULL) {
   1.698 +    MemoryUsage usage = pool->get_peak_memory_usage();
   1.699 +    Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
   1.700 +    return JNIHandles::make_local(env, h());
   1.701 +  } else {
   1.702 +    return NULL;
   1.703 +  }
   1.704 +JVM_END
   1.705 +
   1.706 +// Returns a java/lang/management/MemoryUsage object containing the memory usage
   1.707 +// of a given memory pool after most recent GC.
   1.708 +JVM_ENTRY(jobject, jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj))
   1.709 +  ResourceMark rm(THREAD);
   1.710 +
   1.711 +  MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_NULL);
   1.712 +  if (pool != NULL && pool->is_collected_pool()) {
   1.713 +    MemoryUsage usage = pool->get_last_collection_usage();
   1.714 +    Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
   1.715 +    return JNIHandles::make_local(env, h());
   1.716 +  } else {
   1.717 +    return NULL;
   1.718 +  }
   1.719 +JVM_END
   1.720 +
   1.721 +// Sets the memory pool sensor for a threshold type
   1.722 +JVM_ENTRY(void, jmm_SetPoolSensor(JNIEnv* env, jobject obj, jmmThresholdType type, jobject sensorObj))
   1.723 +  if (obj == NULL || sensorObj == NULL) {
   1.724 +    THROW(vmSymbols::java_lang_NullPointerException());
   1.725 +  }
   1.726 +
   1.727 +  Klass* sensor_klass = Management::sun_management_Sensor_klass(CHECK);
   1.728 +  oop s = JNIHandles::resolve(sensorObj);
   1.729 +  assert(s->is_instance(), "Sensor should be an instanceOop");
   1.730 +  instanceHandle sensor_h(THREAD, (instanceOop) s);
   1.731 +  if (!sensor_h->is_a(sensor_klass)) {
   1.732 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   1.733 +              "Sensor is not an instance of sun.management.Sensor class");
   1.734 +  }
   1.735 +
   1.736 +  MemoryPool* mpool = get_memory_pool_from_jobject(obj, CHECK);
   1.737 +  assert(mpool != NULL, "MemoryPool should exist");
   1.738 +
   1.739 +  switch (type) {
   1.740 +    case JMM_USAGE_THRESHOLD_HIGH:
   1.741 +    case JMM_USAGE_THRESHOLD_LOW:
   1.742 +      // have only one sensor for threshold high and low
   1.743 +      mpool->set_usage_sensor_obj(sensor_h);
   1.744 +      break;
   1.745 +    case JMM_COLLECTION_USAGE_THRESHOLD_HIGH:
   1.746 +    case JMM_COLLECTION_USAGE_THRESHOLD_LOW:
   1.747 +      // have only one sensor for threshold high and low
   1.748 +      mpool->set_gc_usage_sensor_obj(sensor_h);
   1.749 +      break;
   1.750 +    default:
   1.751 +      assert(false, "Unrecognized type");
   1.752 +  }
   1.753 +
   1.754 +JVM_END
   1.755 +
   1.756 +
   1.757 +// Sets the threshold of a given memory pool.
   1.758 +// Returns the previous threshold.
   1.759 +//
   1.760 +// Input parameters:
   1.761 +//   pool      - the MemoryPoolMXBean object
   1.762 +//   type      - threshold type
   1.763 +//   threshold - the new threshold (must not be negative)
   1.764 +//
   1.765 +JVM_ENTRY(jlong, jmm_SetPoolThreshold(JNIEnv* env, jobject obj, jmmThresholdType type, jlong threshold))
   1.766 +  if (threshold < 0) {
   1.767 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
   1.768 +               "Invalid threshold value",
   1.769 +               -1);
   1.770 +  }
   1.771 +
   1.772 +  if ((size_t)threshold > max_uintx) {
   1.773 +    stringStream st;
   1.774 +    st.print("Invalid valid threshold value. Threshold value (" UINT64_FORMAT ") > max value of size_t (" SIZE_FORMAT ")", (size_t)threshold, max_uintx);
   1.775 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), st.as_string(), -1);
   1.776 +  }
   1.777 +
   1.778 +  MemoryPool* pool = get_memory_pool_from_jobject(obj, CHECK_(0L));
   1.779 +  assert(pool != NULL, "MemoryPool should exist");
   1.780 +
   1.781 +  jlong prev = 0;
   1.782 +  switch (type) {
   1.783 +    case JMM_USAGE_THRESHOLD_HIGH:
   1.784 +      if (!pool->usage_threshold()->is_high_threshold_supported()) {
   1.785 +        return -1;
   1.786 +      }
   1.787 +      prev = pool->usage_threshold()->set_high_threshold((size_t) threshold);
   1.788 +      break;
   1.789 +
   1.790 +    case JMM_USAGE_THRESHOLD_LOW:
   1.791 +      if (!pool->usage_threshold()->is_low_threshold_supported()) {
   1.792 +        return -1;
   1.793 +      }
   1.794 +      prev = pool->usage_threshold()->set_low_threshold((size_t) threshold);
   1.795 +      break;
   1.796 +
   1.797 +    case JMM_COLLECTION_USAGE_THRESHOLD_HIGH:
   1.798 +      if (!pool->gc_usage_threshold()->is_high_threshold_supported()) {
   1.799 +        return -1;
   1.800 +      }
   1.801 +      // return and the new threshold is effective for the next GC
   1.802 +      return pool->gc_usage_threshold()->set_high_threshold((size_t) threshold);
   1.803 +
   1.804 +    case JMM_COLLECTION_USAGE_THRESHOLD_LOW:
   1.805 +      if (!pool->gc_usage_threshold()->is_low_threshold_supported()) {
   1.806 +        return -1;
   1.807 +      }
   1.808 +      // return and the new threshold is effective for the next GC
   1.809 +      return pool->gc_usage_threshold()->set_low_threshold((size_t) threshold);
   1.810 +
   1.811 +    default:
   1.812 +      assert(false, "Unrecognized type");
   1.813 +      return -1;
   1.814 +  }
   1.815 +
   1.816 +  // When the threshold is changed, reevaluate if the low memory
   1.817 +  // detection is enabled.
   1.818 +  if (prev != threshold) {
   1.819 +    LowMemoryDetector::recompute_enabled_for_collected_pools();
   1.820 +    LowMemoryDetector::detect_low_memory(pool);
   1.821 +  }
   1.822 +  return prev;
   1.823 +JVM_END
   1.824 +
   1.825 +// Gets an array containing the amount of memory allocated on the Java
   1.826 +// heap for a set of threads (in bytes).  Each element of the array is
   1.827 +// the amount of memory allocated for the thread ID specified in the
   1.828 +// corresponding entry in the given array of thread IDs; or -1 if the
   1.829 +// thread does not exist or has terminated.
   1.830 +JVM_ENTRY(void, jmm_GetThreadAllocatedMemory(JNIEnv *env, jlongArray ids,
   1.831 +                                             jlongArray sizeArray))
   1.832 +  // Check if threads is null
   1.833 +  if (ids == NULL || sizeArray == NULL) {
   1.834 +    THROW(vmSymbols::java_lang_NullPointerException());
   1.835 +  }
   1.836 +
   1.837 +  ResourceMark rm(THREAD);
   1.838 +  typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
   1.839 +  typeArrayHandle ids_ah(THREAD, ta);
   1.840 +
   1.841 +  typeArrayOop sa = typeArrayOop(JNIHandles::resolve_non_null(sizeArray));
   1.842 +  typeArrayHandle sizeArray_h(THREAD, sa);
   1.843 +
   1.844 +  // validate the thread id array
   1.845 +  validate_thread_id_array(ids_ah, CHECK);
   1.846 +
   1.847 +  // sizeArray must be of the same length as the given array of thread IDs
   1.848 +  int num_threads = ids_ah->length();
   1.849 +  if (num_threads != sizeArray_h->length()) {
   1.850 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
   1.851 +              "The length of the given long array does not match the length of "
   1.852 +              "the given array of thread IDs");
   1.853 +  }
   1.854 +
   1.855 +  MutexLockerEx ml(Threads_lock);
   1.856 +  for (int i = 0; i < num_threads; i++) {
   1.857 +    JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
   1.858 +    if (java_thread != NULL) {
   1.859 +      sizeArray_h->long_at_put(i, java_thread->cooked_allocated_bytes());
   1.860 +    }
   1.861 +  }
   1.862 +JVM_END
   1.863 +
   1.864 +// Returns a java/lang/management/MemoryUsage object representing
   1.865 +// the memory usage for the heap or non-heap memory.
   1.866 +JVM_ENTRY(jobject, jmm_GetMemoryUsage(JNIEnv* env, jboolean heap))
   1.867 +  ResourceMark rm(THREAD);
   1.868 +
   1.869 +  // Calculate the memory usage
   1.870 +  size_t total_init = 0;
   1.871 +  size_t total_used = 0;
   1.872 +  size_t total_committed = 0;
   1.873 +  size_t total_max = 0;
   1.874 +  bool   has_undefined_init_size = false;
   1.875 +  bool   has_undefined_max_size = false;
   1.876 +
   1.877 +  for (int i = 0; i < MemoryService::num_memory_pools(); i++) {
   1.878 +    MemoryPool* pool = MemoryService::get_memory_pool(i);
   1.879 +    if ((heap && pool->is_heap()) || (!heap && pool->is_non_heap())) {
   1.880 +      MemoryUsage u = pool->get_memory_usage();
   1.881 +      total_used += u.used();
   1.882 +      total_committed += u.committed();
   1.883 +
   1.884 +      if (u.init_size() == (size_t)-1) {
   1.885 +        has_undefined_init_size = true;
   1.886 +      }
   1.887 +      if (!has_undefined_init_size) {
   1.888 +        total_init += u.init_size();
   1.889 +      }
   1.890 +
   1.891 +      if (u.max_size() == (size_t)-1) {
   1.892 +        has_undefined_max_size = true;
   1.893 +      }
   1.894 +      if (!has_undefined_max_size) {
   1.895 +        total_max += u.max_size();
   1.896 +      }
   1.897 +    }
   1.898 +  }
   1.899 +
   1.900 +  // if any one of the memory pool has undefined init_size or max_size,
   1.901 +  // set it to -1
   1.902 +  if (has_undefined_init_size) {
   1.903 +    total_init = (size_t)-1;
   1.904 +  }
   1.905 +  if (has_undefined_max_size) {
   1.906 +    total_max = (size_t)-1;
   1.907 +  }
   1.908 +
   1.909 +  MemoryUsage usage((heap ? InitialHeapSize : total_init),
   1.910 +                    total_used,
   1.911 +                    total_committed,
   1.912 +                    (heap ? Universe::heap()->max_capacity() : total_max));
   1.913 +
   1.914 +  Handle obj = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
   1.915 +  return JNIHandles::make_local(env, obj());
   1.916 +JVM_END
   1.917 +
   1.918 +// Returns the boolean value of a given attribute.
   1.919 +JVM_LEAF(jboolean, jmm_GetBoolAttribute(JNIEnv *env, jmmBoolAttribute att))
   1.920 +  switch (att) {
   1.921 +  case JMM_VERBOSE_GC:
   1.922 +    return MemoryService::get_verbose();
   1.923 +  case JMM_VERBOSE_CLASS:
   1.924 +    return ClassLoadingService::get_verbose();
   1.925 +  case JMM_THREAD_CONTENTION_MONITORING:
   1.926 +    return ThreadService::is_thread_monitoring_contention();
   1.927 +  case JMM_THREAD_CPU_TIME:
   1.928 +    return ThreadService::is_thread_cpu_time_enabled();
   1.929 +  case JMM_THREAD_ALLOCATED_MEMORY:
   1.930 +    return ThreadService::is_thread_allocated_memory_enabled();
   1.931 +  default:
   1.932 +    assert(0, "Unrecognized attribute");
   1.933 +    return false;
   1.934 +  }
   1.935 +JVM_END
   1.936 +
   1.937 +// Sets the given boolean attribute and returns the previous value.
   1.938 +JVM_ENTRY(jboolean, jmm_SetBoolAttribute(JNIEnv *env, jmmBoolAttribute att, jboolean flag))
   1.939 +  switch (att) {
   1.940 +  case JMM_VERBOSE_GC:
   1.941 +    return MemoryService::set_verbose(flag != 0);
   1.942 +  case JMM_VERBOSE_CLASS:
   1.943 +    return ClassLoadingService::set_verbose(flag != 0);
   1.944 +  case JMM_THREAD_CONTENTION_MONITORING:
   1.945 +    return ThreadService::set_thread_monitoring_contention(flag != 0);
   1.946 +  case JMM_THREAD_CPU_TIME:
   1.947 +    return ThreadService::set_thread_cpu_time_enabled(flag != 0);
   1.948 +  case JMM_THREAD_ALLOCATED_MEMORY:
   1.949 +    return ThreadService::set_thread_allocated_memory_enabled(flag != 0);
   1.950 +  default:
   1.951 +    assert(0, "Unrecognized attribute");
   1.952 +    return false;
   1.953 +  }
   1.954 +JVM_END
   1.955 +
   1.956 +
   1.957 +static jlong get_gc_attribute(GCMemoryManager* mgr, jmmLongAttribute att) {
   1.958 +  switch (att) {
   1.959 +  case JMM_GC_TIME_MS:
   1.960 +    return mgr->gc_time_ms();
   1.961 +
   1.962 +  case JMM_GC_COUNT:
   1.963 +    return mgr->gc_count();
   1.964 +
   1.965 +  case JMM_GC_EXT_ATTRIBUTE_INFO_SIZE:
   1.966 +    // current implementation only has 1 ext attribute
   1.967 +    return 1;
   1.968 +
   1.969 +  default:
   1.970 +    assert(0, "Unrecognized GC attribute");
   1.971 +    return -1;
   1.972 +  }
   1.973 +}
   1.974 +
   1.975 +class VmThreadCountClosure: public ThreadClosure {
   1.976 + private:
   1.977 +  int _count;
   1.978 + public:
   1.979 +  VmThreadCountClosure() : _count(0) {};
   1.980 +  void do_thread(Thread* thread);
   1.981 +  int count() { return _count; }
   1.982 +};
   1.983 +
   1.984 +void VmThreadCountClosure::do_thread(Thread* thread) {
   1.985 +  // exclude externally visible JavaThreads
   1.986 +  if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {
   1.987 +    return;
   1.988 +  }
   1.989 +
   1.990 +  _count++;
   1.991 +}
   1.992 +
   1.993 +static jint get_vm_thread_count() {
   1.994 +  VmThreadCountClosure vmtcc;
   1.995 +  {
   1.996 +    MutexLockerEx ml(Threads_lock);
   1.997 +    Threads::threads_do(&vmtcc);
   1.998 +  }
   1.999 +
  1.1000 +  return vmtcc.count();
  1.1001 +}
  1.1002 +
  1.1003 +static jint get_num_flags() {
  1.1004 +  // last flag entry is always NULL, so subtract 1
  1.1005 +  int nFlags = (int) Flag::numFlags - 1;
  1.1006 +  int count = 0;
  1.1007 +  for (int i = 0; i < nFlags; i++) {
  1.1008 +    Flag* flag = &Flag::flags[i];
  1.1009 +    // Exclude the locked (diagnostic, experimental) flags
  1.1010 +    if (flag->is_unlocked() || flag->is_unlocker()) {
  1.1011 +      count++;
  1.1012 +    }
  1.1013 +  }
  1.1014 +  return count;
  1.1015 +}
  1.1016 +
  1.1017 +static jlong get_long_attribute(jmmLongAttribute att) {
  1.1018 +  switch (att) {
  1.1019 +  case JMM_CLASS_LOADED_COUNT:
  1.1020 +    return ClassLoadingService::loaded_class_count();
  1.1021 +
  1.1022 +  case JMM_CLASS_UNLOADED_COUNT:
  1.1023 +    return ClassLoadingService::unloaded_class_count();
  1.1024 +
  1.1025 +  case JMM_THREAD_TOTAL_COUNT:
  1.1026 +    return ThreadService::get_total_thread_count();
  1.1027 +
  1.1028 +  case JMM_THREAD_LIVE_COUNT:
  1.1029 +    return ThreadService::get_live_thread_count();
  1.1030 +
  1.1031 +  case JMM_THREAD_PEAK_COUNT:
  1.1032 +    return ThreadService::get_peak_thread_count();
  1.1033 +
  1.1034 +  case JMM_THREAD_DAEMON_COUNT:
  1.1035 +    return ThreadService::get_daemon_thread_count();
  1.1036 +
  1.1037 +  case JMM_JVM_INIT_DONE_TIME_MS:
  1.1038 +    return Management::vm_init_done_time();
  1.1039 +
  1.1040 +  case JMM_JVM_UPTIME_MS:
  1.1041 +    return Management::ticks_to_ms(os::elapsed_counter());
  1.1042 +
  1.1043 +  case JMM_COMPILE_TOTAL_TIME_MS:
  1.1044 +    return Management::ticks_to_ms(CompileBroker::total_compilation_ticks());
  1.1045 +
  1.1046 +  case JMM_OS_PROCESS_ID:
  1.1047 +    return os::current_process_id();
  1.1048 +
  1.1049 +  // Hotspot-specific counters
  1.1050 +  case JMM_CLASS_LOADED_BYTES:
  1.1051 +    return ClassLoadingService::loaded_class_bytes();
  1.1052 +
  1.1053 +  case JMM_CLASS_UNLOADED_BYTES:
  1.1054 +    return ClassLoadingService::unloaded_class_bytes();
  1.1055 +
  1.1056 +  case JMM_SHARED_CLASS_LOADED_COUNT:
  1.1057 +    return ClassLoadingService::loaded_shared_class_count();
  1.1058 +
  1.1059 +  case JMM_SHARED_CLASS_UNLOADED_COUNT:
  1.1060 +    return ClassLoadingService::unloaded_shared_class_count();
  1.1061 +
  1.1062 +
  1.1063 +  case JMM_SHARED_CLASS_LOADED_BYTES:
  1.1064 +    return ClassLoadingService::loaded_shared_class_bytes();
  1.1065 +
  1.1066 +  case JMM_SHARED_CLASS_UNLOADED_BYTES:
  1.1067 +    return ClassLoadingService::unloaded_shared_class_bytes();
  1.1068 +
  1.1069 +  case JMM_TOTAL_CLASSLOAD_TIME_MS:
  1.1070 +    return ClassLoader::classloader_time_ms();
  1.1071 +
  1.1072 +  case JMM_VM_GLOBAL_COUNT:
  1.1073 +    return get_num_flags();
  1.1074 +
  1.1075 +  case JMM_SAFEPOINT_COUNT:
  1.1076 +    return RuntimeService::safepoint_count();
  1.1077 +
  1.1078 +  case JMM_TOTAL_SAFEPOINTSYNC_TIME_MS:
  1.1079 +    return RuntimeService::safepoint_sync_time_ms();
  1.1080 +
  1.1081 +  case JMM_TOTAL_STOPPED_TIME_MS:
  1.1082 +    return RuntimeService::safepoint_time_ms();
  1.1083 +
  1.1084 +  case JMM_TOTAL_APP_TIME_MS:
  1.1085 +    return RuntimeService::application_time_ms();
  1.1086 +
  1.1087 +  case JMM_VM_THREAD_COUNT:
  1.1088 +    return get_vm_thread_count();
  1.1089 +
  1.1090 +  case JMM_CLASS_INIT_TOTAL_COUNT:
  1.1091 +    return ClassLoader::class_init_count();
  1.1092 +
  1.1093 +  case JMM_CLASS_INIT_TOTAL_TIME_MS:
  1.1094 +    return ClassLoader::class_init_time_ms();
  1.1095 +
  1.1096 +  case JMM_CLASS_VERIFY_TOTAL_TIME_MS:
  1.1097 +    return ClassLoader::class_verify_time_ms();
  1.1098 +
  1.1099 +  case JMM_METHOD_DATA_SIZE_BYTES:
  1.1100 +    return ClassLoadingService::class_method_data_size();
  1.1101 +
  1.1102 +  case JMM_OS_MEM_TOTAL_PHYSICAL_BYTES:
  1.1103 +    return os::physical_memory();
  1.1104 +
  1.1105 +  default:
  1.1106 +    return -1;
  1.1107 +  }
  1.1108 +}
  1.1109 +
  1.1110 +
  1.1111 +// Returns the long value of a given attribute.
  1.1112 +JVM_ENTRY(jlong, jmm_GetLongAttribute(JNIEnv *env, jobject obj, jmmLongAttribute att))
  1.1113 +  if (obj == NULL) {
  1.1114 +    return get_long_attribute(att);
  1.1115 +  } else {
  1.1116 +    GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK_(0L));
  1.1117 +    if (mgr != NULL) {
  1.1118 +      return get_gc_attribute(mgr, att);
  1.1119 +    }
  1.1120 +  }
  1.1121 +  return -1;
  1.1122 +JVM_END
  1.1123 +
  1.1124 +// Gets the value of all attributes specified in the given array
  1.1125 +// and sets the value in the result array.
  1.1126 +// Returns the number of attributes found.
  1.1127 +JVM_ENTRY(jint, jmm_GetLongAttributes(JNIEnv *env,
  1.1128 +                                      jobject obj,
  1.1129 +                                      jmmLongAttribute* atts,
  1.1130 +                                      jint count,
  1.1131 +                                      jlong* result))
  1.1132 +
  1.1133 +  int num_atts = 0;
  1.1134 +  if (obj == NULL) {
  1.1135 +    for (int i = 0; i < count; i++) {
  1.1136 +      result[i] = get_long_attribute(atts[i]);
  1.1137 +      if (result[i] != -1) {
  1.1138 +        num_atts++;
  1.1139 +      }
  1.1140 +    }
  1.1141 +  } else {
  1.1142 +    GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK_0);
  1.1143 +    for (int i = 0; i < count; i++) {
  1.1144 +      result[i] = get_gc_attribute(mgr, atts[i]);
  1.1145 +      if (result[i] != -1) {
  1.1146 +        num_atts++;
  1.1147 +      }
  1.1148 +    }
  1.1149 +  }
  1.1150 +  return num_atts;
  1.1151 +JVM_END
  1.1152 +
  1.1153 +// Helper function to do thread dump for a specific list of threads
  1.1154 +static void do_thread_dump(ThreadDumpResult* dump_result,
  1.1155 +                           typeArrayHandle ids_ah,  // array of thread ID (long[])
  1.1156 +                           int num_threads,
  1.1157 +                           int max_depth,
  1.1158 +                           bool with_locked_monitors,
  1.1159 +                           bool with_locked_synchronizers,
  1.1160 +                           TRAPS) {
  1.1161 +
  1.1162 +  // First get an array of threadObj handles.
  1.1163 +  // A JavaThread may terminate before we get the stack trace.
  1.1164 +  GrowableArray<instanceHandle>* thread_handle_array = new GrowableArray<instanceHandle>(num_threads);
  1.1165 +  {
  1.1166 +    MutexLockerEx ml(Threads_lock);
  1.1167 +    for (int i = 0; i < num_threads; i++) {
  1.1168 +      jlong tid = ids_ah->long_at(i);
  1.1169 +      JavaThread* jt = find_java_thread_from_id(tid);
  1.1170 +      oop thread_obj = (jt != NULL ? jt->threadObj() : (oop)NULL);
  1.1171 +      instanceHandle threadObj_h(THREAD, (instanceOop) thread_obj);
  1.1172 +      thread_handle_array->append(threadObj_h);
  1.1173 +    }
  1.1174 +  }
  1.1175 +
  1.1176 +  // Obtain thread dumps and thread snapshot information
  1.1177 +  VM_ThreadDump op(dump_result,
  1.1178 +                   thread_handle_array,
  1.1179 +                   num_threads,
  1.1180 +                   max_depth, /* stack depth */
  1.1181 +                   with_locked_monitors,
  1.1182 +                   with_locked_synchronizers);
  1.1183 +  VMThread::execute(&op);
  1.1184 +}
  1.1185 +
  1.1186 +// Gets an array of ThreadInfo objects. Each element is the ThreadInfo
  1.1187 +// for the thread ID specified in the corresponding entry in
  1.1188 +// the given array of thread IDs; or NULL if the thread does not exist
  1.1189 +// or has terminated.
  1.1190 +//
  1.1191 +// Input parameters:
  1.1192 +//   ids       - array of thread IDs
  1.1193 +//   maxDepth  - the maximum depth of stack traces to be dumped:
  1.1194 +//               maxDepth == -1 requests to dump entire stack trace.
  1.1195 +//               maxDepth == 0  requests no stack trace.
  1.1196 +//   infoArray - array of ThreadInfo objects
  1.1197 +//
  1.1198 +// QQQ - Why does this method return a value instead of void?
  1.1199 +JVM_ENTRY(jint, jmm_GetThreadInfo(JNIEnv *env, jlongArray ids, jint maxDepth, jobjectArray infoArray))
  1.1200 +  // Check if threads is null
  1.1201 +  if (ids == NULL || infoArray == NULL) {
  1.1202 +    THROW_(vmSymbols::java_lang_NullPointerException(), -1);
  1.1203 +  }
  1.1204 +
  1.1205 +  if (maxDepth < -1) {
  1.1206 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.1207 +               "Invalid maxDepth", -1);
  1.1208 +  }
  1.1209 +
  1.1210 +  ResourceMark rm(THREAD);
  1.1211 +  typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
  1.1212 +  typeArrayHandle ids_ah(THREAD, ta);
  1.1213 +
  1.1214 +  oop infoArray_obj = JNIHandles::resolve_non_null(infoArray);
  1.1215 +  objArrayOop oa = objArrayOop(infoArray_obj);
  1.1216 +  objArrayHandle infoArray_h(THREAD, oa);
  1.1217 +
  1.1218 +  // validate the thread id array
  1.1219 +  validate_thread_id_array(ids_ah, CHECK_0);
  1.1220 +
  1.1221 +  // validate the ThreadInfo[] parameters
  1.1222 +  validate_thread_info_array(infoArray_h, CHECK_0);
  1.1223 +
  1.1224 +  // infoArray must be of the same length as the given array of thread IDs
  1.1225 +  int num_threads = ids_ah->length();
  1.1226 +  if (num_threads != infoArray_h->length()) {
  1.1227 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.1228 +               "The length of the given ThreadInfo array does not match the length of the given array of thread IDs", -1);
  1.1229 +  }
  1.1230 +
  1.1231 +  if (JDK_Version::is_gte_jdk16x_version()) {
  1.1232 +    // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
  1.1233 +    java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_0);
  1.1234 +  }
  1.1235 +
  1.1236 +  // Must use ThreadDumpResult to store the ThreadSnapshot.
  1.1237 +  // GC may occur after the thread snapshots are taken but before
  1.1238 +  // this function returns. The threadObj and other oops kept
  1.1239 +  // in the ThreadSnapshot are marked and adjusted during GC.
  1.1240 +  ThreadDumpResult dump_result(num_threads);
  1.1241 +
  1.1242 +  if (maxDepth == 0) {
  1.1243 +    // no stack trace dumped - do not need to stop the world
  1.1244 +    {
  1.1245 +      MutexLockerEx ml(Threads_lock);
  1.1246 +      for (int i = 0; i < num_threads; i++) {
  1.1247 +        jlong tid = ids_ah->long_at(i);
  1.1248 +        JavaThread* jt = find_java_thread_from_id(tid);
  1.1249 +        ThreadSnapshot* ts;
  1.1250 +        if (jt == NULL) {
  1.1251 +          // if the thread does not exist or now it is terminated,
  1.1252 +          // create dummy snapshot
  1.1253 +          ts = new ThreadSnapshot();
  1.1254 +        } else {
  1.1255 +          ts = new ThreadSnapshot(jt);
  1.1256 +        }
  1.1257 +        dump_result.add_thread_snapshot(ts);
  1.1258 +      }
  1.1259 +    }
  1.1260 +  } else {
  1.1261 +    // obtain thread dump with the specific list of threads with stack trace
  1.1262 +    do_thread_dump(&dump_result,
  1.1263 +                   ids_ah,
  1.1264 +                   num_threads,
  1.1265 +                   maxDepth,
  1.1266 +                   false, /* no locked monitor */
  1.1267 +                   false, /* no locked synchronizers */
  1.1268 +                   CHECK_0);
  1.1269 +  }
  1.1270 +
  1.1271 +  int num_snapshots = dump_result.num_snapshots();
  1.1272 +  assert(num_snapshots == num_threads, "Must match the number of thread snapshots");
  1.1273 +  int index = 0;
  1.1274 +  for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; index++, ts = ts->next()) {
  1.1275 +    // For each thread, create an java/lang/management/ThreadInfo object
  1.1276 +    // and fill with the thread information
  1.1277 +
  1.1278 +    if (ts->threadObj() == NULL) {
  1.1279 +     // if the thread does not exist or now it is terminated, set threadinfo to NULL
  1.1280 +      infoArray_h->obj_at_put(index, NULL);
  1.1281 +      continue;
  1.1282 +    }
  1.1283 +
  1.1284 +    // Create java.lang.management.ThreadInfo object
  1.1285 +    instanceOop info_obj = Management::create_thread_info_instance(ts, CHECK_0);
  1.1286 +    infoArray_h->obj_at_put(index, info_obj);
  1.1287 +  }
  1.1288 +  return 0;
  1.1289 +JVM_END
  1.1290 +
  1.1291 +// Dump thread info for the specified threads.
  1.1292 +// It returns an array of ThreadInfo objects. Each element is the ThreadInfo
  1.1293 +// for the thread ID specified in the corresponding entry in
  1.1294 +// the given array of thread IDs; or NULL if the thread does not exist
  1.1295 +// or has terminated.
  1.1296 +//
  1.1297 +// Input parameter:
  1.1298 +//    ids - array of thread IDs; NULL indicates all live threads
  1.1299 +//    locked_monitors - if true, dump locked object monitors
  1.1300 +//    locked_synchronizers - if true, dump locked JSR-166 synchronizers
  1.1301 +//
  1.1302 +JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, jboolean locked_synchronizers))
  1.1303 +  ResourceMark rm(THREAD);
  1.1304 +
  1.1305 +  if (JDK_Version::is_gte_jdk16x_version()) {
  1.1306 +    // make sure the AbstractOwnableSynchronizer klass is loaded before taking thread snapshots
  1.1307 +    java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(CHECK_NULL);
  1.1308 +  }
  1.1309 +
  1.1310 +  typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids));
  1.1311 +  int num_threads = (ta != NULL ? ta->length() : 0);
  1.1312 +  typeArrayHandle ids_ah(THREAD, ta);
  1.1313 +
  1.1314 +  ThreadDumpResult dump_result(num_threads);  // can safepoint
  1.1315 +
  1.1316 +  if (ids_ah() != NULL) {
  1.1317 +
  1.1318 +    // validate the thread id array
  1.1319 +    validate_thread_id_array(ids_ah, CHECK_NULL);
  1.1320 +
  1.1321 +    // obtain thread dump of a specific list of threads
  1.1322 +    do_thread_dump(&dump_result,
  1.1323 +                   ids_ah,
  1.1324 +                   num_threads,
  1.1325 +                   -1, /* entire stack */
  1.1326 +                   (locked_monitors ? true : false),      /* with locked monitors */
  1.1327 +                   (locked_synchronizers ? true : false), /* with locked synchronizers */
  1.1328 +                   CHECK_NULL);
  1.1329 +  } else {
  1.1330 +    // obtain thread dump of all threads
  1.1331 +    VM_ThreadDump op(&dump_result,
  1.1332 +                     -1, /* entire stack */
  1.1333 +                     (locked_monitors ? true : false),     /* with locked monitors */
  1.1334 +                     (locked_synchronizers ? true : false) /* with locked synchronizers */);
  1.1335 +    VMThread::execute(&op);
  1.1336 +  }
  1.1337 +
  1.1338 +  int num_snapshots = dump_result.num_snapshots();
  1.1339 +
  1.1340 +  // create the result ThreadInfo[] object
  1.1341 +  Klass* k = Management::java_lang_management_ThreadInfo_klass(CHECK_NULL);
  1.1342 +  instanceKlassHandle ik (THREAD, k);
  1.1343 +  objArrayOop r = oopFactory::new_objArray(ik(), num_snapshots, CHECK_NULL);
  1.1344 +  objArrayHandle result_h(THREAD, r);
  1.1345 +
  1.1346 +  int index = 0;
  1.1347 +  for (ThreadSnapshot* ts = dump_result.snapshots(); ts != NULL; ts = ts->next(), index++) {
  1.1348 +    if (ts->threadObj() == NULL) {
  1.1349 +     // if the thread does not exist or now it is terminated, set threadinfo to NULL
  1.1350 +      result_h->obj_at_put(index, NULL);
  1.1351 +      continue;
  1.1352 +    }
  1.1353 +
  1.1354 +    ThreadStackTrace* stacktrace = ts->get_stack_trace();
  1.1355 +    assert(stacktrace != NULL, "Must have a stack trace dumped");
  1.1356 +
  1.1357 +    // Create Object[] filled with locked monitors
  1.1358 +    // Create int[] filled with the stack depth where a monitor was locked
  1.1359 +    int num_frames = stacktrace->get_stack_depth();
  1.1360 +    int num_locked_monitors = stacktrace->num_jni_locked_monitors();
  1.1361 +
  1.1362 +    // Count the total number of locked monitors
  1.1363 +    for (int i = 0; i < num_frames; i++) {
  1.1364 +      StackFrameInfo* frame = stacktrace->stack_frame_at(i);
  1.1365 +      num_locked_monitors += frame->num_locked_monitors();
  1.1366 +    }
  1.1367 +
  1.1368 +    objArrayHandle monitors_array;
  1.1369 +    typeArrayHandle depths_array;
  1.1370 +    objArrayHandle synchronizers_array;
  1.1371 +
  1.1372 +    if (locked_monitors) {
  1.1373 +      // Constructs Object[] and int[] to contain the object monitor and the stack depth
  1.1374 +      // where the thread locked it
  1.1375 +      objArrayOop array = oopFactory::new_objArray(SystemDictionary::Object_klass(), num_locked_monitors, CHECK_NULL);
  1.1376 +      objArrayHandle mh(THREAD, array);
  1.1377 +      monitors_array = mh;
  1.1378 +
  1.1379 +      typeArrayOop tarray = oopFactory::new_typeArray(T_INT, num_locked_monitors, CHECK_NULL);
  1.1380 +      typeArrayHandle dh(THREAD, tarray);
  1.1381 +      depths_array = dh;
  1.1382 +
  1.1383 +      int count = 0;
  1.1384 +      int j = 0;
  1.1385 +      for (int depth = 0; depth < num_frames; depth++) {
  1.1386 +        StackFrameInfo* frame = stacktrace->stack_frame_at(depth);
  1.1387 +        int len = frame->num_locked_monitors();
  1.1388 +        GrowableArray<oop>* locked_monitors = frame->locked_monitors();
  1.1389 +        for (j = 0; j < len; j++) {
  1.1390 +          oop monitor = locked_monitors->at(j);
  1.1391 +          assert(monitor != NULL && monitor->is_instance(), "must be a Java object");
  1.1392 +          monitors_array->obj_at_put(count, monitor);
  1.1393 +          depths_array->int_at_put(count, depth);
  1.1394 +          count++;
  1.1395 +        }
  1.1396 +      }
  1.1397 +
  1.1398 +      GrowableArray<oop>* jni_locked_monitors = stacktrace->jni_locked_monitors();
  1.1399 +      for (j = 0; j < jni_locked_monitors->length(); j++) {
  1.1400 +        oop object = jni_locked_monitors->at(j);
  1.1401 +        assert(object != NULL && object->is_instance(), "must be a Java object");
  1.1402 +        monitors_array->obj_at_put(count, object);
  1.1403 +        // Monitor locked via JNI MonitorEnter call doesn't have stack depth info
  1.1404 +        depths_array->int_at_put(count, -1);
  1.1405 +        count++;
  1.1406 +      }
  1.1407 +      assert(count == num_locked_monitors, "number of locked monitors doesn't match");
  1.1408 +    }
  1.1409 +
  1.1410 +    if (locked_synchronizers) {
  1.1411 +      // Create Object[] filled with locked JSR-166 synchronizers
  1.1412 +      assert(ts->threadObj() != NULL, "Must be a valid JavaThread");
  1.1413 +      ThreadConcurrentLocks* tcl = ts->get_concurrent_locks();
  1.1414 +      GrowableArray<instanceOop>* locks = (tcl != NULL ? tcl->owned_locks() : NULL);
  1.1415 +      int num_locked_synchronizers = (locks != NULL ? locks->length() : 0);
  1.1416 +
  1.1417 +      objArrayOop array = oopFactory::new_objArray(SystemDictionary::Object_klass(), num_locked_synchronizers, CHECK_NULL);
  1.1418 +      objArrayHandle sh(THREAD, array);
  1.1419 +      synchronizers_array = sh;
  1.1420 +
  1.1421 +      for (int k = 0; k < num_locked_synchronizers; k++) {
  1.1422 +        synchronizers_array->obj_at_put(k, locks->at(k));
  1.1423 +      }
  1.1424 +    }
  1.1425 +
  1.1426 +    // Create java.lang.management.ThreadInfo object
  1.1427 +    instanceOop info_obj = Management::create_thread_info_instance(ts,
  1.1428 +                                                                   monitors_array,
  1.1429 +                                                                   depths_array,
  1.1430 +                                                                   synchronizers_array,
  1.1431 +                                                                   CHECK_NULL);
  1.1432 +    result_h->obj_at_put(index, info_obj);
  1.1433 +  }
  1.1434 +
  1.1435 +  return (jobjectArray) JNIHandles::make_local(env, result_h());
  1.1436 +JVM_END
  1.1437 +
  1.1438 +// Returns an array of Class objects.
  1.1439 +JVM_ENTRY(jobjectArray, jmm_GetLoadedClasses(JNIEnv *env))
  1.1440 +  ResourceMark rm(THREAD);
  1.1441 +
  1.1442 +  LoadedClassesEnumerator lce(THREAD);  // Pass current Thread as parameter
  1.1443 +
  1.1444 +  int num_classes = lce.num_loaded_classes();
  1.1445 +  objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), num_classes, CHECK_0);
  1.1446 +  objArrayHandle classes_ah(THREAD, r);
  1.1447 +
  1.1448 +  for (int i = 0; i < num_classes; i++) {
  1.1449 +    KlassHandle kh = lce.get_klass(i);
  1.1450 +    oop mirror = kh()->java_mirror();
  1.1451 +    classes_ah->obj_at_put(i, mirror);
  1.1452 +  }
  1.1453 +
  1.1454 +  return (jobjectArray) JNIHandles::make_local(env, classes_ah());
  1.1455 +JVM_END
  1.1456 +
  1.1457 +// Reset statistic.  Return true if the requested statistic is reset.
  1.1458 +// Otherwise, return false.
  1.1459 +//
  1.1460 +// Input parameters:
  1.1461 +//  obj  - specify which instance the statistic associated with to be reset
  1.1462 +//         For PEAK_POOL_USAGE stat, obj is required to be a memory pool object.
  1.1463 +//         For THREAD_CONTENTION_COUNT and TIME stat, obj is required to be a thread ID.
  1.1464 +//  type - the type of statistic to be reset
  1.1465 +//
  1.1466 +JVM_ENTRY(jboolean, jmm_ResetStatistic(JNIEnv *env, jvalue obj, jmmStatisticType type))
  1.1467 +  ResourceMark rm(THREAD);
  1.1468 +
  1.1469 +  switch (type) {
  1.1470 +    case JMM_STAT_PEAK_THREAD_COUNT:
  1.1471 +      ThreadService::reset_peak_thread_count();
  1.1472 +      return true;
  1.1473 +
  1.1474 +    case JMM_STAT_THREAD_CONTENTION_COUNT:
  1.1475 +    case JMM_STAT_THREAD_CONTENTION_TIME: {
  1.1476 +      jlong tid = obj.j;
  1.1477 +      if (tid < 0) {
  1.1478 +        THROW_(vmSymbols::java_lang_IllegalArgumentException(), JNI_FALSE);
  1.1479 +      }
  1.1480 +
  1.1481 +      // Look for the JavaThread of this given tid
  1.1482 +      MutexLockerEx ml(Threads_lock);
  1.1483 +      if (tid == 0) {
  1.1484 +        // reset contention statistics for all threads if tid == 0
  1.1485 +        for (JavaThread* java_thread = Threads::first(); java_thread != NULL; java_thread = java_thread->next()) {
  1.1486 +          if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
  1.1487 +            ThreadService::reset_contention_count_stat(java_thread);
  1.1488 +          } else {
  1.1489 +            ThreadService::reset_contention_time_stat(java_thread);
  1.1490 +          }
  1.1491 +        }
  1.1492 +      } else {
  1.1493 +        // reset contention statistics for a given thread
  1.1494 +        JavaThread* java_thread = find_java_thread_from_id(tid);
  1.1495 +        if (java_thread == NULL) {
  1.1496 +          return false;
  1.1497 +        }
  1.1498 +
  1.1499 +        if (type == JMM_STAT_THREAD_CONTENTION_COUNT) {
  1.1500 +          ThreadService::reset_contention_count_stat(java_thread);
  1.1501 +        } else {
  1.1502 +          ThreadService::reset_contention_time_stat(java_thread);
  1.1503 +        }
  1.1504 +      }
  1.1505 +      return true;
  1.1506 +      break;
  1.1507 +    }
  1.1508 +    case JMM_STAT_PEAK_POOL_USAGE: {
  1.1509 +      jobject o = obj.l;
  1.1510 +      if (o == NULL) {
  1.1511 +        THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
  1.1512 +      }
  1.1513 +
  1.1514 +      oop pool_obj = JNIHandles::resolve(o);
  1.1515 +      assert(pool_obj->is_instance(), "Should be an instanceOop");
  1.1516 +      instanceHandle ph(THREAD, (instanceOop) pool_obj);
  1.1517 +
  1.1518 +      MemoryPool* pool = MemoryService::get_memory_pool(ph);
  1.1519 +      if (pool != NULL) {
  1.1520 +        pool->reset_peak_memory_usage();
  1.1521 +        return true;
  1.1522 +      }
  1.1523 +      break;
  1.1524 +    }
  1.1525 +    case JMM_STAT_GC_STAT: {
  1.1526 +      jobject o = obj.l;
  1.1527 +      if (o == NULL) {
  1.1528 +        THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
  1.1529 +      }
  1.1530 +
  1.1531 +      GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(o, CHECK_0);
  1.1532 +      if (mgr != NULL) {
  1.1533 +        mgr->reset_gc_stat();
  1.1534 +        return true;
  1.1535 +      }
  1.1536 +      break;
  1.1537 +    }
  1.1538 +    default:
  1.1539 +      assert(0, "Unknown Statistic Type");
  1.1540 +  }
  1.1541 +  return false;
  1.1542 +JVM_END
  1.1543 +
  1.1544 +// Returns the fast estimate of CPU time consumed by
  1.1545 +// a given thread (in nanoseconds).
  1.1546 +// If thread_id == 0, return CPU time for the current thread.
  1.1547 +JVM_ENTRY(jlong, jmm_GetThreadCpuTime(JNIEnv *env, jlong thread_id))
  1.1548 +  if (!os::is_thread_cpu_time_supported()) {
  1.1549 +    return -1;
  1.1550 +  }
  1.1551 +
  1.1552 +  if (thread_id < 0) {
  1.1553 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.1554 +               "Invalid thread ID", -1);
  1.1555 +  }
  1.1556 +
  1.1557 +  JavaThread* java_thread = NULL;
  1.1558 +  if (thread_id == 0) {
  1.1559 +    // current thread
  1.1560 +    return os::current_thread_cpu_time();
  1.1561 +  } else {
  1.1562 +    MutexLockerEx ml(Threads_lock);
  1.1563 +    java_thread = find_java_thread_from_id(thread_id);
  1.1564 +    if (java_thread != NULL) {
  1.1565 +      return os::thread_cpu_time((Thread*) java_thread);
  1.1566 +    }
  1.1567 +  }
  1.1568 +  return -1;
  1.1569 +JVM_END
  1.1570 +
  1.1571 +// Returns the CPU time consumed by a given thread (in nanoseconds).
  1.1572 +// If thread_id == 0, CPU time for the current thread is returned.
  1.1573 +// If user_sys_cpu_time = true, user level and system CPU time of
  1.1574 +// a given thread is returned; otherwise, only user level CPU time
  1.1575 +// is returned.
  1.1576 +JVM_ENTRY(jlong, jmm_GetThreadCpuTimeWithKind(JNIEnv *env, jlong thread_id, jboolean user_sys_cpu_time))
  1.1577 +  if (!os::is_thread_cpu_time_supported()) {
  1.1578 +    return -1;
  1.1579 +  }
  1.1580 +
  1.1581 +  if (thread_id < 0) {
  1.1582 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.1583 +               "Invalid thread ID", -1);
  1.1584 +  }
  1.1585 +
  1.1586 +  JavaThread* java_thread = NULL;
  1.1587 +  if (thread_id == 0) {
  1.1588 +    // current thread
  1.1589 +    return os::current_thread_cpu_time(user_sys_cpu_time != 0);
  1.1590 +  } else {
  1.1591 +    MutexLockerEx ml(Threads_lock);
  1.1592 +    java_thread = find_java_thread_from_id(thread_id);
  1.1593 +    if (java_thread != NULL) {
  1.1594 +      return os::thread_cpu_time((Thread*) java_thread, user_sys_cpu_time != 0);
  1.1595 +    }
  1.1596 +  }
  1.1597 +  return -1;
  1.1598 +JVM_END
  1.1599 +
  1.1600 +// Gets an array containing the CPU times consumed by a set of threads
  1.1601 +// (in nanoseconds).  Each element of the array is the CPU time for the
  1.1602 +// thread ID specified in the corresponding entry in the given array
  1.1603 +// of thread IDs; or -1 if the thread does not exist or has terminated.
  1.1604 +// If user_sys_cpu_time = true, the sum of user level and system CPU time
  1.1605 +// for the given thread is returned; otherwise, only user level CPU time
  1.1606 +// is returned.
  1.1607 +JVM_ENTRY(void, jmm_GetThreadCpuTimesWithKind(JNIEnv *env, jlongArray ids,
  1.1608 +                                              jlongArray timeArray,
  1.1609 +                                              jboolean user_sys_cpu_time))
  1.1610 +  // Check if threads is null
  1.1611 +  if (ids == NULL || timeArray == NULL) {
  1.1612 +    THROW(vmSymbols::java_lang_NullPointerException());
  1.1613 +  }
  1.1614 +
  1.1615 +  ResourceMark rm(THREAD);
  1.1616 +  typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(ids));
  1.1617 +  typeArrayHandle ids_ah(THREAD, ta);
  1.1618 +
  1.1619 +  typeArrayOop tia = typeArrayOop(JNIHandles::resolve_non_null(timeArray));
  1.1620 +  typeArrayHandle timeArray_h(THREAD, tia);
  1.1621 +
  1.1622 +  // validate the thread id array
  1.1623 +  validate_thread_id_array(ids_ah, CHECK);
  1.1624 +
  1.1625 +  // timeArray must be of the same length as the given array of thread IDs
  1.1626 +  int num_threads = ids_ah->length();
  1.1627 +  if (num_threads != timeArray_h->length()) {
  1.1628 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  1.1629 +              "The length of the given long array does not match the length of "
  1.1630 +              "the given array of thread IDs");
  1.1631 +  }
  1.1632 +
  1.1633 +  MutexLockerEx ml(Threads_lock);
  1.1634 +  for (int i = 0; i < num_threads; i++) {
  1.1635 +    JavaThread* java_thread = find_java_thread_from_id(ids_ah->long_at(i));
  1.1636 +    if (java_thread != NULL) {
  1.1637 +      timeArray_h->long_at_put(i, os::thread_cpu_time((Thread*)java_thread,
  1.1638 +                                                      user_sys_cpu_time != 0));
  1.1639 +    }
  1.1640 +  }
  1.1641 +JVM_END
  1.1642 +
  1.1643 +// Returns a String array of all VM global flag names
  1.1644 +JVM_ENTRY(jobjectArray, jmm_GetVMGlobalNames(JNIEnv *env))
  1.1645 +  // last flag entry is always NULL, so subtract 1
  1.1646 +  int nFlags = (int) Flag::numFlags - 1;
  1.1647 +  // allocate a temp array
  1.1648 +  objArrayOop r = oopFactory::new_objArray(SystemDictionary::String_klass(),
  1.1649 +                                           nFlags, CHECK_0);
  1.1650 +  objArrayHandle flags_ah(THREAD, r);
  1.1651 +  int num_entries = 0;
  1.1652 +  for (int i = 0; i < nFlags; i++) {
  1.1653 +    Flag* flag = &Flag::flags[i];
  1.1654 +    // Exclude notproduct and develop flags in product builds.
  1.1655 +    if (flag->is_constant_in_binary()) {
  1.1656 +      continue;
  1.1657 +    }
  1.1658 +    // Exclude the locked (experimental, diagnostic) flags
  1.1659 +    if (flag->is_unlocked() || flag->is_unlocker()) {
  1.1660 +      Handle s = java_lang_String::create_from_str(flag->_name, CHECK_0);
  1.1661 +      flags_ah->obj_at_put(num_entries, s());
  1.1662 +      num_entries++;
  1.1663 +    }
  1.1664 +  }
  1.1665 +
  1.1666 +  if (num_entries < nFlags) {
  1.1667 +    // Return array of right length
  1.1668 +    objArrayOop res = oopFactory::new_objArray(SystemDictionary::String_klass(), num_entries, CHECK_0);
  1.1669 +    for(int i = 0; i < num_entries; i++) {
  1.1670 +      res->obj_at_put(i, flags_ah->obj_at(i));
  1.1671 +    }
  1.1672 +    return (jobjectArray)JNIHandles::make_local(env, res);
  1.1673 +  }
  1.1674 +
  1.1675 +  return (jobjectArray)JNIHandles::make_local(env, flags_ah());
  1.1676 +JVM_END
  1.1677 +
  1.1678 +// Utility function used by jmm_GetVMGlobals.  Returns false if flag type
  1.1679 +// can't be determined, true otherwise.  If false is returned, then *global
  1.1680 +// will be incomplete and invalid.
  1.1681 +bool add_global_entry(JNIEnv* env, Handle name, jmmVMGlobal *global, Flag *flag, TRAPS) {
  1.1682 +  Handle flag_name;
  1.1683 +  if (name() == NULL) {
  1.1684 +    flag_name = java_lang_String::create_from_str(flag->_name, CHECK_false);
  1.1685 +  } else {
  1.1686 +    flag_name = name;
  1.1687 +  }
  1.1688 +  global->name = (jstring)JNIHandles::make_local(env, flag_name());
  1.1689 +
  1.1690 +  if (flag->is_bool()) {
  1.1691 +    global->value.z = flag->get_bool() ? JNI_TRUE : JNI_FALSE;
  1.1692 +    global->type = JMM_VMGLOBAL_TYPE_JBOOLEAN;
  1.1693 +  } else if (flag->is_intx()) {
  1.1694 +    global->value.j = (jlong)flag->get_intx();
  1.1695 +    global->type = JMM_VMGLOBAL_TYPE_JLONG;
  1.1696 +  } else if (flag->is_uintx()) {
  1.1697 +    global->value.j = (jlong)flag->get_uintx();
  1.1698 +    global->type = JMM_VMGLOBAL_TYPE_JLONG;
  1.1699 +  } else if (flag->is_uint64_t()) {
  1.1700 +    global->value.j = (jlong)flag->get_uint64_t();
  1.1701 +    global->type = JMM_VMGLOBAL_TYPE_JLONG;
  1.1702 +  } else if (flag->is_ccstr()) {
  1.1703 +    Handle str = java_lang_String::create_from_str(flag->get_ccstr(), CHECK_false);
  1.1704 +    global->value.l = (jobject)JNIHandles::make_local(env, str());
  1.1705 +    global->type = JMM_VMGLOBAL_TYPE_JSTRING;
  1.1706 +  } else {
  1.1707 +    global->type = JMM_VMGLOBAL_TYPE_UNKNOWN;
  1.1708 +    return false;
  1.1709 +  }
  1.1710 +
  1.1711 +  global->writeable = flag->is_writeable();
  1.1712 +  global->external = flag->is_external();
  1.1713 +  switch (flag->get_origin()) {
  1.1714 +    case Flag::DEFAULT:
  1.1715 +      global->origin = JMM_VMGLOBAL_ORIGIN_DEFAULT;
  1.1716 +      break;
  1.1717 +    case Flag::COMMAND_LINE:
  1.1718 +      global->origin = JMM_VMGLOBAL_ORIGIN_COMMAND_LINE;
  1.1719 +      break;
  1.1720 +    case Flag::ENVIRON_VAR:
  1.1721 +      global->origin = JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR;
  1.1722 +      break;
  1.1723 +    case Flag::CONFIG_FILE:
  1.1724 +      global->origin = JMM_VMGLOBAL_ORIGIN_CONFIG_FILE;
  1.1725 +      break;
  1.1726 +    case Flag::MANAGEMENT:
  1.1727 +      global->origin = JMM_VMGLOBAL_ORIGIN_MANAGEMENT;
  1.1728 +      break;
  1.1729 +    case Flag::ERGONOMIC:
  1.1730 +      global->origin = JMM_VMGLOBAL_ORIGIN_ERGONOMIC;
  1.1731 +      break;
  1.1732 +    default:
  1.1733 +      global->origin = JMM_VMGLOBAL_ORIGIN_OTHER;
  1.1734 +  }
  1.1735 +
  1.1736 +  return true;
  1.1737 +}
  1.1738 +
  1.1739 +// Fill globals array of count length with jmmVMGlobal entries
  1.1740 +// specified by names. If names == NULL, fill globals array
  1.1741 +// with all Flags. Return value is number of entries
  1.1742 +// created in globals.
  1.1743 +// If a Flag with a given name in an array element does not
  1.1744 +// exist, globals[i].name will be set to NULL.
  1.1745 +JVM_ENTRY(jint, jmm_GetVMGlobals(JNIEnv *env,
  1.1746 +                                 jobjectArray names,
  1.1747 +                                 jmmVMGlobal *globals,
  1.1748 +                                 jint count))
  1.1749 +
  1.1750 +
  1.1751 +  if (globals == NULL) {
  1.1752 +    THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  1.1753 +  }
  1.1754 +
  1.1755 +  ResourceMark rm(THREAD);
  1.1756 +
  1.1757 +  if (names != NULL) {
  1.1758 +    // return the requested globals
  1.1759 +    objArrayOop ta = objArrayOop(JNIHandles::resolve_non_null(names));
  1.1760 +    objArrayHandle names_ah(THREAD, ta);
  1.1761 +    // Make sure we have a String array
  1.1762 +    Klass* element_klass = ObjArrayKlass::cast(names_ah->klass())->element_klass();
  1.1763 +    if (element_klass != SystemDictionary::String_klass()) {
  1.1764 +      THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.1765 +                 "Array element type is not String class", 0);
  1.1766 +    }
  1.1767 +
  1.1768 +    int names_length = names_ah->length();
  1.1769 +    int num_entries = 0;
  1.1770 +    for (int i = 0; i < names_length && i < count; i++) {
  1.1771 +      oop s = names_ah->obj_at(i);
  1.1772 +      if (s == NULL) {
  1.1773 +        THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  1.1774 +      }
  1.1775 +
  1.1776 +      Handle sh(THREAD, s);
  1.1777 +      char* str = java_lang_String::as_utf8_string(s);
  1.1778 +      Flag* flag = Flag::find_flag(str, strlen(str));
  1.1779 +      if (flag != NULL &&
  1.1780 +          add_global_entry(env, sh, &globals[i], flag, THREAD)) {
  1.1781 +        num_entries++;
  1.1782 +      } else {
  1.1783 +        globals[i].name = NULL;
  1.1784 +      }
  1.1785 +    }
  1.1786 +    return num_entries;
  1.1787 +  } else {
  1.1788 +    // return all globals if names == NULL
  1.1789 +
  1.1790 +    // last flag entry is always NULL, so subtract 1
  1.1791 +    int nFlags = (int) Flag::numFlags - 1;
  1.1792 +    Handle null_h;
  1.1793 +    int num_entries = 0;
  1.1794 +    for (int i = 0; i < nFlags && num_entries < count;  i++) {
  1.1795 +      Flag* flag = &Flag::flags[i];
  1.1796 +      // Exclude notproduct and develop flags in product builds.
  1.1797 +      if (flag->is_constant_in_binary()) {
  1.1798 +        continue;
  1.1799 +      }
  1.1800 +      // Exclude the locked (diagnostic, experimental) flags
  1.1801 +      if ((flag->is_unlocked() || flag->is_unlocker()) &&
  1.1802 +          add_global_entry(env, null_h, &globals[num_entries], flag, THREAD)) {
  1.1803 +        num_entries++;
  1.1804 +      }
  1.1805 +    }
  1.1806 +    return num_entries;
  1.1807 +  }
  1.1808 +JVM_END
  1.1809 +
  1.1810 +JVM_ENTRY(void, jmm_SetVMGlobal(JNIEnv *env, jstring flag_name, jvalue new_value))
  1.1811 +  ResourceMark rm(THREAD);
  1.1812 +
  1.1813 +  oop fn = JNIHandles::resolve_external_guard(flag_name);
  1.1814 +  if (fn == NULL) {
  1.1815 +    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
  1.1816 +              "The flag name cannot be null.");
  1.1817 +  }
  1.1818 +  char* name = java_lang_String::as_utf8_string(fn);
  1.1819 +  Flag* flag = Flag::find_flag(name, strlen(name));
  1.1820 +  if (flag == NULL) {
  1.1821 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  1.1822 +              "Flag does not exist.");
  1.1823 +  }
  1.1824 +  if (!flag->is_writeable()) {
  1.1825 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  1.1826 +              "This flag is not writeable.");
  1.1827 +  }
  1.1828 +
  1.1829 +  bool succeed;
  1.1830 +  if (flag->is_bool()) {
  1.1831 +    bool bvalue = (new_value.z == JNI_TRUE ? true : false);
  1.1832 +    succeed = CommandLineFlags::boolAtPut(name, &bvalue, Flag::MANAGEMENT);
  1.1833 +  } else if (flag->is_intx()) {
  1.1834 +    intx ivalue = (intx)new_value.j;
  1.1835 +    succeed = CommandLineFlags::intxAtPut(name, &ivalue, Flag::MANAGEMENT);
  1.1836 +  } else if (flag->is_uintx()) {
  1.1837 +    uintx uvalue = (uintx)new_value.j;
  1.1838 +
  1.1839 +    if (strncmp(name, "MaxHeapFreeRatio", 17) == 0) {
  1.1840 +      FormatBuffer<80> err_msg("%s", "");
  1.1841 +      if (!Arguments::verify_MaxHeapFreeRatio(err_msg, uvalue)) {
  1.1842 +        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer());
  1.1843 +      }
  1.1844 +    } else if (strncmp(name, "MinHeapFreeRatio", 17) == 0) {
  1.1845 +      FormatBuffer<80> err_msg("%s", "");
  1.1846 +      if (!Arguments::verify_MinHeapFreeRatio(err_msg, uvalue)) {
  1.1847 +        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), err_msg.buffer());
  1.1848 +      }
  1.1849 +    }
  1.1850 +    succeed = CommandLineFlags::uintxAtPut(name, &uvalue, Flag::MANAGEMENT);
  1.1851 +  } else if (flag->is_uint64_t()) {
  1.1852 +    uint64_t uvalue = (uint64_t)new_value.j;
  1.1853 +    succeed = CommandLineFlags::uint64_tAtPut(name, &uvalue, Flag::MANAGEMENT);
  1.1854 +  } else if (flag->is_ccstr()) {
  1.1855 +    oop str = JNIHandles::resolve_external_guard(new_value.l);
  1.1856 +    if (str == NULL) {
  1.1857 +      THROW(vmSymbols::java_lang_NullPointerException());
  1.1858 +    }
  1.1859 +    ccstr svalue = java_lang_String::as_utf8_string(str);
  1.1860 +    succeed = CommandLineFlags::ccstrAtPut(name, &svalue, Flag::MANAGEMENT);
  1.1861 +  }
  1.1862 +  assert(succeed, "Setting flag should succeed");
  1.1863 +JVM_END
  1.1864 +
  1.1865 +class ThreadTimesClosure: public ThreadClosure {
  1.1866 + private:
  1.1867 +  objArrayHandle _names_strings;
  1.1868 +  char **_names_chars;
  1.1869 +  typeArrayHandle _times;
  1.1870 +  int _names_len;
  1.1871 +  int _times_len;
  1.1872 +  int _count;
  1.1873 +
  1.1874 + public:
  1.1875 +  ThreadTimesClosure(objArrayHandle names, typeArrayHandle times);
  1.1876 +  ~ThreadTimesClosure();
  1.1877 +  virtual void do_thread(Thread* thread);
  1.1878 +  void do_unlocked();
  1.1879 +  int count() { return _count; }
  1.1880 +};
  1.1881 +
  1.1882 +ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
  1.1883 +                                       typeArrayHandle times) {
  1.1884 +  assert(names() != NULL, "names was NULL");
  1.1885 +  assert(times() != NULL, "times was NULL");
  1.1886 +  _names_strings = names;
  1.1887 +  _names_len = names->length();
  1.1888 +  _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
  1.1889 +  _times = times;
  1.1890 +  _times_len = times->length();
  1.1891 +  _count = 0;
  1.1892 +}
  1.1893 +
  1.1894 +//
  1.1895 +// Called with Threads_lock held
  1.1896 +//
  1.1897 +void ThreadTimesClosure::do_thread(Thread* thread) {
  1.1898 +  assert(thread != NULL, "thread was NULL");
  1.1899 +
  1.1900 +  // exclude externally visible JavaThreads
  1.1901 +  if (thread->is_Java_thread() && !thread->is_hidden_from_external_view()) {
  1.1902 +    return;
  1.1903 +  }
  1.1904 +
  1.1905 +  if (_count >= _names_len || _count >= _times_len) {
  1.1906 +    // skip if the result array is not big enough
  1.1907 +    return;
  1.1908 +  }
  1.1909 +
  1.1910 +  EXCEPTION_MARK;
  1.1911 +  ResourceMark rm(THREAD); // thread->name() uses ResourceArea
  1.1912 +
  1.1913 +  assert(thread->name() != NULL, "All threads should have a name");
  1.1914 +  _names_chars[_count] = strdup(thread->name());
  1.1915 +  _times->long_at_put(_count, os::is_thread_cpu_time_supported() ?
  1.1916 +                        os::thread_cpu_time(thread) : -1);
  1.1917 +  _count++;
  1.1918 +}
  1.1919 +
  1.1920 +// Called without Threads_lock, we can allocate String objects.
  1.1921 +void ThreadTimesClosure::do_unlocked() {
  1.1922 +
  1.1923 +  EXCEPTION_MARK;
  1.1924 +  for (int i = 0; i < _count; i++) {
  1.1925 +    Handle s = java_lang_String::create_from_str(_names_chars[i],  CHECK);
  1.1926 +    _names_strings->obj_at_put(i, s());
  1.1927 +  }
  1.1928 +}
  1.1929 +
  1.1930 +ThreadTimesClosure::~ThreadTimesClosure() {
  1.1931 +  for (int i = 0; i < _count; i++) {
  1.1932 +    free(_names_chars[i]);
  1.1933 +  }
  1.1934 +  FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal);
  1.1935 +}
  1.1936 +
  1.1937 +// Fills names with VM internal thread names and times with the corresponding
  1.1938 +// CPU times.  If names or times is NULL, a NullPointerException is thrown.
  1.1939 +// If the element type of names is not String, an IllegalArgumentException is
  1.1940 +// thrown.
  1.1941 +// If an array is not large enough to hold all the entries, only the entries
  1.1942 +// that fit will be returned.  Return value is the number of VM internal
  1.1943 +// threads entries.
  1.1944 +JVM_ENTRY(jint, jmm_GetInternalThreadTimes(JNIEnv *env,
  1.1945 +                                           jobjectArray names,
  1.1946 +                                           jlongArray times))
  1.1947 +  if (names == NULL || times == NULL) {
  1.1948 +     THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  1.1949 +  }
  1.1950 +  objArrayOop na = objArrayOop(JNIHandles::resolve_non_null(names));
  1.1951 +  objArrayHandle names_ah(THREAD, na);
  1.1952 +
  1.1953 +  // Make sure we have a String array
  1.1954 +  Klass* element_klass = ObjArrayKlass::cast(names_ah->klass())->element_klass();
  1.1955 +  if (element_klass != SystemDictionary::String_klass()) {
  1.1956 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.1957 +               "Array element type is not String class", 0);
  1.1958 +  }
  1.1959 +
  1.1960 +  typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));
  1.1961 +  typeArrayHandle times_ah(THREAD, ta);
  1.1962 +
  1.1963 +  ThreadTimesClosure ttc(names_ah, times_ah);
  1.1964 +  {
  1.1965 +    MutexLockerEx ml(Threads_lock);
  1.1966 +    Threads::threads_do(&ttc);
  1.1967 +  }
  1.1968 +  ttc.do_unlocked();
  1.1969 +  return ttc.count();
  1.1970 +JVM_END
  1.1971 +
  1.1972 +static Handle find_deadlocks(bool object_monitors_only, TRAPS) {
  1.1973 +  ResourceMark rm(THREAD);
  1.1974 +
  1.1975 +  VM_FindDeadlocks op(!object_monitors_only /* also check concurrent locks? */);
  1.1976 +  VMThread::execute(&op);
  1.1977 +
  1.1978 +  DeadlockCycle* deadlocks = op.result();
  1.1979 +  if (deadlocks == NULL) {
  1.1980 +    // no deadlock found and return
  1.1981 +    return Handle();
  1.1982 +  }
  1.1983 +
  1.1984 +  int num_threads = 0;
  1.1985 +  DeadlockCycle* cycle;
  1.1986 +  for (cycle = deadlocks; cycle != NULL; cycle = cycle->next()) {
  1.1987 +    num_threads += cycle->num_threads();
  1.1988 +  }
  1.1989 +
  1.1990 +  objArrayOop r = oopFactory::new_objArray(SystemDictionary::Thread_klass(), num_threads, CHECK_NH);
  1.1991 +  objArrayHandle threads_ah(THREAD, r);
  1.1992 +
  1.1993 +  int index = 0;
  1.1994 +  for (cycle = deadlocks; cycle != NULL; cycle = cycle->next()) {
  1.1995 +    GrowableArray<JavaThread*>* deadlock_threads = cycle->threads();
  1.1996 +    int len = deadlock_threads->length();
  1.1997 +    for (int i = 0; i < len; i++) {
  1.1998 +      threads_ah->obj_at_put(index, deadlock_threads->at(i)->threadObj());
  1.1999 +      index++;
  1.2000 +    }
  1.2001 +  }
  1.2002 +  return threads_ah;
  1.2003 +}
  1.2004 +
  1.2005 +// Finds cycles of threads that are deadlocked involved in object monitors
  1.2006 +// and JSR-166 synchronizers.
  1.2007 +// Returns an array of Thread objects which are in deadlock, if any.
  1.2008 +// Otherwise, returns NULL.
  1.2009 +//
  1.2010 +// Input parameter:
  1.2011 +//    object_monitors_only - if true, only check object monitors
  1.2012 +//
  1.2013 +JVM_ENTRY(jobjectArray, jmm_FindDeadlockedThreads(JNIEnv *env, jboolean object_monitors_only))
  1.2014 +  Handle result = find_deadlocks(object_monitors_only != 0, CHECK_0);
  1.2015 +  return (jobjectArray) JNIHandles::make_local(env, result());
  1.2016 +JVM_END
  1.2017 +
  1.2018 +// Finds cycles of threads that are deadlocked on monitor locks
  1.2019 +// Returns an array of Thread objects which are in deadlock, if any.
  1.2020 +// Otherwise, returns NULL.
  1.2021 +JVM_ENTRY(jobjectArray, jmm_FindMonitorDeadlockedThreads(JNIEnv *env))
  1.2022 +  Handle result = find_deadlocks(true, CHECK_0);
  1.2023 +  return (jobjectArray) JNIHandles::make_local(env, result());
  1.2024 +JVM_END
  1.2025 +
  1.2026 +// Gets the information about GC extension attributes including
  1.2027 +// the name of the attribute, its type, and a short description.
  1.2028 +//
  1.2029 +// Input parameters:
  1.2030 +//   mgr   - GC memory manager
  1.2031 +//   info  - caller allocated array of jmmExtAttributeInfo
  1.2032 +//   count - number of elements of the info array
  1.2033 +//
  1.2034 +// Returns the number of GC extension attributes filled in the info array; or
  1.2035 +// -1 if info is not big enough
  1.2036 +//
  1.2037 +JVM_ENTRY(jint, jmm_GetGCExtAttributeInfo(JNIEnv *env, jobject mgr, jmmExtAttributeInfo* info, jint count))
  1.2038 +  // All GC memory managers have 1 attribute (number of GC threads)
  1.2039 +  if (count == 0) {
  1.2040 +    return 0;
  1.2041 +  }
  1.2042 +
  1.2043 +  if (info == NULL) {
  1.2044 +   THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  1.2045 +  }
  1.2046 +
  1.2047 +  info[0].name = "GcThreadCount";
  1.2048 +  info[0].type = 'I';
  1.2049 +  info[0].description = "Number of GC threads";
  1.2050 +  return 1;
  1.2051 +JVM_END
  1.2052 +
  1.2053 +// verify the given array is an array of java/lang/management/MemoryUsage objects
  1.2054 +// of a given length and return the objArrayOop
  1.2055 +static objArrayOop get_memory_usage_objArray(jobjectArray array, int length, TRAPS) {
  1.2056 +  if (array == NULL) {
  1.2057 +    THROW_(vmSymbols::java_lang_NullPointerException(), 0);
  1.2058 +  }
  1.2059 +
  1.2060 +  objArrayOop oa = objArrayOop(JNIHandles::resolve_non_null(array));
  1.2061 +  objArrayHandle array_h(THREAD, oa);
  1.2062 +
  1.2063 +  // array must be of the given length
  1.2064 +  if (length != array_h->length()) {
  1.2065 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.2066 +               "The length of the given MemoryUsage array does not match the number of memory pools.", 0);
  1.2067 +  }
  1.2068 +
  1.2069 +  // check if the element of array is of type MemoryUsage class
  1.2070 +  Klass* usage_klass = Management::java_lang_management_MemoryUsage_klass(CHECK_0);
  1.2071 +  Klass* element_klass = ObjArrayKlass::cast(array_h->klass())->element_klass();
  1.2072 +  if (element_klass != usage_klass) {
  1.2073 +    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
  1.2074 +               "The element type is not MemoryUsage class", 0);
  1.2075 +  }
  1.2076 +
  1.2077 +  return array_h();
  1.2078 +}
  1.2079 +
  1.2080 +// Gets the statistics of the last GC of a given GC memory manager.
  1.2081 +// Input parameters:
  1.2082 +//   obj     - GarbageCollectorMXBean object
  1.2083 +//   gc_stat - caller allocated jmmGCStat where:
  1.2084 +//     a. before_gc_usage - array of MemoryUsage objects
  1.2085 +//     b. after_gc_usage  - array of MemoryUsage objects
  1.2086 +//     c. gc_ext_attributes_values_size is set to the
  1.2087 +//        gc_ext_attribute_values array allocated
  1.2088 +//     d. gc_ext_attribute_values is a caller allocated array of jvalue.
  1.2089 +//
  1.2090 +// On return,
  1.2091 +//   gc_index == 0 indicates no GC statistics available
  1.2092 +//
  1.2093 +//   before_gc_usage and after_gc_usage - filled with per memory pool
  1.2094 +//      before and after GC usage in the same order as the memory pools
  1.2095 +//      returned by GetMemoryPools for a given GC memory manager.
  1.2096 +//   num_gc_ext_attributes indicates the number of elements in
  1.2097 +//      the gc_ext_attribute_values array is filled; or
  1.2098 +//      -1 if the gc_ext_attributes_values array is not big enough
  1.2099 +//
  1.2100 +JVM_ENTRY(void, jmm_GetLastGCStat(JNIEnv *env, jobject obj, jmmGCStat *gc_stat))
  1.2101 +  ResourceMark rm(THREAD);
  1.2102 +
  1.2103 +  if (gc_stat->gc_ext_attribute_values_size > 0 && gc_stat->gc_ext_attribute_values == NULL) {
  1.2104 +    THROW(vmSymbols::java_lang_NullPointerException());
  1.2105 +  }
  1.2106 +
  1.2107 +  // Get the GCMemoryManager
  1.2108 +  GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK);
  1.2109 +
  1.2110 +  // Make a copy of the last GC statistics
  1.2111 +  // GC may occur while constructing the last GC information
  1.2112 +  int num_pools = MemoryService::num_memory_pools();
  1.2113 +  GCStatInfo stat(num_pools);
  1.2114 +  if (mgr->get_last_gc_stat(&stat) == 0) {
  1.2115 +    gc_stat->gc_index = 0;
  1.2116 +    return;
  1.2117 +  }
  1.2118 +
  1.2119 +  gc_stat->gc_index = stat.gc_index();
  1.2120 +  gc_stat->start_time = Management::ticks_to_ms(stat.start_time());
  1.2121 +  gc_stat->end_time = Management::ticks_to_ms(stat.end_time());
  1.2122 +
  1.2123 +  // Current implementation does not have GC extension attributes
  1.2124 +  gc_stat->num_gc_ext_attributes = 0;
  1.2125 +
  1.2126 +  // Fill the arrays of MemoryUsage objects with before and after GC
  1.2127 +  // per pool memory usage
  1.2128 +  objArrayOop bu = get_memory_usage_objArray(gc_stat->usage_before_gc,
  1.2129 +                                             num_pools,
  1.2130 +                                             CHECK);
  1.2131 +  objArrayHandle usage_before_gc_ah(THREAD, bu);
  1.2132 +
  1.2133 +  objArrayOop au = get_memory_usage_objArray(gc_stat->usage_after_gc,
  1.2134 +                                             num_pools,
  1.2135 +                                             CHECK);
  1.2136 +  objArrayHandle usage_after_gc_ah(THREAD, au);
  1.2137 +
  1.2138 +  for (int i = 0; i < num_pools; i++) {
  1.2139 +    Handle before_usage = MemoryService::create_MemoryUsage_obj(stat.before_gc_usage_for_pool(i), CHECK);
  1.2140 +    Handle after_usage;
  1.2141 +
  1.2142 +    MemoryUsage u = stat.after_gc_usage_for_pool(i);
  1.2143 +    if (u.max_size() == 0 && u.used() > 0) {
  1.2144 +      // If max size == 0, this pool is a survivor space.
  1.2145 +      // Set max size = -1 since the pools will be swapped after GC.
  1.2146 +      MemoryUsage usage(u.init_size(), u.used(), u.committed(), (size_t)-1);
  1.2147 +      after_usage = MemoryService::create_MemoryUsage_obj(usage, CHECK);
  1.2148 +    } else {
  1.2149 +      after_usage = MemoryService::create_MemoryUsage_obj(stat.after_gc_usage_for_pool(i), CHECK);
  1.2150 +    }
  1.2151 +    usage_before_gc_ah->obj_at_put(i, before_usage());
  1.2152 +    usage_after_gc_ah->obj_at_put(i, after_usage());
  1.2153 +  }
  1.2154 +
  1.2155 +  if (gc_stat->gc_ext_attribute_values_size > 0) {
  1.2156 +    // Current implementation only has 1 attribute (number of GC threads)
  1.2157 +    // The type is 'I'
  1.2158 +    gc_stat->gc_ext_attribute_values[0].i = mgr->num_gc_threads();
  1.2159 +  }
  1.2160 +JVM_END
  1.2161 +
  1.2162 +JVM_ENTRY(void, jmm_SetGCNotificationEnabled(JNIEnv *env, jobject obj, jboolean enabled))
  1.2163 +  ResourceMark rm(THREAD);
  1.2164 +  // Get the GCMemoryManager
  1.2165 +  GCMemoryManager* mgr = get_gc_memory_manager_from_jobject(obj, CHECK);
  1.2166 +  mgr->set_notification_enabled(enabled?true:false);
  1.2167 +JVM_END
  1.2168 +
  1.2169 +// Dump heap - Returns 0 if succeeds.
  1.2170 +JVM_ENTRY(jint, jmm_DumpHeap0(JNIEnv *env, jstring outputfile, jboolean live))
  1.2171 +#if INCLUDE_SERVICES
  1.2172 +  ResourceMark rm(THREAD);
  1.2173 +  oop on = JNIHandles::resolve_external_guard(outputfile);
  1.2174 +  if (on == NULL) {
  1.2175 +    THROW_MSG_(vmSymbols::java_lang_NullPointerException(),
  1.2176 +               "Output file name cannot be null.", -1);
  1.2177 +  }
  1.2178 +  char* name = java_lang_String::as_platform_dependent_str(on, CHECK_(-1));
  1.2179 +  if (name == NULL) {
  1.2180 +    THROW_MSG_(vmSymbols::java_lang_NullPointerException(),
  1.2181 +               "Output file name cannot be null.", -1);
  1.2182 +  }
  1.2183 +  HeapDumper dumper(live ? true : false);
  1.2184 +  if (dumper.dump(name) != 0) {
  1.2185 +    const char* errmsg = dumper.error_as_C_string();
  1.2186 +    THROW_MSG_(vmSymbols::java_io_IOException(), errmsg, -1);
  1.2187 +  }
  1.2188 +  return 0;
  1.2189 +#else  // INCLUDE_SERVICES
  1.2190 +  return -1;
  1.2191 +#endif // INCLUDE_SERVICES
  1.2192 +JVM_END
  1.2193 +
  1.2194 +JVM_ENTRY(jobjectArray, jmm_GetDiagnosticCommands(JNIEnv *env))
  1.2195 +  ResourceMark rm(THREAD);
  1.2196 +  GrowableArray<const char *>* dcmd_list = DCmdFactory::DCmd_list(DCmd_Source_MBean);
  1.2197 +  objArrayOop cmd_array_oop = oopFactory::new_objArray(SystemDictionary::String_klass(),
  1.2198 +          dcmd_list->length(), CHECK_NULL);
  1.2199 +  objArrayHandle cmd_array(THREAD, cmd_array_oop);
  1.2200 +  for (int i = 0; i < dcmd_list->length(); i++) {
  1.2201 +    oop cmd_name = java_lang_String::create_oop_from_str(dcmd_list->at(i), CHECK_NULL);
  1.2202 +    cmd_array->obj_at_put(i, cmd_name);
  1.2203 +  }
  1.2204 +  return (jobjectArray) JNIHandles::make_local(env, cmd_array());
  1.2205 +JVM_END
  1.2206 +
  1.2207 +JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds,
  1.2208 +          dcmdInfo* infoArray))
  1.2209 +  if (cmds == NULL || infoArray == NULL) {
  1.2210 +    THROW(vmSymbols::java_lang_NullPointerException());
  1.2211 +  }
  1.2212 +
  1.2213 +  ResourceMark rm(THREAD);
  1.2214 +
  1.2215 +  objArrayOop ca = objArrayOop(JNIHandles::resolve_non_null(cmds));
  1.2216 +  objArrayHandle cmds_ah(THREAD, ca);
  1.2217 +
  1.2218 +  // Make sure we have a String array
  1.2219 +  Klass* element_klass = ObjArrayKlass::cast(cmds_ah->klass())->element_klass();
  1.2220 +  if (element_klass != SystemDictionary::String_klass()) {
  1.2221 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  1.2222 +               "Array element type is not String class");
  1.2223 +  }
  1.2224 +
  1.2225 +  GrowableArray<DCmdInfo *>* info_list = DCmdFactory::DCmdInfo_list(DCmd_Source_MBean);
  1.2226 +
  1.2227 +  int num_cmds = cmds_ah->length();
  1.2228 +  for (int i = 0; i < num_cmds; i++) {
  1.2229 +    oop cmd = cmds_ah->obj_at(i);
  1.2230 +    if (cmd == NULL) {
  1.2231 +        THROW_MSG(vmSymbols::java_lang_NullPointerException(),
  1.2232 +                "Command name cannot be null.");
  1.2233 +    }
  1.2234 +    char* cmd_name = java_lang_String::as_utf8_string(cmd);
  1.2235 +    if (cmd_name == NULL) {
  1.2236 +        THROW_MSG(vmSymbols::java_lang_NullPointerException(),
  1.2237 +                "Command name cannot be null.");
  1.2238 +    }
  1.2239 +    int pos = info_list->find((void*)cmd_name,DCmdInfo::by_name);
  1.2240 +    if (pos == -1) {
  1.2241 +        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  1.2242 +             "Unknown diagnostic command");
  1.2243 +    }
  1.2244 +    DCmdInfo* info = info_list->at(pos);
  1.2245 +    infoArray[i].name = info->name();
  1.2246 +    infoArray[i].description = info->description();
  1.2247 +    infoArray[i].impact = info->impact();
  1.2248 +    JavaPermission p = info->permission();
  1.2249 +    infoArray[i].permission_class = p._class;
  1.2250 +    infoArray[i].permission_name = p._name;
  1.2251 +    infoArray[i].permission_action = p._action;
  1.2252 +    infoArray[i].num_arguments = info->num_arguments();
  1.2253 +    infoArray[i].enabled = info->is_enabled();
  1.2254 +  }
  1.2255 +JVM_END
  1.2256 +
  1.2257 +JVM_ENTRY(void, jmm_GetDiagnosticCommandArgumentsInfo(JNIEnv *env,
  1.2258 +          jstring command, dcmdArgInfo* infoArray))
  1.2259 +  ResourceMark rm(THREAD);
  1.2260 +  oop cmd = JNIHandles::resolve_external_guard(command);
  1.2261 +  if (cmd == NULL) {
  1.2262 +    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
  1.2263 +              "Command line cannot be null.");
  1.2264 +  }
  1.2265 +  char* cmd_name = java_lang_String::as_utf8_string(cmd);
  1.2266 +  if (cmd_name == NULL) {
  1.2267 +    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
  1.2268 +              "Command line content cannot be null.");
  1.2269 +  }
  1.2270 +  DCmd* dcmd = NULL;
  1.2271 +  DCmdFactory*factory = DCmdFactory::factory(DCmd_Source_MBean, cmd_name,
  1.2272 +                                             strlen(cmd_name));
  1.2273 +  if (factory != NULL) {
  1.2274 +    dcmd = factory->create_resource_instance(NULL);
  1.2275 +  }
  1.2276 +  if (dcmd == NULL) {
  1.2277 +    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
  1.2278 +              "Unknown diagnostic command");
  1.2279 +  }
  1.2280 +  DCmdMark mark(dcmd);
  1.2281 +  GrowableArray<DCmdArgumentInfo*>* array = dcmd->argument_info_array();
  1.2282 +  if (array->length() == 0) {
  1.2283 +    return;
  1.2284 +  }
  1.2285 +  for (int i = 0; i < array->length(); i++) {
  1.2286 +    infoArray[i].name = array->at(i)->name();
  1.2287 +    infoArray[i].description = array->at(i)->description();
  1.2288 +    infoArray[i].type = array->at(i)->type();
  1.2289 +    infoArray[i].default_string = array->at(i)->default_string();
  1.2290 +    infoArray[i].mandatory = array->at(i)->is_mandatory();
  1.2291 +    infoArray[i].option = array->at(i)->is_option();
  1.2292 +    infoArray[i].multiple = array->at(i)->is_multiple();
  1.2293 +    infoArray[i].position = array->at(i)->position();
  1.2294 +  }
  1.2295 +  return;
  1.2296 +JVM_END
  1.2297 +
  1.2298 +JVM_ENTRY(jstring, jmm_ExecuteDiagnosticCommand(JNIEnv *env, jstring commandline))
  1.2299 +  ResourceMark rm(THREAD);
  1.2300 +  oop cmd = JNIHandles::resolve_external_guard(commandline);
  1.2301 +  if (cmd == NULL) {
  1.2302 +    THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
  1.2303 +                   "Command line cannot be null.");
  1.2304 +  }
  1.2305 +  char* cmdline = java_lang_String::as_utf8_string(cmd);
  1.2306 +  if (cmdline == NULL) {
  1.2307 +    THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
  1.2308 +                   "Command line content cannot be null.");
  1.2309 +  }
  1.2310 +  bufferedStream output;
  1.2311 +  DCmd::parse_and_execute(DCmd_Source_MBean, &output, cmdline, ' ', CHECK_NULL);
  1.2312 +  oop result = java_lang_String::create_oop_from_str(output.as_string(), CHECK_NULL);
  1.2313 +  return (jstring) JNIHandles::make_local(env, result);
  1.2314 +JVM_END
  1.2315 +
  1.2316 +JVM_ENTRY(void, jmm_SetDiagnosticFrameworkNotificationEnabled(JNIEnv *env, jboolean enabled))
  1.2317 +  DCmdFactory::set_jmx_notification_enabled(enabled?true:false);
  1.2318 +JVM_END
  1.2319 +
  1.2320 +jlong Management::ticks_to_ms(jlong ticks) {
  1.2321 +  assert(os::elapsed_frequency() > 0, "Must be non-zero");
  1.2322 +  return (jlong)(((double)ticks / (double)os::elapsed_frequency())
  1.2323 +                 * (double)1000.0);
  1.2324 +}
  1.2325 +
  1.2326 +const struct jmmInterface_1_ jmm_interface = {
  1.2327 +  NULL,
  1.2328 +  NULL,
  1.2329 +  jmm_GetVersion,
  1.2330 +  jmm_GetOptionalSupport,
  1.2331 +  jmm_GetInputArguments,
  1.2332 +  jmm_GetThreadInfo,
  1.2333 +  jmm_GetInputArgumentArray,
  1.2334 +  jmm_GetMemoryPools,
  1.2335 +  jmm_GetMemoryManagers,
  1.2336 +  jmm_GetMemoryPoolUsage,
  1.2337 +  jmm_GetPeakMemoryPoolUsage,
  1.2338 +  jmm_GetThreadAllocatedMemory,
  1.2339 +  jmm_GetMemoryUsage,
  1.2340 +  jmm_GetLongAttribute,
  1.2341 +  jmm_GetBoolAttribute,
  1.2342 +  jmm_SetBoolAttribute,
  1.2343 +  jmm_GetLongAttributes,
  1.2344 +  jmm_FindMonitorDeadlockedThreads,
  1.2345 +  jmm_GetThreadCpuTime,
  1.2346 +  jmm_GetVMGlobalNames,
  1.2347 +  jmm_GetVMGlobals,
  1.2348 +  jmm_GetInternalThreadTimes,
  1.2349 +  jmm_ResetStatistic,
  1.2350 +  jmm_SetPoolSensor,
  1.2351 +  jmm_SetPoolThreshold,
  1.2352 +  jmm_GetPoolCollectionUsage,
  1.2353 +  jmm_GetGCExtAttributeInfo,
  1.2354 +  jmm_GetLastGCStat,
  1.2355 +  jmm_GetThreadCpuTimeWithKind,
  1.2356 +  jmm_GetThreadCpuTimesWithKind,
  1.2357 +  jmm_DumpHeap0,
  1.2358 +  jmm_FindDeadlockedThreads,
  1.2359 +  jmm_SetVMGlobal,
  1.2360 +  NULL,
  1.2361 +  jmm_DumpThreads,
  1.2362 +  jmm_SetGCNotificationEnabled,
  1.2363 +  jmm_GetDiagnosticCommands,
  1.2364 +  jmm_GetDiagnosticCommandInfo,
  1.2365 +  jmm_GetDiagnosticCommandArgumentsInfo,
  1.2366 +  jmm_ExecuteDiagnosticCommand,
  1.2367 +  jmm_SetDiagnosticFrameworkNotificationEnabled
  1.2368 +};
  1.2369 +#endif // INCLUDE_MANAGEMENT
  1.2370 +
  1.2371 +void* Management::get_jmm_interface(int version) {
  1.2372 +#if INCLUDE_MANAGEMENT
  1.2373 +  if (version == JMM_VERSION_1_0) {
  1.2374 +    return (void*) &jmm_interface;
  1.2375 +  }
  1.2376 +#endif // INCLUDE_MANAGEMENT
  1.2377 +  return NULL;
  1.2378 +}

mercurial