/* src/native/vm/openjdk/management.cpp - HotSpot management interface functions Copyright (C) 2009 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO Copyright (C) 2008, 2009 Theobroma Systems Ltd. This file is part of CACAO. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include // Include our JNI header before the JMM header, because the JMM // header include jni.h and we want to override the typedefs in jni.h. #include "native/jni.hpp" #include INCLUDE_JMM_H #include "native/vm/openjdk/management.hpp" #include "threads/threadlist.hpp" #include "toolbox/logging.hpp" #include "vm/array.hpp" #include "vm/classcache.hpp" #include "vm/globals.hpp" // XXX Remove!!! #include "vm/options.h" #include "vm/os.hpp" #include "vm/vm.hpp" /* debugging macros ***********************************************************/ #if !defined(NDEBUG) # define TRACEJMMCALLS(x) \ do { \ if (opt_TraceJMMCalls) { \ log_println x; \ } \ } while (0) #else # define TRACEJMMCALLS(x) #endif /** * Initialize the Management subsystem. */ Management::Management() { // Initialize optional support _optional_support.isLowMemoryDetectionSupported = 1; _optional_support.isCompilationTimeMonitoringSupported = 1; _optional_support.isThreadContentionMonitoringSupported = 1; // if (os::is_thread_cpu_time_supported()) { if (false) { _optional_support.isCurrentThreadCpuTimeSupported = 1; _optional_support.isOtherThreadCpuTimeSupported = 1; } else { _optional_support.isCurrentThreadCpuTimeSupported = 0; _optional_support.isOtherThreadCpuTimeSupported = 0; } _optional_support.isBootClassPathSupported = 1; _optional_support.isObjectMonitorUsageSupported = 1; _optional_support.isSynchronizerUsageSupported = 1; } /** * Return a pointer to the optional support structure. * * @param Pointer to optional support structure. */ const jmmOptionalSupport& Management::get_optional_support() const { return _optional_support; } // Interface functions are exported as C functions. extern "C" { jint jmm_GetVersion(JNIEnv* env) { return JMM_VERSION; } jint jmm_GetOptionalSupport(JNIEnv* env, jmmOptionalSupport* support) { if (support == NULL) { return -1; } Management& mm = VM::get_current()->get_management(); // memcpy the structure. os::memcpy(support, &mm.get_optional_support(), sizeof(jmmOptionalSupport)); return 0; } jobject jmm_GetInputArguments(JNIEnv* env) { log_println("jmm_GetInputArguments: IMPLEMENT ME!"); return NULL; } jobjectArray jmm_GetInputArgumentArray(JNIEnv* env) { log_println("jmm_GetInputArgumentArray: IMPLEMENT ME!"); return NULL; } jobjectArray jmm_GetMemoryPools(JNIEnv* env, jobject obj) { TRACEJMMCALLS(("jmm_GetMemoryPools(env=%p, obj=%p)", env, obj)); // XXX This should be an array of java/lang/management/MemoryPoolMXBean. log_println("jmm_GetMemoryPools: FIX ME!"); ObjectArray oa(0, class_java_lang_String); return oa.get_handle(); } jobjectArray jmm_GetMemoryManagers(JNIEnv* env, jobject obj) { TRACEJMMCALLS(("jmm_GetMemoryManagers(env=%p, obj=%p)", env, obj)); // XXX This should be an array of java/lang/management/MemoryManagerMXBean. log_println("jmm_GetMemoryManagers: FIX ME!"); ObjectArray oa(0, class_java_lang_String); return oa.get_handle(); } jobject jmm_GetMemoryPoolUsage(JNIEnv* env, jobject obj) { log_println("jmm_GetMemoryPoolUsage: IMPLEMENT ME!"); return NULL; } jobject jmm_GetPeakMemoryPoolUsage(JNIEnv* env, jobject obj) { log_println("jmm_GetPeakMemoryPoolUsage: IMPLEMENT ME!"); return NULL; } jobject jmm_GetPoolCollectionUsage(JNIEnv* env, jobject obj) { log_println("jmm_GetPoolCollectionUsage: IMPLEMENT ME!"); return NULL; } void jmm_SetPoolSensor(JNIEnv* env, jobject obj, jmmThresholdType type, jobject sensorObj) { log_println("jmm_SetPoolSensor: IMPLEMENT ME!"); } jlong jmm_SetPoolThreshold(JNIEnv* env, jobject obj, jmmThresholdType type, jlong threshold) { log_println("jmm_SetPoolThreshold: IMPLEMENT ME!"); return 0; } jobject jmm_GetMemoryUsage(JNIEnv* env, jboolean heap) { log_println("jmm_GetMemoryUsage: IMPLEMENT ME!"); return NULL; } jboolean jmm_GetBoolAttribute(JNIEnv* env, jmmBoolAttribute att) { TRACEJMMCALLS(("jmm_GetBoolAttribute(env=%p, att=%d)", env, att)); jboolean result; switch (att) { case JMM_VERBOSE_GC: result = opt_verbosegc; break; case JMM_VERBOSE_CLASS: result = opt_verboseclass; break; default: log_println("jmm_GetBoolAttribute: Unknown attribute %d", att); return false; } return result; } jboolean jmm_SetBoolAttribute(JNIEnv* env, jmmBoolAttribute att, jboolean flag) { TRACEJMMCALLS(("jmm_SetBoolAttribute(env=%p, att=%d, flag=%d)", env, att, flag)); switch (att) { case JMM_VERBOSE_GC: opt_verbosegc = flag; break; case JMM_VERBOSE_CLASS: opt_verboseclass = flag; break; default: log_println("jmm_SetBoolAttribute: Unknown attribute %d", att); return false; } return true; } jlong jmm_GetLongAttribute(JNIEnv* env, jobject obj, jmmLongAttribute att) { TRACEJMMCALLS(("jmm_GetLongAttribute(env=%p, obj=%p, att=%d)", env, obj, att)); jlong result; switch (att) { case JMM_CLASS_LOADED_COUNT: result = classcache_get_loaded_class_count(); break; case JMM_CLASS_UNLOADED_COUNT: // XXX Fix this once we support class unloading! result = 0; break; case JMM_THREAD_TOTAL_COUNT: result = ThreadList::get_number_of_started_java_threads(); break; case JMM_THREAD_LIVE_COUNT: result = ThreadList::get_number_of_active_java_threads(); break; case JMM_THREAD_PEAK_COUNT: result = ThreadList::get_peak_of_active_java_threads(); break; case JMM_THREAD_DAEMON_COUNT: result = ThreadList::get_number_of_daemon_java_threads(); break; case JMM_JVM_INIT_DONE_TIME_MS: result = VM::get_current()->get_inittime(); break; case JMM_OS_PROCESS_ID: result = os::getpid(); break; default: log_println("jmm_GetLongAttribute: Unknown attribute %d", att); return -1; } return result; } jint jmm_GetLongAttributes(JNIEnv* env, jobject obj, jmmLongAttribute* atts, jint count, jlong* result) { log_println("jmm_GetLongAttributes: IMPLEMENT ME!"); return 0; } jint jmm_GetThreadInfo(JNIEnv* env, jlongArray ids, jint maxDepth, jobjectArray infoArray) { log_println("jmm_GetThreadInfo: IMPLEMENT ME!"); return 0; } jobjectArray jmm_DumpThreads(JNIEnv* env, jlongArray thread_ids, jboolean locked_monitors, jboolean locked_synchronizers) { log_println("jmm_DumpThreads: IMPLEMENT ME!"); return NULL; } jobjectArray jmm_GetLoadedClasses(JNIEnv* env) { log_println("jmm_GetLoadedClasses: IMPLEMENT ME!"); return NULL; } jboolean jmm_ResetStatistic(JNIEnv* env, jvalue obj, jmmStatisticType type) { TRACEJMMCALLS(("jmm_ResetStatistic(env=%p, obj=%p, type=%d)", env, obj, type)); switch (type) { case JMM_STAT_PEAK_THREAD_COUNT: ThreadList::reset_peak_of_active_java_threads(); break; default: log_println("jmm_ResetStatistic: Unknown statistic type %d", type); return false; } return true; } jlong jmm_GetThreadCpuTime(JNIEnv* env, jlong thread_id) { log_println("jmm_GetThreadCpuTime: IMPLEMENT ME!"); return 0; } jlong jmm_GetThreadCpuTimeWithKind(JNIEnv* env, jlong thread_id, jboolean user_sys_cpu_time) { log_println("jmm_GetThreadCpuTimeWithKind: IMPLEMENT ME!"); return 0; } jobjectArray jmm_GetVMGlobalNames(JNIEnv* env) { log_println("jmm_GetVMGlobalNames: IMPLEMENT ME!"); return NULL; } jint jmm_GetVMGlobals(JNIEnv* env, jobjectArray names, jmmVMGlobal* globals, jint count) { log_println("jmm_GetVMGlobals: IMPLEMENT ME!"); return 0; } void jmm_SetVMGlobal(JNIEnv* env, jstring flag_name, jvalue new_value) { log_println("jmm_SetVMGlobal: IMPLEMENT ME!"); } jint jmm_GetInternalThreadTimes(JNIEnv* env, jobjectArray names, jlongArray times) { log_println("jmm_GetInternalThreadTimes: IMPLEMENT ME!"); return 0; } jobjectArray jmm_FindDeadlockedThreads(JNIEnv* env, jboolean object_monitors_only) { log_println("jmm_FindDeadlockedThreads: IMPLEMENT ME!"); return NULL; } jobjectArray jmm_FindMonitorDeadlockedThreads(JNIEnv* env) { log_println("jmm_FindMonitorDeadlockedThreads: IMPLEMENT ME!"); return NULL; } jint jmm_GetGCExtAttributeInfo(JNIEnv* env, jobject mgr, jmmExtAttributeInfo* info, jint count) { log_println("jmm_GetGCExtAttributeInfo: IMPLEMENT ME!"); return 0; } void jmm_GetLastGCStat(JNIEnv* env, jobject obj, jmmGCStat* gc_stat) { log_println("jmm_GetLastGCStat: IMPLEMENT ME!"); } jint jmm_DumpHeap0(JNIEnv* env, jstring outputfile, jboolean live) { log_println("jmm_DumpHeap0: IMPLEMENT ME!"); return 0; } } // extern "C" const struct jmmInterface_1_ jmm_interface = { NULL, NULL, jmm_GetVersion, jmm_GetOptionalSupport, jmm_GetInputArguments, jmm_GetThreadInfo, jmm_GetInputArgumentArray, jmm_GetMemoryPools, jmm_GetMemoryManagers, jmm_GetMemoryPoolUsage, jmm_GetPeakMemoryPoolUsage, NULL, jmm_GetMemoryUsage, jmm_GetLongAttribute, jmm_GetBoolAttribute, jmm_SetBoolAttribute, jmm_GetLongAttributes, jmm_FindMonitorDeadlockedThreads, jmm_GetThreadCpuTime, jmm_GetVMGlobalNames, jmm_GetVMGlobals, jmm_GetInternalThreadTimes, jmm_ResetStatistic, jmm_SetPoolSensor, jmm_SetPoolThreshold, jmm_GetPoolCollectionUsage, jmm_GetGCExtAttributeInfo, jmm_GetLastGCStat, jmm_GetThreadCpuTimeWithKind, NULL, jmm_DumpHeap0, jmm_FindDeadlockedThreads, jmm_SetVMGlobal, NULL, jmm_DumpThreads }; /** * Return the requested management interface. * * @param version Requested management interface version. * * @return Pointer to management interface structure. */ void* Management::get_jmm_interface(int version) { if (version == JMM_VERSION_1_0) { return (void*) &jmm_interface; } return NULL; } /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: * mode: c++ * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 * End: * vim:noexpandtab:sw=4:ts=4: */