--- a/jdk/make/Import.gmk Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/make/Import.gmk Fri May 01 03:56:04 2015 -0700
@@ -32,11 +32,11 @@
# Put the libraries here. Different locations for different target OS types.
ifneq ($(OPENJDK_TARGET_OS), windows)
- HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)
+ HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)
BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR)
SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent$(OPENJDK_TARGET_CPU_LIBDIR)
else
- HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/jre/bin
+ HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/bin
BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base
SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent
endif
@@ -80,11 +80,11 @@
################################################################################
ifeq ($(OPENJDK_TARGET_OS), macosx)
- JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
- $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
+ JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \
+ $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
else
- JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
- $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
+ JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \
+ $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) )
endif
ifneq ($(OPENJDK_TARGET_OS), windows)
--- a/jdk/make/lib/Lib-java.instrument.gmk Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/make/lib/Lib-java.instrument.gmk Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,9 @@
include LibCommon.gmk
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, jdk, lib/Lib-java.instrument.gmk))
+
################################################################################
LIBINSTRUMENT_SRC := $(JDK_TOPDIR)/src/java.instrument/share/native/libinstrument \
--- a/jdk/make/lib/Lib-java.management.gmk Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/make/lib/Lib-java.management.gmk Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,10 @@
################################################################################
-BUILD_LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement \
+LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement \
$(JDK_TOPDIR)/src/java.management/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement
-BUILD_LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \
- $(addprefix -I,$(BUILD_LIBMANAGEMENT_SRC)) \
+LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \
+ $(addprefix -I,$(LIBMANAGEMENT_SRC)) \
-I$(SUPPORT_OUTPUTDIR)/headers/java.management \
$(LIBJAVA_HEADER_FLAGS) \
#
@@ -43,20 +43,6 @@
# See MSDN documentation for GetProcessMemoryInfo for more information.
BUILD_LIBMANAGEMENT_CFLAGS += -DPSAPI_VERSION=1
-BUILD_LIBMANAGEMENT_EXCLUDES :=
-
-ifneq ($(OPENJDK_TARGET_OS), solaris)
- BUILD_LIBMANAGEMENT_EXCLUDES += SolarisOperatingSystem.c
-endif
-
-ifneq ($(OPENJDK_TARGET_OS), linux)
- BUILD_LIBMANAGEMENT_EXCLUDES += LinuxOperatingSystem.c
-endif
-
-ifneq ($(OPENJDK_TARGET_OS), macosx)
- BUILD_LIBMANAGEMENT_EXCLUDES += MacosxOperatingSystem.c
-endif
-
LIBMANAGEMENT_OPTIMIZATION := HIGH
ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), )
ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
@@ -64,17 +50,13 @@
endif
endif
-# Make it possible to override this variable
-LIBMANAGEMENT_MAPFILE ?= $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers
-
$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \
LIBRARY := management, \
OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
- SRC := $(BUILD_LIBMANAGEMENT_SRC), \
- EXCLUDE_FILES := $(BUILD_LIBMANAGEMENT_EXCLUDES), \
+ SRC := $(LIBMANAGEMENT_SRC), \
OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \
- CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(BUILD_LIBMANAGEMENT_CFLAGS), \
- MAPFILE := $(LIBMANAGEMENT_MAPFILE), \
+ CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_CFLAGS), \
+ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers, \
LDFLAGS := $(LDFLAGS_JDKLIB) \
$(call SET_SHARED_LIBRARY_ORIGIN), \
LDFLAGS_solaris := -lkstat, \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-jdk.management.gmk Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,75 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+include LibCommon.gmk
+
+# Hook to include the corresponding custom file, if present.
+$(eval $(call IncludeCustomExtension, jdk, lib/Lib-jdk.management.gmk))
+
+################################################################################
+
+LIBMANAGEMENT_EXT_SRC += $(JDK_TOPDIR)/src/jdk.management/share/native/libmanagement_ext \
+ $(JDK_TOPDIR)/src/jdk.management/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement_ext \
+ $(JDK_TOPDIR)/src/jdk.management/$(OPENJDK_TARGET_OS)/native/libmanagement_ext
+LIBMANAGEMENT_EXT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \
+ $(addprefix -I,$(LIBMANAGEMENT_EXT_SRC)) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.management \
+ $(LIBJAVA_HEADER_FLAGS) \
+ #
+
+LIBMANAGEMENT_EXT_OPTIMIZATION := HIGH
+ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), )
+ ifeq ($(ENABLE_DEBUG_SYMBOLS), true)
+ LIBMANAGEMENT_EXT_OPTIMIZATION := LOW
+ endif
+endif
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_EXT, \
+ LIBRARY := management_ext, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ SRC := $(LIBMANAGEMENT_EXT_SRC), \
+ LANG := C, \
+ OPTIMIZATION := $(LIBMANAGEMENT_EXT_OPTIMIZATION), \
+ CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_EXT_CFLAGS), \
+ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement_ext/mapfile-vers, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LDFLAGS_solaris := -lkstat, \
+ LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \
+ LDFLAGS_SUFFIX_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \
+ LDFLAGS_SUFFIX_aix := -lperfstat,\
+ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+ RC_FLAGS := $(RC_FLAGS) \
+ -D "JDK_FNAME=management_ext.dll" \
+ -D "JDK_INTERNAL_NAME=management_ext" \
+ -D "JDK_FTYPE=0x2L", \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement_ext, \
+ DEBUG_SYMBOLS := true))
+
+$(BUILD_LIBMANAGEMENT_EXT): $(call FindLib, java.base, java)
+
+TARGETS += $(BUILD_LIBMANAGEMENT_EXT)
+
+################################################################################
--- a/jdk/make/mapfiles/libmanagement/mapfile-vers Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/make/mapfiles/libmanagement/mapfile-vers Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -27,37 +27,10 @@
SUNWprivate_1.1 {
global:
- Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0;
- Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0;
- Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0;
- Java_sun_management_OperatingSystemImpl_getMaxFileDescriptorCount0;
- Java_sun_management_OperatingSystemImpl_getOpenFileDescriptorCount0;
- Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0;
- Java_sun_management_OperatingSystemImpl_getProcessCpuTime0;
- Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0;
- Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0;
- Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0;
- Java_sun_management_OperatingSystemImpl_initialize0;
Java_sun_management_ClassLoadingImpl_setVerboseClass;
- Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand;
- Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands;
- Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo;
- Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled;
- Java_sun_management_FileSystemImpl_isAccessUserOnly0;
- Java_sun_management_Flag_getAllFlagNames;
- Java_sun_management_Flag_getFlags;
- Java_sun_management_Flag_getInternalFlagCount;
- Java_sun_management_Flag_initialize;
- Java_sun_management_Flag_setLongValue;
- Java_sun_management_Flag_setBooleanValue;
- Java_sun_management_Flag_setStringValue;
- Java_sun_management_GarbageCollectorImpl_getCollectionCount;
+ Java_sun_management_FileSystemImpl_isAccessUserOnly0;
+ Java_sun_management_GarbageCollectorImpl_getCollectionCount;
Java_sun_management_GarbageCollectorImpl_getCollectionTime;
- Java_sun_management_GarbageCollectorImpl_setNotificationEnabled;
- Java_sun_management_GcInfoBuilder_fillGcAttributeInfo;
- Java_sun_management_GcInfoBuilder_getLastGcInfo0;
- Java_sun_management_GcInfoBuilder_getNumGcExtAttributes;
- Java_sun_management_HotSpotDiagnostic_dumpHeap0;
Java_sun_management_HotspotThread_getInternalThreadCount;
Java_sun_management_HotspotThread_getInternalThreadTimes0;
Java_sun_management_MemoryImpl_getMemoryManagers0;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/libmanagement_ext/mapfile-vers Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Define library interface.
+
+SUNWprivate_1.1 {
+ global:
+ Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getFreePhysicalMemorySize0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getMaxFileDescriptorCount0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getOpenFileDescriptorCount0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getTotalPhysicalMemorySize0;
+ Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0;
+ Java_com_sun_management_internal_OperatingSystemImpl_initialize0;
+ Java_com_sun_management_internal_DiagnosticCommandImpl_executeDiagnosticCommand;
+ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommands;
+ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo;
+ Java_com_sun_management_internal_DiagnosticCommandImpl_setNotificationEnabled;
+ Java_com_sun_management_internal_Flag_getAllFlagNames;
+ Java_com_sun_management_internal_Flag_getFlags;
+ Java_com_sun_management_internal_Flag_getInternalFlagCount;
+ Java_com_sun_management_internal_Flag_initialize;
+ Java_com_sun_management_internal_Flag_setLongValue;
+ Java_com_sun_management_internal_Flag_setBooleanValue;
+ Java_com_sun_management_internal_Flag_setStringValue;
+ Java_com_sun_management_internal_GarbageCollectorExtImpl_setNotificationEnabled;
+ Java_com_sun_management_internal_GcInfoBuilder_fillGcAttributeInfo;
+ Java_com_sun_management_internal_GcInfoBuilder_getLastGcInfo0;
+ Java_com_sun_management_internal_GcInfoBuilder_getNumGcExtAttributes;
+ Java_com_sun_management_internal_HotSpotDiagnostic_dumpHeap0;
+ JNI_OnLoad;
+ local:
+ *;
+};
--- a/jdk/make/src/classes/build/tools/module/boot.modules Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/make/src/classes/build/tools/module/boot.modules Fri May 01 03:56:04 2015 -0700
@@ -22,6 +22,7 @@
jdk.hprof.agent
jdk.httpserver
jdk.jfr
+jdk.management
jdk.management.cmm
jdk.naming.rmi
jdk.sctp
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java Fri May 01 03:56:04 2015 -0700
@@ -38,7 +38,17 @@
* under section 6.5. It needs to be constructed w/ an initialized
* cipher object, and initial counter block(ICB). Given an input X
* of arbitrary length, it processes and returns an output which has
- * the same length as X.
+ * the same length as X. The invariants of this class are:
+ *
+ * (1) The length of intialCounterBlk (and also of its clones, e.g.,
+ * fields counter and counterSave) is equal to AES_BLOCK_SIZE.
+ *
+ * (2) After construction, the field counter never becomes null, it
+ * always contains a byte array of length AES_BLOCK_SIZE.
+ *
+ * If any invariant is broken, failures can occur because the
+ * AESCrypt.encryptBlock method can be intrinsified on the HotSpot VM
+ * (see JDK-8067648 for details).
*
* <p>This function is used in the implementation of GCM mode.
*
@@ -59,6 +69,10 @@
// NOTE: cipher should already be initialized
GCTR(SymmetricCipher cipher, byte[] initialCounterBlk) {
this.aes = cipher;
+ if (initialCounterBlk.length != AES_BLOCK_SIZE) {
+ throw new RuntimeException("length of initial counter block (" + initialCounterBlk.length +
+ ") not equal to AES_BLOCK_SIZE (" + AES_BLOCK_SIZE + ")");
+ }
this.icb = initialCounterBlk;
this.counter = icb.clone();
}
@@ -137,6 +151,8 @@
* Restores the content of this object to the previous saved one.
*/
void restore() {
- this.counter = this.counterSave;
+ if (this.counterSave != null) {
+ this.counter = this.counterSave;
+ }
}
}
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Fri May 01 03:56:04 2015 -0700
@@ -1312,7 +1312,7 @@
// e) Anonymous classes
- // JVM Spec 4.8.6: A class must have an EnclosingMethod
+ // JVM Spec 4.7.7: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@@ -1357,28 +1357,7 @@
simpleName = getName();
return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name
}
- // According to JLS3 "Binary Compatibility" (13.1) the binary
- // name of non-package classes (not top level) is the binary
- // name of the immediately enclosing class followed by a '$' followed by:
- // (for nested and inner classes): the simple name.
- // (for local classes): 1 or more digits followed by the simple name.
- // (for anonymous classes): 1 or more digits.
-
- // Since getSimpleBinaryName() will strip the binary name of
- // the immediately enclosing class, we are now looking at a
- // string that matches the regular expression "\$[0-9]*"
- // followed by a simple name (considering the simple of an
- // anonymous class to be the empty string).
-
- // Remove leading "\$[0-9]*" from the name
- int length = simpleName.length();
- if (length < 1 || simpleName.charAt(0) != '$')
- throw new InternalError("Malformed class name");
- int index = 1;
- while (index < length && isAsciiDigit(simpleName.charAt(index)))
- index++;
- // Eventually, this is the empty string iff this is an anonymous class
- return simpleName.substring(index);
+ return simpleName;
}
/**
@@ -1489,20 +1468,20 @@
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) // top level class
return null;
- // Otherwise, strip the enclosing class' name
- try {
- return getName().substring(enclosingClass.getName().length());
- } catch (IndexOutOfBoundsException ex) {
- throw new InternalError("Malformed class name", ex);
- }
+ String name = getSimpleBinaryName0();
+ if (name == null) // anonymous class
+ return "";
+ return name;
}
+ private native String getSimpleBinaryName0();
+
/**
* Returns {@code true} if this is a local class or an anonymous
* class. Returns {@code false} otherwise.
*/
private boolean isLocalOrAnonymousClass() {
- // JVM Spec 4.8.6: A class must have an EnclosingMethod
+ // JVM Spec 4.7.7: A class must have an EnclosingMethod
// attribute if and only if it is a local class or an
// anonymous class.
return getEnclosingMethodInfo() != null;
--- a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Fri May 01 03:56:04 2015 -0700
@@ -25,9 +25,10 @@
package java.lang.invoke;
-import sun.invoke.empty.Empty;
import static java.lang.invoke.MethodHandleStatics.*;
import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import java.lang.reflect.Field;
+import sun.misc.Cleaner;
/**
* A {@code CallSite} is a holder for a variable {@link MethodHandle},
@@ -136,6 +137,50 @@
}
/**
+ * {@code CallSite} dependency context.
+ * VM uses context class to store nmethod dependencies on the call site target.
+ * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance.
+ * Lazily initialized when CallSite instance is linked to some indy call site or VM needs
+ * it to store dependencies. As a corollary, "null" context means there are no dependencies
+ * registered yet. {@code Cleaner} is used in 2 roles:
+ * (a) context class access for VM;
+ * (b) stale context class cleanup.
+ * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}).
+ * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly
+ * from {@code Reference.referent} field.
+ */
+ private volatile Cleaner context = null;
+
+ /**
+ * Default context.
+ * VM uses it to initialize non-linked CallSite context.
+ */
+ private static class DefaultContext {}
+ private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null);
+
+ private static Cleaner makeContext(Class<?> referent, final CallSite holder) {
+ return Cleaner.create(referent,
+ new Runnable() {
+ @Override public void run() {
+ MethodHandleNatives.invalidateDependentNMethods(holder);
+ }
+ });
+ }
+
+ /** Initialize context class used for nmethod dependency tracking */
+ /*package-private*/
+ void initContext(Class<?> newContext) {
+ // If there are concurrent actions, exactly one succeeds.
+ if (context == null) {
+ UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this));
+ // No need to care about failed CAS attempt.
+ // Since initContext is called from indy call site linkage in newContext class, there's no risk
+ // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup
+ // action in the wrong context).
+ }
+ }
+
+ /**
* Returns the type of this call site's target.
* Although targets may change, any call site's type is permanent, and can never change to an unequal type.
* The {@code setTarget} method enforces this invariant by refusing any new target that does
@@ -246,11 +291,13 @@
}
// unsafe stuff:
- private static final long TARGET_OFFSET;
+ private static final long TARGET_OFFSET;
+ private static final long CONTEXT_OFFSET;
static {
try {
- TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
- } catch (Exception ex) { throw new Error(ex); }
+ TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+ CONTEXT_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("context"));
+ } catch (Exception ex) { throw newInternalError(ex); }
}
/*package-private*/
--- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java Fri May 01 03:56:04 2015 -0700
@@ -691,10 +691,4 @@
}
}
}
-
- @Override
- void customize() {
- assert(form.customized == null);
- // No need to customize DMHs.
- }
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri May 01 03:56:04 2015 -0700
@@ -847,11 +847,7 @@
refKind = REF_invokeVirtual;
}
- if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) {
- // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind.
- // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected.
- refKind = REF_invokeInterface;
- }
+ assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual));
// push arguments
emitPushArguments(name);
--- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java Fri May 01 03:56:04 2015 -0700
@@ -281,7 +281,7 @@
outArgs[0] = names[CHECK_TYPE];
}
if (CHECK_CUSTOM != -1) {
- names[CHECK_CUSTOM] = new Name(NF_checkCustomized, names[CALL_MH]);
+ names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]);
}
names[LINKER_CALL] = new Name(outCallType, outArgs);
lform = new LambdaForm(debugName, INARG_LIMIT, names);
@@ -394,6 +394,7 @@
@ForceInline
void checkCustomized(Object o) {
MethodHandle mh = (MethodHandle)o;
+ if (MethodHandleImpl.isCompileConstant(mh)) return;
if (mh.form.customized == null) {
maybeCustomize(mh);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri May 01 03:56:04 2015 -0700
@@ -722,6 +722,13 @@
return result;
}
+ // Intrinsified by C2. Returns true if obj is a compile-time constant.
+ @LambdaForm.Hidden
+ static
+ boolean isCompileConstant(Object obj) {
+ return false;
+ }
+
static
MethodHandle makeGuardWithTest(MethodHandle test,
MethodHandle target,
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,121 +55,42 @@
static native Object staticFieldBase(MemberName self); // e.g., returns clazz
static native Object getMemberVMInfo(MemberName self); // returns {vmindex,vmtarget}
- /// MethodHandle support
-
- /** Fetch MH-related JVM parameter.
- * which=0 retrieves MethodHandlePushLimit
- * which=1 retrieves stack slot push size (in address units)
- */
- static native int getConstant(int which);
-
- static final boolean COUNT_GWT;
-
/// CallSite support
/** Tell the JVM that we need to change the target of a CallSite. */
static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
+ /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */
+ static native void invalidateDependentNMethods(CallSite site);
+
private static native void registerNatives();
static {
registerNatives();
- COUNT_GWT = getConstant(Constants.GC_COUNT_GWT) != 0;
// The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> calls as needed:
MethodHandleImpl.initStatics();
}
- // All compile-time constants go here.
- // There is an opportunity to check them against the JVM's idea of them.
+ /**
+ * Compile-time constants go here. This collection exists not only for
+ * reference from clients, but also for ensuring the VM and JDK agree on the
+ * values of these constants (see {@link #verifyConstants()}).
+ */
static class Constants {
Constants() { } // static only
- // MethodHandleImpl
- static final int // for getConstant
- GC_COUNT_GWT = 4,
- GC_LAMBDA_SUPPORT = 5;
- // MemberName
- // The JVM uses values of -2 and above for vtable indexes.
- // Field values are simple positive offsets.
- // Ref: src/share/vm/oops/methodOop.hpp
- // This value is negative enough to avoid such numbers,
- // but not too negative.
- static final int
- MN_IS_METHOD = 0x00010000, // method (not constructor)
- MN_IS_CONSTRUCTOR = 0x00020000, // constructor
- MN_IS_FIELD = 0x00040000, // field
- MN_IS_TYPE = 0x00080000, // nested type
- MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
- MN_REFERENCE_KIND_SHIFT = 24, // refKind
- MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
- // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
- MN_SEARCH_SUPERCLASSES = 0x00100000,
- MN_SEARCH_INTERFACES = 0x00200000;
-
- /**
- * Basic types as encoded in the JVM. These code values are not
- * intended for use outside this class. They are used as part of
- * a private interface between the JVM and this class.
- */
static final int
- T_BOOLEAN = 4,
- T_CHAR = 5,
- T_FLOAT = 6,
- T_DOUBLE = 7,
- T_BYTE = 8,
- T_SHORT = 9,
- T_INT = 10,
- T_LONG = 11,
- T_OBJECT = 12,
- //T_ARRAY = 13
- T_VOID = 14,
- //T_ADDRESS = 15
- T_ILLEGAL = 99;
-
- /**
- * Constant pool entry types.
- */
- static final byte
- CONSTANT_Utf8 = 1,
- CONSTANT_Integer = 3,
- CONSTANT_Float = 4,
- CONSTANT_Long = 5,
- CONSTANT_Double = 6,
- CONSTANT_Class = 7,
- CONSTANT_String = 8,
- CONSTANT_Fieldref = 9,
- CONSTANT_Methodref = 10,
- CONSTANT_InterfaceMethodref = 11,
- CONSTANT_NameAndType = 12,
- CONSTANT_MethodHandle = 15, // JSR 292
- CONSTANT_MethodType = 16, // JSR 292
- CONSTANT_InvokeDynamic = 18,
- CONSTANT_LIMIT = 19; // Limit to tags found in classfiles
-
- /**
- * Access modifier flags.
- */
- static final char
- ACC_PUBLIC = 0x0001,
- ACC_PRIVATE = 0x0002,
- ACC_PROTECTED = 0x0004,
- ACC_STATIC = 0x0008,
- ACC_FINAL = 0x0010,
- ACC_SYNCHRONIZED = 0x0020,
- ACC_VOLATILE = 0x0040,
- ACC_TRANSIENT = 0x0080,
- ACC_NATIVE = 0x0100,
- ACC_INTERFACE = 0x0200,
- ACC_ABSTRACT = 0x0400,
- ACC_STRICT = 0x0800,
- ACC_SYNTHETIC = 0x1000,
- ACC_ANNOTATION = 0x2000,
- ACC_ENUM = 0x4000,
- // aliases:
- ACC_SUPER = ACC_SYNCHRONIZED,
- ACC_BRIDGE = ACC_VOLATILE,
- ACC_VARARGS = ACC_TRANSIENT;
+ MN_IS_METHOD = 0x00010000, // method (not constructor)
+ MN_IS_CONSTRUCTOR = 0x00020000, // constructor
+ MN_IS_FIELD = 0x00040000, // field
+ MN_IS_TYPE = 0x00080000, // nested type
+ MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected
+ MN_REFERENCE_KIND_SHIFT = 24, // refKind
+ MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+ // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+ MN_SEARCH_SUPERCLASSES = 0x00100000,
+ MN_SEARCH_INTERFACES = 0x00200000;
/**
* Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
@@ -314,6 +235,7 @@
return Invokers.linkToTargetMethod(type);
} else {
appendixResult[0] = callSite;
+ callSite.initContext(caller);
return Invokers.linkToCallSiteMethod(type);
}
}
--- a/jdk/src/java.base/share/classes/java/nio/Bits.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/nio/Bits.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -567,32 +567,13 @@
// -- Processor and memory-system properties --
- private static final ByteOrder byteOrder;
+ private static final ByteOrder byteOrder
+ = unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
static ByteOrder byteOrder() {
- if (byteOrder == null)
- throw new Error("Unknown byte order");
return byteOrder;
}
- static {
- long a = unsafe.allocateMemory(8);
- try {
- unsafe.putLong(a, 0x0102030405060708L);
- byte b = unsafe.getByte(a);
- switch (b) {
- case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break;
- case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break;
- default:
- assert false;
- byteOrder = null;
- }
- } finally {
- unsafe.freeMemory(a);
- }
- }
-
-
private static int pageSize = -1;
static int pageSize() {
@@ -605,17 +586,9 @@
return (int)(size + (long)pageSize() - 1L) / pageSize();
}
- private static boolean unaligned;
- private static boolean unalignedKnown = false;
+ private static boolean unaligned = unsafe.unalignedAccess();
static boolean unaligned() {
- if (unalignedKnown)
- return unaligned;
- String arch = AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("os.arch"));
- unaligned = arch.equals("i386") || arch.equals("x86")
- || arch.equals("amd64") || arch.equals("x86_64");
- unalignedKnown = true;
return unaligned;
}
--- a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
package java.nio;
+import sun.misc.Unsafe;
/**
#if[rw]
@@ -52,6 +53,16 @@
#end[rw]
*/
+#if[byte]
+
+ // Cached unsafe-access object
+ private static final Unsafe unsafe = Bits.unsafe();
+
+ // Cached array base offset
+ private static final long arrayBaseOffset = unsafe.arrayBaseOffset($type$[].class);
+
+#end[byte]
+
Heap$Type$Buffer$RW$(int cap, int lim) { // package-private
#if[rw]
super(-1, 0, lim, cap, new $type$[cap], 0);
@@ -131,6 +142,12 @@
return i + offset;
}
+#if[byte]
+ private long byteOffset(long i) {
+ return arrayBaseOffset + i + offset;
+ }
+#end[byte]
+
public $type$ get() {
return hb[ix(nextGetIndex())];
}
@@ -256,18 +273,18 @@
#if[rw]
public char getChar() {
- return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
+ return unsafe.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
}
public char getChar(int i) {
- return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
+ return unsafe.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
}
#end[rw]
public $Type$Buffer putChar(char x) {
#if[rw]
- Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
+ unsafe.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -276,7 +293,7 @@
public $Type$Buffer putChar(int i, char x) {
#if[rw]
- Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
+ unsafe.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -307,18 +324,18 @@
#if[rw]
public short getShort() {
- return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
+ return unsafe.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian);
}
public short getShort(int i) {
- return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
+ return unsafe.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian);
}
#end[rw]
public $Type$Buffer putShort(short x) {
#if[rw]
- Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
+ unsafe.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -327,7 +344,7 @@
public $Type$Buffer putShort(int i, short x) {
#if[rw]
- Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
+ unsafe.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -358,18 +375,18 @@
#if[rw]
public int getInt() {
- return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
+ return unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian);
}
public int getInt(int i) {
- return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
+ return unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
}
#end[rw]
public $Type$Buffer putInt(int x) {
#if[rw]
- Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
+ unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -378,7 +395,7 @@
public $Type$Buffer putInt(int i, int x) {
#if[rw]
- Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
+ unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -409,18 +426,18 @@
#if[rw]
public long getLong() {
- return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
+ return unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
}
public long getLong(int i) {
- return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
+ return unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
}
#end[rw]
public $Type$Buffer putLong(long x) {
#if[rw]
- Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
+ unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -429,7 +446,7 @@
public $Type$Buffer putLong(int i, long x) {
#if[rw]
- Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
+ unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -460,18 +477,21 @@
#if[rw]
public float getFloat() {
- return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
+ int x = unsafe.getIntUnaligned(hb, byteOffset(nextPutIndex(4)), bigEndian);
+ return Float.intBitsToFloat(x);
}
public float getFloat(int i) {
- return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
+ int x = unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian);
+ return Float.intBitsToFloat(x);
}
#end[rw]
public $Type$Buffer putFloat(float x) {
#if[rw]
- Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
+ int y = Float.floatToRawIntBits(x);
+ unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -480,7 +500,8 @@
public $Type$Buffer putFloat(int i, float x) {
#if[rw]
- Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
+ int y = Float.floatToRawIntBits(x);
+ unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -511,18 +532,21 @@
#if[rw]
public double getDouble() {
- return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
+ long x = unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian);
+ return Double.longBitsToDouble(x);
}
public double getDouble(int i) {
- return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
+ long x = unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian);
+ return Double.longBitsToDouble(x);
}
#end[rw]
public $Type$Buffer putDouble(double x) {
#if[rw]
- Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
+ long y = Double.doubleToRawLongBits(x);
+ unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
@@ -531,7 +555,8 @@
public $Type$Buffer putDouble(int i, double x) {
#if[rw]
- Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
+ long y = Double.doubleToRawLongBits(x);
+ unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
return this;
#else[rw]
throw new ReadOnlyBufferException();
--- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Fri May 01 03:56:04 2015 -0700
@@ -183,7 +183,7 @@
* <p>
* Unless the reference {@code x} being stored is either null
* or matches the field type, the results are undefined.
- * If the reference {@code o} is non-null, car marks or
+ * If the reference {@code o} is non-null, card marks or
* other store barriers for that object (if the VM requires them)
* are updated.
* @see #putInt(Object, long, int)
@@ -219,6 +219,35 @@
/** @see #putInt(Object, long, int) */
public native void putDouble(Object o, long offset, double x);
+ // These read VM internal data.
+
+ /**
+ * Fetches an uncompressed reference value from a given native variable
+ * ignoring the VM's compressed references mode.
+ *
+ * @param address a memory address locating the variable
+ * @return the value fetched from the indicated native variable
+ */
+ public native Object getUncompressedObject(long address);
+
+ /**
+ * Fetches the {@link java.lang.Class} Java mirror for the given native
+ * metaspace {@code Klass} pointer.
+ *
+ * @param metaspaceKlass a native metaspace {@code Klass} pointer
+ * @return the {@link java.lang.Class} Java mirror
+ */
+ public native Class<?> getJavaMirror(long metaspaceKlass);
+
+ /**
+ * Fetches a native metaspace {@code Klass} pointer for the given Java
+ * object.
+ *
+ * @param o Java heap object for which to fetch the class pointer
+ * @return a native metaspace {@code Klass} pointer
+ */
+ public native long getKlassPointer(Object o);
+
// These work on values in the C heap.
/**
@@ -934,4 +963,347 @@
private static void throwIllegalAccessError() {
throw new IllegalAccessError();
}
+
+ /**
+ * @return Returns true if the native byte ordering of this
+ * platform is big-endian, false if it is little-endian.
+ */
+ public final boolean isBigEndian() { return BE; }
+
+ /**
+ * @return Returns true if this platform is capable of performing
+ * accesses at addresses which are not aligned for the type of the
+ * primitive type being accessed, false otherwise.
+ */
+ public final boolean unalignedAccess() { return unalignedAccess; }
+
+ /**
+ * Fetches a value at some byte offset into a given Java object.
+ * More specifically, fetches a value within the given object
+ * <code>o</code> at the given offset, or (if <code>o</code> is
+ * null) from the memory address whose numerical value is the
+ * given offset. <p>
+ *
+ * The specification of this method is the same as {@link
+ * #getLong(Object, long)} except that the offset does not need to
+ * have been obtained from {@link #objectFieldOffset} on the
+ * {@link java.lang.reflect.Field} of some Java field. The value
+ * in memory is raw data, and need not correspond to any Java
+ * variable. Unless <code>o</code> is null, the value accessed
+ * must be entirely within the allocated object. The endianness
+ * of the value in memory is the endianness of the native platform.
+ *
+ * <p> The read will be atomic with respect to the largest power
+ * of two that divides the GCD of the offset and the storage size.
+ * For example, getLongUnaligned will make atomic reads of 2-, 4-,
+ * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
+ * respectively. There are no other guarantees of atomicity.
+ * <p>
+ * 8-byte atomicity is only guaranteed on platforms on which
+ * support atomic accesses to longs.
+ *
+ * @param o Java heap object in which the value resides, if any, else
+ * null
+ * @param offset The offset in bytes from the start of the object
+ * @return the value fetched from the indicated object
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ * @since 1.9
+ */
+ public final long getLongUnaligned(Object o, long offset) {
+ if ((offset & 7) == 0) {
+ return getLong(o, offset);
+ } else if ((offset & 3) == 0) {
+ return makeLong(getInt(o, offset),
+ getInt(o, offset + 4));
+ } else if ((offset & 1) == 0) {
+ return makeLong(getShort(o, offset),
+ getShort(o, offset + 2),
+ getShort(o, offset + 4),
+ getShort(o, offset + 6));
+ } else {
+ return makeLong(getByte(o, offset),
+ getByte(o, offset + 1),
+ getByte(o, offset + 2),
+ getByte(o, offset + 3),
+ getByte(o, offset + 4),
+ getByte(o, offset + 5),
+ getByte(o, offset + 6),
+ getByte(o, offset + 7));
+ }
+ }
+ /**
+ * As {@link #getLongUnaligned(Object, long)} but with an
+ * additional argument which specifies the endianness of the value
+ * as stored in memory.
+ *
+ * @param o Java heap object in which the variable resides
+ * @param offset The offset in bytes from the start of the object
+ * @param bigEndian The endianness of the value
+ * @return the value fetched from the indicated object
+ * @since 1.9
+ */
+ public final long getLongUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getLongUnaligned(o, offset));
+ }
+
+ /** @see #getLongUnaligned(Object, long) */
+ public final int getIntUnaligned(Object o, long offset) {
+ if ((offset & 3) == 0) {
+ return getInt(o, offset);
+ } else if ((offset & 1) == 0) {
+ return makeInt(getShort(o, offset),
+ getShort(o, offset + 2));
+ } else {
+ return makeInt(getByte(o, offset),
+ getByte(o, offset + 1),
+ getByte(o, offset + 2),
+ getByte(o, offset + 3));
+ }
+ }
+ /** @see #getLongUnaligned(Object, long, boolean) */
+ public final int getIntUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getIntUnaligned(o, offset));
+ }
+
+ /** @see #getLongUnaligned(Object, long) */
+ public final short getShortUnaligned(Object o, long offset) {
+ if ((offset & 1) == 0) {
+ return getShort(o, offset);
+ } else {
+ return makeShort(getByte(o, offset),
+ getByte(o, offset + 1));
+ }
+ }
+ /** @see #getLongUnaligned(Object, long, boolean) */
+ public final short getShortUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getShortUnaligned(o, offset));
+ }
+
+ /** @see #getLongUnaligned(Object, long) */
+ public final char getCharUnaligned(Object o, long offset) {
+ return (char)getShortUnaligned(o, offset);
+ }
+ /** @see #getLongUnaligned(Object, long, boolean) */
+ public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
+ return convEndian(bigEndian, getCharUnaligned(o, offset));
+ }
+
+ /**
+ * Stores a value at some byte offset into a given Java object.
+ * <p>
+ * The specification of this method is the same as {@link
+ * #getLong(Object, long)} except that the offset does not need to
+ * have been obtained from {@link #objectFieldOffset} on the
+ * {@link java.lang.reflect.Field} of some Java field. The value
+ * in memory is raw data, and need not correspond to any Java
+ * variable. The endianness of the value in memory is the
+ * endianness of the native platform.
+ * <p>
+ * The write will be atomic with respect to the largest power of
+ * two that divides the GCD of the offset and the storage size.
+ * For example, putLongUnaligned will make atomic writes of 2-, 4-,
+ * or 8-byte storage units if the offset is zero mod 2, 4, or 8,
+ * respectively. There are no other guarantees of atomicity.
+ * <p>
+ * 8-byte atomicity is only guaranteed on platforms on which
+ * support atomic accesses to longs.
+ * <p>
+ *
+ * @param o Java heap object in which the value resides, if any, else
+ * null
+ * @param offset The offset in bytes from the start of the object
+ * @param x the value to store
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ * @since 1.9
+ */
+ public final void putLongUnaligned(Object o, long offset, long x) {
+ if ((offset & 7) == 0) {
+ putLong(o, offset, x);
+ } else if ((offset & 3) == 0) {
+ putLongParts(o, offset,
+ (int)(x >> 0),
+ (int)(x >>> 32));
+ } else if ((offset & 1) == 0) {
+ putLongParts(o, offset,
+ (short)(x >>> 0),
+ (short)(x >>> 16),
+ (short)(x >>> 32),
+ (short)(x >>> 48));
+ } else {
+ putLongParts(o, offset,
+ (byte)(x >>> 0),
+ (byte)(x >>> 8),
+ (byte)(x >>> 16),
+ (byte)(x >>> 24),
+ (byte)(x >>> 32),
+ (byte)(x >>> 40),
+ (byte)(x >>> 48),
+ (byte)(x >>> 56));
+ }
+ }
+ /**
+ * As {@link #putLongUnaligned(Object, long, long)} but with an additional
+ * argument which specifies the endianness of the value as stored in memory.
+ * @param o Java heap object in which the value resides
+ * @param offset The offset in bytes from the start of the object
+ * @param x the value to store
+ * @param bigEndian The endianness of the value
+ * @throws RuntimeException No defined exceptions are thrown, not even
+ * {@link NullPointerException}
+ * @since 1.9
+ */
+ public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) {
+ putLongUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ /** @see #putLongUnaligned(Object, long, long) */
+ public final void putIntUnaligned(Object o, long offset, int x) {
+ if ((offset & 3) == 0) {
+ putInt(o, offset, x);
+ } else if ((offset & 1) == 0) {
+ putIntParts(o, offset,
+ (short)(x >> 0),
+ (short)(x >>> 16));
+ } else {
+ putIntParts(o, offset,
+ (byte)(x >>> 0),
+ (byte)(x >>> 8),
+ (byte)(x >>> 16),
+ (byte)(x >>> 24));
+ }
+ }
+ /** @see #putLongUnaligned(Object, long, long, boolean) */
+ public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) {
+ putIntUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ /** @see #putLongUnaligned(Object, long, long) */
+ public final void putShortUnaligned(Object o, long offset, short x) {
+ if ((offset & 1) == 0) {
+ putShort(o, offset, x);
+ } else {
+ putShortParts(o, offset,
+ (byte)(x >>> 0),
+ (byte)(x >>> 8));
+ }
+ }
+ /** @see #putLongUnaligned(Object, long, long, boolean) */
+ public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) {
+ putShortUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ /** @see #putLongUnaligned(Object, long, long) */
+ public final void putCharUnaligned(Object o, long offset, char x) {
+ putShortUnaligned(o, offset, (short)x);
+ }
+ /** @see #putLongUnaligned(Object, long, long, boolean) */
+ public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) {
+ putCharUnaligned(o, offset, convEndian(bigEndian, x));
+ }
+
+ // JVM interface methods
+ private native boolean unalignedAccess0();
+ private native boolean isBigEndian0();
+
+ // BE is true iff the native endianness of this platform is big.
+ private static final boolean BE = theUnsafe.isBigEndian0();
+
+ // unalignedAccess is true iff this platform can perform unaligned accesses.
+ private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
+
+ private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
+
+ // These methods construct integers from bytes. The byte ordering
+ // is the native endianness of this platform.
+ private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
+ return ((toUnsignedLong(i0) << pickPos(56, 0))
+ | (toUnsignedLong(i1) << pickPos(56, 8))
+ | (toUnsignedLong(i2) << pickPos(56, 16))
+ | (toUnsignedLong(i3) << pickPos(56, 24))
+ | (toUnsignedLong(i4) << pickPos(56, 32))
+ | (toUnsignedLong(i5) << pickPos(56, 40))
+ | (toUnsignedLong(i6) << pickPos(56, 48))
+ | (toUnsignedLong(i7) << pickPos(56, 56)));
+ }
+ private static long makeLong(short i0, short i1, short i2, short i3) {
+ return ((toUnsignedLong(i0) << pickPos(48, 0))
+ | (toUnsignedLong(i1) << pickPos(48, 16))
+ | (toUnsignedLong(i2) << pickPos(48, 32))
+ | (toUnsignedLong(i3) << pickPos(48, 48)));
+ }
+ private static long makeLong(int i0, int i1) {
+ return (toUnsignedLong(i0) << pickPos(32, 0))
+ | (toUnsignedLong(i1) << pickPos(32, 32));
+ }
+ private static int makeInt(short i0, short i1) {
+ return (toUnsignedInt(i0) << pickPos(16, 0))
+ | (toUnsignedInt(i1) << pickPos(16, 16));
+ }
+ private static int makeInt(byte i0, byte i1, byte i2, byte i3) {
+ return ((toUnsignedInt(i0) << pickPos(24, 0))
+ | (toUnsignedInt(i1) << pickPos(24, 8))
+ | (toUnsignedInt(i2) << pickPos(24, 16))
+ | (toUnsignedInt(i3) << pickPos(24, 24)));
+ }
+ private static short makeShort(byte i0, byte i1) {
+ return (short)((toUnsignedInt(i0) << pickPos(8, 0))
+ | (toUnsignedInt(i1) << pickPos(8, 8)));
+ }
+
+ private static byte pick(byte le, byte be) { return BE ? be : le; }
+ private static short pick(short le, short be) { return BE ? be : le; }
+ private static int pick(int le, int be) { return BE ? be : le; }
+
+ // These methods write integers to memory from smaller parts
+ // provided by their caller. The ordering in which these parts
+ // are written is the native endianness of this platform.
+ private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) {
+ putByte(o, offset + 0, pick(i0, i7));
+ putByte(o, offset + 1, pick(i1, i6));
+ putByte(o, offset + 2, pick(i2, i5));
+ putByte(o, offset + 3, pick(i3, i4));
+ putByte(o, offset + 4, pick(i4, i3));
+ putByte(o, offset + 5, pick(i5, i2));
+ putByte(o, offset + 6, pick(i6, i1));
+ putByte(o, offset + 7, pick(i7, i0));
+ }
+ private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) {
+ putShort(o, offset + 0, pick(i0, i3));
+ putShort(o, offset + 2, pick(i1, i2));
+ putShort(o, offset + 4, pick(i2, i1));
+ putShort(o, offset + 6, pick(i3, i0));
+ }
+ private void putLongParts(Object o, long offset, int i0, int i1) {
+ putInt(o, offset + 0, pick(i0, i1));
+ putInt(o, offset + 4, pick(i1, i0));
+ }
+ private void putIntParts(Object o, long offset, short i0, short i1) {
+ putShort(o, offset + 0, pick(i0, i1));
+ putShort(o, offset + 2, pick(i1, i0));
+ }
+ private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) {
+ putByte(o, offset + 0, pick(i0, i3));
+ putByte(o, offset + 1, pick(i1, i2));
+ putByte(o, offset + 2, pick(i2, i1));
+ putByte(o, offset + 3, pick(i3, i0));
+ }
+ private void putShortParts(Object o, long offset, byte i0, byte i1) {
+ putByte(o, offset + 0, pick(i0, i1));
+ putByte(o, offset + 1, pick(i1, i0));
+ }
+
+ // Zero-extend an integer
+ private static int toUnsignedInt(byte n) { return n & 0xff; }
+ private static int toUnsignedInt(short n) { return n & 0xffff; }
+ private static long toUnsignedLong(byte n) { return n & 0xffl; }
+ private static long toUnsignedLong(short n) { return n & 0xffffl; }
+ private static long toUnsignedLong(int n) { return n & 0xffffffffl; }
+
+ // Maybe byte-reverse an integer
+ private static char convEndian(boolean big, char n) { return big == BE ? n : Character.reverseBytes(n); }
+ private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; }
+ private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; }
+ private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -88,13 +88,8 @@
// Return whether this platform supports full speed int/long memory access
// at unaligned addresses.
- // This code was copied from java.nio.Bits because there is no equivalent
- // public API.
private static boolean unaligned() {
- String arch = java.security.AccessController.doPrivileged
- (new sun.security.action.GetPropertyAction("os.arch", ""));
- return arch.equals("i386") || arch.equals("x86") || arch.equals("amd64")
- || arch.equals("x86_64");
+ return unsafe.unalignedAccess();
}
/**
--- a/jdk/src/java.base/share/native/include/jvm.h Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/native/include/jvm.h Fri May 01 03:56:04 2015 -0700
@@ -395,6 +395,9 @@
JNIEXPORT jclass JNICALL
JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass);
+JNIEXPORT jstring JNICALL
+JVM_GetSimpleBinaryName(JNIEnv *env, jclass ofClass);
+
/* Generics support (JDK 1.5) */
JNIEXPORT jstring JNICALL
JVM_GetClassSignature(JNIEnv *env, jclass cls);
--- a/jdk/src/java.base/share/native/libjava/Class.c Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.base/share/native/libjava/Class.c Fri May 01 03:56:04 2015 -0700
@@ -67,6 +67,7 @@
{"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain},
{"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses},
{"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass},
+ {"getSimpleBinaryName0", "()" STR, (void *)&JVM_GetSimpleBinaryName},
{"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature},
{"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations},
{"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool},
--- a/jdk/src/java.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code 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
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-com.sun.management.internal.PlatformMBeanProviderImpl
--- a/jdk/src/java.management/share/classes/com/sun/management/DiagnosticCommandMBean.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import java.lang.management.PlatformManagedObject;
-import javax.management.DynamicMBean;
-
-/**
- * Management interface for the diagnostic commands for the HotSpot Virtual Machine.
- *
- * <p>The {@code DiagnosticCommandMBean} is registered to the
- * {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
- * platform MBeanServer} as are other platform MBeans.
- *
- * <p>The {@link javax.management.ObjectName ObjectName} for uniquely identifying
- * the diagnostic MBean within an MBeanServer is:
- * <blockquote>
- * {@code com.sun.management:type=DiagnosticCommand}
- * </blockquote>
- *
- * <p>This MBean is a {@link javax.management.DynamicMBean DynamicMBean}
- * and also a {@link javax.management.NotificationEmitter}.
- * The {@code DiagnosticCommandMBean} is generated at runtime and is subject to
- * modifications during the lifetime of the Java virtual machine.
- *
- * A <em>diagnostic command</em> is represented as an operation of
- * the {@code DiagnosticCommandMBean} interface. Each diagnostic command has:
- * <ul>
- * <li>the diagnostic command name which is the name being referenced in
- * the HotSpot Virtual Machine</li>
- * <li>the MBean operation name which is the
- * {@linkplain javax.management.MBeanOperationInfo#getName() name}
- * generated for the diagnostic command operation invocation.
- * The MBean operation name is implementation dependent</li>
- * </ul>
- *
- * The recommended way to transform a diagnostic command name into a MBean
- * operation name is as follows:
- * <ul>
- * <li>All characters from the first one to the first dot are set to be
- * lower-case characters</li>
- * <li>Every dot or underline character is removed and the following
- * character is set to be an upper-case character</li>
- * <li>All other characters are copied without modification</li>
- * </ul>
- *
- * <p>The diagnostic command name is always provided with the meta-data on the
- * operation in a field named {@code dcmd.name} (see below).
- *
- * <p>A diagnostic command may or may not support options or arguments.
- * All the operations return {@code String} and either take
- * no parameter for operations that do not support any option or argument,
- * or take a {@code String[]} parameter for operations that support at least
- * one option or argument.
- * Each option or argument must be stored in a single String.
- * Options or arguments split across several String instances are not supported.
- *
- * <p>The distinction between options and arguments: options are identified by
- * the option name while arguments are identified by their position in the
- * command line. Options and arguments are processed in the order of the array
- * passed to the invocation method.
- *
- * <p>Like any operation of a dynamic MBean, each of these operations is
- * described by {@link javax.management.MBeanOperationInfo MBeanOperationInfo}
- * instance. Here's the values returned by this object:
- * <ul>
- * <li>{@link javax.management.MBeanOperationInfo#getName() getName()}
- * returns the operation name generated from the diagnostic command name</li>
- * <li>{@link javax.management.MBeanOperationInfo#getDescription() getDescription()}
- * returns the diagnostic command description
- * (the same as the one return in the 'help' command)</li>
- * <li>{@link javax.management.MBeanOperationInfo#getImpact() getImpact()}
- * returns {@code ACTION_INFO}</li>
- * <li>{@link javax.management.MBeanOperationInfo#getReturnType() getReturnType()}
- * returns {@code java.lang.String}</li>
- * <li>{@link javax.management.MBeanOperationInfo#getDescriptor() getDescriptor()}
- * returns a Descriptor instance (see below)</li>
- * </ul>
- *
- * <p>The {@link javax.management.Descriptor Descriptor}
- * is a collection of fields containing additional
- * meta-data for a JMX element. A field is a name and an associated value.
- * The additional meta-data provided for an operation associated with a
- * diagnostic command are described in the table below:
- *
- * <table border="1" cellpadding="5">
- * <tr>
- * <th>Name</th><th>Type</th><th>Description</th>
- * </tr>
- * <tr>
- * <td>dcmd.name</td><td>String</td>
- * <td>The original diagnostic command name (not the operation name)</td>
- * </tr>
- * <tr>
- * <td>dcmd.description</td><td>String</td>
- * <td>The diagnostic command description</td>
- * </tr>
- * <tr>
- * <td>dcmd.help</td><td>String</td>
- * <td>The full help message for this diagnostic command (same output as
- * the one produced by the 'help' command)</td>
- * </tr>
- * <tr>
- * <td>dcmd.vmImpact</td><td>String</td>
- * <td>The impact of the diagnostic command,
- * this value is the same as the one printed in the 'impact'
- * section of the help message of the diagnostic command, and it
- * is different from the getImpact() of the MBeanOperationInfo</td>
- * </tr>
- * <tr>
- * <td>dcmd.enabled</td><td>boolean</td>
- * <td>True if the diagnostic command is enabled, false otherwise</td>
- * </tr>
- * <tr>
- * <td>dcmd.permissionClass</td><td>String</td>
- * <td>Some diagnostic command might require a specific permission to be
- * executed, in addition to the MBeanPermission to invoke their
- * associated MBean operation. This field returns the fully qualified
- * name of the permission class or null if no permission is required
- * </td>
- * </tr>
- * <tr>
- * <td>dcmd.permissionName</td><td>String</td>
- * <td>The fist argument of the permission required to execute this
- * diagnostic command or null if no permission is required</td>
- * </tr>
- * <tr>
- * <td>dcmd.permissionAction</td><td>String</td>
- * <td>The second argument of the permission required to execute this
- * diagnostic command or null if the permission constructor has only
- * one argument (like the ManagementPermission) or if no permission
- * is required</td>
- * </tr>
- * <tr>
- * <td>dcmd.arguments</td><td>Descriptor</td>
- * <td>A Descriptor instance containing the descriptions of options and
- * arguments supported by the diagnostic command (see below)</td>
- * </tr>
- * </table>
- *
- * <p>The description of parameters (options or arguments) of a diagnostic
- * command is provided within a Descriptor instance. In this Descriptor,
- * each field name is a parameter name, and each field value is itself
- * a Descriptor instance. The fields provided in this second Descriptor
- * instance are described in the table below:
- *
- * <table border="1" cellpadding="5">
- * <tr>
- * <th>Name</th><th>Type</th><th>Description</th>
- * </tr>
- * <tr>
- * <td>dcmd.arg.name</td><td>String</td>
- * <td>The name of the parameter</td>
- * </tr>
- * <tr>
- * <td>dcmd.arg.type</td><td>String</td>
- * <td>The type of the parameter. The returned String is the name of a type
- * recognized by the diagnostic command parser. These types are not
- * Java types and are implementation dependent.
- * </td>
- * </tr>
- * <tr>
- * <td>dcmd.arg.description</td><td>String</td>
- * <td>The parameter description</td>
- * </tr>
- * <tr>
- * <td>dcmd.arg.isMandatory</td><td>boolean</td>
- * <td>True if the parameter is mandatory, false otherwise</td>
- * </tr>
- * <tr>
- * <td>dcmd.arg.isOption</td><td>boolean</td>
- * <td>True if the parameter is an option, false if it is an argument</td>
- * </tr>
- * <tr>
- * <td>dcmd.arg.isMultiple</td><td>boolean</td>
- * <td>True if the parameter can be specified several times, false
- * otherwise</td>
- * </tr>
- * </table>
- *
- * <p>When the set of diagnostic commands currently supported by the Java
- * Virtual Machine is modified, the {@code DiagnosticCommandMBean} emits
- * a {@link javax.management.Notification} with a
- * {@linkplain javax.management.Notification#getType() type} of
- * <a href="{@docRoot}/../../../../api/javax/management/MBeanInfo.html#info-changed">
- * {@code "jmx.mbean.info.changed"}</a> and a
- * {@linkplain javax.management.Notification#getUserData() userData} that
- * is the new {@code MBeanInfo}.
- *
- * @since 1.8
- */
-public interface DiagnosticCommandMBean extends DynamicMBean
-{
-
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import javax.management.Notification;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataView;
-import javax.management.openmbean.CompositeType;
-import java.util.Collection;
-import java.util.Collections;
-import sun.management.GarbageCollectionNotifInfoCompositeData;
-
-/**
- * The information about a garbage collection
- *
- * <p>
- * A garbage collection notification is emitted by {@link GarbageCollectorMXBean}
- * when the Java virtual machine completes a garbage collection action
- * The notification emitted will contain the garbage collection notification
- * information about the status of the memory:
- * <ul>
- * <li>The name of the garbage collector used to perform the collection.</li>
- * <li>The action performed by the garbage collector.</li>
- * <li>The cause of the garbage collection action.</li>
- * <li>A {@link GcInfo} object containing some statistics about the GC cycle
- (start time, end time) and the memory usage before and after
- the GC cycle.</li>
- * </ul>
- *
- * <p>
- * A {@link CompositeData CompositeData} representing
- * the {@code GarbageCollectionNotificationInfo} object
- * is stored in the
- * {@linkplain javax.management.Notification#setUserData userdata}
- * of a {@linkplain javax.management.Notification notification}.
- * The {@link #from from} method is provided to convert from
- * a {@code CompositeData} to a {@code GarbageCollectionNotificationInfo}
- * object. For example:
- *
- * <blockquote><pre>
- * Notification notif;
- *
- * // receive the notification emitted by a GarbageCollectorMXBean and set to notif
- * ...
- *
- * String notifType = notif.getType();
- * if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
- * // retrieve the garbage collection notification information
- * CompositeData cd = (CompositeData) notif.getUserData();
- * GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
- * ....
- * }
- * </pre></blockquote>
- *
- * <p>
- * The type of the notification emitted by a {@code GarbageCollectorMXBean} is:
- * <ul>
- * <li>A {@linkplain #GARBAGE_COLLECTION_NOTIFICATION garbage collection notification}.
- * <br>Used by every notification emitted by the garbage collector, the details about
- * the notification are provided in the {@linkplain #getGcAction action} String
- * </li>
- * </ul>
- **/
-
-@jdk.Exported
-public class GarbageCollectionNotificationInfo implements CompositeDataView {
-
- private final String gcName;
- private final String gcAction;
- private final String gcCause;
- private final GcInfo gcInfo;
- private final CompositeData cdata;
-
- /**
- * Notification type denoting that
- * the Java virtual machine has completed a garbage collection cycle.
- * This notification is emitted by a {@link GarbageCollectorMXBean}.
- * The value of this notification type is
- * {@code com.sun.management.gc.notification}.
- */
- public static final String GARBAGE_COLLECTION_NOTIFICATION =
- "com.sun.management.gc.notification";
-
- /**
- * Constructs a {@code GarbageCollectionNotificationInfo} object.
- *
- * @param gcName The name of the garbage collector used to perform the collection
- * @param gcAction The name of the action performed by the garbage collector
- * @param gcCause The cause of the garbage collection action
- * @param gcInfo a GcInfo object providing statistics about the GC cycle
- */
- public GarbageCollectionNotificationInfo(String gcName,
- String gcAction,
- String gcCause,
- GcInfo gcInfo) {
- if (gcName == null) {
- throw new NullPointerException("Null gcName");
- }
- if (gcAction == null) {
- throw new NullPointerException("Null gcAction");
- }
- if (gcCause == null) {
- throw new NullPointerException("Null gcCause");
- }
- this.gcName = gcName;
- this.gcAction = gcAction;
- this.gcCause = gcCause;
- this.gcInfo = gcInfo;
- this.cdata = new GarbageCollectionNotifInfoCompositeData(this);
- }
-
- GarbageCollectionNotificationInfo(CompositeData cd) {
- GarbageCollectionNotifInfoCompositeData.validateCompositeData(cd);
-
- this.gcName = GarbageCollectionNotifInfoCompositeData.getGcName(cd);
- this.gcAction = GarbageCollectionNotifInfoCompositeData.getGcAction(cd);
- this.gcCause = GarbageCollectionNotifInfoCompositeData.getGcCause(cd);
- this.gcInfo = GarbageCollectionNotifInfoCompositeData.getGcInfo(cd);
- this.cdata = cd;
- }
-
- /**
- * Returns the name of the garbage collector used to perform the collection
- *
- * @return the name of the garbage collector used to perform the collection
- */
- public String getGcName() {
- return gcName;
- }
-
- /**
- * Returns the action performed by the garbage collector
- *
- * @return the action performed by the garbage collector
- */
- public String getGcAction() {
- return gcAction;
- }
-
- /**
- * Returns the cause of the garbage collection
- *
- * @return the cause of the garbage collection
- */
- public String getGcCause() {
- return gcCause;
- }
-
- /**
- * Returns the GC information related to the last garbage collection
- *
- * @return the GC information related to the
- * last garbage collection
- */
- public GcInfo getGcInfo() {
- return gcInfo;
- }
-
- /**
- * Returns a {@code GarbageCollectionNotificationInfo} object represented by the
- * given {@code CompositeData}.
- * The given {@code CompositeData} must contain
- * the following attributes:
- * <blockquote>
- * <table border>
- * <tr>
- * <th align=left>Attribute Name</th>
- * <th align=left>Type</th>
- * </tr>
- * <tr>
- * <td>gcName</td>
- * <td>{@code java.lang.String}</td>
- * </tr>
- * <tr>
- * <td>gcAction</td>
- * <td>{@code java.lang.String}</td>
- * </tr>
- * <tr>
- * <td>gcCause</td>
- * <td>{@code java.lang.String}</td>
- * </tr>
- * <tr>
- * <td>gcInfo</td>
- * <td>{@code javax.management.openmbean.CompositeData}</td>
- * </tr>
- * </table>
- * </blockquote>
- *
- * @param cd {@code CompositeData} representing a
- * {@code GarbageCollectionNotificationInfo}
- *
- * @throws IllegalArgumentException if {@code cd} does not
- * represent a {@code GarbaageCollectionNotificationInfo} object.
- *
- * @return a {@code GarbageCollectionNotificationInfo} object represented
- * by {@code cd} if {@code cd} is not {@code null};
- * {@code null} otherwise.
- */
- public static GarbageCollectionNotificationInfo from(CompositeData cd) {
- if (cd == null) {
- return null;
- }
-
- if (cd instanceof GarbageCollectionNotifInfoCompositeData) {
- return ((GarbageCollectionNotifInfoCompositeData) cd).getGarbageCollectionNotifInfo();
- } else {
- return new GarbageCollectionNotificationInfo(cd);
- }
- }
-
- public CompositeData toCompositeData(CompositeType ct) {
- return cdata;
- }
-
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/GarbageCollectorMXBean.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeType;
-
-/**
- * Platform-specific management interface for a garbage collector
- * which performs collections in cycles.
- *
- * <p> This platform extension is only available to the garbage
- * collection implementation that supports this extension.
- *
- * @author Mandy Chung
- * @since 1.5
- */
-@jdk.Exported
-public interface GarbageCollectorMXBean
- extends java.lang.management.GarbageCollectorMXBean {
-
- /**
- * Returns the GC information about the most recent GC.
- * This method returns a {@link GcInfo}.
- * If no GC information is available, <tt>null</tt> is returned.
- * The collector-specific attributes, if any, can be obtained
- * via the {@link CompositeData CompositeData} interface.
- * <p>
- * <b>MBeanServer access:</b>
- * The mapped type of <tt>GcInfo</tt> is <tt>CompositeData</tt>
- * with attributes specified in {@link GcInfo#from GcInfo}.
- *
- * @return a <tt>GcInfo</tt> object representing
- * the most GC information; or <tt>null</tt> if no GC
- * information available.
- */
- public GcInfo getLastGcInfo();
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/GcInfo.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import java.lang.management.MemoryUsage;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataView;
-import javax.management.openmbean.CompositeType;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.List;
-import sun.management.GcInfoCompositeData;
-import sun.management.GcInfoBuilder;
-
-/**
- * Garbage collection information. It contains the following
- * information for one garbage collection as well as GC-specific
- * attributes:
- * <blockquote>
- * <ul>
- * <li>Start time</li>
- * <li>End time</li>
- * <li>Duration</li>
- * <li>Memory usage before the collection starts</li>
- * <li>Memory usage after the collection ends</li>
- * </ul>
- * </blockquote>
- *
- * <p>
- * {@code GcInfo} is a {@link CompositeData CompositeData}
- * The GC-specific attributes can be obtained via the CompositeData
- * interface. This is a historical relic, and other classes should
- * not copy this pattern. Use {@link CompositeDataView} instead.
- *
- * <h4>MXBean Mapping</h4>
- * {@code GcInfo} is mapped to a {@link CompositeData CompositeData}
- * with attributes as specified in the {@link #from from} method.
- *
- * @author Mandy Chung
- * @since 1.5
- */
-@jdk.Exported
-public class GcInfo implements CompositeData, CompositeDataView {
- private final long index;
- private final long startTime;
- private final long endTime;
- private final Map<String, MemoryUsage> usageBeforeGc;
- private final Map<String, MemoryUsage> usageAfterGc;
- private final Object[] extAttributes;
- private final CompositeData cdata;
- private final GcInfoBuilder builder;
-
- private GcInfo(GcInfoBuilder builder,
- long index, long startTime, long endTime,
- MemoryUsage[] muBeforeGc,
- MemoryUsage[] muAfterGc,
- Object[] extAttributes) {
- this.builder = builder;
- this.index = index;
- this.startTime = startTime;
- this.endTime = endTime;
- String[] poolNames = builder.getPoolNames();
- this.usageBeforeGc = new HashMap<String, MemoryUsage>(poolNames.length);
- this.usageAfterGc = new HashMap<String, MemoryUsage>(poolNames.length);
- for (int i = 0; i < poolNames.length; i++) {
- this.usageBeforeGc.put(poolNames[i], muBeforeGc[i]);
- this.usageAfterGc.put(poolNames[i], muAfterGc[i]);
- }
- this.extAttributes = extAttributes;
- this.cdata = new GcInfoCompositeData(this, builder, extAttributes);
- }
-
- private GcInfo(CompositeData cd) {
- GcInfoCompositeData.validateCompositeData(cd);
-
- this.index = GcInfoCompositeData.getId(cd);
- this.startTime = GcInfoCompositeData.getStartTime(cd);
- this.endTime = GcInfoCompositeData.getEndTime(cd);
- this.usageBeforeGc = GcInfoCompositeData.getMemoryUsageBeforeGc(cd);
- this.usageAfterGc = GcInfoCompositeData.getMemoryUsageAfterGc(cd);
- this.extAttributes = null;
- this.builder = null;
- this.cdata = cd;
- }
-
- /**
- * Returns the identifier of this garbage collection which is
- * the number of collections that this collector has done.
- *
- * @return the identifier of this garbage collection which is
- * the number of collections that this collector has done.
- */
- public long getId() {
- return index;
- }
-
- /**
- * Returns the start time of this GC in milliseconds
- * since the Java virtual machine was started.
- *
- * @return the start time of this GC.
- */
- public long getStartTime() {
- return startTime;
- }
-
- /**
- * Returns the end time of this GC in milliseconds
- * since the Java virtual machine was started.
- *
- * @return the end time of this GC.
- */
- public long getEndTime() {
- return endTime;
- }
-
- /**
- * Returns the elapsed time of this GC in milliseconds.
- *
- * @return the elapsed time of this GC in milliseconds.
- */
- public long getDuration() {
- return endTime - startTime;
- }
-
- /**
- * Returns the memory usage of all memory pools
- * at the beginning of this GC.
- * This method returns
- * a {@code Map} of the name of a memory pool
- * to the memory usage of the corresponding
- * memory pool before GC starts.
- *
- * @return a {@code Map} of memory pool names to the memory
- * usage of a memory pool before GC starts.
- */
- public Map<String, MemoryUsage> getMemoryUsageBeforeGc() {
- return Collections.unmodifiableMap(usageBeforeGc);
- }
-
- /**
- * Returns the memory usage of all memory pools
- * at the end of this GC.
- * This method returns
- * a {@code Map} of the name of a memory pool
- * to the memory usage of the corresponding
- * memory pool when GC finishes.
- *
- * @return a {@code Map} of memory pool names to the memory
- * usage of a memory pool when GC finishes.
- */
- public Map<String, MemoryUsage> getMemoryUsageAfterGc() {
- return Collections.unmodifiableMap(usageAfterGc);
- }
-
- /**
- * Returns a {@code GcInfo} object represented by the
- * given {@code CompositeData}. The given
- * {@code CompositeData} must contain
- * all the following attributes:
- *
- * <blockquote>
- * <table border>
- * <tr>
- * <th align=left>Attribute Name</th>
- * <th align=left>Type</th>
- * </tr>
- * <tr>
- * <td>index</td>
- * <td>{@code java.lang.Long}</td>
- * </tr>
- * <tr>
- * <td>startTime</td>
- * <td>{@code java.lang.Long}</td>
- * </tr>
- * <tr>
- * <td>endTime</td>
- * <td>{@code java.lang.Long}</td>
- * </tr>
- * <tr>
- * <td>memoryUsageBeforeGc</td>
- * <td>{@code javax.management.openmbean.TabularData}</td>
- * </tr>
- * <tr>
- * <td>memoryUsageAfterGc</td>
- * <td>{@code javax.management.openmbean.TabularData}</td>
- * </tr>
- * </table>
- * </blockquote>
- *
- * @throws IllegalArgumentException if {@code cd} does not
- * represent a {@code GcInfo} object with the attributes
- * described above.
- *
- * @return a {@code GcInfo} object represented by {@code cd}
- * if {@code cd} is not {@code null}; {@code null} otherwise.
- */
- public static GcInfo from(CompositeData cd) {
- if (cd == null) {
- return null;
- }
-
- if (cd instanceof GcInfoCompositeData) {
- return ((GcInfoCompositeData) cd).getGcInfo();
- } else {
- return new GcInfo(cd);
- }
-
- }
-
- // Implementation of the CompositeData interface
- public boolean containsKey(String key) {
- return cdata.containsKey(key);
- }
-
- public boolean containsValue(Object value) {
- return cdata.containsValue(value);
- }
-
- public boolean equals(Object obj) {
- return cdata.equals(obj);
- }
-
- public Object get(String key) {
- return cdata.get(key);
- }
-
- public Object[] getAll(String[] keys) {
- return cdata.getAll(keys);
- }
-
- public CompositeType getCompositeType() {
- return cdata.getCompositeType();
- }
-
- public int hashCode() {
- return cdata.hashCode();
- }
-
- public String toString() {
- return cdata.toString();
- }
-
- public Collection<?> values() {
- return cdata.values();
- }
-
- /**
- * Return the {@code CompositeData} representation of this
- * {@code GcInfo}, including any GC-specific attributes. The
- * returned value will have at least all the attributes described
- * in the {@link #from(CompositeData) from} method, plus optionally
- * other attributes.
- *
- * @param ct the {@code CompositeType} that the caller expects.
- * This parameter is ignored and can be null.
- *
- * @return the {@code CompositeData} representation.
- */
- public CompositeData toCompositeData(CompositeType ct) {
- return cdata;
- }
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import java.lang.management.PlatformManagedObject;
-
-/**
- * Diagnostic management interface for the HotSpot Virtual Machine.
- *
- * <p>The diagnostic MBean is registered to the platform MBeanServer
- * as are other platform MBeans.
- *
- * <p>The <tt>ObjectName</tt> for uniquely identifying the diagnostic
- * MXBean within an MBeanServer is:
- * <blockquote>
- * <tt>com.sun.management:type=HotSpotDiagnostic</tt>
- * </blockquote>
-.*
- * It can be obtained by calling the
- * {@link PlatformManagedObject#getObjectName} method.
- *
- * All methods throw a {@code NullPointerException} if any input argument is
- * {@code null} unless it's stated otherwise.
- *
- * @see java.lang.management.ManagementFactory#getPlatformMXBeans(Class)
- */
-@jdk.Exported
-public interface HotSpotDiagnosticMXBean extends PlatformManagedObject {
- /**
- * Dumps the heap to the <tt>outputFile</tt> file in the same
- * format as the hprof heap dump.
- * <p>
- * If this method is called remotely from another process,
- * the heap dump output is written to a file named <tt>outputFile</tt>
- * on the machine where the target VM is running. If outputFile is
- * a relative path, it is relative to the working directory where
- * the target VM was started.
- *
- * @param outputFile the system-dependent filename
- * @param live if <tt>true</tt> dump only <i>live</i> objects
- * i.e. objects that are reachable from others
- * @throws IOException if the <tt>outputFile</tt>
- * cannot be created, opened, or written to.
- * @throws UnsupportedOperationException if this operation is not supported.
- * @throws NullPointerException if <tt>outputFile</tt> is <tt>null</tt>.
- * @throws SecurityException
- * If a security manager exists and its {@link
- * java.lang.SecurityManager#checkWrite(java.lang.String)}
- * method denies write access to the named file
- * or the caller does not have ManagmentPermission("control").
- */
- public void dumpHeap(String outputFile, boolean live) throws java.io.IOException;
-
- /**
- * Returns a list of <tt>VMOption</tt> objects for all diagnostic options.
- * A diagnostic option is a {@link VMOption#isWriteable writeable}
- * VM option that can be set dynamically mainly for troubleshooting
- * and diagnosis.
- *
- * @return a list of <tt>VMOption</tt> objects for all diagnostic options.
- */
- public java.util.List<VMOption> getDiagnosticOptions();
-
- /**
- * Returns a <tt>VMOption</tt> object for a VM option of the given
- * name.
- *
- * @return a <tt>VMOption</tt> object for a VM option of the given name.
- * @throws NullPointerException if name is <tt>null</tt>.
- * @throws IllegalArgumentException if a VM option of the given name
- * does not exist.
- */
- public VMOption getVMOption(String name);
-
- /**
- * Sets a VM option of the given name to the specified value.
- * The new value will be reflected in a new <tt>VMOption</tt>
- * object returned by the {@link #getVMOption} method or
- * the {@link #getDiagnosticOptions} method. This method does
- * not change the value of this <tt>VMOption</tt> object.
- *
- * @param name Name of a VM option
- * @param value New value of the VM option to be set
- *
- * @throws IllegalArgumentException if the VM option of the given name
- * does not exist.
- * @throws IllegalArgumentException if the new value is invalid.
- * @throws IllegalArgumentException if the VM option is not writable.
- * @throws NullPointerException if name or value is <tt>null</tt>.
- *
- * @throws java.lang.SecurityException
- * if a security manager exists and the caller does not have
- * ManagementPermission("control").
- */
- public void setVMOption(String name, String value);
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/OperatingSystemMXBean.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-/**
- * Platform-specific management interface for the operating system
- * on which the Java virtual machine is running.
- *
- * <p>
- * The <tt>OperatingSystemMXBean</tt> object returned by
- * {@link java.lang.management.ManagementFactory#getOperatingSystemMXBean()}
- * is an instance of the implementation class of this interface
- * or {@link UnixOperatingSystemMXBean} interface depending on
- * its underlying operating system.
- *
- * @author Mandy Chung
- * @since 1.5
- */
-@jdk.Exported
-public interface OperatingSystemMXBean extends
- java.lang.management.OperatingSystemMXBean {
-
- /**
- * Returns the amount of virtual memory that is guaranteed to
- * be available to the running process in bytes,
- * or <tt>-1</tt> if this operation is not supported.
- *
- * @return the amount of virtual memory that is guaranteed to
- * be available to the running process in bytes,
- * or <tt>-1</tt> if this operation is not supported.
- */
- public long getCommittedVirtualMemorySize();
-
- /**
- * Returns the total amount of swap space in bytes.
- *
- * @return the total amount of swap space in bytes.
- */
- public long getTotalSwapSpaceSize();
-
- /**
- * Returns the amount of free swap space in bytes.
- *
- * @return the amount of free swap space in bytes.
- */
- public long getFreeSwapSpaceSize();
-
- /**
- * Returns the CPU time used by the process on which the Java
- * virtual machine is running in nanoseconds. The returned value
- * is of nanoseconds precision but not necessarily nanoseconds
- * accuracy. This method returns <tt>-1</tt> if the
- * the platform does not support this operation.
- *
- * @return the CPU time used by the process in nanoseconds,
- * or <tt>-1</tt> if this operation is not supported.
- */
- public long getProcessCpuTime();
-
- /**
- * Returns the amount of free physical memory in bytes.
- *
- * @return the amount of free physical memory in bytes.
- */
- public long getFreePhysicalMemorySize();
-
- /**
- * Returns the total amount of physical memory in bytes.
- *
- * @return the total amount of physical memory in bytes.
- */
- public long getTotalPhysicalMemorySize();
-
- /**
- * Returns the "recent cpu usage" for the whole system. This value is a
- * double in the [0.0,1.0] interval. A value of 0.0 means that all CPUs
- * were idle during the recent period of time observed, while a value
- * of 1.0 means that all CPUs were actively running 100% of the time
- * during the recent period being observed. All values betweens 0.0 and
- * 1.0 are possible depending of the activities going on in the system.
- * If the system recent cpu usage is not available, the method returns a
- * negative value.
- *
- * @return the "recent cpu usage" for the whole system; a negative
- * value if not available.
- * @since 1.7
- */
- public double getSystemCpuLoad();
-
- /**
- * Returns the "recent cpu usage" for the Java Virtual Machine process.
- * This value is a double in the [0.0,1.0] interval. A value of 0.0 means
- * that none of the CPUs were running threads from the JVM process during
- * the recent period of time observed, while a value of 1.0 means that all
- * CPUs were actively running threads from the JVM 100% of the time
- * during the recent period being observed. Threads from the JVM include
- * the application threads as well as the JVM internal threads. All values
- * betweens 0.0 and 1.0 are possible depending of the activities going on
- * in the JVM process and the whole system. If the Java Virtual Machine
- * recent CPU usage is not available, the method returns a negative value.
- *
- * @return the "recent cpu usage" for the Java Virtual Machine process;
- * a negative value if not available.
- * @since 1.7
- */
- public double getProcessCpuLoad();
-
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/ThreadMXBean.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import java.util.Map;
-
-/**
- * Platform-specific management interface for the thread system
- * of the Java virtual machine.
- * <p>
- * This platform extension is only available to a thread
- * implementation that supports this extension.
- *
- * @author Paul Hohensee
- * @since 6u25
- */
-
-@jdk.Exported
-public interface ThreadMXBean extends java.lang.management.ThreadMXBean {
- /**
- * Returns the total CPU time for each thread whose ID is
- * in the input array {@code ids} in nanoseconds.
- * The returned values are of nanoseconds precision but
- * not necessarily nanoseconds accuracy.
- * <p>
- * This method is equivalent to calling the
- * {@link ThreadMXBean#getThreadCpuTime(long)}
- * method for each thread ID in the input array {@code ids} and setting the
- * returned value in the corresponding element of the returned array.
- *
- * @param ids an array of thread IDs.
- * @return an array of long values, each of which is the amount of CPU
- * time the thread whose ID is in the corresponding element of the input
- * array of IDs has used,
- * if the thread of a specified ID exists, the thread is alive,
- * and CPU time measurement is enabled;
- * {@code -1} otherwise.
- *
- * @throws NullPointerException if {@code ids} is {@code null}
- * @throws IllegalArgumentException if any element in the input array
- * {@code ids} is {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java
- * virtual machine implementation does not support CPU time
- * measurement.
- *
- * @see ThreadMXBean#getThreadCpuTime(long)
- * @see #getThreadUserTime
- * @see ThreadMXBean#isThreadCpuTimeSupported
- * @see ThreadMXBean#isThreadCpuTimeEnabled
- * @see ThreadMXBean#setThreadCpuTimeEnabled
- */
- public long[] getThreadCpuTime(long[] ids);
-
- /**
- * Returns the CPU time that each thread whose ID is in the input array
- * {@code ids} has executed in user mode in nanoseconds.
- * The returned values are of nanoseconds precision but
- * not necessarily nanoseconds accuracy.
- * <p>
- * This method is equivalent to calling the
- * {@link ThreadMXBean#getThreadUserTime(long)}
- * method for each thread ID in the input array {@code ids} and setting the
- * returned value in the corresponding element of the returned array.
- *
- * @param ids an array of thread IDs.
- * @return an array of long values, each of which is the amount of user
- * mode CPU time the thread whose ID is in the corresponding element of
- * the input array of IDs has used,
- * if the thread of a specified ID exists, the thread is alive,
- * and CPU time measurement is enabled;
- * {@code -1} otherwise.
- *
- * @throws NullPointerException if {@code ids} is {@code null}
- * @throws IllegalArgumentException if any element in the input array
- * {@code ids} is {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java
- * virtual machine implementation does not support CPU time
- * measurement.
- *
- * @see ThreadMXBean#getThreadUserTime(long)
- * @see #getThreadCpuTime
- * @see ThreadMXBean#isThreadCpuTimeSupported
- * @see ThreadMXBean#isThreadCpuTimeEnabled
- * @see ThreadMXBean#setThreadCpuTimeEnabled
- */
- public long[] getThreadUserTime(long[] ids);
-
- /**
- * Returns an approximation of the total amount of memory, in bytes,
- * allocated in heap memory for the thread of the specified ID.
- * The returned value is an approximation because some Java virtual machine
- * implementations may use object allocation mechanisms that result in a
- * delay between the time an object is allocated and the time its size is
- * recorded.
- * <p>
- * If the thread of the specified ID is not alive or does not exist,
- * this method returns {@code -1}. If thread memory allocation measurement
- * is disabled, this method returns {@code -1}.
- * A thread is alive if it has been started and has not yet died.
- * <p>
- * If thread memory allocation measurement is enabled after the thread has
- * started, the Java virtual machine implementation may choose any time up
- * to and including the time that the capability is enabled as the point
- * where thread memory allocation measurement starts.
- *
- * @param id the thread ID of a thread
- * @return an approximation of the total memory allocated, in bytes, in
- * heap memory for a thread of the specified ID
- * if the thread of the specified ID exists, the thread is alive,
- * and thread memory allocation measurement is enabled;
- * {@code -1} otherwise.
- *
- * @throws IllegalArgumentException if {@code id} {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java virtual
- * machine implementation does not support thread memory allocation
- * measurement.
- *
- * @see #isThreadAllocatedMemorySupported
- * @see #isThreadAllocatedMemoryEnabled
- * @see #setThreadAllocatedMemoryEnabled
- */
- public long getThreadAllocatedBytes(long id);
-
- /**
- * Returns an approximation of the total amount of memory, in bytes,
- * allocated in heap memory for each thread whose ID is in the input
- * array {@code ids}.
- * The returned values are approximations because some Java virtual machine
- * implementations may use object allocation mechanisms that result in a
- * delay between the time an object is allocated and the time its size is
- * recorded.
- * <p>
- * This method is equivalent to calling the
- * {@link #getThreadAllocatedBytes(long)}
- * method for each thread ID in the input array {@code ids} and setting the
- * returned value in the corresponding element of the returned array.
- *
- * @param ids an array of thread IDs.
- * @return an array of long values, each of which is an approximation of
- * the total memory allocated, in bytes, in heap memory for the thread
- * whose ID is in the corresponding element of the input array of IDs.
- *
- * @throws NullPointerException if {@code ids} is {@code null}
- * @throws IllegalArgumentException if any element in the input array
- * {@code ids} is {@code <=} {@code 0}.
- * @throws java.lang.UnsupportedOperationException if the Java virtual
- * machine implementation does not support thread memory allocation
- * measurement.
- *
- * @see #getThreadAllocatedBytes(long)
- * @see #isThreadAllocatedMemorySupported
- * @see #isThreadAllocatedMemoryEnabled
- * @see #setThreadAllocatedMemoryEnabled
- */
- public long[] getThreadAllocatedBytes(long[] ids);
-
- /**
- * Tests if the Java virtual machine implementation supports thread memory
- * allocation measurement.
- *
- * @return
- * {@code true}
- * if the Java virtual machine implementation supports thread memory
- * allocation measurement;
- * {@code false} otherwise.
- */
- public boolean isThreadAllocatedMemorySupported();
-
- /**
- * Tests if thread memory allocation measurement is enabled.
- *
- * @return {@code true} if thread memory allocation measurement is enabled;
- * {@code false} otherwise.
- *
- * @throws java.lang.UnsupportedOperationException if the Java virtual
- * machine does not support thread memory allocation measurement.
- *
- * @see #isThreadAllocatedMemorySupported
- */
- public boolean isThreadAllocatedMemoryEnabled();
-
- /**
- * Enables or disables thread memory allocation measurement. The default
- * is platform dependent.
- *
- * @param enable {@code true} to enable;
- * {@code false} to disable.
- *
- * @throws java.lang.UnsupportedOperationException if the Java virtual
- * machine does not support thread memory allocation measurement.
- *
- * @throws java.lang.SecurityException if a security manager
- * exists and the caller does not have
- * ManagementPermission("control").
- *
- * @see #isThreadAllocatedMemorySupported
- */
- public void setThreadAllocatedMemoryEnabled(boolean enable);
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/UnixOperatingSystemMXBean.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-/**
- * Platform-specific management interface for the Unix
- * operating system on which the Java virtual machine is running.
- *
- * @author Mandy Chung
- * @since 1.5
- */
-@jdk.Exported
-public interface UnixOperatingSystemMXBean extends
- com.sun.management.OperatingSystemMXBean {
-
- /**
- * Returns the number of open file descriptors.
- *
- * @return the number of open file descriptors.
- */
- public long getOpenFileDescriptorCount();
-
- /**
- * Returns the maximum number of file descriptors.
- *
- * @return the maximum number of file descriptors.
- */
- public long getMaxFileDescriptorCount();
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/VMOption.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.management;
-
-import sun.management.VMOptionCompositeData;
-import javax.management.openmbean.CompositeData;
-
-/**
- * Information about a VM option including its value and
- * where the value came from which is referred as its
- * {@link VMOption.Origin <i>origin</i>}.
- * <p>
- * Each VM option has a default value. A VM option can
- * be set at VM creation time typically as a command line
- * argument to the launcher or an argument passed to the
- * VM created using the JNI invocation interface.
- * In addition, a VM option may be set via an environment
- * variable or a configuration file. A VM option can also
- * be set dynamically via a management interface after
- * the VM was started.
- *
- * A {@code VMOption} contains the value of a VM option
- * and the origin of that value at the time this {@code VMOption}
- * object was constructed. The value of the VM option
- * may be changed after the {@code VMOption} object was constructed,
- *
- * @see <a href="{@docRoot}/../../../../technotes/guides/vm/index.html">
- * Java Virtual Machine</a>
- * @author Mandy Chung
- * @since 1.6
- */
-@jdk.Exported
-public class VMOption {
- private String name;
- private String value;
- private boolean writeable;
- private Origin origin;
-
- /**
- * Origin of the value of a VM option. It tells where the
- * value of a VM option came from.
- *
- * @since 1.6
- */
- @jdk.Exported
- public enum Origin {
- /**
- * The VM option has not been set and its value
- * is the default value.
- */
- DEFAULT,
- /**
- * The VM option was set at VM creation time typically
- * as a command line argument to the launcher or
- * an argument passed to the VM created using the
- * JNI invocation interface.
- */
- VM_CREATION,
- /**
- * The VM option was set via an environment variable.
- */
- ENVIRON_VAR,
- /**
- * The VM option was set via a configuration file.
- */
- CONFIG_FILE,
- /**
- * The VM option was set via the management interface after the VM
- * was started.
- */
- MANAGEMENT,
- /**
- * The VM option was set via the VM ergonomic support.
- */
- ERGONOMIC,
- /**
- * The VM option was set using the attach framework.
- * @since 1.9
- */
- ATTACH_ON_DEMAND,
- /**
- * The VM option was set via some other mechanism.
- */
- OTHER
- }
-
- /**
- * Constructs a {@code VMOption}.
- *
- * @param name Name of a VM option.
- * @param value Value of a VM option.
- * @param writeable {@code true} if a VM option can be set dynamically,
- * or {@code false} otherwise.
- * @param origin where the value of a VM option came from.
- *
- * @throws NullPointerException if the name or value is {@code null}
- */
- public VMOption(String name, String value, boolean writeable, Origin origin) {
- this.name = name;
- this.value = value;
- this.writeable = writeable;
- this.origin = origin;
- }
-
- /**
- * Constructs a {@code VMOption} object from a
- * {@link CompositeData CompositeData}.
- */
- private VMOption(CompositeData cd) {
- // validate the input composite data
- VMOptionCompositeData.validateCompositeData(cd);
-
- this.name = VMOptionCompositeData.getName(cd);
- this.value = VMOptionCompositeData.getValue(cd);
- this.writeable = VMOptionCompositeData.isWriteable(cd);
- this.origin = VMOptionCompositeData.getOrigin(cd);
- }
-
- /**
- * Returns the name of this VM option.
- *
- * @return the name of this VM option.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Returns the value of this VM option at the time when
- * this {@code VMOption} was created. The value could have been changed.
- *
- * @return the value of the VM option at the time when
- * this {@code VMOption} was created.
- */
- public String getValue() {
- return value;
- }
-
- /**
- * Returns the origin of the value of this VM option. That is,
- * where the value of this VM option came from.
- *
- * @return where the value of this VM option came from.
- */
- public Origin getOrigin() {
- return origin;
- }
-
- /**
- * Tests if this VM option is writeable. If this VM option is writeable,
- * it can be set by the {@link HotSpotDiagnosticMXBean#setVMOption
- * HotSpotDiagnosticMXBean.setVMOption} method.
- *
- * @return {@code true} if this VM option is writeable; {@code false}
- * otherwise.
- */
- public boolean isWriteable() {
- return writeable;
- }
-
- public String toString() {
- return "VM option: " + getName() +
- " value: " + value + " " +
- " origin: " + origin + " " +
- (writeable ? "(read-write)" : "(read-only)");
- }
-
- /**
- * Returns a {@code VMOption} object represented by the
- * given {@code CompositeData}. The given {@code CompositeData}
- * must contain the following attributes:
- *
- * <blockquote>
- * <table border>
- * <tr>
- * <th align=left>Attribute Name</th>
- * <th align=left>Type</th>
- * </tr>
- * <tr>
- * <td>name</td>
- * <td>{@code java.lang.String}</td>
- * </tr>
- * <tr>
- * <td>value</td>
- * <td>{@code java.lang.String}</td>
- * </tr>
- * <tr>
- * <td>origin</td>
- * <td>{@code java.lang.String}</td>
- * </tr>
- * <tr>
- * <td>writeable</td>
- * <td>{@code java.lang.Boolean}</td>
- * </tr>
- * </table>
- * </blockquote>
- *
- * @param cd {@code CompositeData} representing a {@code VMOption}
- *
- * @throws IllegalArgumentException if {@code cd} does not
- * represent a {@code VMOption} with the attributes described
- * above.
- *
- * @return a {@code VMOption} object represented by {@code cd}
- * if {@code cd} is not {@code null};
- * {@code null} otherwise.
- */
- public static VMOption from(CompositeData cd) {
- if (cd == null) {
- return null;
- }
-
- if (cd instanceof VMOptionCompositeData) {
- return ((VMOptionCompositeData) cd).getVMOption();
- } else {
- return new VMOption(cd);
- }
-
- }
-
-
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.management.internal;
-
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import javax.management.DynamicMBean;
-import javax.management.ObjectName;
-import sun.management.ManagementFactoryHelper;
-import sun.management.spi.PlatformMBeanProvider;
-
-public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider {
- private final List<PlatformComponent<?>> mxbeanList;
-
- public PlatformMBeanProviderImpl() {
- mxbeanList = Collections.unmodifiableList(init());
- }
-
- @Override
- public List<PlatformComponent<?>> getPlatformComponentList() {
- return mxbeanList;
- }
-
- private List<PlatformComponent<?>> init() {
- ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>();
- /**
- * Garbage Collector in the Java virtual machine.
- */
- initMBeanList.add(new PlatformComponent<java.lang.management.MemoryManagerMXBean>() {
- private final Set<String> garbageCollectorMXBeanInterfaceNames
- = Collections.unmodifiableSet(
- Stream.of("java.lang.management.MemoryManagerMXBean",
- "java.lang.management.GarbageCollectorMXBean",
- "com.sun.management.GarbageCollectorMXBean")
- .collect(Collectors.toSet()));
-
- @Override
- public Set<Class<? extends java.lang.management.MemoryManagerMXBean>> mbeanInterfaces() {
- return Stream.of(java.lang.management.MemoryManagerMXBean.class,
- java.lang.management.GarbageCollectorMXBean.class,
- com.sun.management.GarbageCollectorMXBean.class)
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<String> mbeanInterfaceNames() {
- return garbageCollectorMXBeanInterfaceNames;
- }
-
- @Override
- public String getObjectNamePattern() {
- return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*";
- }
-
- @Override
- public boolean isSingleton() {
- return false; // zero or more instances
- }
-
- @Override
- public Map<String, java.lang.management.MemoryManagerMXBean> nameToMBeanMap() {
- List<java.lang.management.GarbageCollectorMXBean> list
- = ManagementFactoryHelper.getGarbageCollectorMXBeans();;
- Map<String, java.lang.management.MemoryManagerMXBean> map;
- if (list.isEmpty()) {
- map = Collections.<String, java.lang.management.MemoryManagerMXBean>emptyMap();
- } else {
- map = new HashMap<>(list.size());
- for (java.lang.management.MemoryManagerMXBean gcm : list) {
- map.put(gcm.getObjectName().getCanonicalName(),
- gcm);
- }
- }
- return map;
- }
- });
-
- /**
- * OperatingSystemMXBean
- */
- initMBeanList.add(new PlatformComponent<java.lang.management.OperatingSystemMXBean>() {
- private final Set<String> operatingSystemMXBeanInterfaceNames
- = Collections.unmodifiableSet(
- Stream.of("java.lang.management.OperatingSystemMXBean",
- "com.sun.management.OperatingSystemMXBean",
- "com.sun.management.UnixOperatingSystemMXBean")
- .collect(Collectors.toSet()));
-
- @Override
- public Set<Class<? extends java.lang.management.OperatingSystemMXBean>> mbeanInterfaces() {
- return Stream.of(java.lang.management.OperatingSystemMXBean.class,
- com.sun.management.OperatingSystemMXBean.class,
- com.sun.management.UnixOperatingSystemMXBean.class)
- .collect(Collectors.toSet());
- }
-
- @Override
- public Set<String> mbeanInterfaceNames() {
- return operatingSystemMXBeanInterfaceNames;
- }
-
- @Override
- public String getObjectNamePattern() {
- return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
- }
-
- @Override
- public Map<String, java.lang.management.OperatingSystemMXBean> nameToMBeanMap() {
- return Collections.<String, java.lang.management.OperatingSystemMXBean>singletonMap(
- ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
- ManagementFactoryHelper.getOperatingSystemMXBean());
- }
- });
-
- /**
- * Diagnostic support for the HotSpot Virtual Machine.
- */
- initMBeanList.add(new PlatformComponent<com.sun.management.HotSpotDiagnosticMXBean>() {
- private final Set<String> hotSpotDiagnosticMXBeanInterfaceNames =
- Collections.unmodifiableSet(Collections.<String>singleton("com.sun.management.HotSpotDiagnosticMXBean"));
-
- @Override
- public Set<Class<? extends com.sun.management.HotSpotDiagnosticMXBean>> mbeanInterfaces() {
- return Collections.singleton(com.sun.management.HotSpotDiagnosticMXBean.class);
- }
-
- @Override
- public Set<String> mbeanInterfaceNames() {
- return hotSpotDiagnosticMXBeanInterfaceNames;
- }
-
- @Override
- public String getObjectNamePattern() {
- return "com.sun.management:type=HotSpotDiagnostic";
- }
-
- @Override
- public Map<String, com.sun.management.HotSpotDiagnosticMXBean> nameToMBeanMap() {
- return Collections.<String, com.sun.management.HotSpotDiagnosticMXBean>singletonMap(
- "com.sun.management:type=HotSpotDiagnostic",
- ManagementFactoryHelper.getDiagnosticMXBean());
- }
- });
-
- /**
- * DynamicMBean
- */
- HashMap<ObjectName, DynamicMBean> dynmbeans
- = ManagementFactoryHelper.getPlatformDynamicMBeans();
- final Set<String> dynamicMBeanInterfaceNames =
- Collections.unmodifiableSet(Collections.<String>singleton("javax.management.DynamicMBean"));
- for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
- initMBeanList.add(new PlatformComponent<DynamicMBean>() {
- @Override
- public Set<String> mbeanInterfaceNames() {
- return dynamicMBeanInterfaceNames;
- }
-
- @Override
- public Set<Class<? extends DynamicMBean>> mbeanInterfaces() {
- return Collections.emptySet(); // DynamicMBean cannot be used to find an MBean by ManagementFactory
- }
-
- @Override
- public String getObjectNamePattern() {
- return e.getKey().getCanonicalName();
- }
-
- @Override
- public Map<String, DynamicMBean> nameToMBeanMap() {
- return Collections.<String, DynamicMBean>singletonMap(
- e.getKey().getCanonicalName(),
- e.getValue());
- }
- });
- }
- initMBeanList.trimToSize();
- return initMBeanList;
- }
-}
--- a/jdk/src/java.management/share/classes/com/sun/management/package-info.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * This package contains Oracle Corporation's platform extension to
- * the implementation of the
- * <a href="{@docRoot}/../../../../api/java/lang/management/package-summary.html">
- * java.lang.management</a> API and also defines the management
- * interface for some other components for the platform.
- *
- * <p>
- * All platform MBeans are registered in the <em>platform MBeanServer</em>
- * which can be obtained via the
- * <a href="{@docRoot}/../../../../api/java/lang/management/ManagementFactory.html#getPlatformMBeanServer()">
- * java.lang.management.ManagementFactory.getPlatformMBeanServer</a>
- *
- * @author Mandy Chung
- * @since 1.5
- */
-
-@jdk.Exported
-package com.sun.management;
--- a/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java Fri May 01 03:56:04 2015 -0700
@@ -33,7 +33,6 @@
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.management.DynamicMBean;
import javax.management.ObjectName;
import sun.management.ManagementFactoryHelper;
import sun.management.spi.PlatformMBeanProvider;
@@ -162,8 +161,7 @@
@Override
public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
return Stream.of(MemoryManagerMXBean.class,
- GarbageCollectorMXBean.class,
- com.sun.management.GarbageCollectorMXBean.class).collect(Collectors.toSet());
+ GarbageCollectorMXBean.class).collect(Collectors.toSet());
}
@Override
@@ -464,39 +462,6 @@
});
- /**
- * DynamicMBean
- */
- HashMap<ObjectName, DynamicMBean> dynmbeans
- = ManagementFactoryHelper.getPlatformDynamicMBeans();
- final Set<String> dynamicMBeanInterfaceNames =
- Collections.unmodifiableSet(Collections.singleton("javax.management.DynamicMBean"));
- for (Map.Entry<ObjectName, DynamicMBean> e : dynmbeans.entrySet()) {
- initMBeanList.add(new PlatformComponent<DynamicMBean>() {
- @Override
- public Set<Class<? extends DynamicMBean>> mbeanInterfaces() {
- return Collections.emptySet();
- }
-
- @Override
- public Set<String> mbeanInterfaceNames() {
- return dynamicMBeanInterfaceNames;
- }
-
- @Override
- public String getObjectNamePattern() {
- return e.getKey().getCanonicalName();
- }
-
- @Override
- public Map<String, DynamicMBean> nameToMBeanMap() {
- return Collections.<String, DynamicMBean>singletonMap(
- e.getKey().getCanonicalName(),
- e.getValue());
- }
- });
- }
-
initMBeanList.trimToSize();
return initMBeanList;
}
--- a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java Fri May 01 03:56:04 2015 -0700
@@ -582,7 +582,7 @@
final Class<?> cls = mxbeanInterface;
ClassLoader loader =
AccessController.doPrivileged(
- (PrivilegedAction<ClassLoader>) () -> cls.getClassLoader());
+ (PrivilegedAction<ClassLoader>) () -> cls.getClassLoader());
if (!sun.misc.VM.isSystemDomainLoader(loader)) {
throw new IllegalArgumentException(mxbeanName +
" is not a platform MXBean");
@@ -883,7 +883,7 @@
all.add(new DefaultPlatformMBeanProvider());
return all;
}, null, new FilePermission("<<ALL FILES>>", "read"),
- new RuntimePermission("sun.management.spi.PlatformMBeanProvider"));
+ new RuntimePermission("sun.management.spi.PlatformMBeanProvider.subclass"));
// load all platform components into a map
componentMap = providers.stream()
@@ -970,4 +970,11 @@
return singleton;
}
}
+
+ static {
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ System.loadLibrary("management");
+ return null;
+ });
+ }
}
--- a/jdk/src/java.management/share/classes/sun/management/Agent.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/Agent.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,6 +34,7 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
+import java.net.MalformedURLException;
import java.net.UnknownHostException;
import java.text.MessageFormat;
import java.util.MissingResourceException;
@@ -55,6 +56,125 @@
* system class loader. Also jmx framework could be started by jcmd
*/
public class Agent {
+ /**
+ * Agent status collector strategy class
+ */
+ private static abstract class StatusCollector {
+ final protected StringBuilder sb = new StringBuilder();
+ final public String collect() {
+ Properties agentProps = VMSupport.getAgentProperties();
+ String localConnAddr = (String)agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP);
+ if (localConnAddr != null || jmxServer != null) {
+ addAgentStatus(true);
+ appendConnections(localConnAddr);
+ } else {
+ addAgentStatus(false);
+ }
+ return sb.toString();
+ }
+
+ private void appendConnections(String localConnAddr) {
+ appendConnectionsHeader();
+ if (localConnAddr != null) {
+ try {
+ JMXServiceURL u = new JMXServiceURL(localConnAddr);
+ addConnection(false, u);
+ } catch (MalformedURLException e) {
+ // will never happen
+ }
+
+ }
+ if (jmxServer != null) {
+ addConnection(true, jmxServer.getAddress());
+ }
+ appendConnectionsFooter();
+ }
+
+ private void addConnection(boolean remote, JMXServiceURL u) {
+ appendConnectionHeader(remote);
+ addConnectionDetails(u);
+ if (remote) {
+ addConfigProperties();
+ }
+ appendConnectionFooter(remote);
+ }
+
+ private void addConfigProperties() {
+ appendConfigPropsHeader();
+ boolean[] first = new boolean[] {true};
+ configProps.entrySet().stream().forEach((e) -> {
+ String key = (String)e.getKey();
+ if (key.startsWith("com.sun.management.")) {
+ addConfigProp(key, e.getValue(), first[0]);
+ first[0] = false;
+ }
+ });
+ appendConfigPropsFooter();
+ }
+
+ abstract protected void addAgentStatus(boolean enabled);
+ abstract protected void appendConnectionsHeader();
+ abstract protected void appendConnectionsFooter();
+ abstract protected void addConnectionDetails(JMXServiceURL u);
+ abstract protected void appendConnectionHeader(boolean remote);
+ abstract protected void appendConnectionFooter(boolean remote);
+ abstract protected void appendConfigPropsHeader();
+ abstract protected void appendConfigPropsFooter();
+ abstract protected void addConfigProp(String key, Object value, boolean first);
+ }
+
+ /**
+ * Free-text status collector strategy implementation
+ */
+ final private static class TextStatusCollector extends StatusCollector {
+
+ @Override
+ protected void addAgentStatus(boolean enabled) {
+ sb.append("Agent: ").append(enabled ? "enabled" : "disabled").append('\n');
+ }
+
+ @Override
+ protected void appendConnectionsHeader() {
+ sb.append('\n');
+ }
+
+ @Override
+ protected void addConnectionDetails(JMXServiceURL u) {
+ sb.append("Protocol : ").append(u.getProtocol()).append('\n')
+ .append("Host : ").append(u.getHost()).append('\n')
+ .append("URL : ").append(u).append('\n');
+ }
+
+ @Override
+ protected void appendConnectionHeader(boolean remote) {
+ sb.append("Connection Type: ").append(remote ? "remote" : "local").append('\n');
+ }
+
+ @Override
+ protected void appendConfigPropsHeader() {
+ sb.append("Properties :\n");
+ }
+
+ @Override
+ protected void addConfigProp(String key, Object value, boolean first) {
+ if (!first) {
+ sb.append('\n');
+ }
+ sb.append(" ").append(key).append(" = ").append(value);
+ }
+
+ @Override
+ protected void appendConnectionsFooter() {}
+
+ @Override
+ protected void appendConnectionFooter(boolean remote) {
+ sb.append('\n');
+ }
+
+ @Override
+ protected void appendConfigPropsFooter() {}
+ }
+
// management properties
private static Properties mgmtProps;
@@ -81,6 +201,8 @@
// The only active agent allowed
private static JMXConnectorServer jmxServer = null;
+ // The properties used to configure the server
+ private static Properties configProps = null;
// Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy
// and return property set if args is null or empty
@@ -161,7 +283,7 @@
try {
Properties argProps = parseString(args);
- Properties configProps = new Properties();
+ configProps = new Properties();
// Load the management properties from the config file
// if config file is not specified readConfiguration implicitly
@@ -228,9 +350,14 @@
// Don't cause any errors.
jmxServer.stop();
jmxServer = null;
+ configProps = null;
}
}
+ private static synchronized String getManagementAgentStatus() throws Exception {
+ return new TextStatusCollector().collect();
+ }
+
private static void startAgent(Properties props) throws Exception {
String snmpPort = props.getProperty(SNMP_PORT);
String jmxremote = props.getProperty(JMXREMOTE);
--- a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandArgumentInfo.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-/**
- * Diagnostic Command Argument information. It contains the description
- * of one parameter of the diagnostic command. A parameter can either be an
- * option or an argument. Options are identified by the option name while
- * arguments are identified by their position in the command line. The generic
- * syntax of a diagnostic command is:
- * <blockquote>
- * <command name> [<option>=<value>] [<argument_value>]
- * </blockquote>
- * Example:
- * <blockquote>
- * command_name option1=value1 option2=value argumentA argumentB argumentC
- * </blockquote>
- * In this command line, the diagnostic command receives five parameters, two
- * options named {@code option1} and {@code option2}, and three arguments.
- * argumentA's position is 0, argumentB's position is 1 and argumentC's
- * position is 2.
- *
- * @since 1.8
- */
-
-class DiagnosticCommandArgumentInfo {
- private final String name;
- private final String description;
- private final String type;
- private final String defaultValue;
- private final boolean mandatory;
- private final boolean option;
- private final boolean multiple;
- private final int position;
-
- /**
- * Returns the argument name.
- *
- * @return the argument name
- */
- String getName() {
- return name;
- }
-
- /**
- * Returns the argument description.
- *
- * @return the argument description
- */
- String getDescription() {
- return description;
- }
-
- /**
- * Returns the argument type.
- *
- * @return the argument type
- */
- String getType() {
- return type;
- }
-
- /**
- * Returns the default value as a String if a default value
- * is defined, null otherwise.
- *
- * @return the default value as a String if a default value
- * is defined, null otherwise.
- */
- String getDefault() {
- return defaultValue;
- }
-
- /**
- * Returns {@code true} if the argument is mandatory,
- * {@code false} otherwise.
- *
- * @return {@code true} if the argument is mandatory,
- * {@code false} otherwise
- */
- boolean isMandatory() {
- return mandatory;
- }
-
- /**
- * Returns {@code true} if the argument is an option,
- * {@code false} otherwise. Options have to be specified using the
- * <key>=<value> syntax on the command line, while other
- * arguments are specified with a single <value> field and are
- * identified by their position on command line.
- *
- * @return {@code true} if the argument is an option,
- * {@code false} otherwise
- */
- boolean isOption() {
- return option;
- }
-
- /**
- * Returns {@code true} if the argument can be specified multiple times,
- * {@code false} otherwise.
- *
- * @return {@code true} if the argument can be specified multiple times,
- * {@code false} otherwise
- */
- boolean isMultiple() {
- return multiple;
- }
-
- /**
- * Returns the expected position of this argument if it is not an option,
- * -1 otherwise. Argument position if defined from left to right,
- * starting at zero and ignoring the diagnostic command name and
- * options.
- *
- * @return the expected position of this argument if it is not an option,
- * -1 otherwise.
- */
- int getPosition() {
- return position;
- }
-
- DiagnosticCommandArgumentInfo(String name, String description,
- String type, String defaultValue,
- boolean mandatory, boolean option,
- boolean multiple, int position) {
- this.name = name;
- this.description = description;
- this.type = type;
- this.defaultValue = defaultValue;
- this.mandatory = mandatory;
- this.option = option;
- this.multiple = multiple;
- this.position = position;
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,380 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import com.sun.management.DiagnosticCommandMBean;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.security.Permission;
-import java.util.*;
-import javax.management.*;
-
-/**
- * Implementation class for the diagnostic commands subsystem.
- *
- * @since 1.8
- */
-class DiagnosticCommandImpl extends NotificationEmitterSupport
- implements DiagnosticCommandMBean {
-
- private final VMManagement jvm;
- private volatile Map<String, Wrapper> wrappers = null;
- private static final String strClassName = "".getClass().getName();
- private static final String strArrayClassName = String[].class.getName();
- private final boolean isSupported;
-
- @Override
- public Object getAttribute(String attribute) throws AttributeNotFoundException,
- MBeanException, ReflectionException {
- throw new AttributeNotFoundException(attribute);
- }
-
- @Override
- public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
- InvalidAttributeValueException, MBeanException, ReflectionException {
- throw new AttributeNotFoundException(attribute.getName());
- }
-
- @Override
- public AttributeList getAttributes(String[] attributes) {
- return new AttributeList();
- }
-
- @Override
- public AttributeList setAttributes(AttributeList attributes) {
- return new AttributeList();
- }
-
- private class Wrapper {
-
- String name;
- String cmd;
- DiagnosticCommandInfo info;
- Permission permission;
-
- Wrapper(String name, String cmd, DiagnosticCommandInfo info)
- throws InstantiationException {
- this.name = name;
- this.cmd = cmd;
- this.info = info;
- this.permission = null;
- Exception cause = null;
- if (info.getPermissionClass() != null) {
- try {
- Class<?> c = Class.forName(info.getPermissionClass());
- if (info.getPermissionAction() == null) {
- try {
- Constructor<?> constructor = c.getConstructor(String.class);
- permission = (Permission) constructor.newInstance(info.getPermissionName());
-
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- cause = ex;
- }
- }
- if (permission == null) {
- try {
- Constructor<?> constructor = c.getConstructor(String.class, String.class);
- permission = (Permission) constructor.newInstance(
- info.getPermissionName(),
- info.getPermissionAction());
- } catch (InstantiationException | IllegalAccessException
- | IllegalArgumentException | InvocationTargetException
- | NoSuchMethodException | SecurityException ex) {
- cause = ex;
- }
- }
- } catch (ClassNotFoundException ex) { }
- if (permission == null) {
- InstantiationException iex =
- new InstantiationException("Unable to instantiate required permission");
- iex.initCause(cause);
- }
- }
- }
-
- public String execute(String[] args) {
- if (permission != null) {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(permission);
- }
- }
- if(args == null) {
- return executeDiagnosticCommand(cmd);
- } else {
- StringBuilder sb = new StringBuilder();
- sb.append(cmd);
- for(int i=0; i<args.length; i++) {
- if(args[i] == null) {
- throw new IllegalArgumentException("Invalid null argument");
- }
- sb.append(" ");
- sb.append(args[i]);
- }
- return executeDiagnosticCommand(sb.toString());
- }
- }
- }
-
- DiagnosticCommandImpl(VMManagement jvm) {
- this.jvm = jvm;
- isSupported = jvm.isRemoteDiagnosticCommandsSupported();
- }
-
- private static class OperationInfoComparator implements Comparator<MBeanOperationInfo> {
- @Override
- public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) {
- return o1.getName().compareTo(o2.getName());
- }
- }
-
- @Override
- public MBeanInfo getMBeanInfo() {
- SortedSet<MBeanOperationInfo> operations = new TreeSet<>(new OperationInfoComparator());
- Map<String, Wrapper> wrappersmap;
- if (!isSupported) {
- wrappersmap = Collections.emptyMap();
- } else {
- try {
- String[] command = getDiagnosticCommands();
- DiagnosticCommandInfo[] info = getDiagnosticCommandInfo(command);
- MBeanParameterInfo stringArgInfo[] = new MBeanParameterInfo[]{
- new MBeanParameterInfo("arguments", strArrayClassName,
- "Array of Diagnostic Commands Arguments and Options")
- };
- wrappersmap = new HashMap<>();
- for (int i = 0; i < command.length; i++) {
- String name = transform(command[i]);
- try {
- Wrapper w = new Wrapper(name, command[i], info[i]);
- wrappersmap.put(name, w);
- operations.add(new MBeanOperationInfo(
- w.name,
- w.info.getDescription(),
- (w.info.getArgumentsInfo() == null
- || w.info.getArgumentsInfo().isEmpty())
- ? null : stringArgInfo,
- strClassName,
- MBeanOperationInfo.ACTION_INFO,
- commandDescriptor(w)));
- } catch (InstantiationException ex) {
- // If for some reasons the creation of a diagnostic command
- // wrappers fails, the diagnostic command is just ignored
- // and won't appear in the DynamicMBean
- }
- }
- } catch (IllegalArgumentException | UnsupportedOperationException e) {
- wrappersmap = Collections.emptyMap();
- }
- }
- wrappers = Collections.unmodifiableMap(wrappersmap);
- HashMap<String, Object> map = new HashMap<>();
- map.put("immutableInfo", "false");
- map.put("interfaceClassName","com.sun.management.DiagnosticCommandMBean");
- map.put("mxbean", "false");
- Descriptor desc = new ImmutableDescriptor(map);
- return new MBeanInfo(
- this.getClass().getName(),
- "Diagnostic Commands",
- null, // attributes
- null, // constructors
- operations.toArray(new MBeanOperationInfo[operations.size()]), // operations
- getNotificationInfo(), // notifications
- desc);
- }
-
- @Override
- public Object invoke(String actionName, Object[] params, String[] signature)
- throws MBeanException, ReflectionException {
- if (!isSupported) {
- throw new UnsupportedOperationException();
- }
- if (wrappers == null) {
- getMBeanInfo();
- }
- Wrapper w = wrappers.get(actionName);
- if (w != null) {
- if (w.info.getArgumentsInfo().isEmpty()
- && (params == null || params.length == 0)
- && (signature == null || signature.length == 0)) {
- return w.execute(null);
- } else if((params != null && params.length == 1)
- && (signature != null && signature.length == 1
- && signature[0] != null
- && signature[0].compareTo(strArrayClassName) == 0)) {
- return w.execute((String[]) params[0]);
- }
- }
- throw new ReflectionException(new NoSuchMethodException(actionName));
- }
-
- private static String transform(String name) {
- StringBuilder sb = new StringBuilder();
- boolean toLower = true;
- boolean toUpper = false;
- for (int i = 0; i < name.length(); i++) {
- char c = name.charAt(i);
- if (c == '.' || c == '_') {
- toLower = false;
- toUpper = true;
- } else {
- if (toUpper) {
- toUpper = false;
- sb.append(Character.toUpperCase(c));
- } else if(toLower) {
- sb.append(Character.toLowerCase(c));
- } else {
- sb.append(c);
- }
- }
- }
- return sb.toString();
- }
-
- private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException {
- HashMap<String, Object> map = new HashMap<>();
- map.put("dcmd.name", w.info.getName());
- map.put("dcmd.description", w.info.getDescription());
- map.put("dcmd.vmImpact", w.info.getImpact());
- map.put("dcmd.permissionClass", w.info.getPermissionClass());
- map.put("dcmd.permissionName", w.info.getPermissionName());
- map.put("dcmd.permissionAction", w.info.getPermissionAction());
- map.put("dcmd.enabled", w.info.isEnabled());
- StringBuilder sb = new StringBuilder();
- sb.append("help ");
- sb.append(w.info.getName());
- map.put("dcmd.help", executeDiagnosticCommand(sb.toString()));
- if (w.info.getArgumentsInfo() != null && !w.info.getArgumentsInfo().isEmpty()) {
- HashMap<String, Object> allargmap = new HashMap<>();
- for (DiagnosticCommandArgumentInfo arginfo : w.info.getArgumentsInfo()) {
- HashMap<String, Object> argmap = new HashMap<>();
- argmap.put("dcmd.arg.name", arginfo.getName());
- argmap.put("dcmd.arg.type", arginfo.getType());
- argmap.put("dcmd.arg.description", arginfo.getDescription());
- argmap.put("dcmd.arg.isMandatory", arginfo.isMandatory());
- argmap.put("dcmd.arg.isMultiple", arginfo.isMultiple());
- boolean isOption = arginfo.isOption();
- argmap.put("dcmd.arg.isOption", isOption);
- if(!isOption) {
- argmap.put("dcmd.arg.position", arginfo.getPosition());
- } else {
- argmap.put("dcmd.arg.position", -1);
- }
- allargmap.put(arginfo.getName(), new ImmutableDescriptor(argmap));
- }
- map.put("dcmd.arguments", new ImmutableDescriptor(allargmap));
- }
- return new ImmutableDescriptor(map);
- }
-
- private final static String notifName =
- "javax.management.Notification";
-
- private final static String[] diagFramNotifTypes = {
- "jmx.mbean.info.changed"
- };
-
- private MBeanNotificationInfo[] notifInfo = null;
-
- @Override
- public MBeanNotificationInfo[] getNotificationInfo() {
- synchronized (this) {
- if (notifInfo == null) {
- notifInfo = new MBeanNotificationInfo[1];
- notifInfo[0] =
- new MBeanNotificationInfo(diagFramNotifTypes,
- notifName,
- "Diagnostic Framework Notification");
- }
- }
- return notifInfo;
- }
-
- private static long seqNumber = 0;
- private static long getNextSeqNumber() {
- return ++seqNumber;
- }
-
- private void createDiagnosticFrameworkNotification() {
-
- if (!hasListeners()) {
- return;
- }
- ObjectName on = null;
- try {
- on = ObjectName.getInstance(ManagementFactoryHelper.HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME);
- } catch (MalformedObjectNameException e) { }
- Notification notif = new Notification("jmx.mbean.info.changed",
- on,
- getNextSeqNumber());
- notif.setUserData(getMBeanInfo());
- sendNotification(notif);
- }
-
- @Override
- public synchronized void addNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
- boolean before = hasListeners();
- super.addNotificationListener(listener, filter, handback);
- boolean after = hasListeners();
- if (!before && after) {
- setNotificationEnabled(true);
- }
- }
-
- @Override
- public synchronized void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- boolean before = hasListeners();
- super.removeNotificationListener(listener);
- boolean after = hasListeners();
- if (before && !after) {
- setNotificationEnabled(false);
- }
- }
-
- @Override
- public synchronized void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws ListenerNotFoundException {
- boolean before = hasListeners();
- super.removeNotificationListener(listener, filter, handback);
- boolean after = hasListeners();
- if (before && !after) {
- setNotificationEnabled(false);
- }
- }
-
- private native void setNotificationEnabled(boolean enabled);
- private native String[] getDiagnosticCommands();
- private native DiagnosticCommandInfo[] getDiagnosticCommandInfo(String[] commands);
- private native String executeDiagnosticCommand(String command);
-
-}
--- a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandInfo.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.util.List;
-
-/**
- * Diagnostic command information. It contains the description of a
- * diagnostic command.
- *
- * @since 1.8
- */
-
-class DiagnosticCommandInfo {
- private final String name;
- private final String description;
- private final String impact;
- private final String permissionClass;
- private final String permissionName;
- private final String permissionAction;
- private final boolean enabled;
- private final List<DiagnosticCommandArgumentInfo> arguments;
-
- /**
- * Returns the diagnostic command name.
- *
- * @return the diagnostic command name
- */
- String getName() {
- return name;
- }
-
- /**
- * Returns the diagnostic command description.
- *
- * @return the diagnostic command description
- */
- String getDescription() {
- return description;
- }
-
- /**
- * Returns the potential impact of the diagnostic command execution
- * on the Java virtual machine behavior.
- *
- * @return the potential impact of the diagnostic command execution
- * on the Java virtual machine behavior
- */
- String getImpact() {
- return impact;
- }
-
- /**
- * Returns the name of the permission class required to be allowed
- * to invoke the diagnostic command, or null if no permission
- * is required.
- *
- * @return the name of the permission class name required to be allowed
- * to invoke the diagnostic command, or null if no permission
- * is required
- */
- String getPermissionClass() {
- return permissionClass;
- }
-
- /**
- * Returns the permission name required to be allowed to invoke the
- * diagnostic command, or null if no permission is required.
- *
- * @return the permission name required to be allowed to invoke the
- * diagnostic command, or null if no permission is required
- */
- String getPermissionName() {
- return permissionName;
- }
-
- /**
- * Returns the permission action required to be allowed to invoke the
- * diagnostic command, or null if no permission is required or
- * if the permission has no action specified.
- *
- * @return the permission action required to be allowed to invoke the
- * diagnostic command, or null if no permission is required or
- * if the permission has no action specified
- */
- String getPermissionAction() {
- return permissionAction;
- }
-
- /**
- * Returns {@code true} if the diagnostic command is enabled,
- * {@code false} otherwise. The enabled/disabled
- * status of a diagnostic command can evolve during
- * the lifetime of the Java virtual machine.
- *
- * @return {@code true} if the diagnostic command is enabled,
- * {@code false} otherwise
- */
- boolean isEnabled() {
- return enabled;
- }
-
- /**
- * Returns the list of the diagnostic command arguments description.
- * If the diagnostic command has no arguments, it returns an empty list.
- *
- * @return a list of the diagnostic command arguments description
- */
- List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
- return arguments;
- }
-
- DiagnosticCommandInfo(String name, String description,
- String impact, String permissionClass,
- String permissionName, String permissionAction,
- boolean enabled,
- List<DiagnosticCommandArgumentInfo> arguments)
- {
- this.name = name;
- this.description = description;
- this.impact = impact;
- this.permissionClass = permissionClass;
- this.permissionName = permissionName;
- this.permissionAction = permissionAction;
- this.enabled = enabled;
- this.arguments = arguments;
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/Flag.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.util.*;
-import com.sun.management.VMOption;
-import com.sun.management.VMOption.Origin;
-import java.security.AccessController;
-
-/**
- * Flag class is a helper class for constructing a VMOption.
- * It has the static methods for getting the Flag objects, each
- * corresponds to one VMOption.
- *
- */
-class Flag {
- private String name;
- private Object value;
- private Origin origin;
- private boolean writeable;
- private boolean external;
-
- Flag(String name, Object value, boolean writeable,
- boolean external, Origin origin) {
- this.name = name;
- this.value = value == null ? "" : value ;
- this.origin = origin;
- this.writeable = writeable;
- this.external = external;
- }
-
- Object getValue() {
- return value;
- }
-
- boolean isWriteable() {
- return writeable;
- }
-
- boolean isExternal() {
- return external;
- }
-
- VMOption getVMOption() {
- return new VMOption(name, value.toString(), writeable, origin);
- }
-
- static Flag getFlag(String name) {
- String[] names = new String[1];
- names[0] = name;
-
- List<Flag> flags = getFlags(names, 1);
- if (flags.isEmpty()) {
- return null;
- } else {
- // flags should have only one element
- return flags.get(0);
- }
- }
-
- static List<Flag> getAllFlags() {
- int numFlags = getInternalFlagCount();
-
- // Get all internal flags with names = null
- return getFlags(null, numFlags);
- }
-
- private static List<Flag> getFlags(String[] names, int numFlags) {
- Flag[] flags = new Flag[numFlags];
- int count = getFlags(names, flags, numFlags);
-
- List<Flag> result = new ArrayList<>();
- for (Flag f : flags) {
- if (f != null) {
- result.add(f);
- }
- }
- return result;
- }
-
- private static native String[] getAllFlagNames();
- // getFlags sets each element in the given flags array
- // with a Flag object only if the name is valid and the
- // type is supported. The flags array may contain null elements.
- private static native int getFlags(String[] names, Flag[] flags, int count);
- private static native int getInternalFlagCount();
-
- // These set* methods are synchronized on the class object
- // to avoid multiple threads updating the same flag at the same time.
- static synchronized native void setLongValue(String name, long value);
- static synchronized native void setDoubleValue(String name, double value);
- static synchronized native void setBooleanValue(String name, boolean value);
- static synchronized native void setStringValue(String name, String value);
-
- static {
- AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("management");
- return null;
- }
- });
- initialize();
- }
- private static native void initialize();
-}
--- a/jdk/src/java.management/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import com.sun.management.GarbageCollectionNotificationInfo;
-import com.sun.management.GcInfo;
-import java.lang.reflect.Method;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.lang.reflect.Field;
-import java.util.HashMap;
-
-/**
- * A CompositeData for GarbageCollectionNotificationInfo for the local management support.
- * This class avoids the performance penalty paid to the
- * construction of a CompositeData use in the local case.
- */
-public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData {
- private final GarbageCollectionNotificationInfo gcNotifInfo;
-
- public GarbageCollectionNotifInfoCompositeData(GarbageCollectionNotificationInfo info) {
- this.gcNotifInfo = info;
- }
-
- public GarbageCollectionNotificationInfo getGarbageCollectionNotifInfo() {
- return gcNotifInfo;
- }
-
- public static CompositeData toCompositeData(GarbageCollectionNotificationInfo info) {
- GarbageCollectionNotifInfoCompositeData gcnicd =
- new GarbageCollectionNotifInfoCompositeData(info);
- return gcnicd.getCompositeData();
- }
-
- private CompositeType getCompositeTypeByBuilder() {
- final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {
- public GcInfoBuilder run() {
- try {
- Class<?> cl = Class.forName("com.sun.management.GcInfo");
- Field f = cl.getDeclaredField("builder");
- f.setAccessible(true);
- return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo());
- } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
- return null;
- }
- }
- });
- CompositeType gict = null;
- synchronized(compositeTypeByBuilder) {
- gict = compositeTypeByBuilder.get(builder);
- if(gict == null) {
- OpenType<?>[] gcNotifInfoItemTypes = new OpenType<?>[] {
- SimpleType.STRING,
- SimpleType.STRING,
- SimpleType.STRING,
- builder.getGcInfoCompositeType(),
- };
- try {
- final String typeName =
- "sun.management.GarbageCollectionNotifInfoCompositeType";
- gict = new CompositeType(typeName,
- "CompositeType for GC notification info",
- gcNotifInfoItemNames,
- gcNotifInfoItemNames,
- gcNotifInfoItemTypes);
- compositeTypeByBuilder.put(builder,gict);
- } catch (OpenDataException e) {
- // shouldn't reach here
- throw Util.newException(e);
- }
- }
- }
- return gict;
- }
-
- protected CompositeData getCompositeData() {
- // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
- // gcNotifInfoItemNames!
- final Object[] gcNotifInfoItemValues;
- gcNotifInfoItemValues = new Object[] {
- gcNotifInfo.getGcName(),
- gcNotifInfo.getGcAction(),
- gcNotifInfo.getGcCause(),
- GcInfoCompositeData.toCompositeData(gcNotifInfo.getGcInfo())
- };
-
- CompositeType gict = getCompositeTypeByBuilder();
-
- try {
- return new CompositeDataSupport(gict,
- gcNotifInfoItemNames,
- gcNotifInfoItemValues);
- } catch (OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- // private static MappedMXBeanType gcInfoMapType;
- private static final String GC_NAME = "gcName";
- private static final String GC_ACTION = "gcAction";
- private static final String GC_CAUSE = "gcCause";
- private static final String GC_INFO = "gcInfo";
- private static final String[] gcNotifInfoItemNames = {
- GC_NAME,
- GC_ACTION,
- GC_CAUSE,
- GC_INFO
- };
- private static HashMap<GcInfoBuilder,CompositeType> compositeTypeByBuilder =
- new HashMap<>();
-
- public static String getGcName(CompositeData cd) {
- String gcname = getString(cd, GC_NAME);
- if (gcname == null) {
- throw new IllegalArgumentException("Invalid composite data: " +
- "Attribute " + GC_NAME + " has null value");
- }
- return gcname;
- }
-
- public static String getGcAction(CompositeData cd) {
- String gcaction = getString(cd, GC_ACTION);
- if (gcaction == null) {
- throw new IllegalArgumentException("Invalid composite data: " +
- "Attribute " + GC_ACTION + " has null value");
- }
- return gcaction;
- }
-
- public static String getGcCause(CompositeData cd) {
- String gccause = getString(cd, GC_CAUSE);
- if (gccause == null) {
- throw new IllegalArgumentException("Invalid composite data: " +
- "Attribute " + GC_CAUSE + " has null value");
- }
- return gccause;
- }
-
- public static GcInfo getGcInfo(CompositeData cd) {
- CompositeData gcInfoData = (CompositeData) cd.get(GC_INFO);
- return GcInfo.from(gcInfoData);
- }
-
- /** Validate if the input CompositeData has the expected
- * CompositeType (i.e. contain all attributes with expected
- * names and types).
- */
- public static void validateCompositeData(CompositeData cd) {
- if (cd == null) {
- throw new NullPointerException("Null CompositeData");
- }
-
- if (!isTypeMatched( getBaseGcNotifInfoCompositeType(), cd.getCompositeType())) {
- throw new IllegalArgumentException(
- "Unexpected composite type for GarbageCollectionNotificationInfo");
- }
- }
-
- // This is only used for validation.
- private static CompositeType baseGcNotifInfoCompositeType = null;
- private static synchronized CompositeType getBaseGcNotifInfoCompositeType() {
- if (baseGcNotifInfoCompositeType == null) {
- try {
- OpenType<?>[] baseGcNotifInfoItemTypes = new OpenType<?>[] {
- SimpleType.STRING,
- SimpleType.STRING,
- SimpleType.STRING,
- GcInfoCompositeData.getBaseGcInfoCompositeType()
- };
- baseGcNotifInfoCompositeType =
- new CompositeType("sun.management.BaseGarbageCollectionNotifInfoCompositeType",
- "CompositeType for Base GarbageCollectionNotificationInfo",
- gcNotifInfoItemNames,
- gcNotifInfoItemNames,
- baseGcNotifInfoItemTypes);
- } catch (OpenDataException e) {
- // shouldn't reach here
- throw Util.newException(e);
- }
- }
- return baseGcNotifInfoCompositeType;
- }
-
- private static final long serialVersionUID = -1805123446483771292L;
-}
--- a/jdk/src/java.management/share/classes/sun/management/GarbageCollectorImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/GarbageCollectorImpl.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,168 +25,31 @@
package sun.management;
-import com.sun.management.GarbageCollectorMXBean;
-import com.sun.management.GarbageCollectionNotificationInfo;
+import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryPoolMXBean;
-import java.lang.management.MemoryUsage;
-
-import com.sun.management.GcInfo;
-import javax.management.openmbean.CompositeData;
-import javax.management.MBeanInfo;
-import javax.management.MBeanAttributeInfo;
import javax.management.ObjectName;
-import javax.management.MBeanNotificationInfo;
-import javax.management.Notification;
-import javax.management.NotificationFilter;
-import javax.management.NotificationListener;
-import javax.management.ListenerNotFoundException;
-
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
/**
* Implementation class for the garbage collector.
- * Standard and committed hotspot-specific metrics if any.
*
* ManagementFactory.getGarbageCollectorMXBeans() returns a list
* of instances of this class.
*/
-class GarbageCollectorImpl extends MemoryManagerImpl
+public class GarbageCollectorImpl extends MemoryManagerImpl
implements GarbageCollectorMXBean {
- GarbageCollectorImpl(String name) {
+ protected GarbageCollectorImpl(String name) {
super(name);
}
+ @Override
public native long getCollectionCount();
+
+ @Override
public native long getCollectionTime();
-
- // The memory pools are static and won't be changed.
- // TODO: If the hotspot implementation begins to have pools
- // dynamically created and removed, this needs to be modified.
- private String[] poolNames = null;
- synchronized String[] getAllPoolNames() {
- if (poolNames == null) {
- List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
- poolNames = new String[pools.size()];
- int i = 0;
- for (MemoryPoolMXBean m : pools) {
- poolNames[i++] = m.getName();
- }
- }
- return poolNames;
- }
-
- // Sun JDK extension
- private GcInfoBuilder gcInfoBuilder;
-
- private synchronized GcInfoBuilder getGcInfoBuilder() {
- if(gcInfoBuilder == null) {
- gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames());
- }
- return gcInfoBuilder;
- }
-
- public GcInfo getLastGcInfo() {
- GcInfo info = getGcInfoBuilder().getLastGcInfo();
- return info;
- }
-
- private final static String notifName =
- "javax.management.Notification";
-
- private final static String[] gcNotifTypes = {
- GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION
- };
-
- private MBeanNotificationInfo[] notifInfo = null;
- public MBeanNotificationInfo[] getNotificationInfo() {
- synchronized (this) {
- if (notifInfo == null) {
- notifInfo = new MBeanNotificationInfo[1];
- notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes,
- notifName,
- "GC Notification");
- }
- }
- return notifInfo;
- }
-
- private static long seqNumber = 0;
- private static long getNextSeqNumber() {
- return ++seqNumber;
- }
-
- void createGCNotification(long timestamp,
- String gcName,
- String gcAction,
- String gcCause,
- GcInfo gcInfo) {
-
- if (!hasListeners()) {
- return;
- }
-
- Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION,
- getObjectName(),
- getNextSeqNumber(),
- timestamp,
- gcName);
- GarbageCollectionNotificationInfo info =
- new GarbageCollectionNotificationInfo(gcName,
- gcAction,
- gcCause,
- gcInfo);
-
- CompositeData cd =
- GarbageCollectionNotifInfoCompositeData.toCompositeData(info);
- notif.setUserData(cd);
- sendNotification(notif);
- }
-
- public synchronized void addNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- {
- boolean before = hasListeners();
- super.addNotificationListener(listener, filter, handback);
- boolean after = hasListeners();
- if (!before && after) {
- setNotificationEnabled(this, true);
- }
- }
-
- public synchronized void removeNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- boolean before = hasListeners();
- super.removeNotificationListener(listener);
- boolean after = hasListeners();
- if (before && !after) {
- setNotificationEnabled(this,false);
- }
- }
-
- public synchronized void removeNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws ListenerNotFoundException
- {
- boolean before = hasListeners();
- super.removeNotificationListener(listener,filter,handback);
- boolean after = hasListeners();
- if (before && !after) {
- setNotificationEnabled(this,false);
- }
- }
-
+ @Override
public ObjectName getObjectName() {
return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName());
}
-
- native void setNotificationEnabled(GarbageCollectorMXBean gc,
- boolean enabled);
-
}
--- a/jdk/src/java.management/share/classes/sun/management/GcInfoBuilder.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management;
-
-import java.lang.management.GarbageCollectorMXBean;
-import java.lang.management.MemoryUsage;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.TabularType;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-import com.sun.management.GcInfo;
-
-/**
- * Helper class to build composite data.
- */
-public class GcInfoBuilder {
- private final GarbageCollectorMXBean gc;
- private final String[] poolNames;
- private String[] allItemNames;
-
- // GC-specific composite type:
- // Each GarbageCollectorMXBean may have different GC-specific attributes
- // the CompositeType for the GcInfo could be different.
- private CompositeType gcInfoCompositeType;
-
- // GC-specific items
- private final int gcExtItemCount;
- private final String[] gcExtItemNames;
- private final String[] gcExtItemDescs;
- private final char[] gcExtItemTypes;
-
- GcInfoBuilder(GarbageCollectorMXBean gc, String[] poolNames) {
- this.gc = gc;
- this.poolNames = poolNames;
- this.gcExtItemCount = getNumGcExtAttributes(gc);
- this.gcExtItemNames = new String[gcExtItemCount];
- this.gcExtItemDescs = new String[gcExtItemCount];
- this.gcExtItemTypes = new char[gcExtItemCount];
-
- // Fill the information about extension attributes
- fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames,
- gcExtItemTypes, gcExtItemDescs);
-
- // lazily build the CompositeType for the GcInfo
- // including the GC-specific extension attributes
- this.gcInfoCompositeType = null;
- }
-
- GcInfo getLastGcInfo() {
- MemoryUsage[] usageBeforeGC = new MemoryUsage[poolNames.length];
- MemoryUsage[] usageAfterGC = new MemoryUsage[poolNames.length];
- Object[] values = new Object[gcExtItemCount];
-
- return getLastGcInfo0(gc, gcExtItemCount, values, gcExtItemTypes,
- usageBeforeGC, usageAfterGC);
- }
-
- public String[] getPoolNames() {
- return poolNames;
- }
-
- int getGcExtItemCount() {
- return gcExtItemCount;
- }
-
- // Returns the CompositeType for the GcInfo including
- // the extension attributes
- synchronized CompositeType getGcInfoCompositeType() {
- if (gcInfoCompositeType != null)
- return gcInfoCompositeType;
-
- // First, fill with the attributes in the GcInfo
- String[] gcInfoItemNames = GcInfoCompositeData.getBaseGcInfoItemNames();
- OpenType<?>[] gcInfoItemTypes = GcInfoCompositeData.getBaseGcInfoItemTypes();
- int numGcInfoItems = gcInfoItemNames.length;
-
- int itemCount = numGcInfoItems + gcExtItemCount;
- allItemNames = new String[itemCount];
- String[] allItemDescs = new String[itemCount];
- OpenType<?>[] allItemTypes = new OpenType<?>[itemCount];
-
- System.arraycopy(gcInfoItemNames, 0, allItemNames, 0, numGcInfoItems);
- System.arraycopy(gcInfoItemNames, 0, allItemDescs, 0, numGcInfoItems);
- System.arraycopy(gcInfoItemTypes, 0, allItemTypes, 0, numGcInfoItems);
-
- // Then fill with the extension GC-specific attributes, if any.
- if (gcExtItemCount > 0) {
- fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames,
- gcExtItemTypes, gcExtItemDescs);
- System.arraycopy(gcExtItemNames, 0, allItemNames,
- numGcInfoItems, gcExtItemCount);
- System.arraycopy(gcExtItemDescs, 0, allItemDescs,
- numGcInfoItems, gcExtItemCount);
- for (int i = numGcInfoItems, j = 0; j < gcExtItemCount; i++, j++) {
- switch (gcExtItemTypes[j]) {
- case 'Z':
- allItemTypes[i] = SimpleType.BOOLEAN;
- break;
- case 'B':
- allItemTypes[i] = SimpleType.BYTE;
- break;
- case 'C':
- allItemTypes[i] = SimpleType.CHARACTER;
- break;
- case 'S':
- allItemTypes[i] = SimpleType.SHORT;
- break;
- case 'I':
- allItemTypes[i] = SimpleType.INTEGER;
- break;
- case 'J':
- allItemTypes[i] = SimpleType.LONG;
- break;
- case 'F':
- allItemTypes[i] = SimpleType.FLOAT;
- break;
- case 'D':
- allItemTypes[i] = SimpleType.DOUBLE;
- break;
- default:
- throw new AssertionError(
- "Unsupported type [" + gcExtItemTypes[i] + "]");
- }
- }
- }
-
- CompositeType gict = null;
- try {
- final String typeName =
- "sun.management." + gc.getName() + ".GcInfoCompositeType";
-
- gict = new CompositeType(typeName,
- "CompositeType for GC info for " +
- gc.getName(),
- allItemNames,
- allItemDescs,
- allItemTypes);
- } catch (OpenDataException e) {
- // shouldn't reach here
- throw Util.newException(e);
- }
- gcInfoCompositeType = gict;
-
- return gcInfoCompositeType;
- }
-
- synchronized String[] getItemNames() {
- if (allItemNames == null) {
- // initialize when forming the composite type
- getGcInfoCompositeType();
- }
- return allItemNames;
- }
-
- // Retrieve information about extension attributes
- private native int getNumGcExtAttributes(GarbageCollectorMXBean gc);
- private native void fillGcAttributeInfo(GarbageCollectorMXBean gc,
- int numAttributes,
- String[] attributeNames,
- char[] types,
- String[] descriptions);
-
- /**
- * Returns the last GcInfo
- *
- * @param gc GarbageCollectorMXBean that the gc info is associated with.
- * @param numExtAtts number of extension attributes
- * @param extAttValues Values of extension attributes to be filled.
- * @param before Memory usage before GC to be filled.
- * @param after Memory usage after GC to be filled.
- */
- private native GcInfo getLastGcInfo0(GarbageCollectorMXBean gc,
- int numExtAtts,
- Object[] extAttValues,
- char[] extAttTypes,
- MemoryUsage[] before,
- MemoryUsage[] after);
-}
--- a/jdk/src/java.management/share/classes/sun/management/GcInfoCompositeData.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.lang.management.MemoryUsage;
-import java.lang.reflect.Method;
-import java.lang.reflect.Field;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Collections;
-import java.io.InvalidObjectException;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.OpenDataException;
-import com.sun.management.GcInfo;
-import com.sun.management.GarbageCollectionNotificationInfo;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * A CompositeData for GcInfo for the local management support.
- * This class avoids the performance penalty paid to the
- * construction of a CompositeData use in the local case.
- */
-public class GcInfoCompositeData extends LazyCompositeData {
- private final GcInfo info;
- private final GcInfoBuilder builder;
- private final Object[] gcExtItemValues;
-
- public GcInfoCompositeData(GcInfo info,
- GcInfoBuilder builder,
- Object[] gcExtItemValues) {
- this.info = info;
- this.builder = builder;
- this.gcExtItemValues = gcExtItemValues;
- }
-
- public GcInfo getGcInfo() {
- return info;
- }
-
- public static CompositeData toCompositeData(final GcInfo info) {
- final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {
- public GcInfoBuilder run() {
- try {
- Class<?> cl = Class.forName("com.sun.management.GcInfo");
- Field f = cl.getDeclaredField("builder");
- f.setAccessible(true);
- return (GcInfoBuilder)f.get(info);
- } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
- return null;
- }
- }
- });
- final Object[] extAttr = AccessController.doPrivileged (new PrivilegedAction<Object[]>() {
- public Object[] run() {
- try {
- Class<?> cl = Class.forName("com.sun.management.GcInfo");
- Field f = cl.getDeclaredField("extAttributes");
- f.setAccessible(true);
- return (Object[])f.get(info);
- } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
- return null;
- }
- }
- });
- GcInfoCompositeData gcicd =
- new GcInfoCompositeData(info,builder,extAttr);
- return gcicd.getCompositeData();
- }
-
- protected CompositeData getCompositeData() {
- // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
- // baseGcInfoItemNames!
- final Object[] baseGcInfoItemValues;
-
- try {
- baseGcInfoItemValues = new Object[] {
- info.getId(),
- info.getStartTime(),
- info.getEndTime(),
- info.getDuration(),
- memoryUsageMapType.toOpenTypeData(info.getMemoryUsageBeforeGc()),
- memoryUsageMapType.toOpenTypeData(info.getMemoryUsageAfterGc()),
- };
- } catch (OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
-
- // Get the item values for the extension attributes
- final int gcExtItemCount = builder.getGcExtItemCount();
- if (gcExtItemCount == 0 &&
- gcExtItemValues != null && gcExtItemValues.length != 0) {
- throw new AssertionError("Unexpected Gc Extension Item Values");
- }
-
- if (gcExtItemCount > 0 && (gcExtItemValues == null ||
- gcExtItemCount != gcExtItemValues.length)) {
- throw new AssertionError("Unmatched Gc Extension Item Values");
- }
-
- Object[] values = new Object[baseGcInfoItemValues.length +
- gcExtItemCount];
- System.arraycopy(baseGcInfoItemValues, 0, values, 0,
- baseGcInfoItemValues.length);
-
- if (gcExtItemCount > 0) {
- System.arraycopy(gcExtItemValues, 0, values,
- baseGcInfoItemValues.length, gcExtItemCount);
- }
-
- try {
- return new CompositeDataSupport(builder.getGcInfoCompositeType(),
- builder.getItemNames(),
- values);
- } catch (OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- private static final String ID = "id";
- private static final String START_TIME = "startTime";
- private static final String END_TIME = "endTime";
- private static final String DURATION = "duration";
- private static final String MEMORY_USAGE_BEFORE_GC = "memoryUsageBeforeGc";
- private static final String MEMORY_USAGE_AFTER_GC = "memoryUsageAfterGc";
-
- private static final String[] baseGcInfoItemNames = {
- ID,
- START_TIME,
- END_TIME,
- DURATION,
- MEMORY_USAGE_BEFORE_GC,
- MEMORY_USAGE_AFTER_GC,
- };
-
-
- private static MappedMXBeanType memoryUsageMapType;
- static {
- try {
- Method m = GcInfo.class.getMethod("getMemoryUsageBeforeGc");
- memoryUsageMapType =
- MappedMXBeanType.getMappedType(m.getGenericReturnType());
- } catch (NoSuchMethodException | OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- static String[] getBaseGcInfoItemNames() {
- return baseGcInfoItemNames;
- }
-
- private static OpenType<?>[] baseGcInfoItemTypes = null;
- static synchronized OpenType<?>[] getBaseGcInfoItemTypes() {
- if (baseGcInfoItemTypes == null) {
- OpenType<?> memoryUsageOpenType = memoryUsageMapType.getOpenType();
- baseGcInfoItemTypes = new OpenType<?>[] {
- SimpleType.LONG,
- SimpleType.LONG,
- SimpleType.LONG,
- SimpleType.LONG,
-
- memoryUsageOpenType,
- memoryUsageOpenType,
- };
- }
- return baseGcInfoItemTypes;
- }
-
- public static long getId(CompositeData cd) {
- return getLong(cd, ID);
- }
- public static long getStartTime(CompositeData cd) {
- return getLong(cd, START_TIME);
- }
- public static long getEndTime(CompositeData cd) {
- return getLong(cd, END_TIME);
- }
-
- public static Map<String, MemoryUsage>
- getMemoryUsageBeforeGc(CompositeData cd) {
- try {
- TabularData td = (TabularData) cd.get(MEMORY_USAGE_BEFORE_GC);
- return cast(memoryUsageMapType.toJavaTypeData(td));
- } catch (InvalidObjectException | OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- public static Map<String, MemoryUsage> cast(Object x) {
- return (Map<String, MemoryUsage>) x;
- }
- public static Map<String, MemoryUsage>
- getMemoryUsageAfterGc(CompositeData cd) {
- try {
- TabularData td = (TabularData) cd.get(MEMORY_USAGE_AFTER_GC);
- //return (Map<String,MemoryUsage>)
- return cast(memoryUsageMapType.toJavaTypeData(td));
- } catch (InvalidObjectException | OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- /**
- * Returns true if the input CompositeData has the expected
- * CompositeType (i.e. contain all attributes with expected
- * names and types). Otherwise, return false.
- */
- public static void validateCompositeData(CompositeData cd) {
- if (cd == null) {
- throw new NullPointerException("Null CompositeData");
- }
-
- if (!isTypeMatched(getBaseGcInfoCompositeType(),
- cd.getCompositeType())) {
- throw new IllegalArgumentException(
- "Unexpected composite type for GcInfo");
- }
- }
-
- // This is only used for validation.
- private static CompositeType baseGcInfoCompositeType = null;
- static synchronized CompositeType getBaseGcInfoCompositeType() {
- if (baseGcInfoCompositeType == null) {
- try {
- baseGcInfoCompositeType =
- new CompositeType("sun.management.BaseGcInfoCompositeType",
- "CompositeType for Base GcInfo",
- getBaseGcInfoItemNames(),
- getBaseGcInfoItemNames(),
- getBaseGcInfoItemTypes());
- } catch (OpenDataException e) {
- // shouldn't reach here
- throw Util.newException(e);
- }
- }
- return baseGcInfoCompositeType;
- }
-
- private static final long serialVersionUID = -5716428894085882742L;
-}
--- a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.management.ObjectName;
-
-import com.sun.management.HotSpotDiagnosticMXBean;
-import com.sun.management.VMOption;
-
-/**
- * Implementation of the diagnostic MBean for Hotspot VM.
- */
-public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
- public HotSpotDiagnostic() {
- }
-
- @Override
- public void dumpHeap(String outputFile, boolean live) throws IOException {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkWrite(outputFile);
- Util.checkControlAccess();
- }
-
- dumpHeap0(outputFile, live);
- }
-
- private native void dumpHeap0(String outputFile, boolean live) throws IOException;
-
- @Override
- public List<VMOption> getDiagnosticOptions() {
- List<Flag> allFlags = Flag.getAllFlags();
- List<VMOption> result = new ArrayList<>();
- for (Flag flag : allFlags) {
- if (flag.isWriteable() && flag.isExternal()) {
- result.add(flag.getVMOption());
- }
- }
- return result;
- }
-
- @Override
- public VMOption getVMOption(String name) {
- if (name == null) {
- throw new NullPointerException("name cannot be null");
- }
-
- Flag f = Flag.getFlag(name);
- if (f == null) {
- throw new IllegalArgumentException("VM option \"" +
- name + "\" does not exist");
- }
- return f.getVMOption();
- }
-
- @Override
- public void setVMOption(String name, String value) {
- if (name == null) {
- throw new NullPointerException("name cannot be null");
- }
- if (value == null) {
- throw new NullPointerException("value cannot be null");
- }
-
- Util.checkControlAccess();
- Flag flag = Flag.getFlag(name);
- if (flag == null) {
- throw new IllegalArgumentException("VM option \"" +
- name + "\" does not exist");
- }
- if (!flag.isWriteable()){
- throw new IllegalArgumentException("VM Option \"" +
- name + "\" is not writeable");
- }
-
- // Check the type of the value
- Object v = flag.getValue();
- if (v instanceof Long) {
- try {
- long l = Long.parseLong(value);
- Flag.setLongValue(name, l);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Invalid value:" +
- " VM Option \"" + name + "\"" +
- " expects numeric value", e);
- }
- } else if (v instanceof Double) {
- try {
- double d = Double.parseDouble(value);
- Flag.setDoubleValue(name, d);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Invalid value:" +
- " VM Option \"" + name + "\"" +
- " expects numeric value", e);
- }
- } else if (v instanceof Boolean) {
- if (!value.equalsIgnoreCase("true") &&
- !value.equalsIgnoreCase("false")) {
- throw new IllegalArgumentException("Invalid value:" +
- " VM Option \"" + name + "\"" +
- " expects \"true\" or \"false\".");
- }
- Flag.setBooleanValue(name, Boolean.parseBoolean(value));
- } else if (v instanceof String) {
- Flag.setStringValue(name, value);
- } else {
- throw new IllegalArgumentException("VM Option \"" +
- name + "\" is of an unsupported type: " +
- v.getClass().getName());
- }
- }
-
- @Override
- public ObjectName getObjectName() {
- return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -115,28 +115,28 @@
protected abstract CompositeData getCompositeData();
// Helper methods
- static String getString(CompositeData cd, String itemName) {
+ public static String getString(CompositeData cd, String itemName) {
if (cd == null)
throw new IllegalArgumentException("Null CompositeData");
return (String) cd.get(itemName);
}
- static boolean getBoolean(CompositeData cd, String itemName) {
+ public static boolean getBoolean(CompositeData cd, String itemName) {
if (cd == null)
throw new IllegalArgumentException("Null CompositeData");
return ((Boolean) cd.get(itemName)).booleanValue();
}
- static long getLong(CompositeData cd, String itemName) {
+ public static long getLong(CompositeData cd, String itemName) {
if (cd == null)
throw new IllegalArgumentException("Null CompositeData");
return ((Long) cd.get(itemName)).longValue();
}
- static int getInt(CompositeData cd, String itemName) {
+ public static int getInt(CompositeData cd, String itemName) {
if (cd == null)
throw new IllegalArgumentException("Null CompositeData");
--- a/jdk/src/java.management/share/classes/sun/management/ManagementFactory.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.lang.management.MemoryManagerMXBean;
-import java.lang.management.MemoryPoolMXBean;
-import java.lang.management.GarbageCollectorMXBean;
-
-/**
- * ManagementFactory class provides the methods that the HotSpot VM
- * will invoke. So the class and method names cannot be renamed.
- */
-class ManagementFactory {
- private ManagementFactory() {};
-
- // Invoked by the VM
- private static MemoryPoolMXBean createMemoryPool
- (String name, boolean isHeap, long uThreshold, long gcThreshold) {
- return new MemoryPoolImpl(name, isHeap, uThreshold, gcThreshold);
- }
-
- private static MemoryManagerMXBean createMemoryManager(String name) {
- return new MemoryManagerImpl(name);
- }
-
- private static GarbageCollectorMXBean
- createGarbageCollector(String name, String type) {
-
- // ignore type parameter which is for future extension
- return new GarbageCollectorImpl(name);
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,6 @@
package sun.management;
import java.lang.management.*;
-
-import javax.management.DynamicMBean;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
@@ -38,30 +36,35 @@
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-
import sun.util.logging.LoggingSupport;
-
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
-import com.sun.management.DiagnosticCommandMBean;
-import com.sun.management.HotSpotDiagnosticMXBean;
/**
* ManagementFactoryHelper provides static factory methods to create
* instances of the management interface.
*/
public class ManagementFactoryHelper {
+ static {
+ // make sure that the management lib is loaded within
+ // java.lang.management.ManagementFactory
+ sun.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class);
+ }
+
+ private static final VMManagement jvm = new VMManagementImpl();
+
private ManagementFactoryHelper() {};
- private static VMManagement jvm;
+ public static VMManagement getVMManagement() {
+ return jvm;
+ }
private static ClassLoadingImpl classMBean = null;
private static MemoryImpl memoryMBean = null;
private static ThreadImpl threadMBean = null;
private static RuntimeImpl runtimeMBean = null;
private static CompilationImpl compileMBean = null;
- private static OperatingSystemImpl osMBean = null;
+ private static BaseOperatingSystemImpl osMBean = null;
public static synchronized ClassLoadingMXBean getClassLoadingMXBean() {
if (classMBean == null) {
@@ -100,7 +103,7 @@
public static synchronized OperatingSystemMXBean getOperatingSystemMXBean() {
if (osMBean == null) {
- osMBean = new OperatingSystemImpl(jvm);
+ osMBean = new BaseOperatingSystemImpl(jvm);
}
return osMBean;
}
@@ -123,7 +126,7 @@
return result;
}
- public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
+ public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers();
List<GarbageCollectorMXBean> result = new ArrayList<>(mgrs.length);
for (MemoryManagerMXBean m : mgrs) {
@@ -257,20 +260,11 @@
};
}
- private static HotSpotDiagnostic hsDiagMBean = null;
private static HotspotRuntime hsRuntimeMBean = null;
private static HotspotClassLoading hsClassMBean = null;
private static HotspotThread hsThreadMBean = null;
private static HotspotCompilation hsCompileMBean = null;
private static HotspotMemory hsMemoryMBean = null;
- private static DiagnosticCommandImpl hsDiagCommandMBean = null;
-
- public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
- if (hsDiagMBean == null) {
- hsDiagMBean = new HotSpotDiagnostic();
- }
- return hsDiagMBean;
- }
/**
* This method is for testing only.
@@ -312,14 +306,6 @@
return hsMemoryMBean;
}
- public static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() {
- // Remote Diagnostic Commands may not be supported
- if (hsDiagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) {
- hsDiagCommandMBean = new DiagnosticCommandImpl(jvm);
- }
- return hsDiagCommandMBean;
- }
-
/**
* This method is for testing only.
*/
@@ -374,18 +360,6 @@
private final static String HOTSPOT_THREAD_MBEAN_NAME =
"sun.management:type=HotspotThreading";
- final static String HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME =
- "com.sun.management:type=DiagnosticCommand";
-
- public static HashMap<ObjectName, DynamicMBean> getPlatformDynamicMBeans() {
- HashMap<ObjectName, DynamicMBean> map = new HashMap<>();
- DiagnosticCommandMBean diagMBean = getDiagnosticCommandMBean();
- if (diagMBean != null) {
- map.put(Util.newObjectName(HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME), diagMBean);
- }
- return map;
- }
-
static void registerInternalMBeans(MBeanServer mbs) {
// register all internal MBeans if not registered
// No exception is thrown if a MBean with that object name
@@ -441,17 +415,6 @@
}
}
- static {
- AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("management");
- return null;
- }
- });
- jvm = new VMManagementImpl();
- }
-
public static boolean isThreadSuspended(int state) {
return ((state & JMM_THREAD_STATE_FLAG_SUSPENDED) != 0);
}
@@ -471,4 +434,20 @@
private static final int JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000;
private static final int JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000;
+ // Invoked by the VM
+ private static MemoryPoolMXBean createMemoryPool
+ (String name, boolean isHeap, long uThreshold, long gcThreshold) {
+ return new MemoryPoolImpl(name, isHeap, uThreshold, gcThreshold);
+ }
+
+ private static MemoryManagerMXBean createMemoryManager(String name) {
+ return new MemoryManagerImpl(name);
+ }
+
+ private static GarbageCollectorMXBean
+ createGarbageCollector(String name, String type) {
+
+ // ignore type parameter which is for future extension
+ return new GarbageCollectorImpl(name);
+ }
}
--- a/jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,10 +38,8 @@
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import javax.management.*;
import javax.management.openmbean.*;
import static javax.management.openmbean.SimpleType.*;
-import com.sun.management.VMOption;
/**
* A mapped mxbean type maps a Java type to an open type.
@@ -113,7 +111,7 @@
return mt;
}
- static synchronized MappedMXBeanType getMappedType(Type t)
+ public static synchronized MappedMXBeanType getMappedType(Type t)
throws OpenDataException {
MappedMXBeanType mt = convertedTypes.get(t);
if (mt == null) {
@@ -152,7 +150,7 @@
}
// Return the mapped open type
- OpenType<?> getOpenType() {
+ public OpenType<?> getOpenType() {
return openType;
}
@@ -177,10 +175,10 @@
// return name of the class or the generic type
abstract String getName();
- abstract Object toOpenTypeData(Object javaTypeData)
+ public abstract Object toOpenTypeData(Object javaTypeData)
throws OpenDataException;
- abstract Object toJavaTypeData(Object openTypeData)
+ public abstract Object toJavaTypeData(Object openTypeData)
throws OpenDataException, InvalidObjectException;
// Basic Types - Classes that do not require data conversion
@@ -208,11 +206,11 @@
return basicType.getName();
}
- Object toOpenTypeData(Object data) throws OpenDataException {
+ public Object toOpenTypeData(Object data) throws OpenDataException {
return data;
}
- Object toJavaTypeData(Object data)
+ public Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
return data;
@@ -243,11 +241,11 @@
return enumClass.getName();
}
- Object toOpenTypeData(Object data) throws OpenDataException {
+ public Object toOpenTypeData(Object data) throws OpenDataException {
return ((Enum) data).name();
}
- Object toJavaTypeData(Object data)
+ public Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
try {
@@ -315,7 +313,7 @@
return arrayClass.getName();
}
- Object toOpenTypeData(Object data) throws OpenDataException {
+ public Object toOpenTypeData(Object data) throws OpenDataException {
// If the base element type is a basic type
// return the data as no conversion is needed.
// Primitive types are not converted to wrappers.
@@ -340,7 +338,7 @@
}
- Object toJavaTypeData(Object data)
+ public Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
// If the base element type is a basic type
@@ -457,7 +455,7 @@
return typeName;
}
- Object toOpenTypeData(Object data) throws OpenDataException {
+ public Object toOpenTypeData(Object data) throws OpenDataException {
final List<Object> list = (List<Object>) data;
final Object[] openArray = (Object[])
@@ -470,7 +468,7 @@
return openArray;
}
- Object toJavaTypeData(Object data)
+ public Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
final Object[] openArray = (Object[]) data;
@@ -538,7 +536,7 @@
return typeName;
}
- Object toOpenTypeData(Object data) throws OpenDataException {
+ public Object toOpenTypeData(Object data) throws OpenDataException {
final Map<Object,Object> map = (Map<Object,Object>) data;
final TabularType tabularType = (TabularType) openType;
final TabularData table = new TabularDataSupport(tabularType);
@@ -556,7 +554,7 @@
return table;
}
- Object toJavaTypeData(Object data)
+ public Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
final TabularData td = (TabularData) data;
@@ -605,8 +603,9 @@
//
static class CompositeDataMXBeanType extends MappedMXBeanType {
final Class<?> javaClass;
- final boolean isCompositeData;
+ boolean isCompositeData = false;
Method fromMethod = null;
+ Method toMethod = null;
CompositeDataMXBeanType(Class<?> c) throws OpenDataException {
this.javaClass = c;
@@ -624,6 +623,26 @@
// that has no from method to be embeded in another class.
}
+ // check if a static "toCompositeData" method exists
+ try {
+ toMethod = AccessController.doPrivileged(new PrivilegedExceptionAction<Method>() {
+ public Method run() throws NoSuchMethodException {
+ Method m = javaClass.getDeclaredMethod("toCompositeData", javaClass);
+ if (m != null
+ && CompositeData.class.isAssignableFrom(m.getReturnType())
+ && Modifier.isStatic(m.getModifiers())) {
+ m.setAccessible(true);
+ return m;
+ } else {
+ return null;
+ }
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ // ignore NoSuchMethodException since we allow classes
+ // that has no from method to be embeded in another class.
+ }
+
if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) {
// c implements CompositeData - set openType to null
// defer generating the CompositeType
@@ -636,16 +655,16 @@
// Make a CompositeData containing all the getters
final Method[] methods =
AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
- public Method[] run() {
- return javaClass.getMethods();
- }
- });
+ public Method[] run() {
+ return javaClass.getMethods();
+ }
+ });
final List<String> names = new ArrayList<>();
final List<OpenType<?>> types = new ArrayList<>();
/* Select public methods that look like "T getX()" or "boolean
- isX()", where T is not void and X is not the empty
- string. Exclude "Class getClass()" inherited from Object. */
+ isX()", where T is not void and X is not the empty
+ string. Exclude "Class getClass()" inherited from Object. */
for (int i = 0; i < methods.length; i++) {
final Method method = methods[i];
final String name = method.getName();
@@ -676,10 +695,10 @@
final String[] nameArray = names.toArray(new String[0]);
openType = new CompositeType(c.getName(),
- c.getName(),
- nameArray, // field names
- nameArray, // field descriptions
- types.toArray(new OpenType<?>[0]));
+ c.getName(),
+ nameArray, // field names
+ nameArray, // field descriptions
+ types.toArray(new OpenType<?>[0]));
}
}
@@ -691,7 +710,23 @@
return javaClass.getName();
}
- Object toOpenTypeData(Object data) throws OpenDataException {
+ public Object toOpenTypeData(Object data) throws OpenDataException {
+ if (toMethod != null) {
+ try {
+ return toMethod.invoke(null, data);
+ } catch (IllegalAccessException e) {
+ // should never reach here
+ throw new AssertionError(e);
+ } catch (InvocationTargetException e) {
+ final OpenDataException ode
+ = new OpenDataException("Failed to invoke "
+ + toMethod.getName() + " to convert " + javaClass.getName()
+ + " to CompositeData");
+ ode.initCause(e);
+ throw ode;
+ }
+ }
+
if (data instanceof MemoryUsage) {
return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data);
}
@@ -712,10 +747,6 @@
toCompositeData((MemoryNotificationInfo) data);
}
- if (data instanceof VMOption) {
- return VMOptionCompositeData.toCompositeData((VMOption) data);
- }
-
if (isCompositeData) {
// Classes that implement CompositeData
//
@@ -732,7 +763,7 @@
" is not supported for platform MXBeans");
}
- Object toJavaTypeData(Object data)
+ public Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
if (fromMethod == null) {
--- a/jdk/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,13 +34,12 @@
import java.util.List;
import java.util.ArrayList;
-import java.util.ListIterator;
import java.util.Collections;
/**
* Abstract helper class for notification emitter support.
*/
-abstract class NotificationEmitterSupport implements NotificationEmitter {
+public abstract class NotificationEmitterSupport implements NotificationEmitter {
protected NotificationEmitterSupport() {
}
@@ -135,7 +134,7 @@
}
}
- void sendNotification(Notification notification) {
+ public void sendNotification(Notification notification) {
if (notification == null) {
return;
@@ -162,7 +161,7 @@
}
}
- boolean hasListeners() {
+ public boolean hasListeners() {
synchronized (listenerLock) {
return !listenerList.isEmpty();
}
--- a/jdk/src/java.management/share/classes/sun/management/ThreadImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/ThreadImpl.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,20 +26,18 @@
package sun.management;
import java.lang.management.ManagementFactory;
-
import java.lang.management.ThreadInfo;
-
+import java.lang.management.ThreadMXBean;
import javax.management.ObjectName;
/**
- * Implementation class for the thread subsystem.
- * Standard and committed hotspot-specific metrics if any.
- *
- * ManagementFactory.getThreadMXBean() returns an instance
- * of this class.
+ * Implementation for java.lang.management.ThreadMXBean as well as providing the
+ * supporting method for com.sun.management.ThreadMXBean.
+ * The supporting method for com.sun.management.ThreadMXBean can be moved to
+ * jdk.management in the future.
*/
-class ThreadImpl implements com.sun.management.ThreadMXBean {
+public class ThreadImpl implements ThreadMXBean {
private final VMManagement jvm;
// default for thread contention monitoring is disabled.
@@ -50,32 +48,38 @@
/**
* Constructor of ThreadImpl class.
*/
- ThreadImpl(VMManagement vm) {
+ protected ThreadImpl(VMManagement vm) {
this.jvm = vm;
this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled();
this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled();
}
+ @Override
public int getThreadCount() {
return jvm.getLiveThreadCount();
}
+ @Override
public int getPeakThreadCount() {
return jvm.getPeakThreadCount();
}
+ @Override
public long getTotalStartedThreadCount() {
return jvm.getTotalThreadCount();
}
+ @Override
public int getDaemonThreadCount() {
return jvm.getDaemonThreadCount();
}
+ @Override
public boolean isThreadContentionMonitoringSupported() {
return jvm.isThreadContentionMonitoringSupported();
}
+ @Override
public synchronized boolean isThreadContentionMonitoringEnabled() {
if (!isThreadContentionMonitoringSupported()) {
throw new UnsupportedOperationException(
@@ -84,18 +88,21 @@
return contentionMonitoringEnabled;
}
+ @Override
public boolean isThreadCpuTimeSupported() {
return jvm.isOtherThreadCpuTimeSupported();
}
+ @Override
public boolean isCurrentThreadCpuTimeSupported() {
return jvm.isCurrentThreadCpuTimeSupported();
}
- public boolean isThreadAllocatedMemorySupported() {
+ protected boolean isThreadAllocatedMemorySupported() {
return jvm.isThreadAllocatedMemorySupported();
}
+ @Override
public boolean isThreadCpuTimeEnabled() {
if (!isThreadCpuTimeSupported() &&
!isCurrentThreadCpuTimeSupported()) {
@@ -105,7 +112,7 @@
return cpuTimeEnabled;
}
- public boolean isThreadAllocatedMemoryEnabled() {
+ protected boolean isThreadAllocatedMemoryEnabled() {
if (!isThreadAllocatedMemorySupported()) {
throw new UnsupportedOperationException(
"Thread allocated memory measurement is not supported");
@@ -113,6 +120,7 @@
return allocatedMemoryEnabled;
}
+ @Override
public long[] getAllThreadIds() {
Util.checkMonitorAccess();
@@ -126,6 +134,7 @@
return ids;
}
+ @Override
public ThreadInfo getThreadInfo(long id) {
long[] ids = new long[1];
ids[0] = id;
@@ -133,6 +142,7 @@
return infos[0];
}
+ @Override
public ThreadInfo getThreadInfo(long id, int maxDepth) {
long[] ids = new long[1];
ids[0] = id;
@@ -140,6 +150,7 @@
return infos[0];
}
+ @Override
public ThreadInfo[] getThreadInfo(long[] ids) {
return getThreadInfo(ids, 0);
}
@@ -157,6 +168,7 @@
}
}
+ @Override
public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) {
verifyThreadIds(ids);
@@ -165,6 +177,10 @@
"Invalid maxDepth parameter: " + maxDepth);
}
+ // ids has been verified to be non-null
+ // an empty array of ids should return an empty array of ThreadInfos
+ if (ids.length == 0) return new ThreadInfo[0];
+
Util.checkMonitorAccess();
ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls
@@ -176,6 +192,7 @@
return infos;
}
+ @Override
public void setThreadContentionMonitoringEnabled(boolean enable) {
if (!isThreadContentionMonitoringSupported()) {
throw new UnsupportedOperationException(
@@ -209,6 +226,7 @@
return isThreadCpuTimeEnabled();
}
+ @Override
public long getCurrentThreadCpuTime() {
if (verifyCurrentThreadCpuTime()) {
return getThreadTotalCpuTime0(0);
@@ -216,6 +234,7 @@
return -1;
}
+ @Override
public long getThreadCpuTime(long id) {
long[] ids = new long[1];
ids[0] = id;
@@ -247,7 +266,7 @@
return isThreadCpuTimeEnabled();
}
- public long[] getThreadCpuTime(long[] ids) {
+ protected long[] getThreadCpuTime(long[] ids) {
boolean verified = verifyThreadCpuTime(ids);
int length = ids.length;
@@ -268,6 +287,7 @@
return times;
}
+ @Override
public long getCurrentThreadUserTime() {
if (verifyCurrentThreadCpuTime()) {
return getThreadUserCpuTime0(0);
@@ -275,6 +295,7 @@
return -1;
}
+ @Override
public long getThreadUserTime(long id) {
long[] ids = new long[1];
ids[0] = id;
@@ -282,7 +303,7 @@
return times[0];
}
- public long[] getThreadUserTime(long[] ids) {
+ protected long[] getThreadUserTime(long[] ids) {
boolean verified = verifyThreadCpuTime(ids);
int length = ids.length;
@@ -303,6 +324,7 @@
return times;
}
+ @Override
public void setThreadCpuTimeEnabled(boolean enable) {
if (!isThreadCpuTimeSupported() &&
!isCurrentThreadCpuTimeSupported()) {
@@ -320,7 +342,7 @@
}
}
- public long getThreadAllocatedBytes(long id) {
+ protected long getThreadAllocatedBytes(long id) {
long[] ids = new long[1];
ids[0] = id;
final long[] sizes = getThreadAllocatedBytes(ids);
@@ -339,7 +361,7 @@
return isThreadAllocatedMemoryEnabled();
}
- public long[] getThreadAllocatedBytes(long[] ids) {
+ protected long[] getThreadAllocatedBytes(long[] ids) {
boolean verified = verifyThreadAllocatedMemory(ids);
long[] sizes = new long[ids.length];
@@ -351,7 +373,7 @@
return sizes;
}
- public void setThreadAllocatedMemoryEnabled(boolean enable) {
+ protected void setThreadAllocatedMemoryEnabled(boolean enable) {
if (!isThreadAllocatedMemorySupported()) {
throw new UnsupportedOperationException(
"Thread allocated memory measurement is not supported.");
@@ -367,6 +389,7 @@
}
}
+ @Override
public long[] findMonitorDeadlockedThreads() {
Util.checkMonitorAccess();
@@ -383,6 +406,7 @@
return ids;
}
+ @Override
public long[] findDeadlockedThreads() {
if (!isSynchronizerUsageSupported()) {
throw new UnsupportedOperationException(
@@ -404,15 +428,18 @@
return ids;
}
+ @Override
public void resetPeakThreadCount() {
Util.checkControlAccess();
resetPeakThreadCount0();
}
+ @Override
public boolean isObjectMonitorUsageSupported() {
return jvm.isObjectMonitorUsageSupported();
}
+ @Override
public boolean isSynchronizerUsageSupported() {
return jvm.isSynchronizerUsageSupported();
}
@@ -432,14 +459,20 @@
Util.checkMonitorAccess();
}
+ @Override
public ThreadInfo[] getThreadInfo(long[] ids,
boolean lockedMonitors,
boolean lockedSynchronizers) {
verifyThreadIds(ids);
+ // ids has been verified to be non-null
+ // an empty array of ids should return an empty array of ThreadInfos
+ if (ids.length == 0) return new ThreadInfo[0];
+
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
return dumpThreads0(ids, lockedMonitors, lockedSynchronizers);
}
+ @Override
public ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
boolean lockedSynchronizers) {
verifyDumpThreads(lockedMonitors, lockedSynchronizers);
@@ -469,6 +502,7 @@
// tid == 0 to reset contention times for all threads
private static native void resetContentionTimes0(long tid);
+ @Override
public ObjectName getObjectName() {
return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME);
}
--- a/jdk/src/java.management/share/classes/sun/management/Util.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/Util.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
static void checkMonitorAccess() throws SecurityException {
checkAccess(monitorPermission);
}
- static void checkControlAccess() throws SecurityException {
+ public static void checkControlAccess() throws SecurityException {
checkAccess(controlPermission);
}
}
--- a/jdk/src/java.management/share/classes/sun/management/VMOptionCompositeData.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import com.sun.management.VMOption;
-import com.sun.management.VMOption.Origin;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.management.openmbean.OpenDataException;
-
-/**
- * A CompositeData for VMOption for the local management support.
- * This class avoids the performance penalty paid to the
- * construction of a CompositeData use in the local case.
- */
-public class VMOptionCompositeData extends LazyCompositeData {
- private final VMOption option;
-
- private VMOptionCompositeData(VMOption option) {
- this.option = option;
- }
-
- public VMOption getVMOption() {
- return option;
- }
-
- public static CompositeData toCompositeData(VMOption option) {
- VMOptionCompositeData vcd = new VMOptionCompositeData(option);
- return vcd.getCompositeData();
- }
-
- protected CompositeData getCompositeData() {
- // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
- // vmOptionItemNames!
- final Object[] vmOptionItemValues = {
- option.getName(),
- option.getValue(),
- option.isWriteable(),
- option.getOrigin().toString(),
- };
-
- try {
- return new CompositeDataSupport(vmOptionCompositeType,
- vmOptionItemNames,
- vmOptionItemValues);
- } catch (OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- private static final CompositeType vmOptionCompositeType;
- static {
- try {
- vmOptionCompositeType = (CompositeType)
- MappedMXBeanType.toOpenType(VMOption.class);
- } catch (OpenDataException e) {
- // Should never reach here
- throw new AssertionError(e);
- }
- }
-
- static CompositeType getVMOptionCompositeType() {
- return vmOptionCompositeType;
- }
-
- private static final String NAME = "name";
- private static final String VALUE = "value";
- private static final String WRITEABLE = "writeable";
- private static final String ORIGIN = "origin";
-
- private static final String[] vmOptionItemNames = {
- NAME,
- VALUE,
- WRITEABLE,
- ORIGIN,
- };
-
- public static String getName(CompositeData cd) {
- return getString(cd, NAME);
- }
- public static String getValue(CompositeData cd) {
- return getString(cd, VALUE);
- }
- public static Origin getOrigin(CompositeData cd) {
- String o = getString(cd, ORIGIN);
- return Enum.valueOf(Origin.class, o);
- }
- public static boolean isWriteable(CompositeData cd) {
- return getBoolean(cd, WRITEABLE);
- }
-
- /** Validate if the input CompositeData has the expected
- * CompositeType (i.e. contain all attributes with expected
- * names and types).
- */
- public static void validateCompositeData(CompositeData cd) {
- if (cd == null) {
- throw new NullPointerException("Null CompositeData");
- }
-
- if (!isTypeMatched(vmOptionCompositeType, cd.getCompositeType())) {
- throw new IllegalArgumentException(
- "Unexpected composite type for VMOption");
- }
- }
-
- private static final long serialVersionUID = -2395573975093578470L;
-}
--- a/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java Fri May 01 03:56:04 2015 -0700
@@ -205,7 +205,7 @@
* Instantiates a new PlatformMBeanProvider.
*
* @throws SecurityException if the subclass (and calling code) does not
- * have {@code RuntimePermission("sun.management.spi.PlatformMBeanProvider", "subclass")}
+ * have {@code RuntimePermission("sun.management.spi.PlatformMBeanProvider.subclass")}
*/
protected PlatformMBeanProvider () {
this(checkSubclassPermission());
@@ -226,7 +226,7 @@
private static Void checkSubclassPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission(PlatformMBeanProvider.class.getName(), "subclass"));
+ sm.checkPermission(new RuntimePermission(PlatformMBeanProvider.class.getName()+".subclass"));
}
return null;
}
--- a/jdk/src/java.management/share/native/libmanagement/DiagnosticCommandImpl.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdlib.h>
-#include <jni.h>
-#include "management.h"
-#include "sun_management_DiagnosticCommandImpl.h"
-
-JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled
-(JNIEnv *env, jobject dummy, jboolean enabled) {
- if (jmm_version <= JMM_VERSION_1_2_2) {
- JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
- "JMX interface to diagnostic framework notifications is not supported by this VM");
- return;
- }
- jmm_interface->SetDiagnosticFrameworkNotificationEnabled(env, enabled);
-}
-
-JNIEXPORT jobjectArray JNICALL
-Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands
- (JNIEnv *env, jobject dummy)
-{
- return jmm_interface->GetDiagnosticCommands(env);
-}
-
-jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
- int num_arg) {
- int i;
- jobject obj;
- jobjectArray result;
- dcmdArgInfo* dcmd_arg_info_array;
- jclass dcmdArgInfoCls;
- jclass arraysCls;
- jmethodID mid;
- jobject resultList;
-
- dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
- /* According to ISO C it is perfectly legal for malloc to return zero if called with a zero argument */
- if (dcmd_arg_info_array == NULL && num_arg != 0) {
- return NULL;
- }
- jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
- dcmd_arg_info_array);
- dcmdArgInfoCls = (*env)->FindClass(env,
- "sun/management/DiagnosticCommandArgumentInfo");
- if ((*env)->ExceptionCheck(env)) {
- free(dcmd_arg_info_array);
- return NULL;
- }
-
- result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
- if (result == NULL) {
- free(dcmd_arg_info_array);
- return NULL;
- }
- for (i=0; i<num_arg; i++) {
- obj = JNU_NewObjectByName(env,
- "sun/management/DiagnosticCommandArgumentInfo",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V",
- (*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
- (*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
- (*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
- dcmd_arg_info_array[i].default_string == NULL ? NULL:
- (*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
- dcmd_arg_info_array[i].mandatory,
- dcmd_arg_info_array[i].option,
- dcmd_arg_info_array[i].multiple,
- dcmd_arg_info_array[i].position);
- if (obj == NULL) {
- free(dcmd_arg_info_array);
- return NULL;
- }
- (*env)->SetObjectArrayElement(env, result, i, obj);
- }
- free(dcmd_arg_info_array);
- arraysCls = (*env)->FindClass(env, "java/util/Arrays");
- if ((*env)->ExceptionCheck(env)) {
- return NULL;
- }
- mid = (*env)->GetStaticMethodID(env, arraysCls,
- "asList", "([Ljava/lang/Object;)Ljava/util/List;");
- resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
- if ((*env)->ExceptionCheck(env)) {
- // Make sure we return NULL in case of OOM inside Java
- return NULL;
- }
- return resultList;
-}
-
-/* Throws IllegalArgumentException if at least one of the diagnostic command
- * passed in argument is not supported by the JVM
- */
-JNIEXPORT jobjectArray JNICALL
-Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo
-(JNIEnv *env, jobject dummy, jobjectArray commands)
-{
- int i;
- jclass dcmdInfoCls;
- jobject result;
- jobjectArray args;
- jobject obj;
- jmmOptionalSupport mos;
- jint ret = jmm_interface->GetOptionalSupport(env, &mos);
- jsize num_commands;
- dcmdInfo* dcmd_info_array;
-
- if (commands == NULL) {
- JNU_ThrowNullPointerException(env, "Invalid String Array");
- return NULL;
- }
- num_commands = (*env)->GetArrayLength(env, commands);
- dcmdInfoCls = (*env)->FindClass(env,
- "sun/management/DiagnosticCommandInfo");
- if ((*env)->ExceptionCheck(env)) {
- return NULL;
- }
-
- result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
- if (result == NULL) {
- JNU_ThrowOutOfMemoryError(env, 0);
- return NULL;
- }
- if (num_commands == 0) {
- /* Handle the 'zero commands' case specially to avoid calling 'malloc()' */
- /* with a zero argument because that may legally return a NULL pointer. */
- return result;
- }
- dcmd_info_array = (dcmdInfo*) malloc(num_commands * sizeof(dcmdInfo));
- if (dcmd_info_array == NULL) {
- JNU_ThrowOutOfMemoryError(env, NULL);
- return NULL;
- }
- jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
- for (i=0; i<num_commands; i++) {
- args = getDiagnosticCommandArgumentInfoArray(env,
- (*env)->GetObjectArrayElement(env,commands,i),
- dcmd_info_array[i].num_arguments);
- if (args == NULL) {
- free(dcmd_info_array);
- JNU_ThrowOutOfMemoryError(env, 0);
- return NULL;
- }
- obj = JNU_NewObjectByName(env,
- "sun/management/DiagnosticCommandInfo",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
- (*env)->NewStringUTF(env,dcmd_info_array[i].name),
- (*env)->NewStringUTF(env,dcmd_info_array[i].description),
- (*env)->NewStringUTF(env,dcmd_info_array[i].impact),
- dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
- dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
- dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
- dcmd_info_array[i].enabled,
- args);
- if (obj == NULL) {
- free(dcmd_info_array);
- JNU_ThrowOutOfMemoryError(env, 0);
- return NULL;
- }
- (*env)->SetObjectArrayElement(env, result, i, obj);
- }
- free(dcmd_info_array);
- return result;
-}
-
-/* Throws IllegalArgumentException if the diagnostic command
- * passed in argument is not supported by the JVM
- */
-JNIEXPORT jstring JNICALL
-Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand
-(JNIEnv *env, jobject dummy, jstring command) {
- return jmm_interface->ExecuteDiagnosticCommand(env, command);
-}
--- a/jdk/src/java.management/share/native/libmanagement/Flag.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <jni.h>
-#include "management.h"
-#include "sun_management_Flag.h"
-
-static jobject default_origin = NULL;
-static jobject vm_creation_origin = NULL;
-static jobject mgmt_origin = NULL;
-static jobject envvar_origin = NULL;
-static jobject config_file_origin = NULL;
-static jobject ergo_origin = NULL;
-static jobject attach_origin = NULL;
-static jobject other_origin = NULL;
-
-JNIEXPORT jint JNICALL
-Java_sun_management_Flag_getInternalFlagCount
- (JNIEnv *env, jclass cls)
-{
- jlong count = jmm_interface->GetLongAttribute(env, NULL,
- JMM_VM_GLOBAL_COUNT);
- return (jint) count;
-}
-
-JNIEXPORT jobjectArray JNICALL
- Java_sun_management_Flag_getAllFlagNames
-(JNIEnv *env, jclass cls)
-{
- return jmm_interface->GetVMGlobalNames(env);
-}
-
-static jobject find_origin_constant(JNIEnv* env, const char* enum_name) {
- jvalue field;
- field = JNU_GetStaticFieldByName(env,
- NULL,
- "com/sun/management/VMOption$Origin",
- enum_name,
- "Lcom/sun/management/VMOption$Origin;");
- return (*env)->NewGlobalRef(env, field.l);
-}
-
-JNIEXPORT void JNICALL
-Java_sun_management_Flag_initialize
- (JNIEnv *env, jclass cls)
-{
- default_origin = find_origin_constant(env, "DEFAULT");
- vm_creation_origin = find_origin_constant(env, "VM_CREATION");
- mgmt_origin = find_origin_constant(env, "MANAGEMENT");
- envvar_origin = find_origin_constant(env, "ENVIRON_VAR");
- config_file_origin = find_origin_constant(env, "CONFIG_FILE");
- ergo_origin = find_origin_constant(env, "ERGONOMIC");
- attach_origin = find_origin_constant(env, "ATTACH_ON_DEMAND");
- other_origin = find_origin_constant(env, "OTHER");
-}
-
-JNIEXPORT jint JNICALL
-Java_sun_management_Flag_getFlags
- (JNIEnv *env, jclass cls, jobjectArray names, jobjectArray flags, jint count)
-{
- jint num_flags, i, index;
- jmmVMGlobal* globals;
- size_t gsize;
- const char* class_name = "sun/management/Flag";
- const char* signature = "(Ljava/lang/String;Ljava/lang/Object;ZZLcom/sun/management/VMOption$Origin;)V";
- jobject origin;
- jobject valueObj;
- jobject flag;
-
- if (flags == NULL) {
- JNU_ThrowNullPointerException(env, 0);
- return 0;
- }
-
- if (count <= 0) {
- JNU_ThrowIllegalArgumentException(env, 0);
- return 0;
- }
-
- gsize = (size_t)count * sizeof(jmmVMGlobal);
- globals = (jmmVMGlobal*) malloc(gsize);
- if (globals == NULL) {
- JNU_ThrowOutOfMemoryError(env, 0);
- return 0;
- }
-
- memset(globals, 0, gsize);
- num_flags = jmm_interface->GetVMGlobals(env, names, globals, count);
- if (num_flags == 0) {
- free(globals);
- return 0;
- }
-
- index = 0;
- for (i = 0; i < count; i++) {
- if (globals[i].name == NULL) {
- continue;
- }
- switch (globals[i].type) {
- case JMM_VMGLOBAL_TYPE_JBOOLEAN:
- valueObj = JNU_NewObjectByName(env, "java/lang/Boolean", "(Z)V",
- globals[i].value.z);
- break;
- case JMM_VMGLOBAL_TYPE_JSTRING:
- valueObj = globals[i].value.l;
- break;
- case JMM_VMGLOBAL_TYPE_JLONG:
- valueObj = JNU_NewObjectByName(env, "java/lang/Long", "(J)V",
- globals[i].value.j);
- break;
- case JMM_VMGLOBAL_TYPE_JDOUBLE:
- valueObj = JNU_NewObjectByName(env, "java/lang/Double", "(D)V",
- globals[i].value.d);
- break;
- default:
- // ignore unsupported type
- continue;
- }
- switch (globals[i].origin) {
- case JMM_VMGLOBAL_ORIGIN_DEFAULT:
- origin = default_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_COMMAND_LINE:
- origin = vm_creation_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_MANAGEMENT:
- origin = mgmt_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR:
- origin = envvar_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_CONFIG_FILE:
- origin = config_file_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_ERGONOMIC:
- origin = ergo_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND:
- origin = attach_origin;
- break;
- case JMM_VMGLOBAL_ORIGIN_OTHER:
- origin = other_origin;
- break;
- default:
- // unknown origin
- origin = other_origin;
- break;
- }
- flag = JNU_NewObjectByName(env, class_name, signature, globals[i].name,
- valueObj, globals[i].writeable,
- globals[i].external, origin);
- if (flag == NULL) {
- free(globals);
- JNU_ThrowOutOfMemoryError(env, 0);
- return 0;
- }
- (*env)->SetObjectArrayElement(env, flags, index, flag);
- index++;
- }
-
- if (index != num_flags) {
- JNU_ThrowInternalError(env, "Number of Flag objects created unmatched");
- free(globals);
- return 0;
- }
-
- free(globals);
-
- /* return the number of Flag objects created */
- return num_flags;
-}
-
-JNIEXPORT void JNICALL
-Java_sun_management_Flag_setLongValue
- (JNIEnv *env, jclass cls, jstring name, jlong value)
-{
- jvalue v;
- v.j = value;
-
- jmm_interface->SetVMGlobal(env, name, v);
-}
-
-JNIEXPORT void JNICALL
-Java_sun_management_Flag_setDoubleValue
- (JNIEnv *env, jclass cls, jstring name, jdouble value)
-{
- jvalue v;
- v.d = value;
-
- jmm_interface->SetVMGlobal(env, name, v);
-}
-
-JNIEXPORT void JNICALL
-Java_sun_management_Flag_setBooleanValue
- (JNIEnv *env, jclass cls, jstring name, jboolean value)
-{
- jvalue v;
- v.z = value;
-
- jmm_interface->SetVMGlobal(env, name, v);
-}
-
-JNIEXPORT void JNICALL
-Java_sun_management_Flag_setStringValue
- (JNIEnv *env, jclass cls, jstring name, jstring value)
-{
- jvalue v;
- v.l = value;
-
- jmm_interface->SetVMGlobal(env, name, v);
-}
--- a/jdk/src/java.management/share/native/libmanagement/GarbageCollectorImpl.c Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/java.management/share/native/libmanagement/GarbageCollectorImpl.c Fri May 01 03:56:04 2015 -0700
@@ -36,17 +36,3 @@
(JNIEnv *env, jobject mgr) {
return jmm_interface->GetLongAttribute(env, mgr, JMM_GC_TIME_MS);
}
-
-
-JNIEXPORT void JNICALL Java_sun_management_GarbageCollectorImpl_setNotificationEnabled
-(JNIEnv *env, jobject dummy, jobject gc,jboolean enabled) {
-
- if (gc == NULL) {
- JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
- return;
- }
- if((jmm_version > JMM_VERSION_1_2)
- || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=1))) {
- jmm_interface->SetGCNotificationEnabled(env, gc, enabled);
- }
-}
--- a/jdk/src/java.management/share/native/libmanagement/GcInfoBuilder.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <jni.h>
-#include "management.h"
-#include "sun_management_GcInfoBuilder.h"
-
-JNIEXPORT jint JNICALL Java_sun_management_GcInfoBuilder_getNumGcExtAttributes
- (JNIEnv *env, jobject dummy, jobject gc) {
- jlong value;
-
- if (gc == NULL) {
- JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
- return 0;
- }
- value = jmm_interface->GetLongAttribute(env, gc,
- JMM_GC_EXT_ATTRIBUTE_INFO_SIZE);
- return (jint) value;
-}
-
-JNIEXPORT void JNICALL Java_sun_management_GcInfoBuilder_fillGcAttributeInfo
- (JNIEnv *env, jobject dummy, jobject gc,
- jint num_attributes, jobjectArray attributeNames,
- jcharArray types, jobjectArray descriptions) {
-
- jmmExtAttributeInfo* ext_att_info;
- jchar* nativeTypes;
- jstring attName = NULL;
- jstring desc = NULL;
- jint ret = 0;
- jint i;
-
- if (gc == NULL) {
- JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
- return;
- }
-
- if (num_attributes <= 0) {
- JNU_ThrowIllegalArgumentException(env, "Invalid num_attributes");
- return;
- }
-
- ext_att_info = (jmmExtAttributeInfo*) malloc((size_t)num_attributes *
- sizeof(jmmExtAttributeInfo));
- if (ext_att_info == NULL) {
- JNU_ThrowOutOfMemoryError(env, 0);
- return;
- }
- ret = jmm_interface->GetGCExtAttributeInfo(env, gc,
- ext_att_info, num_attributes);
- if (ret != num_attributes) {
- JNU_ThrowInternalError(env, "Unexpected num_attributes");
- free(ext_att_info);
- return;
- }
-
- nativeTypes = (jchar*) malloc((size_t)num_attributes * sizeof(jchar));
- if (nativeTypes == NULL) {
- free(ext_att_info);
- JNU_ThrowOutOfMemoryError(env, 0);
- return;
- }
- for (i = 0; i < num_attributes; i++) {
- nativeTypes[i] = ext_att_info[i].type;
- attName = (*env)->NewStringUTF(env, ext_att_info[i].name);
- desc = (*env)->NewStringUTF(env, ext_att_info[i].description);
- (*env)->SetObjectArrayElement(env, attributeNames, i, attName);
- (*env)->SetObjectArrayElement(env, descriptions, i, desc);
- }
- (*env)->SetCharArrayRegion(env, types, 0, num_attributes, nativeTypes);
-
- if (ext_att_info != NULL) {
- free(ext_att_info);
- }
- if (nativeTypes != NULL) {
- free(nativeTypes);
- }
-}
-
-static void setLongValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jlong value) {
- static const char* class_name = "java/lang/Long";
- static const char* signature = "(J)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setBooleanValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jboolean value) {
- static const char* class_name = "java/lang/Boolean";
- static const char* signature = "(Z)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setByteValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jbyte value) {
- static const char* class_name = "java/lang/Byte";
- static const char* signature = "(B)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setIntValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jint value) {
- static const char* class_name = "java/lang/Integer";
- static const char* signature = "(I)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setShortValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jshort value) {
- static const char* class_name = "java/lang/Short";
- static const char* signature = "(S)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setDoubleValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jdouble value) {
- static const char* class_name = "java/lang/Double";
- static const char* signature = "(D)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setFloatValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jfloat value) {
- static const char* class_name = "java/lang/Float";
- static const char* signature = "(D)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-static void setCharValueAtObjectArray(JNIEnv *env, jobjectArray array,
- jsize index, jchar value) {
- static const char* class_name = "java/lang/Character";
- static const char* signature = "(C)V";
- jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
-
- (*env)->SetObjectArrayElement(env, array, index, obj);
-}
-
-JNIEXPORT jobject JNICALL Java_sun_management_GcInfoBuilder_getLastGcInfo0
- (JNIEnv *env, jobject builder, jobject gc,
- jint ext_att_count, jobjectArray ext_att_values, jcharArray ext_att_types,
- jobjectArray usageBeforeGC, jobjectArray usageAfterGC) {
-
- jmmGCStat gc_stat;
- jchar* nativeTypes;
- jsize i;
- jvalue v;
-
- if (gc == NULL) {
- JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
- return 0;
- }
-
- if (ext_att_count <= 0) {
- JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count");
- return 0;
- }
-
- gc_stat.usage_before_gc = usageBeforeGC;
- gc_stat.usage_after_gc = usageAfterGC;
- gc_stat.gc_ext_attribute_values_size = ext_att_count;
- if (ext_att_count > 0) {
- gc_stat.gc_ext_attribute_values = (jvalue*) malloc((size_t)ext_att_count *
- sizeof(jvalue));
- if (gc_stat.gc_ext_attribute_values == NULL) {
- JNU_ThrowOutOfMemoryError(env, 0);
- return 0;
- }
- } else {
- gc_stat.gc_ext_attribute_values = NULL;
- }
-
-
- jmm_interface->GetLastGCStat(env, gc, &gc_stat);
- if (gc_stat.gc_index == 0) {
- if (gc_stat.gc_ext_attribute_values != NULL) {
- free(gc_stat.gc_ext_attribute_values);
- }
- return 0;
- }
-
- // convert the ext_att_types to native types
- nativeTypes = (jchar*) malloc((size_t)ext_att_count * sizeof(jchar));
- if (nativeTypes == NULL) {
- if (gc_stat.gc_ext_attribute_values != NULL) {
- free(gc_stat.gc_ext_attribute_values);
- }
- JNU_ThrowOutOfMemoryError(env, 0);
- return 0;
- }
- (*env)->GetCharArrayRegion(env, ext_att_types, 0, ext_att_count, nativeTypes);
- for (i = 0; i < ext_att_count; i++) {
- v = gc_stat.gc_ext_attribute_values[i];
- switch (nativeTypes[i]) {
- case 'Z':
- setBooleanValueAtObjectArray(env, ext_att_values, i, v.z);
- break;
- case 'B':
- setByteValueAtObjectArray(env, ext_att_values, i, v.b);
- break;
- case 'C':
- setCharValueAtObjectArray(env, ext_att_values, i, v.c);
- break;
- case 'S':
- setShortValueAtObjectArray(env, ext_att_values, i, v.s);
- break;
- case 'I':
- setIntValueAtObjectArray(env, ext_att_values, i, v.i);
- break;
- case 'J':
- setLongValueAtObjectArray(env, ext_att_values, i, v.j);
- break;
- case 'F':
- setFloatValueAtObjectArray(env, ext_att_values, i, v.f);
- break;
- case 'D':
- setDoubleValueAtObjectArray(env, ext_att_values, i, v.d);
- break;
- default:
- if (gc_stat.gc_ext_attribute_values != NULL) {
- free(gc_stat.gc_ext_attribute_values);
- }
- if (nativeTypes != NULL) {
- free(nativeTypes);
- }
- JNU_ThrowInternalError(env, "Unsupported attribute type");
- return 0;
- }
- }
- if (gc_stat.gc_ext_attribute_values != NULL) {
- free(gc_stat.gc_ext_attribute_values);
- }
- if (nativeTypes != NULL) {
- free(nativeTypes);
- }
-
- return JNU_NewObjectByName(env,
- "com/sun/management/GcInfo",
- "(Lsun/management/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V",
- builder,
- gc_stat.gc_index,
- gc_stat.start_time,
- gc_stat.end_time,
- usageBeforeGC,
- usageAfterGC,
- ext_att_values);
-}
--- a/jdk/src/java.management/share/native/libmanagement/HotSpotDiagnostic.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-#include "jvm.h"
-#include "management.h"
-#include "sun_management_HotSpotDiagnostic.h"
-
-JNIEXPORT void JNICALL
-Java_sun_management_HotSpotDiagnostic_dumpHeap0
- (JNIEnv *env, jobject dummy, jstring outputfile, jboolean live)
-{
- jmm_interface->DumpHeap0(env, outputfile, live);
-}
--- a/jdk/src/java.management/unix/classes/sun/management/OperatingSystemImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-/**
- * Implementation class for the operating system.
- * Standard and committed hotspot-specific metrics if any.
- *
- * ManagementFactory.getOperatingSystemMXBean() returns an instance
- * of this class.
- */
-class OperatingSystemImpl extends BaseOperatingSystemImpl
- implements com.sun.management.UnixOperatingSystemMXBean {
-
- OperatingSystemImpl(VMManagement vm) {
- super(vm);
- }
-
- public long getCommittedVirtualMemorySize() {
- return getCommittedVirtualMemorySize0();
- }
-
- public long getTotalSwapSpaceSize() {
- return getTotalSwapSpaceSize0();
- }
-
- public long getFreeSwapSpaceSize() {
- return getFreeSwapSpaceSize0();
- }
-
- public long getProcessCpuTime() {
- return getProcessCpuTime0();
- }
-
- public long getFreePhysicalMemorySize() {
- return getFreePhysicalMemorySize0();
- }
-
- public long getTotalPhysicalMemorySize() {
- return getTotalPhysicalMemorySize0();
- }
-
- public long getOpenFileDescriptorCount() {
- return getOpenFileDescriptorCount0();
- }
-
- public long getMaxFileDescriptorCount() {
- return getMaxFileDescriptorCount0();
- }
-
- public double getSystemCpuLoad() {
- return getSystemCpuLoad0();
- }
-
- public double getProcessCpuLoad() {
- return getProcessCpuLoad0();
- }
-
- /* native methods */
- private native long getCommittedVirtualMemorySize0();
- private native long getFreePhysicalMemorySize0();
- private native long getFreeSwapSpaceSize0();
- private native long getMaxFileDescriptorCount0();
- private native long getOpenFileDescriptorCount0();
- private native long getProcessCpuTime0();
- private native double getProcessCpuLoad0();
- private native double getSystemCpuLoad0();
- private native long getTotalPhysicalMemorySize0();
- private native long getTotalSwapSpaceSize0();
-
- static {
- initialize0();
- }
-
- private static native void initialize0();
-}
--- a/jdk/src/java.management/unix/native/libmanagement/LinuxOperatingSystem.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-#include <pthread.h>
-#include <inttypes.h>
-#include "sun_management_OperatingSystemImpl.h"
-
-struct ticks {
- uint64_t used;
- uint64_t usedKernel;
- uint64_t total;
-};
-
-typedef struct ticks ticks;
-
-typedef enum {
- CPU_LOAD_VM_ONLY,
- CPU_LOAD_GLOBAL,
-} CpuLoadTarget;
-
-static struct perfbuf {
- int nProcs;
- ticks jvmTicks;
- ticks cpuTicks;
- ticks *cpus;
-} counters;
-
-#define DEC_64 "%"SCNd64
-
-static void next_line(FILE *f) {
- while (fgetc(f) != '\n');
-}
-
-/**
- * Return the total number of ticks since the system was booted.
- * If the usedTicks parameter is not NULL, it will be filled with
- * the number of ticks spent on actual processes (user, system or
- * nice processes) since system boot. Note that this is the total number
- * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is
- * n times the number of ticks that has passed in clock time.
- *
- * Returns a negative value if the reading of the ticks failed.
- */
-static int get_totalticks(int which, ticks *pticks) {
- FILE *fh;
- uint64_t userTicks, niceTicks, systemTicks, idleTicks;
- int n;
-
- if((fh = fopen("/proc/stat", "r")) == NULL) {
- return -1;
- }
-
- n = fscanf(fh, "cpu " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64,
- &userTicks, &niceTicks, &systemTicks, &idleTicks);
-
- // Move to next line
- next_line(fh);
-
- //find the line for requested cpu faster to just iterate linefeeds?
- if (which != -1) {
- int i;
- for (i = 0; i < which; i++) {
- if (fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64, &userTicks, &niceTicks, &systemTicks, &idleTicks) != 4) {
- fclose(fh);
- return -2;
- }
- next_line(fh);
- }
- n = fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 "\n",
- &userTicks, &niceTicks, &systemTicks, &idleTicks);
- }
-
- fclose(fh);
- if (n != 4) {
- return -2;
- }
-
- pticks->used = userTicks + niceTicks;
- pticks->usedKernel = systemTicks;
- pticks->total = userTicks + niceTicks + systemTicks + idleTicks;
-
- return 0;
-}
-
-static int vread_statdata(const char *procfile, const char *fmt, va_list args) {
- FILE *f;
- int n;
- char buf[2048];
-
- if ((f = fopen(procfile, "r")) == NULL) {
- return -1;
- }
-
- if ((n = fread(buf, 1, sizeof(buf), f)) != -1) {
- char *tmp;
-
- buf[n-1] = '\0';
- /** skip through pid and exec name. the exec name _could be wacky_ (renamed) and
- * make scanf go mupp.
- */
- if ((tmp = strrchr(buf, ')')) != NULL) {
- // skip the ')' and the following space but check that the buffer is long enough
- tmp += 2;
- if (tmp < buf + n) {
- n = vsscanf(tmp, fmt, args);
- }
- }
- }
-
- fclose(f);
-
- return n;
-}
-
-static int read_statdata(const char *procfile, const char *fmt, ...) {
- int n;
- va_list args;
-
- va_start(args, fmt);
- n = vread_statdata(procfile, fmt, args);
- va_end(args);
- return n;
-}
-
-/** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */
-static int read_ticks(const char *procfile, uint64_t *userTicks, uint64_t *systemTicks) {
- return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u "DEC_64" "DEC_64,
- userTicks, systemTicks
- );
-}
-
-/**
- * Return the number of ticks spent in any of the processes belonging
- * to the JVM on any CPU.
- */
-static int get_jvmticks(ticks *pticks) {
- uint64_t userTicks;
- uint64_t systemTicks;
-
- if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) < 0) {
- return -1;
- }
-
- // get the total
- if (get_totalticks(-1, pticks) < 0) {
- return -1;
- }
-
- pticks->used = userTicks;
- pticks->usedKernel = systemTicks;
-
- return 0;
-}
-
-/**
- * This method must be called first, before any data can be gathererd.
- */
-int perfInit() {
- static int initialized=1;
-
- if (!initialized) {
- int i;
-
- int n = sysconf(_SC_NPROCESSORS_ONLN);
- if (n <= 0) {
- n = 1;
- }
-
- counters.cpus = calloc(n,sizeof(ticks));
- if (counters.cpus != NULL) {
- // For the CPU load
- get_totalticks(-1, &counters.cpuTicks);
-
- for (i = 0; i < n; i++) {
- get_totalticks(i, &counters.cpus[i]);
- }
- // For JVM load
- get_jvmticks(&counters.jvmTicks);
- initialized = 1;
- }
- }
-
- return initialized ? 0 : -1;
-}
-
-#define MAX(a,b) (a>b?a:b)
-#define MIN(a,b) (a<b?a:b)
-
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-
-/**
- * Return the load of the CPU as a double. 1.0 means the CPU process uses all
- * available time for user or system processes, 0.0 means the CPU uses all time
- * being idle.
- *
- * Returns a negative value if there is a problem in determining the CPU load.
- */
-
-static double get_cpuload_internal(int which, double *pkernelLoad, CpuLoadTarget target) {
- uint64_t udiff, kdiff, tdiff;
- ticks *pticks, tmp;
- double user_load = -1.0;
- int failed = 0;
-
- *pkernelLoad = 0.0;
-
- pthread_mutex_lock(&lock);
-
- if(perfInit() == 0) {
-
- if (target == CPU_LOAD_VM_ONLY) {
- pticks = &counters.jvmTicks;
- } else if (which == -1) {
- pticks = &counters.cpuTicks;
- } else {
- pticks = &counters.cpus[which];
- }
-
- tmp = *pticks;
-
- if (target == CPU_LOAD_VM_ONLY) {
- if (get_jvmticks(pticks) != 0) {
- failed = 1;
- }
- } else if (get_totalticks(which, pticks) < 0) {
- failed = 1;
- }
-
- if(!failed) {
- // seems like we sometimes end up with less kernel ticks when
- // reading /proc/self/stat a second time, timing issue between cpus?
- if (pticks->usedKernel < tmp.usedKernel) {
- kdiff = 0;
- } else {
- kdiff = pticks->usedKernel - tmp.usedKernel;
- }
- tdiff = pticks->total - tmp.total;
- udiff = pticks->used - tmp.used;
-
- if (tdiff == 0) {
- user_load = 0;
- } else {
- if (tdiff < (udiff + kdiff)) {
- tdiff = udiff + kdiff;
- }
- *pkernelLoad = (kdiff / (double)tdiff);
- // BUG9044876, normalize return values to sane values
- *pkernelLoad = MAX(*pkernelLoad, 0.0);
- *pkernelLoad = MIN(*pkernelLoad, 1.0);
-
- user_load = (udiff / (double)tdiff);
- user_load = MAX(user_load, 0.0);
- user_load = MIN(user_load, 1.0);
- }
- }
- }
- pthread_mutex_unlock(&lock);
- return user_load;
-}
-
-double get_cpu_load(int which) {
- double u, s;
- u = get_cpuload_internal(which, &s, CPU_LOAD_GLOBAL);
- if (u < 0) {
- return -1.0;
- }
- // Cap total systemload to 1.0
- return MIN((u + s), 1.0);
-}
-
-double get_process_load() {
- double u, s;
- u = get_cpuload_internal(-1, &s, CPU_LOAD_VM_ONLY);
- if (u < 0) {
- return -1.0;
- }
- return u + s;
-}
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- if(perfInit() == 0) {
- return get_cpu_load(-1);
- } else {
- return -1.0;
- }
-}
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- if(perfInit() == 0) {
- return get_process_load();
- } else {
- return -1.0;
- }
-}
--- a/jdk/src/java.management/unix/native/libmanagement/MacosxOperatingSystem.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "sun_management_OperatingSystemImpl.h"
-
-#include <sys/time.h>
-#include <mach/mach.h>
-#include <mach/task_info.h>
-
-#include "jvm.h"
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- // This code is influenced by the darwin top source
-
- kern_return_t kr;
- mach_msg_type_number_t count;
- host_cpu_load_info_data_t load;
-
- static jlong last_used = 0;
- static jlong last_total = 0;
-
- count = HOST_CPU_LOAD_INFO_COUNT;
- kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&load, &count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
-
- jlong used = load.cpu_ticks[CPU_STATE_USER] + load.cpu_ticks[CPU_STATE_NICE] + load.cpu_ticks[CPU_STATE_SYSTEM];
- jlong total = used + load.cpu_ticks[CPU_STATE_IDLE];
-
- if (last_used == 0 || last_total == 0) {
- // First call, just set the last values
- last_used = used;
- last_total = total;
- // return 0 since we have no data, not -1 which indicates error
- return 0;
- }
-
- jlong used_delta = used - last_used;
- jlong total_delta = total - last_total;
-
- jdouble cpu = (jdouble) used_delta / total_delta;
-
- last_used = used;
- last_total = total;
-
- return cpu;
-}
-
-
-#define TIME_VALUE_TO_TIMEVAL(a, r) do { \
- (r)->tv_sec = (a)->seconds; \
- (r)->tv_usec = (a)->microseconds; \
-} while (0)
-
-
-#define TIME_VALUE_TO_MICROSECONDS(TV) \
- ((TV).tv_sec * 1000 * 1000 + (TV).tv_usec)
-
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- // This code is influenced by the darwin top source
-
- struct task_basic_info_64 task_info_data;
- struct task_thread_times_info thread_info_data;
- struct timeval user_timeval, system_timeval, task_timeval;
- struct timeval now;
- mach_port_t task = mach_task_self();
- kern_return_t kr;
-
- static jlong last_task_time = 0;
- static jlong last_time = 0;
-
- mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
- kr = task_info(task,
- TASK_THREAD_TIMES_INFO,
- (task_info_t)&thread_info_data,
- &thread_info_count);
- if (kr != KERN_SUCCESS) {
- // Most likely cause: |task| is a zombie.
- return -1;
- }
-
- mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
- kr = task_info(task,
- TASK_BASIC_INFO_64,
- (task_info_t)&task_info_data,
- &count);
- if (kr != KERN_SUCCESS) {
- // Most likely cause: |task| is a zombie.
- return -1;
- }
-
- /* Set total_time. */
- // thread info contains live time...
- TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval);
- TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval);
- timeradd(&user_timeval, &system_timeval, &task_timeval);
-
- // ... task info contains terminated time.
- TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval);
- TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval);
- timeradd(&user_timeval, &task_timeval, &task_timeval);
- timeradd(&system_timeval, &task_timeval, &task_timeval);
-
- if (gettimeofday(&now, NULL) < 0) {
- return -1;
- }
- jint ncpus = JVM_ActiveProcessorCount();
- jlong time = TIME_VALUE_TO_MICROSECONDS(now) * ncpus;
- jlong task_time = TIME_VALUE_TO_MICROSECONDS(task_timeval);
-
- if ((last_task_time == 0) || (last_time == 0)) {
- // First call, just set the last values.
- last_task_time = task_time;
- last_time = time;
- // return 0 since we have no data, not -1 which indicates error
- return 0;
- }
-
- jlong task_time_delta = task_time - last_task_time;
- jlong time_delta = time - last_time;
- if (time_delta == 0) {
- return -1;
- }
-
- jdouble cpu = (jdouble) task_time_delta / time_delta;
-
- last_task_time = task_time;
- last_time = time;
-
- return cpu;
- }
--- a/jdk/src/java.management/unix/native/libmanagement/OperatingSystemImpl.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,479 +0,0 @@
-/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jlong.h"
-#include "jvm.h"
-#include "management.h"
-#include "sun_management_OperatingSystemImpl.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#if defined(_ALLBSD_SOURCE)
-#include <sys/sysctl.h>
-#ifdef __APPLE__
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <mach/mach.h>
-#include <sys/proc_info.h>
-#include <libproc.h>
-#endif
-#elif !defined(_AIX)
-#include <sys/swap.h>
-#endif
-#include <sys/resource.h>
-#include <sys/times.h>
-#ifndef _ALLBSD_SOURCE
-#include <sys/sysinfo.h>
-#endif
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#if defined(_AIX)
-#include <libperfstat.h>
-#endif
-
-static jlong page_size = 0;
-
-#if defined(_ALLBSD_SOURCE) || defined(_AIX)
-#define MB (1024UL * 1024UL)
-#else
-
-/* This gets us the new structured proc interfaces of 5.6 & later */
-/* - see comment in <sys/procfs.h> */
-#define _STRUCTURED_PROC 1
-#include <sys/procfs.h>
-
-#endif /* _ALLBSD_SOURCE */
-
-static struct dirent* read_dir(DIR* dirp, struct dirent* entry) {
-#ifdef __solaris__
- struct dirent* dbuf = readdir(dirp);
- return dbuf;
-#else /* __linux__ || _ALLBSD_SOURCE */
- struct dirent* p;
- if (readdir_r(dirp, entry, &p) == 0) {
- return p;
- } else {
- return NULL;
- }
-#endif
-}
-
-// true = get available swap in bytes
-// false = get total swap in bytes
-static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) {
-#ifdef __solaris__
- long total, avail;
- int nswap, i, count;
- swaptbl_t *stbl;
- char *strtab;
-
- // First get the number of swap resource entries
- if ((nswap = swapctl(SC_GETNSWP, NULL)) == -1) {
- throw_internal_error(env, "swapctl failed to get nswap");
- return -1;
- }
- if (nswap == 0) {
- return 0;
- }
-
- // Allocate storage for resource entries
- stbl = (swaptbl_t*) malloc(nswap * sizeof(swapent_t) +
- sizeof(struct swaptable));
- if (stbl == NULL) {
- JNU_ThrowOutOfMemoryError(env, 0);
- return -1;
- }
-
- // Allocate storage for the table
- strtab = (char*) malloc((nswap + 1) * MAXPATHLEN);
- if (strtab == NULL) {
- free(stbl);
- JNU_ThrowOutOfMemoryError(env, 0);
- return -1;
- }
-
- for (i = 0; i < (nswap + 1); i++) {
- stbl->swt_ent[i].ste_path = strtab + (i * MAXPATHLEN);
- }
- stbl->swt_n = nswap + 1;
-
- // Get the entries
- if ((count = swapctl(SC_LIST, stbl)) < 0) {
- free(stbl);
- free(strtab);
- throw_internal_error(env, "swapctl failed to get swap list");
- return -1;
- }
-
- // Sum the entries to get total and free swap
- total = 0;
- avail = 0;
- for (i = 0; i < count; i++) {
- total += stbl->swt_ent[i].ste_pages;
- avail += stbl->swt_ent[i].ste_free;
- }
-
- free(stbl);
- free(strtab);
- return available ? ((jlong)avail * page_size) :
- ((jlong)total * page_size);
-#elif defined(__linux__)
- int ret;
- FILE *fp;
- jlong total = 0, avail = 0;
-
- struct sysinfo si;
- ret = sysinfo(&si);
- if (ret != 0) {
- throw_internal_error(env, "sysinfo failed to get swap size");
- }
- total = (jlong)si.totalswap * si.mem_unit;
- avail = (jlong)si.freeswap * si.mem_unit;
-
- return available ? avail : total;
-#elif defined(__APPLE__)
- struct xsw_usage vmusage;
- size_t size = sizeof(vmusage);
- if (sysctlbyname("vm.swapusage", &vmusage, &size, NULL, 0) != 0) {
- throw_internal_error(env, "sysctlbyname failed");
- }
- return available ? (jlong)vmusage.xsu_avail : (jlong)vmusage.xsu_total;
-#else /* _ALLBSD_SOURCE */
- /*
- * XXXBSD: there's no way available to get swap info in
- * FreeBSD. Usage of libkvm is not an option here
- */
- // throw_internal_error(env, "Unimplemented in FreeBSD");
- return (0);
-#endif
-}
-
-JNIEXPORT void JNICALL
-Java_sun_management_OperatingSystemImpl_initialize0
- (JNIEnv *env, jclass cls)
-{
- page_size = sysconf(_SC_PAGESIZE);
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0
- (JNIEnv *env, jobject mbean)
-{
-#ifdef __solaris__
- psinfo_t psinfo;
- ssize_t result;
- size_t remaining;
- char* addr;
- int fd;
-
- fd = open64("/proc/self/psinfo", O_RDONLY, 0);
- if (fd < 0) {
- throw_internal_error(env, "Unable to open /proc/self/psinfo");
- return -1;
- }
-
- addr = (char *)&psinfo;
- for (remaining = sizeof(psinfo_t); remaining > 0;) {
- result = read(fd, addr, remaining);
- if (result < 0) {
- if (errno != EINTR) {
- close(fd);
- throw_internal_error(env, "Unable to read /proc/self/psinfo");
- return -1;
- }
- } else {
- remaining -= result;
- addr += result;
- }
- }
-
- close(fd);
- return (jlong) psinfo.pr_size * 1024;
-#elif defined(__linux__)
- FILE *fp;
- unsigned long vsize = 0;
-
- if ((fp = fopen("/proc/self/stat", "r")) == NULL) {
- throw_internal_error(env, "Unable to open /proc/self/stat");
- return -1;
- }
-
- // Ignore everything except the vsize entry
- if (fscanf(fp, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %lu %*[^\n]\n", &vsize) == EOF) {
- throw_internal_error(env, "Unable to get virtual memory usage");
- fclose(fp);
- return -1;
- }
-
- fclose(fp);
- return (jlong)vsize;
-#elif defined(__APPLE__)
- struct task_basic_info t_info;
- mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
-
- kern_return_t res = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
- if (res != KERN_SUCCESS) {
- throw_internal_error(env, "task_info failed");
- }
- return t_info.virtual_size;
-#else /* _ALLBSD_SOURCE */
- /*
- * XXXBSD: there's no way available to do it in FreeBSD, AFAIK.
- */
- // throw_internal_error(env, "Unimplemented in FreeBSD");
- return (64 * MB);
-#endif
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0
- (JNIEnv *env, jobject mbean)
-{
- return get_total_or_available_swap_space_size(env, JNI_FALSE);
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0
- (JNIEnv *env, jobject mbean)
-{
- return get_total_or_available_swap_space_size(env, JNI_TRUE);
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getProcessCpuTime0
- (JNIEnv *env, jobject mbean)
-{
-#ifdef __APPLE__
- struct rusage usage;
- if (getrusage(RUSAGE_SELF, &usage) != 0) {
- throw_internal_error(env, "getrusage failed");
- return -1;
- }
- jlong microsecs =
- usage.ru_utime.tv_sec * 1000 * 1000 + usage.ru_utime.tv_usec +
- usage.ru_stime.tv_sec * 1000 * 1000 + usage.ru_stime.tv_usec;
- return microsecs * 1000;
-#else
- jlong clk_tck, ns_per_clock_tick;
- jlong cpu_time_ns;
- struct tms time;
-
- /*
- * BSDNOTE: FreeBSD implements _SC_CLK_TCK since FreeBSD 5, so
- * add a magic to handle it
- */
-#if defined(__solaris__) || defined(_SC_CLK_TCK)
- clk_tck = (jlong) sysconf(_SC_CLK_TCK);
-#elif defined(__linux__) || defined(_ALLBSD_SOURCE)
- clk_tck = 100;
-#endif
- if (clk_tck == -1) {
- throw_internal_error(env,
- "sysconf failed - not able to get clock tick");
- return -1;
- }
-
- times(&time);
- ns_per_clock_tick = (jlong) 1000 * 1000 * 1000 / (jlong) clk_tck;
- cpu_time_ns = ((jlong)time.tms_utime + (jlong) time.tms_stime) *
- ns_per_clock_tick;
- return cpu_time_ns;
-#endif
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0
- (JNIEnv *env, jobject mbean)
-{
-#ifdef __APPLE__
- mach_msg_type_number_t count;
- vm_statistics_data_t vm_stats;
- kern_return_t res;
-
- count = HOST_VM_INFO_COUNT;
- res = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stats, &count);
- if (res != KERN_SUCCESS) {
- throw_internal_error(env, "host_statistics failed");
- return -1;
- }
- return (jlong)vm_stats.free_count * page_size;
-#elif defined(_ALLBSD_SOURCE)
- /*
- * XXBSDL no way to do it in FreeBSD
- */
- // throw_internal_error(env, "unimplemented in FreeBSD")
- return (128 * MB);
-#elif defined(_AIX)
- perfstat_memory_total_t memory_info;
- if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) {
- return (jlong)(memory_info.real_free * 4L * 1024L);
- }
- return -1;
-#else // solaris / linux
- jlong num_avail_physical_pages = sysconf(_SC_AVPHYS_PAGES);
- return (num_avail_physical_pages * page_size);
-#endif
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0
- (JNIEnv *env, jobject mbean)
-{
-#ifdef _ALLBSD_SOURCE
- jlong result = 0;
- int mib[2];
- size_t rlen;
-
- mib[0] = CTL_HW;
- mib[1] = HW_MEMSIZE;
- rlen = sizeof(result);
- if (sysctl(mib, 2, &result, &rlen, NULL, 0) != 0) {
- throw_internal_error(env, "sysctl failed");
- return -1;
- }
- return result;
-#elif defined(_AIX)
- perfstat_memory_total_t memory_info;
- if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) {
- return (jlong)(memory_info.real_total * 4L * 1024L);
- }
- return -1;
-#else // solaris / linux
- jlong num_physical_pages = sysconf(_SC_PHYS_PAGES);
- return (num_physical_pages * page_size);
-#endif
-}
-
-
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getOpenFileDescriptorCount0
- (JNIEnv *env, jobject mbean)
-{
-#ifdef __APPLE__
- // This code is influenced by the darwin lsof source
- pid_t my_pid;
- struct proc_bsdinfo bsdinfo;
- struct proc_fdinfo *fds;
- int nfiles;
- kern_return_t kres;
- int res;
- size_t fds_size;
-
- kres = pid_for_task(mach_task_self(), &my_pid);
- if (kres != KERN_SUCCESS) {
- throw_internal_error(env, "pid_for_task failed");
- return -1;
- }
-
- // get the maximum number of file descriptors
- res = proc_pidinfo(my_pid, PROC_PIDTBSDINFO, 0, &bsdinfo, PROC_PIDTBSDINFO_SIZE);
- if (res <= 0) {
- throw_internal_error(env, "proc_pidinfo with PROC_PIDTBSDINFO failed");
- return -1;
- }
-
- // allocate memory to hold the fd information (we don't acutally use this information
- // but need it to get the number of open files)
- fds_size = bsdinfo.pbi_nfiles * sizeof(struct proc_fdinfo);
- fds = malloc(fds_size);
- if (fds == NULL) {
- JNU_ThrowOutOfMemoryError(env, "could not allocate space for file descriptors");
- return -1;
- }
-
- // get the list of open files - the return value is the number of bytes
- // proc_pidinfo filled in
- res = proc_pidinfo(my_pid, PROC_PIDLISTFDS, 0, fds, fds_size);
- if (res <= 0) {
- free(fds);
- throw_internal_error(env, "proc_pidinfo failed for PROC_PIDLISTFDS");
- return -1;
- }
- nfiles = res / sizeof(struct proc_fdinfo);
- free(fds);
-
- return nfiles;
-#elif defined(_ALLBSD_SOURCE)
- /*
- * XXXBSD: there's no way available to do it in FreeBSD, AFAIK.
- */
- // throw_internal_error(env, "Unimplemented in FreeBSD");
- return (100);
-#else /* solaris/linux */
- DIR *dirp;
- struct dirent dbuf;
- struct dirent* dentp;
- jlong fds = 0;
-
-#if defined(_AIX)
-/* AIX does not understand '/proc/self' - it requires the real process ID */
-#define FD_DIR aix_fd_dir
- char aix_fd_dir[32]; /* the pid has at most 19 digits */
- snprintf(aix_fd_dir, 32, "/proc/%d/fd", getpid());
-#else
-#define FD_DIR "/proc/self/fd"
-#endif
-
- dirp = opendir(FD_DIR);
- if (dirp == NULL) {
- throw_internal_error(env, "Unable to open directory /proc/self/fd");
- return -1;
- }
-
- // iterate through directory entries, skipping '.' and '..'
- // each entry represents an open file descriptor.
- while ((dentp = read_dir(dirp, &dbuf)) != NULL) {
- if (isdigit(dentp->d_name[0])) {
- fds++;
- }
- }
-
- closedir(dirp);
- // subtract by 1 which was the fd open for this implementation
- return (fds - 1);
-#endif
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getMaxFileDescriptorCount0
- (JNIEnv *env, jobject mbean)
-{
- struct rlimit rlp;
-
- if (getrlimit(RLIMIT_NOFILE, &rlp) == -1) {
- throw_internal_error(env, "getrlimit failed");
- return -1;
- }
- return (jlong) rlp.rlim_cur;
-}
--- a/jdk/src/java.management/unix/native/libmanagement/SolarisOperatingSystem.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <fcntl.h>
-#include <kstat.h>
-#include <procfs.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/sysinfo.h>
-#include <sys/lwp.h>
-#include <pthread.h>
-#include <utmpx.h>
-#include <dlfcn.h>
-#include <sys/loadavg.h>
-#include <jni.h>
-#include "jvm.h"
-#include "sun_management_OperatingSystemImpl.h"
-
-typedef struct {
- kstat_t *kstat;
- uint64_t last_idle;
- uint64_t last_total;
- double last_ratio;
-} cpuload_t;
-
-static cpuload_t *cpu_loads = NULL;
-static unsigned int num_cpus;
-static kstat_ctl_t *kstat_ctrl = NULL;
-
-static void map_cpu_kstat_counters() {
- kstat_t *kstat;
- int i;
-
- // Get number of CPU(s)
- if ((num_cpus = sysconf(_SC_NPROCESSORS_ONLN)) == -1) {
- num_cpus = 1;
- }
-
- // Data structure for saving CPU load
- if ((cpu_loads = calloc(num_cpus,sizeof(cpuload_t))) == NULL) {
- return;
- }
-
- // Get kstat cpu_stat counters for every CPU
- // (loop over kstat to find our cpu_stat(s)
- i = 0;
- for (kstat = kstat_ctrl->kc_chain; kstat != NULL; kstat = kstat->ks_next) {
- if (strncmp(kstat->ks_module, "cpu_stat", 8) == 0) {
-
- if (kstat_read(kstat_ctrl, kstat, NULL) == -1) {
- // Failed to initialize kstat for this CPU so ignore it
- continue;
- }
-
- if (i == num_cpus) {
- // Found more cpu_stats than reported CPUs
- break;
- }
-
- cpu_loads[i++].kstat = kstat;
- }
- }
-}
-
-static int init_cpu_kstat_counters() {
- static int initialized = 0;
-
- // Concurrence in this method is prevented by the lock in
- // the calling method get_cpu_load();
- if(!initialized) {
- if ((kstat_ctrl = kstat_open()) != NULL) {
- map_cpu_kstat_counters();
- initialized = 1;
- }
- }
- return initialized ? 0 : -1;
-}
-
-static void update_cpu_kstat_counters() {
- if(kstat_chain_update(kstat_ctrl) != 0) {
- free(cpu_loads);
- map_cpu_kstat_counters();
- }
-}
-
-int read_cpustat(cpuload_t *load, cpu_stat_t *cpu_stat) {
- if (load->kstat == NULL) {
- // no handle.
- return -1;
- }
- if (kstat_read(kstat_ctrl, load->kstat, cpu_stat) == -1) {
- // disabling for now, a kstat chain update is likely to happen next time
- load->kstat = NULL;
- return -1;
- }
- return 0;
-}
-
-double get_single_cpu_load(unsigned int n) {
- cpuload_t *load;
- cpu_stat_t cpu_stat;
- uint_t *usage;
- uint64_t c_idle;
- uint64_t c_total;
- uint64_t d_idle;
- uint64_t d_total;
- int i;
-
- if (n >= num_cpus) {
- return -1.0;
- }
-
- load = &cpu_loads[n];
- if (read_cpustat(load, &cpu_stat) < 0) {
- return -1.0;
- }
-
- usage = cpu_stat.cpu_sysinfo.cpu;
- c_idle = usage[CPU_IDLE];
-
- for (c_total = 0, i = 0; i < CPU_STATES; i++) {
- c_total += usage[i];
- }
-
- // Calculate diff against previous snapshot
- d_idle = c_idle - load->last_idle;
- d_total = c_total - load->last_total;
-
- /** update if weve moved */
- if (d_total > 0) {
- // Save current values for next time around
- load->last_idle = c_idle;
- load->last_total = c_total;
- load->last_ratio = (double) (d_total - d_idle) / d_total;
- }
-
- return load->last_ratio;
-}
-
-int get_info(const char *path, void *info, size_t s, off_t o) {
- int fd;
- int ret = 0;
- if ((fd = open(path, O_RDONLY)) < 0) {
- return -1;
- }
- if (pread(fd, info, s, o) != s) {
- ret = -1;
- }
- close(fd);
- return ret;
-}
-
-#define MIN(a, b) ((a < b) ? a : b)
-
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-
-/**
- * Return the cpu load (0-1) for proc number 'which' (or average all if which == -1)
- */
-double get_cpu_load(int which) {
- double load =.0;
-
- pthread_mutex_lock(&lock);
- if(init_cpu_kstat_counters()==0) {
-
- update_cpu_kstat_counters();
-
- if (which == -1) {
- unsigned int i;
- double t;
-
- for (t = .0, i = 0; i < num_cpus; i++) {
- t += get_single_cpu_load(i);
- }
-
- // Cap total systemload to 1.0
- load = MIN((t / num_cpus), 1.0);
- } else {
- load = MIN(get_single_cpu_load(which), 1.0);
- }
- } else {
- load = -1.0;
- }
- pthread_mutex_unlock(&lock);
-
- return load;
-}
-
-/**
- * Return the cpu load (0-1) for the current process (i.e the JVM)
- * or -1.0 if the get_info() call failed
- */
-double get_process_load(void) {
- psinfo_t info;
-
- // Get the percentage of "recent cpu usage" from all the lwp:s in the JVM:s
- // process. This is returned as a value between 0.0 and 1.0 multiplied by 0x8000.
- if (get_info("/proc/self/psinfo",&info.pr_pctcpu, sizeof(info.pr_pctcpu), offsetof(psinfo_t, pr_pctcpu)) == 0) {
- return (double) info.pr_pctcpu / 0x8000;
- }
- return -1.0;
-}
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- return get_cpu_load(-1);
-}
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- return get_process_load();
-}
-
--- a/jdk/src/java.management/windows/classes/sun/management/OperatingSystemImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import com.sun.management.OperatingSystemMXBean;
-
-/**
- * Implementation class for the operating system.
- * Standard and committed hotspot-specific metrics if any.
- *
- * ManagementFactory.getOperatingSystemMXBean() returns an instance
- * of this class.
- */
-class OperatingSystemImpl extends BaseOperatingSystemImpl
- implements OperatingSystemMXBean {
-
- // psapiLock is a lock to make sure only one thread loading
- // PSAPI DLL.
- private static Object psapiLock = new Object();
-
- OperatingSystemImpl(VMManagement vm) {
- super(vm);
- }
-
- public long getCommittedVirtualMemorySize() {
- synchronized (psapiLock) {
- return getCommittedVirtualMemorySize0();
- }
- }
-
- public long getTotalSwapSpaceSize() {
- return getTotalSwapSpaceSize0();
- }
-
- public long getFreeSwapSpaceSize() {
- return getFreeSwapSpaceSize0();
- }
-
- public long getProcessCpuTime() {
- return getProcessCpuTime0();
- }
-
- public long getFreePhysicalMemorySize() {
- return getFreePhysicalMemorySize0();
- }
-
- public long getTotalPhysicalMemorySize() {
- return getTotalPhysicalMemorySize0();
- }
-
- public double getSystemCpuLoad() {
- return getSystemCpuLoad0();
- }
-
- public double getProcessCpuLoad() {
- return getProcessCpuLoad0();
- }
-
- /* native methods */
- private native long getCommittedVirtualMemorySize0();
- private native long getFreePhysicalMemorySize0();
- private native long getFreeSwapSpaceSize0();
- private native double getProcessCpuLoad0();
- private native long getProcessCpuTime0();
- private native double getSystemCpuLoad0();
- private native long getTotalPhysicalMemorySize0();
- private native long getTotalSwapSpaceSize0();
-
- static {
- initialize0();
- }
-
- private static native void initialize0();
-}
--- a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1363 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "jni.h"
-#include "jni_util.h"
-#include "jlong.h"
-#include "jvm.h"
-#include "management.h"
-#include "sun_management_OperatingSystemImpl.h"
-
-#include <psapi.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include <malloc.h>
-#pragma warning (push,0)
-#include <windows.h>
-#pragma warning (pop)
-#include <stdio.h>
-#include <time.h>
-#include <stdint.h>
-#include <assert.h>
-
-/* Disable warnings due to broken header files from Microsoft... */
-#pragma warning(push, 3)
-#include <pdh.h>
-#include <pdhmsg.h>
-#include <process.h>
-#pragma warning(pop)
-
-typedef unsigned __int32 juint;
-typedef unsigned __int64 julong;
-
-static void set_low(jlong* value, jint low) {
- *value &= (jlong)0xffffffff << 32;
- *value |= (jlong)(julong)(juint)low;
-}
-
-static void set_high(jlong* value, jint high) {
- *value &= (jlong)(julong)(juint)0xffffffff;
- *value |= (jlong)high << 32;
-}
-
-static jlong jlong_from(jint h, jint l) {
- jlong result = 0; // initialization to avoid warning
- set_high(&result, h);
- set_low(&result, l);
- return result;
-}
-
-static HANDLE main_process;
-
-static void perfInit(void);
-
-JNIEXPORT void JNICALL
-Java_sun_management_OperatingSystemImpl_initialize0
- (JNIEnv *env, jclass cls)
-{
- main_process = GetCurrentProcess();
- perfInit();
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0
- (JNIEnv *env, jobject mbean)
-{
- PROCESS_MEMORY_COUNTERS pmc;
- if (GetProcessMemoryInfo(main_process, &pmc, sizeof(PROCESS_MEMORY_COUNTERS)) == 0) {
- return (jlong)-1L;
- } else {
- return (jlong) pmc.PagefileUsage;
- }
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0
- (JNIEnv *env, jobject mbean)
-{
- MEMORYSTATUSEX ms;
- ms.dwLength = sizeof(ms);
- GlobalMemoryStatusEx(&ms);
- return (jlong) ms.ullTotalPageFile;
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0
- (JNIEnv *env, jobject mbean)
-{
- MEMORYSTATUSEX ms;
- ms.dwLength = sizeof(ms);
- GlobalMemoryStatusEx(&ms);
- return (jlong) ms.ullAvailPageFile;
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getProcessCpuTime0
- (JNIEnv *env, jobject mbean)
-{
-
- FILETIME process_creation_time, process_exit_time,
- process_user_time, process_kernel_time;
-
- // Using static variables declared above
- // Units are 100-ns intervals. Convert to ns.
- GetProcessTimes(main_process, &process_creation_time,
- &process_exit_time,
- &process_kernel_time, &process_user_time);
- return (jlong_from(process_user_time.dwHighDateTime,
- process_user_time.dwLowDateTime) +
- jlong_from(process_kernel_time.dwHighDateTime,
- process_kernel_time.dwLowDateTime)) * 100;
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0
- (JNIEnv *env, jobject mbean)
-{
- MEMORYSTATUSEX ms;
- ms.dwLength = sizeof(ms);
- GlobalMemoryStatusEx(&ms);
- return (jlong) ms.ullAvailPhys;
-}
-
-JNIEXPORT jlong JNICALL
-Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0
- (JNIEnv *env, jobject mbean)
-{
- MEMORYSTATUSEX ms;
- ms.dwLength = sizeof(ms);
- GlobalMemoryStatusEx(&ms);
- return (jlong) ms.ullTotalPhys;
-}
-
-/* Performance Data Helper API (PDH) support */
-
-typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
- HQUERY hQuery,
- LPCSTR szFullCounterPath,
- DWORD dwUserData,
- HCOUNTER *phCounter
- );
-typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
- LPCWSTR szDataSource,
- DWORD dwUserData,
- HQUERY *phQuery
- );
-typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
- HQUERY hQuery
- );
-
-typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
- LPCTSTR szDataSource,
- LPCTSTR szMachineName,
- LPCTSTR szObjectName,
- LPTSTR mszCounterList,
- LPDWORD pcchCounterListLength,
- LPTSTR mszInstanceList,
- LPDWORD pcchInstanceListLength,
- DWORD dwDetailLevel,
- DWORD dwFlags
- );
-typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
- HCOUNTER hCounter
- );
-typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
- LPCSTR szMachineName,
- DWORD dwNameIndex,
- LPSTR szNameBuffer,
- LPDWORD pcchNameBufferSize
- );
-typedef DWORD (WINAPI *PdhCloseQueryFunc)(
- HQUERY hQuery
- );
-
-typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
- HCOUNTER hCounter,
- DWORD dwFormat,
- LPDWORD lpdwType,
- PPDH_FMT_COUNTERVALUE pValue
- );
-
-static PdhAddCounterFunc PdhAddCounter_i;
-static PdhOpenQueryFunc PdhOpenQuery_i;
-static PdhCloseQueryFunc PdhCloseQuery_i;
-static PdhCollectQueryDataFunc PdhCollectQueryData_i;
-static PdhGetFormattedCounterValueFunc PdhGetFormattedCounterValue_i;
-static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
-static PdhRemoveCounterFunc PdhRemoveCounter_i;
-static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;
-
-/*
- * Struct for PDH queries.
- */
-typedef struct {
- HQUERY query;
- uint64_t lastUpdate; // Last time query was updated (ticks)
-} UpdateQueryS, *UpdateQueryP;
-
-// Min time between query updates (ticks)
-static const int MIN_UPDATE_INTERVAL = 500;
-
-/*
- * Struct for a PDH query with multiple counters.
- */
-typedef struct {
- UpdateQueryS query;
- HCOUNTER* counters;
- int noOfCounters;
-} MultipleCounterQueryS, *MultipleCounterQueryP;
-
-/*
- * Struct for a PDH query with a single counter.
- */
-typedef struct {
- UpdateQueryS query;
- HCOUNTER counter;
-} SingleCounterQueryS, *SingleCounterQueryP;
-
-
-typedef struct {
- CRITICAL_SECTION cs;
- DWORD owningThread;
- DWORD recursionCount;
-} PdhCriticalSectionS, *PdhCriticalSectionP;
-
-static PdhCriticalSectionS initializationLock;
-
-static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
- assert(criticalSection);
-
- InitializeCriticalSection(&criticalSection->cs);
- criticalSection->owningThread = 0;
- criticalSection->recursionCount = 0;
-}
-
-static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
- assert(criticalSection);
-
- EnterCriticalSection(&criticalSection->cs);
- criticalSection->recursionCount++;
- if (!criticalSection->owningThread) {
- criticalSection->owningThread = GetCurrentThreadId();
- }
-}
-
-static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
- assert(criticalSection);
- assert(GetCurrentThreadId() == criticalSection->owningThread);
- assert(criticalSection->recursionCount >= 1);
-
- criticalSection->recursionCount--;
- if (!criticalSection->recursionCount) {
- criticalSection->owningThread = 0;
- }
- LeaveCriticalSection(&criticalSection->cs);
-}
-
-/*
- * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
- * http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
- * The index value for the base system counters and objects like processor,
- * process, thread, memory, and so forth are always the same irrespective
- * of the localized version of the operating system or service pack installed.
- * To find the correct index for an object or counter, inspect the registry key/value:
- * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
- */
-static const DWORD PDH_PROCESSOR_IDX = 238;
-static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
-static const DWORD PDH_PROCESS_IDX = 230;
-static const DWORD PDH_ID_PROCESS_IDX = 784;
-
-/* useful pdh fmt's */
-static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
-static const size_t OBJECT_COUNTER_FMT_LEN = 2;
-static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
-static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
-static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
-static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;
-
-static const char* pdhProcessImageName = NULL; /* "java" */
-static char* pdhIDProcessCounterFmt = NULL; /* "\Process(java#%d)\ID Process" */
-
-static int numberOfJavaProcessesAtInitialization = 0;
-
-/*
- * Currently used CPU queries/counters and variables
- */
-static SingleCounterQueryP processTotalCPULoad = NULL;
-static MultipleCounterQueryP multiCounterCPULoad = NULL;
-static double cpuFactor = .0;
-static DWORD numCpus = 0;
-
-/*
- * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
- * Let's just ignore it, since we make sure we have enough buffer anyway.
- */
-static int
-pdhFail(PDH_STATUS pdhStat) {
- return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
-}
-
-static const char*
-allocateAndCopy(const char* const originalString) {
- size_t len;
- char* allocatedString;
-
- assert(originalString);
-
- len = strlen(originalString);
-
- allocatedString = malloc(len + 1);
-
- if (!allocatedString) {
- return NULL;
- }
-
- strncpy(allocatedString, originalString, len);
- allocatedString[len] = '\0';
-
- return allocatedString;
-}
-
-/*
- * Allocates memory into the supplied pointer and
- * fills it with the localized PDH artifact description, if indexed correctly.
- * Caller owns the memory from the point of returning from this function.
- *
- * @param index the PDH counter index as specified in the registry
- * @param ppBuffer pointer to a char*.
- * @return 0 if successful, negative on failure.
- */
-static int
-lookupNameByIndex(DWORD index, char** ppBuffer) {
- DWORD size;
-
- assert(ppBuffer);
-
- /* determine size needed */
- if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
- /* invalid index? */
- return -1;
- }
-
- *ppBuffer = malloc((size_t)size);
-
- if (!*ppBuffer) {
- return -1;
- }
-
- if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
- free(*ppBuffer);
- *ppBuffer = NULL;
- return -1;
- }
-
- /* windows vista does not null-terminate the string
- * (although the docs says it will) */
- (*ppBuffer)[size - 1] = '\0';
-
- return 0;
-}
-
-/*
-* Construct a fully qualified PDH path
-*
-* @param objectName a PDH Object string representation (required)
-* @param counterName a PDH Counter string representation (required)
-* @param imageName a process image name string, ex. "java" (opt)
-* @param instance an instance string, ex. "0", "1", ... (opt)
-* @return the fully qualified PDH path.
-*
-* Caller will own the returned malloc:ed string
-*/
-static const char*
-makeFullCounterPath(const char* const objectName,
- const char* const counterName,
- const char* const imageName,
- const char* const instance) {
-
- size_t fullCounterPathLen;
- char* fullCounterPath;
-
- assert(objectName);
- assert(counterName);
-
- fullCounterPathLen = strlen(objectName);
- fullCounterPathLen += strlen(counterName);
-
- if (imageName) {
- /*
- * For paths using the "Process" Object.
- *
- * Examples:
- * abstract: "\Process(imageName#instance)\Counter"
- * actual: "\Process(java#2)\ID Process"
- */
- fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
- fullCounterPathLen += strlen(imageName);
-
- /*
- * imageName must be passed together with an associated
- * instance "number" ("0", "1", "2", ...).
- * This is required in order to create valid "Process" Object paths.
- *
- * Examples: "\Process(java#0)", \Process(java#1"), ...
- */
- assert(instance);
-
- fullCounterPathLen += strlen(instance);
-
- fullCounterPath = malloc(fullCounterPathLen + 1);
-
- if (!fullCounterPath) {
- return NULL;
- }
-
- _snprintf(fullCounterPath,
- fullCounterPathLen,
- PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
- objectName,
- imageName,
- instance,
- counterName);
- } else {
- if (instance) {
- /*
- * For paths where the Object has multiple instances.
- *
- * Examples:
- * abstract: "\Object(instance)\Counter"
- * actual: "\Processor(0)\% Privileged Time"
- */
- fullCounterPathLen += strlen(instance);
- fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
- } else {
- /*
- * For "normal" paths.
- *
- * Examples:
- * abstract: "\Object\Counter"
- * actual: "\Memory\Available Mbytes"
- */
- fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
- }
-
- fullCounterPath = malloc(fullCounterPathLen + 1);
-
- if (!fullCounterPath) {
- return NULL;
- }
-
- if (instance) {
- _snprintf(fullCounterPath,
- fullCounterPathLen,
- OBJECT_WITH_INSTANCES_COUNTER_FMT,
- objectName,
- instance,
- counterName);
- } else {
- _snprintf(fullCounterPath,
- fullCounterPathLen,
- OBJECT_COUNTER_FMT,
- objectName,
- counterName);
- }
- }
-
- fullCounterPath[fullCounterPathLen] = '\0';
-
- return fullCounterPath;
-}
-
-/*
- * Resolves an index for a PDH artifact to
- * a localized, malloc:ed string representation.
- * Caller will own the returned malloc:ed string.
- *
- * @param pdhArtifactIndex PDH index
- * @return malloc:ed string representation
- * of the requested pdh artifact (localized).
- * NULL on failure.
- */
-static const char*
-getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
- char* pdhLocalizedArtifactString;
-
- if (lookupNameByIndex(pdhArtifactIndex,
- &pdhLocalizedArtifactString) != 0) {
- return NULL;
- }
-
- return pdhLocalizedArtifactString;
-}
-
-static void
-pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
- if (counter && *counter) {
- PdhRemoveCounter_i(*counter);
- *counter = NULL;
- }
- if (query && *query) {
- PdhCloseQuery_i(*query);
- *query = NULL;
- }
-}
-
-static void
-destroySingleCounter(SingleCounterQueryP counterQuery) {
- if (counterQuery) {
- pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
- }
-}
-
-static void
-destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
- int i;
- if (multiCounterQuery) {
- if (multiCounterQuery->counters) {
- for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
- pdhCleanup(NULL, &multiCounterQuery->counters[i]);
- }
- free(multiCounterQuery->counters);
- multiCounterQuery->counters = NULL;
- }
- pdhCleanup(&multiCounterQuery->query.query, NULL);
- }
-}
-
-static int
-openQuery(HQUERY* const query) {
- assert(query);
-
- if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
- return -1;
- }
-
- return 0;
-}
-
-static int
-addCounter(HQUERY query,
- const char* const fullCounterPath,
- HCOUNTER* const counter) {
-
- assert(fullCounterPath);
- assert(counter);
-
- if (PdhAddCounter_i(query,
- fullCounterPath,
- 0,
- counter) != ERROR_SUCCESS) {
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Sets up the supplied SingleCounterQuery to listen for the specified counter.
- *
- * @param counterQuery the counter query to set up.
- * @param fullCounterPath the string specifying the full path to the counter.
- * @returns 0 if successful, negative on failure.
- */
-static int
-initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
- const char* const fullCounterPath) {
- assert(counterQuery);
- assert(fullCounterPath);
-
- if (openQuery(&counterQuery->query.query) == 0) {
- if (addCounter(counterQuery->query.query,
- fullCounterPath,
- &counterQuery->counter) == 0) {
- return 0;
- }
- }
-
- return -1;
-}
-
-/*
- * Sets up a SingleCounterQuery
- *
- * param counter the counter query to set up.
- * param localizedObject string representing the PDH object to query
- * param localizedCounter string representing the PDH counter to query
- * param processImageName if the counter query needs the process image name ("java")
- * param instance if the counter has instances, this is the instance ("\Processor(0)\")
- where 0 is the instance
- * param firstSampleOnInit for counters that need two queries to yield their values,
- the first query can be issued just after initialization
- *
- * @returns 0 if successful, negative on failure.
- */
-static int
-initializeSingleCounter(SingleCounterQueryP const counter,
- const char* const localizedObject,
- const char* const localizedCounter,
- const char* const processImageName,
- const char* const instance,
- BOOL firstSampleOnInit) {
- int retValue = -1;
-
- const char* fullCounterPath = makeFullCounterPath(localizedObject,
- localizedCounter,
- processImageName,
- instance);
-
- if (fullCounterPath) {
-
- assert(counter);
-
- if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
- /*
- * According to the MSDN documentation, rate counters must be read twice:
- *
- * "Obtaining the value of rate counters such as Page faults/sec requires that
- * PdhCollectQueryData be called twice, with a specific time interval between
- * the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
- * implement the waiting period between the two calls to PdhCollectQueryData."
- *
- * Take the first sample here already to allow for the next (first) "real" sample
- * to succeed.
- */
- if (firstSampleOnInit) {
- PdhCollectQueryData_i(counter->query.query);
- }
-
- retValue = 0;
- }
- free((char*)fullCounterPath);
- }
-
- return retValue;
-}
-
-static void
-perfInit(void) {
- InitializePdhCriticalSection(&initializationLock);
-}
-
-static int
-getProcessID() {
- static int myPid = 0;
- if (0 == myPid) {
- myPid = _getpid();
- }
- return myPid;
-}
-
-/*
- * Working against the Process object and it's related counters is inherently problematic
- * when using the PDH API:
- *
- * For PDH, a process is not primarily identified by it's process id,
- * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
- * The really bad part is that this list is reset as soon as one process exits:
- * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
- *
- * The PDH query api requires a process identifier to be submitted when registering
- * a query, but as soon as the list resets, the query is invalidated (since the name
- * changed).
- *
- * Solution:
- * The #number identifier for a Process query can only decrease after process creation.
- *
- * Therefore we create an array of counter queries for all process object instances
- * up to and including ourselves:
- *
- * Ex. we come in as third process instance (java#2), we then create and register
- * queries for the following Process object instances:
- * java#0, java#1, java#2
- *
- * currentQueryIndexForProcess() keeps track of the current "correct" query
- * (in order to keep this index valid when the list resets from underneath,
- * ensure to call getCurrentQueryIndexForProcess() before every query involving
- * Process object instance data).
- */
-static int
-currentQueryIndexForProcess(void) {
- HQUERY tmpQuery = NULL;
- HCOUNTER handleCounter = NULL;
- int retValue = -1;
-
- assert(pdhProcessImageName);
- assert(pdhIDProcessCounterFmt);
-
- if (openQuery(&tmpQuery) == 0) {
- int index;
-
- /* iterate over all instance indexes and try to find our own pid */
- for (index = 0; index < INT_MAX; ++index) {
- char fullIDProcessCounterPath[MAX_PATH];
- PDH_FMT_COUNTERVALUE counterValue;
- PDH_STATUS res;
-
- _snprintf(fullIDProcessCounterPath,
- MAX_PATH,
- pdhIDProcessCounterFmt,
- index);
-
- if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
- break;
- }
-
- res = PdhCollectQueryData_i(tmpQuery);
-
- if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
- break;
- }
-
- PdhGetFormattedCounterValue_i(handleCounter,
- PDH_FMT_LONG,
- NULL,
- &counterValue);
- /*
- * This check seems to be needed for Win2k SMP boxes, since
- * they for some reason don't return PDH_NO_DATA for non existing
- * counters.
- */
- if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
- break;
- }
-
- if ((LONG)getProcessID() == counterValue.longValue) {
- retValue = index;
- break;
- }
- }
- }
-
- pdhCleanup(&tmpQuery, &handleCounter);
-
- return retValue;
-}
-
-/*
- * If successful, returns the #index corresponding to our PID
- * as resolved by the pdh query:
- * "\Process(java#index)\ID Process" (or localized equivalent)
- *
- * This function should be called before attempting to read
- * from any Process related counter(s), and the return value
- * is the index to be used for indexing an array of Process object query's:
- *
- * Example:
- * processTotalCPULoad[currentQueryIndex].query
- *
- * Returns -1 on failure.
- */
-static int
-getCurrentQueryIndexForProcess() {
- int currentQueryIndex = currentQueryIndexForProcess();
-
- assert(currentQueryIndex >= 0 &&
- currentQueryIndex < numberOfJavaProcessesAtInitialization);
-
- return currentQueryIndex;
-}
-
-/*
- * Returns the PDH string identifying the current process image name.
- * Use this name as a qualifier when getting counters from the PDH Process Object
- * representing your process.
-
- * Example:
- * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
- * image name.
- *
- * Please note that the process image name is not necessarily "java",
- * hence the use of GetModuleFileName() to detect the process image name.
- *
- * @return the process image name to be used when retrieving
- * PDH counters from the current process. The caller will
- own the returned malloc:ed string. NULL if failure.
- */
-static const char*
-getPdhProcessImageName() {
- char moduleName[MAX_PATH];
- char* processImageName;
- char* dotPos;
-
- // Find our module name and use it to extract the image name used by PDH
- DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
-
- if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- return NULL;
- }
-
- if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
- return NULL;
- }
-
- processImageName = strrchr(moduleName, '\\'); //drop path
- processImageName++; //skip slash
- dotPos = strrchr(processImageName, '.'); //drop .exe
- dotPos[0] = '\0';
-
- return allocateAndCopy(processImageName);
-}
-
-/*
- * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
- * TODO: Refactor and prettify as with the the SingleCounter queries
- * if more MultipleCounterQueries are discovered/needed.
- *
- * @param multiCounterCPULoad a pointer to a MultipleCounterQueryS, will be filled in with
- * the necessary info to check the PDH processor counters.
- * @return 0 if successful, negative on failure.
- */
-static int
-initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
- DWORD cSize = 0;
- DWORD iSize = 0;
- DWORD pCount;
- DWORD index;
- char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
- char* time = NULL; //'Time' == PDH_PROCESSOR_TIME_IDX
- char* instances = NULL;
- char* tmp;
- int retValue = -1;
- PDH_STATUS pdhStat;
-
- if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
- goto end;
- }
-
- if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
- goto end;
- }
-
- //ok, now we have enough to enumerate all processors.
- pdhStat = PdhEnumObjectItems_i(
- NULL, // reserved
- NULL, // local machine
- processor, // object to enumerate
- NULL, // pass in NULL buffers
- &cSize, // and 0 length to get
- NULL, // required size
- &iSize, // of the buffers in chars
- PERF_DETAIL_WIZARD, // counter detail level
- 0);
-
- if (pdhFail(pdhStat)) {
- goto end;
- }
-
- instances = calloc(iSize, 1);
-
- if (!instances) {
- goto end;
- }
-
- cSize = 0;
-
- pdhStat = PdhEnumObjectItems_i(
- NULL, // reserved
- NULL, // local machine
- processor, // object to enumerate
- NULL, // pass in NULL buffers
- &cSize,
- instances, // now allocated to be filled in
- &iSize, // and size is known
- PERF_DETAIL_WIZARD, // counter detail level
- 0);
-
- if (pdhFail(pdhStat)) {
- goto end;
- }
-
- // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
- for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);
-
- assert(pCount == numCpus+1);
-
- //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
- multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));
-
- if (!multiCounterCPULoad->counters) {
- goto end;
- }
-
- multiCounterCPULoad->noOfCounters = pCount;
-
- if (openQuery(&multiCounterCPULoad->query.query) != 0) {
- goto end;
- }
-
- // fetch instance and register its corresponding HCOUNTER with the query
- for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
- const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);
-
- if (!fullCounterPath) {
- goto end;
- }
-
- retValue = addCounter(multiCounterCPULoad->query.query,
- fullCounterPath,
- &multiCounterCPULoad->counters[index]);
-
- free((char*)fullCounterPath);
-
- if (retValue != 0) {
- goto end;
- }
- }
-
- // Query once to initialize the counters which require at least two samples
- // (like the % CPU usage) to calculate correctly.
- PdhCollectQueryData_i(multiCounterCPULoad->query.query);
-
- end:
- if (processor) {
- free(processor);
- }
-
- if (time) {
- free(time);
- }
-
- if (instances) {
- free(instances);
- }
-
- return retValue;
-}
-
-/*
- * Dynamically sets up function pointers to the PDH library.
- *
- * @param h HMODULE for the PDH library
- * @return 0 on success, negative on failure.
- */
-static int
-bindPdhFunctionPointers(HMODULE h) {
- assert(h);
- assert(GetCurrentThreadId() == initializationLock.owningThread);
-
- /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */
- PdhAddCounter_i = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
- PdhOpenQuery_i = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
- PdhCloseQuery_i = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
- PdhCollectQueryData_i = (PdhCollectQueryDataFunc)GetProcAddress(h, "PdhCollectQueryData");
- PdhGetFormattedCounterValue_i = (PdhGetFormattedCounterValueFunc)GetProcAddress(h, "PdhGetFormattedCounterValue");
- PdhEnumObjectItems_i = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
- PdhRemoveCounter_i = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
- PdhLookupPerfNameByIndex_i = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");
-
- if (!PdhAddCounter_i || !PdhOpenQuery_i ||
- !PdhCloseQuery_i || !PdhCollectQueryData_i ||
- !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
- !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
- {
- return -1;
- }
- return 0;
-}
-
-/*
- * Returns the counter value as a double for the specified query.
- * Will collect the query data and update the counter values as necessary.
- *
- * @param query the query to update (if needed).
- * @param c the counter to read.
- * @param value where to store the formatted value.
- * @param format the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
- * @return 0 if no error
- * -1 if PdhCollectQueryData fails
- * -2 if PdhGetFormattedCounterValue fails
- */
-static int
-getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
- clock_t now = clock();
-
- /*
- * Need to limit how often we update the query
- * to minimize the Heisenberg effect.
- * (PDH behaves erratically if the counters are
- * queried too often, especially counters that
- * store and use values from two consecutive updates,
- * like cpu load.)
- */
- if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
- if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
- return -1;
- }
- query->lastUpdate = now;
- }
-
- if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
- return -2;
- }
-
- return 0;
-}
-
-static int
-allocateAndInitializePdhConstants() {
- const char* pdhLocalizedProcessObject = NULL;
- const char* pdhLocalizedIDProcessCounter = NULL;
- size_t pdhIDProcessCounterFmtLen;
- int currentQueryIndex;
- int retValue = -1;
-
- assert(GetCurrentThreadId() == initializationLock.owningThread);
-
- assert(!pdhProcessImageName);
- pdhProcessImageName = getPdhProcessImageName();
- if (!pdhProcessImageName) {
- goto end;
- }
-
- pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
- if (!pdhLocalizedProcessObject) {
- goto end;
- }
-
- pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
- if (!pdhLocalizedIDProcessCounter) {
- goto end;
- }
-
- assert(!pdhIDProcessCounterFmt);
-
- pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
- pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
- pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
- pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
- pdhIDProcessCounterFmtLen += 2; // "%d"
-
- assert(pdhIDProcessCounterFmtLen < MAX_PATH);
- pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1);
- if (!pdhIDProcessCounterFmt) {
- goto end;
- }
-
- /* "\Process(java#%d)\ID Process" */
- _snprintf(pdhIDProcessCounterFmt,
- pdhIDProcessCounterFmtLen,
- PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
- pdhLocalizedProcessObject,
- pdhProcessImageName,
- "%d",
- pdhLocalizedIDProcessCounter);
-
- pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';
-
- assert(0 == numberOfJavaProcessesAtInitialization);
- currentQueryIndex = currentQueryIndexForProcess();
- if (-1 == currentQueryIndex) {
- goto end;
- }
-
- numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
- assert(numberOfJavaProcessesAtInitialization >= 1);
-
- retValue = 0;
-
- end:
-
- if (pdhLocalizedProcessObject) {
- free((char*)pdhLocalizedProcessObject);
- }
-
- if (pdhLocalizedIDProcessCounter) {
- free((char*)pdhLocalizedIDProcessCounter);
- }
-
- return retValue;
-}
-
-static void
-deallocatePdhConstants() {
- assert(GetCurrentThreadId() == initializationLock.owningThread);
-
- if (pdhProcessImageName) {
- free((char*)pdhProcessImageName);
- pdhProcessImageName = NULL;
- }
-
- if (pdhIDProcessCounterFmt) {
- free(pdhIDProcessCounterFmt);
- pdhIDProcessCounterFmt = NULL;
- }
-
- numberOfJavaProcessesAtInitialization = 0;
-}
-
-static int
-initializeCPUCounters() {
- SYSTEM_INFO si;
- char* localizedProcessObject;
- char* localizedProcessorTimeCounter;
- int i;
- int retValue = -1;
-
- assert(GetCurrentThreadId() == initializationLock.owningThread);
-
- assert(0 == numCpus);
- GetSystemInfo(&si);
- numCpus = si.dwNumberOfProcessors;
- assert(numCpus >= 1);
-
- /* Initialize the denominator for the jvm load calculations */
- assert(.0 == cpuFactor);
- cpuFactor = numCpus * 100;
-
- if (lookupNameByIndex(PDH_PROCESS_IDX,
- &localizedProcessObject) == 0) {
-
- if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
- &localizedProcessorTimeCounter) == 0) {
-
- assert(processTotalCPULoad);
- assert(pdhProcessImageName);
-
- for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
- char instanceIndexBuffer[32];
- retValue = initializeSingleCounter(&processTotalCPULoad[i],
- localizedProcessObject,
- localizedProcessorTimeCounter,
- pdhProcessImageName,
- itoa(i, instanceIndexBuffer, 10),
- TRUE);
- if (retValue != 0) {
- break;
- }
- }
- free(localizedProcessorTimeCounter);
- }
- free(localizedProcessObject);
- }
-
- if (retValue != 0) {
- return -1;
- }
-
- assert(multiCounterCPULoad);
- return initializeMultipleCounterForCPUs(multiCounterCPULoad);
-}
-
-static void
-deallocateCPUCounters() {
- int i;
-
- assert(GetCurrentThreadId() == initializationLock.owningThread);
-
- if (processTotalCPULoad) {
- for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
- destroySingleCounter(&processTotalCPULoad[i]);
- }
- free(processTotalCPULoad);
- processTotalCPULoad = NULL;
- }
-
- if (multiCounterCPULoad) {
- destroyMultiCounter(multiCounterCPULoad);
- free(multiCounterCPULoad);
- multiCounterCPULoad = NULL;
- }
-
- cpuFactor = .0;
- numCpus = 0;
-}
-
-static void
-pdhInitErrorHandler(HMODULE h) {
- assert(GetCurrentThreadId() == initializationLock.owningThread);
-
- deallocatePdhConstants();
-
- if (h) {
- FreeLibrary(h);
- }
-}
-
-/*
- * Helper to initialize the PDH library, function pointers and constants.
- *
- * @return 0 if successful, negative on failure.
- */
-static int
-pdhInit() {
- static BOOL initialized = FALSE;
- int retValue;
-
- if (initialized) {
- return 0;
- }
-
- retValue = 0;
-
- EnterPdhCriticalSection(&initializationLock); {
- if (!initialized) {
- HMODULE h = NULL;
- if ((h = LoadLibrary("pdh.dll")) == NULL) {
- retValue = -1;
- } else if (bindPdhFunctionPointers(h) < 0) {
- retValue = -1;
- } else if (allocateAndInitializePdhConstants() < 0) {
- retValue = -1;
- }
-
- if (0 == retValue) {
- initialized = TRUE;
- } else {
- pdhInitErrorHandler(h);
- }
- }
- } LeavePdhCriticalSection(&initializationLock);
-
- return retValue;
-}
-
-static int
-allocateCPUCounters() {
- assert(GetCurrentThreadId() == initializationLock.owningThread);
- assert(numberOfJavaProcessesAtInitialization >= 1);
- assert(!processTotalCPULoad);
- assert(!multiCounterCPULoad);
-
- /*
- * Create an array of Process object queries, for each instance
- * up to and including our own (java#0, java#1, java#2, ...).
- */
- processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
- sizeof(SingleCounterQueryS));
-
- if (!processTotalCPULoad) {
- return -1;
- }
-
- multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));
-
- if (!multiCounterCPULoad) {
- return -1;
- }
-
- return 0;
-}
-
-static int
-initializePdhCPUCounters() {
- static BOOL initialized = FALSE;
- int retValue;
-
- if (initialized) {
- return 0;
- }
-
- retValue = 0;
-
- EnterPdhCriticalSection(&initializationLock); {
- if (!initialized) {
- if (pdhInit() < 0) {
- retValue = -1;
- } else if (allocateCPUCounters() < 0) {
- retValue = -1;
- } else if (initializeCPUCounters() < 0) {
- retValue = -1;
- }
-
- if (0 == retValue) {
- initialized = TRUE;
- } else {
- deallocateCPUCounters();
- }
- }
- } LeavePdhCriticalSection(&initializationLock);
-
- return retValue;
-}
-
-static int
-perfCPUInit() {
- return initializePdhCPUCounters();
-}
-
-static double
-perfGetProcessCPULoad() {
- PDH_FMT_COUNTERVALUE cv;
- int currentQueryIndex;
-
- if (perfCPUInit() < 0) {
- // warn?
- return -1.0;
- }
-
- currentQueryIndex = getCurrentQueryIndexForProcess();
-
- if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
- processTotalCPULoad[currentQueryIndex].counter,
- &cv,
- PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
- double d = cv.doubleValue / cpuFactor;
- d = min(1, d);
- d = max(0, d);
- return d;
- }
- return -1.0;
-}
-
-static double
-perfGetCPULoad(int which) {
- PDH_FMT_COUNTERVALUE cv;
- HCOUNTER c;
-
- if (perfCPUInit() < 0) {
- // warn?
- return -1.0;
- }
-
- if (-1 == which) {
- c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
- } else {
- if (which < multiCounterCPULoad->noOfCounters) {
- c = multiCounterCPULoad->counters[which];
- } else {
- return -1.0;
- }
- }
- if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
- return cv.doubleValue / 100;
- }
- return -1.0;
-}
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- return perfGetCPULoad(-1);
-}
-
-JNIEXPORT jdouble JNICALL
-Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0
-(JNIEnv *env, jobject dummy)
-{
- return perfGetProcessCPULoad();
-}
--- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -131,6 +131,15 @@
}
@Override
+ boolean isAssignableTo(ReferenceType type) {
+ if (type.name().equals("java.lang.Object")) {
+ // interfaces are always assignable to j.l.Object
+ return true;
+ }
+ return super.isAssignableTo(type);
+ }
+
+ @Override
List<InterfaceType> interfaces() {
return superinterfaces();
}
@@ -140,4 +149,4 @@
// method must be directly in this interface
return this.equals(method.declaringType());
}
-}
\ No newline at end of file
+}
--- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,15 +64,9 @@
int localport = (port < 0) ? Registry.REGISTRY_PORT : port;
registry = LocateRegistry.createRegistry(localport);
bind(name, remoteHost);
+ } else {
+ throw e;
}
- else {
- System.out.println("Could not contact registry\n"
- + e.getMessage());
- e.printStackTrace();
- }
- } catch (RemoteException e) {
- System.err.println("Could not bind " + name + " to RMI Registry");
- e.printStackTrace();
}
}
@@ -142,23 +136,28 @@
RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject(
remoteHost, 0);
bind(name.toString(), remoteHost);
+ System.out.println("jstatd started (bound to " + name.toString() + ")");
+ System.out.flush();
} catch (MalformedURLException e) {
if (rminame != null) {
System.out.println("Bad RMI server name: " + rminame);
} else {
- System.out.println("Bad RMI URL: " + name + " : "
- + e.getMessage());
+ System.out.println("Bad RMI URL: " + name);
}
+ e.printStackTrace(System.out);
System.exit(1);
} catch (java.rmi.ConnectException e) {
// could not attach to or create a registry
- System.out.println("Could not contact RMI registry\n"
- + e.getMessage());
+ System.out.println("Could not contact RMI registry");
+ e.printStackTrace(System.out);
+ System.exit(1);
+ } catch (RemoteException e) {
+ System.out.println("Could not bind " + name + " to RMI Registry");
+ e.printStackTrace(System.out);
System.exit(1);
} catch (Exception e) {
- System.out.println("Could not create remote object\n"
- + e.getMessage());
- e.printStackTrace();
+ System.out.println("Could not create remote object");
+ e.printStackTrace(System.out);
System.exit(1);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <inttypes.h>
+#include "com_sun_management_internal_OperatingSystemImpl.h"
+
+struct ticks {
+ uint64_t used;
+ uint64_t usedKernel;
+ uint64_t total;
+};
+
+typedef struct ticks ticks;
+
+typedef enum {
+ CPU_LOAD_VM_ONLY,
+ CPU_LOAD_GLOBAL,
+} CpuLoadTarget;
+
+static struct perfbuf {
+ int nProcs;
+ ticks jvmTicks;
+ ticks cpuTicks;
+ ticks *cpus;
+} counters;
+
+#define DEC_64 "%"SCNd64
+
+static void next_line(FILE *f) {
+ while (fgetc(f) != '\n');
+}
+
+/**
+ * Return the total number of ticks since the system was booted.
+ * If the usedTicks parameter is not NULL, it will be filled with
+ * the number of ticks spent on actual processes (user, system or
+ * nice processes) since system boot. Note that this is the total number
+ * of "executed" ticks on _all_ CPU:s, that is on a n-way system it is
+ * n times the number of ticks that has passed in clock time.
+ *
+ * Returns a negative value if the reading of the ticks failed.
+ */
+static int get_totalticks(int which, ticks *pticks) {
+ FILE *fh;
+ uint64_t userTicks, niceTicks, systemTicks, idleTicks;
+ int n;
+
+ if((fh = fopen("/proc/stat", "r")) == NULL) {
+ return -1;
+ }
+
+ n = fscanf(fh, "cpu " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64,
+ &userTicks, &niceTicks, &systemTicks, &idleTicks);
+
+ // Move to next line
+ next_line(fh);
+
+ //find the line for requested cpu faster to just iterate linefeeds?
+ if (which != -1) {
+ int i;
+ for (i = 0; i < which; i++) {
+ if (fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64, &userTicks, &niceTicks, &systemTicks, &idleTicks) != 4) {
+ fclose(fh);
+ return -2;
+ }
+ next_line(fh);
+ }
+ n = fscanf(fh, "cpu%*d " DEC_64 " " DEC_64 " " DEC_64 " " DEC_64 "\n",
+ &userTicks, &niceTicks, &systemTicks, &idleTicks);
+ }
+
+ fclose(fh);
+ if (n != 4) {
+ return -2;
+ }
+
+ pticks->used = userTicks + niceTicks;
+ pticks->usedKernel = systemTicks;
+ pticks->total = userTicks + niceTicks + systemTicks + idleTicks;
+
+ return 0;
+}
+
+static int vread_statdata(const char *procfile, const char *fmt, va_list args) {
+ FILE *f;
+ int n;
+ char buf[2048];
+
+ if ((f = fopen(procfile, "r")) == NULL) {
+ return -1;
+ }
+
+ if ((n = fread(buf, 1, sizeof(buf), f)) != -1) {
+ char *tmp;
+
+ buf[n-1] = '\0';
+ /** skip through pid and exec name. the exec name _could be wacky_ (renamed) and
+ * make scanf go mupp.
+ */
+ if ((tmp = strrchr(buf, ')')) != NULL) {
+ // skip the ')' and the following space but check that the buffer is long enough
+ tmp += 2;
+ if (tmp < buf + n) {
+ n = vsscanf(tmp, fmt, args);
+ }
+ }
+ }
+
+ fclose(f);
+
+ return n;
+}
+
+static int read_statdata(const char *procfile, const char *fmt, ...) {
+ int n;
+ va_list args;
+
+ va_start(args, fmt);
+ n = vread_statdata(procfile, fmt, args);
+ va_end(args);
+ return n;
+}
+
+/** read user and system ticks from a named procfile, assumed to be in 'stat' format then. */
+static int read_ticks(const char *procfile, uint64_t *userTicks, uint64_t *systemTicks) {
+ return read_statdata(procfile, "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u "DEC_64" "DEC_64,
+ userTicks, systemTicks
+ );
+}
+
+/**
+ * Return the number of ticks spent in any of the processes belonging
+ * to the JVM on any CPU.
+ */
+static int get_jvmticks(ticks *pticks) {
+ uint64_t userTicks;
+ uint64_t systemTicks;
+
+ if (read_ticks("/proc/self/stat", &userTicks, &systemTicks) < 0) {
+ return -1;
+ }
+
+ // get the total
+ if (get_totalticks(-1, pticks) < 0) {
+ return -1;
+ }
+
+ pticks->used = userTicks;
+ pticks->usedKernel = systemTicks;
+
+ return 0;
+}
+
+/**
+ * This method must be called first, before any data can be gathererd.
+ */
+int perfInit() {
+ static int initialized=1;
+
+ if (!initialized) {
+ int i;
+
+ int n = sysconf(_SC_NPROCESSORS_ONLN);
+ if (n <= 0) {
+ n = 1;
+ }
+
+ counters.cpus = calloc(n,sizeof(ticks));
+ if (counters.cpus != NULL) {
+ // For the CPU load
+ get_totalticks(-1, &counters.cpuTicks);
+
+ for (i = 0; i < n; i++) {
+ get_totalticks(i, &counters.cpus[i]);
+ }
+ // For JVM load
+ get_jvmticks(&counters.jvmTicks);
+ initialized = 1;
+ }
+ }
+
+ return initialized ? 0 : -1;
+}
+
+#define MAX(a,b) (a>b?a:b)
+#define MIN(a,b) (a<b?a:b)
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Return the load of the CPU as a double. 1.0 means the CPU process uses all
+ * available time for user or system processes, 0.0 means the CPU uses all time
+ * being idle.
+ *
+ * Returns a negative value if there is a problem in determining the CPU load.
+ */
+
+static double get_cpuload_internal(int which, double *pkernelLoad, CpuLoadTarget target) {
+ uint64_t udiff, kdiff, tdiff;
+ ticks *pticks, tmp;
+ double user_load = -1.0;
+ int failed = 0;
+
+ *pkernelLoad = 0.0;
+
+ pthread_mutex_lock(&lock);
+
+ if(perfInit() == 0) {
+
+ if (target == CPU_LOAD_VM_ONLY) {
+ pticks = &counters.jvmTicks;
+ } else if (which == -1) {
+ pticks = &counters.cpuTicks;
+ } else {
+ pticks = &counters.cpus[which];
+ }
+
+ tmp = *pticks;
+
+ if (target == CPU_LOAD_VM_ONLY) {
+ if (get_jvmticks(pticks) != 0) {
+ failed = 1;
+ }
+ } else if (get_totalticks(which, pticks) < 0) {
+ failed = 1;
+ }
+
+ if(!failed) {
+ // seems like we sometimes end up with less kernel ticks when
+ // reading /proc/self/stat a second time, timing issue between cpus?
+ if (pticks->usedKernel < tmp.usedKernel) {
+ kdiff = 0;
+ } else {
+ kdiff = pticks->usedKernel - tmp.usedKernel;
+ }
+ tdiff = pticks->total - tmp.total;
+ udiff = pticks->used - tmp.used;
+
+ if (tdiff == 0) {
+ user_load = 0;
+ } else {
+ if (tdiff < (udiff + kdiff)) {
+ tdiff = udiff + kdiff;
+ }
+ *pkernelLoad = (kdiff / (double)tdiff);
+ // BUG9044876, normalize return values to sane values
+ *pkernelLoad = MAX(*pkernelLoad, 0.0);
+ *pkernelLoad = MIN(*pkernelLoad, 1.0);
+
+ user_load = (udiff / (double)tdiff);
+ user_load = MAX(user_load, 0.0);
+ user_load = MIN(user_load, 1.0);
+ }
+ }
+ }
+ pthread_mutex_unlock(&lock);
+ return user_load;
+}
+
+double get_cpu_load(int which) {
+ double u, s;
+ u = get_cpuload_internal(which, &s, CPU_LOAD_GLOBAL);
+ if (u < 0) {
+ return -1.0;
+ }
+ // Cap total systemload to 1.0
+ return MIN((u + s), 1.0);
+}
+
+double get_process_load() {
+ double u, s;
+ u = get_cpuload_internal(-1, &s, CPU_LOAD_VM_ONLY);
+ if (u < 0) {
+ return -1.0;
+ }
+ return u + s;
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ if(perfInit() == 0) {
+ return get_cpu_load(-1);
+ } else {
+ return -1.0;
+ }
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ if(perfInit() == 0) {
+ return get_process_load();
+ } else {
+ return -1.0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "com_sun_management_internal_OperatingSystemImpl.h"
+
+#include <sys/time.h>
+#include <mach/mach.h>
+#include <mach/task_info.h>
+
+#include "jvm.h"
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ // This code is influenced by the darwin top source
+
+ kern_return_t kr;
+ mach_msg_type_number_t count;
+ host_cpu_load_info_data_t load;
+
+ static jlong last_used = 0;
+ static jlong last_total = 0;
+
+ count = HOST_CPU_LOAD_INFO_COUNT;
+ kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&load, &count);
+ if (kr != KERN_SUCCESS) {
+ return -1;
+ }
+
+ jlong used = load.cpu_ticks[CPU_STATE_USER] + load.cpu_ticks[CPU_STATE_NICE] + load.cpu_ticks[CPU_STATE_SYSTEM];
+ jlong total = used + load.cpu_ticks[CPU_STATE_IDLE];
+
+ if (last_used == 0 || last_total == 0) {
+ // First call, just set the last values
+ last_used = used;
+ last_total = total;
+ // return 0 since we have no data, not -1 which indicates error
+ return 0;
+ }
+
+ jlong used_delta = used - last_used;
+ jlong total_delta = total - last_total;
+
+ jdouble cpu = (jdouble) used_delta / total_delta;
+
+ last_used = used;
+ last_total = total;
+
+ return cpu;
+}
+
+
+#define TIME_VALUE_TO_TIMEVAL(a, r) do { \
+ (r)->tv_sec = (a)->seconds; \
+ (r)->tv_usec = (a)->microseconds; \
+} while (0)
+
+
+#define TIME_VALUE_TO_MICROSECONDS(TV) \
+ ((TV).tv_sec * 1000 * 1000 + (TV).tv_usec)
+
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ // This code is influenced by the darwin top source
+
+ struct task_basic_info_64 task_info_data;
+ struct task_thread_times_info thread_info_data;
+ struct timeval user_timeval, system_timeval, task_timeval;
+ struct timeval now;
+ mach_port_t task = mach_task_self();
+ kern_return_t kr;
+
+ static jlong last_task_time = 0;
+ static jlong last_time = 0;
+
+ mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
+ kr = task_info(task,
+ TASK_THREAD_TIMES_INFO,
+ (task_info_t)&thread_info_data,
+ &thread_info_count);
+ if (kr != KERN_SUCCESS) {
+ // Most likely cause: |task| is a zombie.
+ return -1;
+ }
+
+ mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT;
+ kr = task_info(task,
+ TASK_BASIC_INFO_64,
+ (task_info_t)&task_info_data,
+ &count);
+ if (kr != KERN_SUCCESS) {
+ // Most likely cause: |task| is a zombie.
+ return -1;
+ }
+
+ /* Set total_time. */
+ // thread info contains live time...
+ TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval);
+ TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval);
+ timeradd(&user_timeval, &system_timeval, &task_timeval);
+
+ // ... task info contains terminated time.
+ TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval);
+ TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval);
+ timeradd(&user_timeval, &task_timeval, &task_timeval);
+ timeradd(&system_timeval, &task_timeval, &task_timeval);
+
+ if (gettimeofday(&now, NULL) < 0) {
+ return -1;
+ }
+ jint ncpus = JVM_ActiveProcessorCount();
+ jlong time = TIME_VALUE_TO_MICROSECONDS(now) * ncpus;
+ jlong task_time = TIME_VALUE_TO_MICROSECONDS(task_timeval);
+
+ if ((last_task_time == 0) || (last_time == 0)) {
+ // First call, just set the last values.
+ last_task_time = task_time;
+ last_time = time;
+ // return 0 since we have no data, not -1 which indicates error
+ return 0;
+ }
+
+ jlong task_time_delta = task_time - last_task_time;
+ jlong time_delta = time - last_time;
+ if (time_delta == 0) {
+ return -1;
+ }
+
+ jdouble cpu = (jdouble) task_time_delta / time_delta;
+
+ last_task_time = task_time;
+ last_time = time;
+
+ return cpu;
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code 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
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+com.sun.management.internal.PlatformMBeanProviderImpl
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import java.lang.management.PlatformManagedObject;
+import javax.management.DynamicMBean;
+
+/**
+ * Management interface for the diagnostic commands for the HotSpot Virtual Machine.
+ *
+ * <p>The {@code DiagnosticCommandMBean} is registered to the
+ * {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer
+ * platform MBeanServer} as are other platform MBeans.
+ *
+ * <p>The {@link javax.management.ObjectName ObjectName} for uniquely identifying
+ * the diagnostic MBean within an MBeanServer is:
+ * <blockquote>
+ * {@code com.sun.management:type=DiagnosticCommand}
+ * </blockquote>
+ *
+ * <p>This MBean is a {@link javax.management.DynamicMBean DynamicMBean}
+ * and also a {@link javax.management.NotificationEmitter}.
+ * The {@code DiagnosticCommandMBean} is generated at runtime and is subject to
+ * modifications during the lifetime of the Java virtual machine.
+ *
+ * A <em>diagnostic command</em> is represented as an operation of
+ * the {@code DiagnosticCommandMBean} interface. Each diagnostic command has:
+ * <ul>
+ * <li>the diagnostic command name which is the name being referenced in
+ * the HotSpot Virtual Machine</li>
+ * <li>the MBean operation name which is the
+ * {@linkplain javax.management.MBeanOperationInfo#getName() name}
+ * generated for the diagnostic command operation invocation.
+ * The MBean operation name is implementation dependent</li>
+ * </ul>
+ *
+ * The recommended way to transform a diagnostic command name into a MBean
+ * operation name is as follows:
+ * <ul>
+ * <li>All characters from the first one to the first dot are set to be
+ * lower-case characters</li>
+ * <li>Every dot or underline character is removed and the following
+ * character is set to be an upper-case character</li>
+ * <li>All other characters are copied without modification</li>
+ * </ul>
+ *
+ * <p>The diagnostic command name is always provided with the meta-data on the
+ * operation in a field named {@code dcmd.name} (see below).
+ *
+ * <p>A diagnostic command may or may not support options or arguments.
+ * All the operations return {@code String} and either take
+ * no parameter for operations that do not support any option or argument,
+ * or take a {@code String[]} parameter for operations that support at least
+ * one option or argument.
+ * Each option or argument must be stored in a single String.
+ * Options or arguments split across several String instances are not supported.
+ *
+ * <p>The distinction between options and arguments: options are identified by
+ * the option name while arguments are identified by their position in the
+ * command line. Options and arguments are processed in the order of the array
+ * passed to the invocation method.
+ *
+ * <p>Like any operation of a dynamic MBean, each of these operations is
+ * described by {@link javax.management.MBeanOperationInfo MBeanOperationInfo}
+ * instance. Here's the values returned by this object:
+ * <ul>
+ * <li>{@link javax.management.MBeanOperationInfo#getName() getName()}
+ * returns the operation name generated from the diagnostic command name</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getDescription() getDescription()}
+ * returns the diagnostic command description
+ * (the same as the one return in the 'help' command)</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getImpact() getImpact()}
+ * returns {@code ACTION_INFO}</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getReturnType() getReturnType()}
+ * returns {@code java.lang.String}</li>
+ * <li>{@link javax.management.MBeanOperationInfo#getDescriptor() getDescriptor()}
+ * returns a Descriptor instance (see below)</li>
+ * </ul>
+ *
+ * <p>The {@link javax.management.Descriptor Descriptor}
+ * is a collection of fields containing additional
+ * meta-data for a JMX element. A field is a name and an associated value.
+ * The additional meta-data provided for an operation associated with a
+ * diagnostic command are described in the table below:
+ *
+ * <table border="1" cellpadding="5">
+ * <tr>
+ * <th>Name</th><th>Type</th><th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>dcmd.name</td><td>String</td>
+ * <td>The original diagnostic command name (not the operation name)</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.description</td><td>String</td>
+ * <td>The diagnostic command description</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.help</td><td>String</td>
+ * <td>The full help message for this diagnostic command (same output as
+ * the one produced by the 'help' command)</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.vmImpact</td><td>String</td>
+ * <td>The impact of the diagnostic command,
+ * this value is the same as the one printed in the 'impact'
+ * section of the help message of the diagnostic command, and it
+ * is different from the getImpact() of the MBeanOperationInfo</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.enabled</td><td>boolean</td>
+ * <td>True if the diagnostic command is enabled, false otherwise</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.permissionClass</td><td>String</td>
+ * <td>Some diagnostic command might require a specific permission to be
+ * executed, in addition to the MBeanPermission to invoke their
+ * associated MBean operation. This field returns the fully qualified
+ * name of the permission class or null if no permission is required
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.permissionName</td><td>String</td>
+ * <td>The fist argument of the permission required to execute this
+ * diagnostic command or null if no permission is required</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.permissionAction</td><td>String</td>
+ * <td>The second argument of the permission required to execute this
+ * diagnostic command or null if the permission constructor has only
+ * one argument (like the ManagementPermission) or if no permission
+ * is required</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arguments</td><td>Descriptor</td>
+ * <td>A Descriptor instance containing the descriptions of options and
+ * arguments supported by the diagnostic command (see below)</td>
+ * </tr>
+ * </table>
+ *
+ * <p>The description of parameters (options or arguments) of a diagnostic
+ * command is provided within a Descriptor instance. In this Descriptor,
+ * each field name is a parameter name, and each field value is itself
+ * a Descriptor instance. The fields provided in this second Descriptor
+ * instance are described in the table below:
+ *
+ * <table border="1" cellpadding="5">
+ * <tr>
+ * <th>Name</th><th>Type</th><th>Description</th>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.name</td><td>String</td>
+ * <td>The name of the parameter</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.type</td><td>String</td>
+ * <td>The type of the parameter. The returned String is the name of a type
+ * recognized by the diagnostic command parser. These types are not
+ * Java types and are implementation dependent.
+ * </td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.description</td><td>String</td>
+ * <td>The parameter description</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.isMandatory</td><td>boolean</td>
+ * <td>True if the parameter is mandatory, false otherwise</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.isOption</td><td>boolean</td>
+ * <td>True if the parameter is an option, false if it is an argument</td>
+ * </tr>
+ * <tr>
+ * <td>dcmd.arg.isMultiple</td><td>boolean</td>
+ * <td>True if the parameter can be specified several times, false
+ * otherwise</td>
+ * </tr>
+ * </table>
+ *
+ * <p>When the set of diagnostic commands currently supported by the Java
+ * Virtual Machine is modified, the {@code DiagnosticCommandMBean} emits
+ * a {@link javax.management.Notification} with a
+ * {@linkplain javax.management.Notification#getType() type} of
+ * <a href="{@docRoot}/../../../../api/javax/management/MBeanInfo.html#info-changed">
+ * {@code "jmx.mbean.info.changed"}</a> and a
+ * {@linkplain javax.management.Notification#getUserData() userData} that
+ * is the new {@code MBeanInfo}.
+ *
+ * @since 1.8
+ */
+public interface DiagnosticCommandMBean extends DynamicMBean
+{
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataView;
+import javax.management.openmbean.CompositeType;
+import com.sun.management.internal.GarbageCollectionNotifInfoCompositeData;
+
+/**
+ * The information about a garbage collection
+ *
+ * <p>
+ * A garbage collection notification is emitted by {@link GarbageCollectorMXBean}
+ * when the Java virtual machine completes a garbage collection action
+ * The notification emitted will contain the garbage collection notification
+ * information about the status of the memory:
+ * <ul>
+ * <li>The name of the garbage collector used to perform the collection.</li>
+ * <li>The action performed by the garbage collector.</li>
+ * <li>The cause of the garbage collection action.</li>
+ * <li>A {@link GcInfo} object containing some statistics about the GC cycle
+ (start time, end time) and the memory usage before and after
+ the GC cycle.</li>
+ * </ul>
+ *
+ * <p>
+ * A {@link CompositeData CompositeData} representing
+ * the {@code GarbageCollectionNotificationInfo} object
+ * is stored in the
+ * {@linkplain javax.management.Notification#setUserData userdata}
+ * of a {@linkplain javax.management.Notification notification}.
+ * The {@link #from from} method is provided to convert from
+ * a {@code CompositeData} to a {@code GarbageCollectionNotificationInfo}
+ * object. For example:
+ *
+ * <blockquote><pre>
+ * Notification notif;
+ *
+ * // receive the notification emitted by a GarbageCollectorMXBean and set to notif
+ * ...
+ *
+ * String notifType = notif.getType();
+ * if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
+ * // retrieve the garbage collection notification information
+ * CompositeData cd = (CompositeData) notif.getUserData();
+ * GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
+ * ....
+ * }
+ * </pre></blockquote>
+ *
+ * <p>
+ * The type of the notification emitted by a {@code GarbageCollectorMXBean} is:
+ * <ul>
+ * <li>A {@linkplain #GARBAGE_COLLECTION_NOTIFICATION garbage collection notification}.
+ * <br>Used by every notification emitted by the garbage collector, the details about
+ * the notification are provided in the {@linkplain #getGcAction action} String
+ * </li>
+ * </ul>
+ **/
+
+@jdk.Exported
+public class GarbageCollectionNotificationInfo implements CompositeDataView {
+
+ private final String gcName;
+ private final String gcAction;
+ private final String gcCause;
+ private final GcInfo gcInfo;
+ private final CompositeData cdata;
+
+ /**
+ * Notification type denoting that
+ * the Java virtual machine has completed a garbage collection cycle.
+ * This notification is emitted by a {@link GarbageCollectorMXBean}.
+ * The value of this notification type is
+ * {@code com.sun.management.gc.notification}.
+ */
+ public static final String GARBAGE_COLLECTION_NOTIFICATION =
+ "com.sun.management.gc.notification";
+
+ /**
+ * Constructs a {@code GarbageCollectionNotificationInfo} object.
+ *
+ * @param gcName The name of the garbage collector used to perform the collection
+ * @param gcAction The name of the action performed by the garbage collector
+ * @param gcCause The cause of the garbage collection action
+ * @param gcInfo a GcInfo object providing statistics about the GC cycle
+ */
+ public GarbageCollectionNotificationInfo(String gcName,
+ String gcAction,
+ String gcCause,
+ GcInfo gcInfo) {
+ if (gcName == null) {
+ throw new NullPointerException("Null gcName");
+ }
+ if (gcAction == null) {
+ throw new NullPointerException("Null gcAction");
+ }
+ if (gcCause == null) {
+ throw new NullPointerException("Null gcCause");
+ }
+ this.gcName = gcName;
+ this.gcAction = gcAction;
+ this.gcCause = gcCause;
+ this.gcInfo = gcInfo;
+ this.cdata = new GarbageCollectionNotifInfoCompositeData(this);
+ }
+
+ GarbageCollectionNotificationInfo(CompositeData cd) {
+ GarbageCollectionNotifInfoCompositeData.validateCompositeData(cd);
+
+ this.gcName = GarbageCollectionNotifInfoCompositeData.getGcName(cd);
+ this.gcAction = GarbageCollectionNotifInfoCompositeData.getGcAction(cd);
+ this.gcCause = GarbageCollectionNotifInfoCompositeData.getGcCause(cd);
+ this.gcInfo = GarbageCollectionNotifInfoCompositeData.getGcInfo(cd);
+ this.cdata = cd;
+ }
+
+ /**
+ * Returns the name of the garbage collector used to perform the collection
+ *
+ * @return the name of the garbage collector used to perform the collection
+ */
+ public String getGcName() {
+ return gcName;
+ }
+
+ /**
+ * Returns the action performed by the garbage collector
+ *
+ * @return the action performed by the garbage collector
+ */
+ public String getGcAction() {
+ return gcAction;
+ }
+
+ /**
+ * Returns the cause of the garbage collection
+ *
+ * @return the cause of the garbage collection
+ */
+ public String getGcCause() {
+ return gcCause;
+ }
+
+ /**
+ * Returns the GC information related to the last garbage collection
+ *
+ * @return the GC information related to the
+ * last garbage collection
+ */
+ public GcInfo getGcInfo() {
+ return gcInfo;
+ }
+
+ /**
+ * Returns a {@code GarbageCollectionNotificationInfo} object represented by the
+ * given {@code CompositeData}.
+ * The given {@code CompositeData} must contain
+ * the following attributes:
+ * <blockquote>
+ * <table border>
+ * <tr>
+ * <th align=left>Attribute Name</th>
+ * <th align=left>Type</th>
+ * </tr>
+ * <tr>
+ * <td>gcName</td>
+ * <td>{@code java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td>gcAction</td>
+ * <td>{@code java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td>gcCause</td>
+ * <td>{@code java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td>gcInfo</td>
+ * <td>{@code javax.management.openmbean.CompositeData}</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * @param cd {@code CompositeData} representing a
+ * {@code GarbageCollectionNotificationInfo}
+ *
+ * @throws IllegalArgumentException if {@code cd} does not
+ * represent a {@code GarbaageCollectionNotificationInfo} object.
+ *
+ * @return a {@code GarbageCollectionNotificationInfo} object represented
+ * by {@code cd} if {@code cd} is not {@code null};
+ * {@code null} otherwise.
+ */
+ public static GarbageCollectionNotificationInfo from(CompositeData cd) {
+ if (cd == null) {
+ return null;
+ }
+
+ if (cd instanceof GarbageCollectionNotifInfoCompositeData) {
+ return ((GarbageCollectionNotifInfoCompositeData) cd).getGarbageCollectionNotifInfo();
+ } else {
+ return new GarbageCollectionNotificationInfo(cd);
+ }
+ }
+
+ public CompositeData toCompositeData(CompositeType ct) {
+ return cdata;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+
+/**
+ * Platform-specific management interface for a garbage collector
+ * which performs collections in cycles.
+ *
+ * <p> This platform extension is only available to the garbage
+ * collection implementation that supports this extension.
+ *
+ * @author Mandy Chung
+ * @since 1.5
+ */
+@jdk.Exported
+public interface GarbageCollectorMXBean
+ extends java.lang.management.GarbageCollectorMXBean {
+
+ /**
+ * Returns the GC information about the most recent GC.
+ * This method returns a {@link GcInfo}.
+ * If no GC information is available, <tt>null</tt> is returned.
+ * The collector-specific attributes, if any, can be obtained
+ * via the {@link CompositeData CompositeData} interface.
+ * <p>
+ * <b>MBeanServer access:</b>
+ * The mapped type of <tt>GcInfo</tt> is <tt>CompositeData</tt>
+ * with attributes specified in {@link GcInfo#from GcInfo}.
+ *
+ * @return a <tt>GcInfo</tt> object representing
+ * the most GC information; or <tt>null</tt> if no GC
+ * information available.
+ */
+ public GcInfo getLastGcInfo();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import java.lang.management.MemoryUsage;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataView;
+import javax.management.openmbean.CompositeType;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import com.sun.management.internal.GcInfoCompositeData;
+import com.sun.management.internal.GcInfoBuilder;
+
+/**
+ * Garbage collection information. It contains the following
+ * information for one garbage collection as well as GC-specific
+ * attributes:
+ * <blockquote>
+ * <ul>
+ * <li>Start time</li>
+ * <li>End time</li>
+ * <li>Duration</li>
+ * <li>Memory usage before the collection starts</li>
+ * <li>Memory usage after the collection ends</li>
+ * </ul>
+ * </blockquote>
+ *
+ * <p>
+ * {@code GcInfo} is a {@link CompositeData CompositeData}
+ * The GC-specific attributes can be obtained via the CompositeData
+ * interface. This is a historical relic, and other classes should
+ * not copy this pattern. Use {@link CompositeDataView} instead.
+ *
+ * <h4>MXBean Mapping</h4>
+ * {@code GcInfo} is mapped to a {@link CompositeData CompositeData}
+ * with attributes as specified in the {@link #from from} method.
+ *
+ * @author Mandy Chung
+ * @since 1.5
+ */
+@jdk.Exported
+public class GcInfo implements CompositeData, CompositeDataView {
+ private final long index;
+ private final long startTime;
+ private final long endTime;
+ private final Map<String, MemoryUsage> usageBeforeGc;
+ private final Map<String, MemoryUsage> usageAfterGc;
+ private final Object[] extAttributes;
+ private final CompositeData cdata;
+ private final GcInfoBuilder builder;
+
+ private GcInfo(GcInfoBuilder builder,
+ long index, long startTime, long endTime,
+ MemoryUsage[] muBeforeGc,
+ MemoryUsage[] muAfterGc,
+ Object[] extAttributes) {
+ this.builder = builder;
+ this.index = index;
+ this.startTime = startTime;
+ this.endTime = endTime;
+ String[] poolNames = builder.getPoolNames();
+ this.usageBeforeGc = new HashMap<String, MemoryUsage>(poolNames.length);
+ this.usageAfterGc = new HashMap<String, MemoryUsage>(poolNames.length);
+ for (int i = 0; i < poolNames.length; i++) {
+ this.usageBeforeGc.put(poolNames[i], muBeforeGc[i]);
+ this.usageAfterGc.put(poolNames[i], muAfterGc[i]);
+ }
+ this.extAttributes = extAttributes;
+ this.cdata = new GcInfoCompositeData(this, builder, extAttributes);
+ }
+
+ private GcInfo(CompositeData cd) {
+ GcInfoCompositeData.validateCompositeData(cd);
+
+ this.index = GcInfoCompositeData.getId(cd);
+ this.startTime = GcInfoCompositeData.getStartTime(cd);
+ this.endTime = GcInfoCompositeData.getEndTime(cd);
+ this.usageBeforeGc = GcInfoCompositeData.getMemoryUsageBeforeGc(cd);
+ this.usageAfterGc = GcInfoCompositeData.getMemoryUsageAfterGc(cd);
+ this.extAttributes = null;
+ this.builder = null;
+ this.cdata = cd;
+ }
+
+ /**
+ * Returns the identifier of this garbage collection which is
+ * the number of collections that this collector has done.
+ *
+ * @return the identifier of this garbage collection which is
+ * the number of collections that this collector has done.
+ */
+ public long getId() {
+ return index;
+ }
+
+ /**
+ * Returns the start time of this GC in milliseconds
+ * since the Java virtual machine was started.
+ *
+ * @return the start time of this GC.
+ */
+ public long getStartTime() {
+ return startTime;
+ }
+
+ /**
+ * Returns the end time of this GC in milliseconds
+ * since the Java virtual machine was started.
+ *
+ * @return the end time of this GC.
+ */
+ public long getEndTime() {
+ return endTime;
+ }
+
+ /**
+ * Returns the elapsed time of this GC in milliseconds.
+ *
+ * @return the elapsed time of this GC in milliseconds.
+ */
+ public long getDuration() {
+ return endTime - startTime;
+ }
+
+ /**
+ * Returns the memory usage of all memory pools
+ * at the beginning of this GC.
+ * This method returns
+ * a {@code Map} of the name of a memory pool
+ * to the memory usage of the corresponding
+ * memory pool before GC starts.
+ *
+ * @return a {@code Map} of memory pool names to the memory
+ * usage of a memory pool before GC starts.
+ */
+ public Map<String, MemoryUsage> getMemoryUsageBeforeGc() {
+ return Collections.unmodifiableMap(usageBeforeGc);
+ }
+
+ /**
+ * Returns the memory usage of all memory pools
+ * at the end of this GC.
+ * This method returns
+ * a {@code Map} of the name of a memory pool
+ * to the memory usage of the corresponding
+ * memory pool when GC finishes.
+ *
+ * @return a {@code Map} of memory pool names to the memory
+ * usage of a memory pool when GC finishes.
+ */
+ public Map<String, MemoryUsage> getMemoryUsageAfterGc() {
+ return Collections.unmodifiableMap(usageAfterGc);
+ }
+
+ /**
+ * Returns a {@code GcInfo} object represented by the
+ * given {@code CompositeData}. The given
+ * {@code CompositeData} must contain
+ * all the following attributes:
+ *
+ * <blockquote>
+ * <table border>
+ * <tr>
+ * <th align=left>Attribute Name</th>
+ * <th align=left>Type</th>
+ * </tr>
+ * <tr>
+ * <td>index</td>
+ * <td>{@code java.lang.Long}</td>
+ * </tr>
+ * <tr>
+ * <td>startTime</td>
+ * <td>{@code java.lang.Long}</td>
+ * </tr>
+ * <tr>
+ * <td>endTime</td>
+ * <td>{@code java.lang.Long}</td>
+ * </tr>
+ * <tr>
+ * <td>memoryUsageBeforeGc</td>
+ * <td>{@code javax.management.openmbean.TabularData}</td>
+ * </tr>
+ * <tr>
+ * <td>memoryUsageAfterGc</td>
+ * <td>{@code javax.management.openmbean.TabularData}</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * @throws IllegalArgumentException if {@code cd} does not
+ * represent a {@code GcInfo} object with the attributes
+ * described above.
+ *
+ * @return a {@code GcInfo} object represented by {@code cd}
+ * if {@code cd} is not {@code null}; {@code null} otherwise.
+ */
+ public static GcInfo from(CompositeData cd) {
+ if (cd == null) {
+ return null;
+ }
+
+ if (cd instanceof GcInfoCompositeData) {
+ return ((GcInfoCompositeData) cd).getGcInfo();
+ } else {
+ return new GcInfo(cd);
+ }
+
+ }
+
+ // Implementation of the CompositeData interface
+ public boolean containsKey(String key) {
+ return cdata.containsKey(key);
+ }
+
+ public boolean containsValue(Object value) {
+ return cdata.containsValue(value);
+ }
+
+ public boolean equals(Object obj) {
+ return cdata.equals(obj);
+ }
+
+ public Object get(String key) {
+ return cdata.get(key);
+ }
+
+ public Object[] getAll(String[] keys) {
+ return cdata.getAll(keys);
+ }
+
+ public CompositeType getCompositeType() {
+ return cdata.getCompositeType();
+ }
+
+ public int hashCode() {
+ return cdata.hashCode();
+ }
+
+ public String toString() {
+ return cdata.toString();
+ }
+
+ public Collection<?> values() {
+ return cdata.values();
+ }
+
+ /**
+ * Return the {@code CompositeData} representation of this
+ * {@code GcInfo}, including any GC-specific attributes. The
+ * returned value will have at least all the attributes described
+ * in the {@link #from(CompositeData) from} method, plus optionally
+ * other attributes.
+ *
+ * @param ct the {@code CompositeType} that the caller expects.
+ * This parameter is ignored and can be null.
+ *
+ * @return the {@code CompositeData} representation.
+ */
+ public CompositeData toCompositeData(CompositeType ct) {
+ return cdata;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import java.lang.management.PlatformManagedObject;
+
+/**
+ * Diagnostic management interface for the HotSpot Virtual Machine.
+ *
+ * <p>The diagnostic MBean is registered to the platform MBeanServer
+ * as are other platform MBeans.
+ *
+ * <p>The <tt>ObjectName</tt> for uniquely identifying the diagnostic
+ * MXBean within an MBeanServer is:
+ * <blockquote>
+ * <tt>com.sun.management:type=HotSpotDiagnostic</tt>
+ * </blockquote>
+.*
+ * It can be obtained by calling the
+ * {@link PlatformManagedObject#getObjectName} method.
+ *
+ * All methods throw a {@code NullPointerException} if any input argument is
+ * {@code null} unless it's stated otherwise.
+ *
+ * @see java.lang.management.ManagementFactory#getPlatformMXBeans(Class)
+ */
+@jdk.Exported
+public interface HotSpotDiagnosticMXBean extends PlatformManagedObject {
+ /**
+ * Dumps the heap to the <tt>outputFile</tt> file in the same
+ * format as the hprof heap dump.
+ * <p>
+ * If this method is called remotely from another process,
+ * the heap dump output is written to a file named <tt>outputFile</tt>
+ * on the machine where the target VM is running. If outputFile is
+ * a relative path, it is relative to the working directory where
+ * the target VM was started.
+ *
+ * @param outputFile the system-dependent filename
+ * @param live if <tt>true</tt> dump only <i>live</i> objects
+ * i.e. objects that are reachable from others
+ * @throws IOException if the <tt>outputFile</tt>
+ * cannot be created, opened, or written to.
+ * @throws UnsupportedOperationException if this operation is not supported.
+ * @throws NullPointerException if <tt>outputFile</tt> is <tt>null</tt>.
+ * @throws SecurityException
+ * If a security manager exists and its {@link
+ * java.lang.SecurityManager#checkWrite(java.lang.String)}
+ * method denies write access to the named file
+ * or the caller does not have ManagmentPermission("control").
+ */
+ public void dumpHeap(String outputFile, boolean live) throws java.io.IOException;
+
+ /**
+ * Returns a list of <tt>VMOption</tt> objects for all diagnostic options.
+ * A diagnostic option is a {@link VMOption#isWriteable writeable}
+ * VM option that can be set dynamically mainly for troubleshooting
+ * and diagnosis.
+ *
+ * @return a list of <tt>VMOption</tt> objects for all diagnostic options.
+ */
+ public java.util.List<VMOption> getDiagnosticOptions();
+
+ /**
+ * Returns a <tt>VMOption</tt> object for a VM option of the given
+ * name.
+ *
+ * @return a <tt>VMOption</tt> object for a VM option of the given name.
+ * @throws NullPointerException if name is <tt>null</tt>.
+ * @throws IllegalArgumentException if a VM option of the given name
+ * does not exist.
+ */
+ public VMOption getVMOption(String name);
+
+ /**
+ * Sets a VM option of the given name to the specified value.
+ * The new value will be reflected in a new <tt>VMOption</tt>
+ * object returned by the {@link #getVMOption} method or
+ * the {@link #getDiagnosticOptions} method. This method does
+ * not change the value of this <tt>VMOption</tt> object.
+ *
+ * @param name Name of a VM option
+ * @param value New value of the VM option to be set
+ *
+ * @throws IllegalArgumentException if the VM option of the given name
+ * does not exist.
+ * @throws IllegalArgumentException if the new value is invalid.
+ * @throws IllegalArgumentException if the VM option is not writable.
+ * @throws NullPointerException if name or value is <tt>null</tt>.
+ *
+ * @throws java.lang.SecurityException
+ * if a security manager exists and the caller does not have
+ * ManagementPermission("control").
+ */
+ public void setVMOption(String name, String value);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+/**
+ * Platform-specific management interface for the operating system
+ * on which the Java virtual machine is running.
+ *
+ * <p>
+ * The <tt>OperatingSystemMXBean</tt> object returned by
+ * {@link java.lang.management.ManagementFactory#getOperatingSystemMXBean()}
+ * is an instance of the implementation class of this interface
+ * or {@link UnixOperatingSystemMXBean} interface depending on
+ * its underlying operating system.
+ *
+ * @author Mandy Chung
+ * @since 1.5
+ */
+@jdk.Exported
+public interface OperatingSystemMXBean extends
+ java.lang.management.OperatingSystemMXBean {
+
+ /**
+ * Returns the amount of virtual memory that is guaranteed to
+ * be available to the running process in bytes,
+ * or <tt>-1</tt> if this operation is not supported.
+ *
+ * @return the amount of virtual memory that is guaranteed to
+ * be available to the running process in bytes,
+ * or <tt>-1</tt> if this operation is not supported.
+ */
+ public long getCommittedVirtualMemorySize();
+
+ /**
+ * Returns the total amount of swap space in bytes.
+ *
+ * @return the total amount of swap space in bytes.
+ */
+ public long getTotalSwapSpaceSize();
+
+ /**
+ * Returns the amount of free swap space in bytes.
+ *
+ * @return the amount of free swap space in bytes.
+ */
+ public long getFreeSwapSpaceSize();
+
+ /**
+ * Returns the CPU time used by the process on which the Java
+ * virtual machine is running in nanoseconds. The returned value
+ * is of nanoseconds precision but not necessarily nanoseconds
+ * accuracy. This method returns <tt>-1</tt> if the
+ * the platform does not support this operation.
+ *
+ * @return the CPU time used by the process in nanoseconds,
+ * or <tt>-1</tt> if this operation is not supported.
+ */
+ public long getProcessCpuTime();
+
+ /**
+ * Returns the amount of free physical memory in bytes.
+ *
+ * @return the amount of free physical memory in bytes.
+ */
+ public long getFreePhysicalMemorySize();
+
+ /**
+ * Returns the total amount of physical memory in bytes.
+ *
+ * @return the total amount of physical memory in bytes.
+ */
+ public long getTotalPhysicalMemorySize();
+
+ /**
+ * Returns the "recent cpu usage" for the whole system. This value is a
+ * double in the [0.0,1.0] interval. A value of 0.0 means that all CPUs
+ * were idle during the recent period of time observed, while a value
+ * of 1.0 means that all CPUs were actively running 100% of the time
+ * during the recent period being observed. All values betweens 0.0 and
+ * 1.0 are possible depending of the activities going on in the system.
+ * If the system recent cpu usage is not available, the method returns a
+ * negative value.
+ *
+ * @return the "recent cpu usage" for the whole system; a negative
+ * value if not available.
+ * @since 1.7
+ */
+ public double getSystemCpuLoad();
+
+ /**
+ * Returns the "recent cpu usage" for the Java Virtual Machine process.
+ * This value is a double in the [0.0,1.0] interval. A value of 0.0 means
+ * that none of the CPUs were running threads from the JVM process during
+ * the recent period of time observed, while a value of 1.0 means that all
+ * CPUs were actively running threads from the JVM 100% of the time
+ * during the recent period being observed. Threads from the JVM include
+ * the application threads as well as the JVM internal threads. All values
+ * betweens 0.0 and 1.0 are possible depending of the activities going on
+ * in the JVM process and the whole system. If the Java Virtual Machine
+ * recent CPU usage is not available, the method returns a negative value.
+ *
+ * @return the "recent cpu usage" for the Java Virtual Machine process;
+ * a negative value if not available.
+ * @since 1.7
+ */
+ public double getProcessCpuLoad();
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import java.util.Map;
+
+/**
+ * Platform-specific management interface for the thread system
+ * of the Java virtual machine.
+ * <p>
+ * This platform extension is only available to a thread
+ * implementation that supports this extension.
+ *
+ * @author Paul Hohensee
+ * @since 6u25
+ */
+
+@jdk.Exported
+public interface ThreadMXBean extends java.lang.management.ThreadMXBean {
+ /**
+ * Returns the total CPU time for each thread whose ID is
+ * in the input array {@code ids} in nanoseconds.
+ * The returned values are of nanoseconds precision but
+ * not necessarily nanoseconds accuracy.
+ * <p>
+ * This method is equivalent to calling the
+ * {@link ThreadMXBean#getThreadCpuTime(long)}
+ * method for each thread ID in the input array {@code ids} and setting the
+ * returned value in the corresponding element of the returned array.
+ *
+ * @param ids an array of thread IDs.
+ * @return an array of long values, each of which is the amount of CPU
+ * time the thread whose ID is in the corresponding element of the input
+ * array of IDs has used,
+ * if the thread of a specified ID exists, the thread is alive,
+ * and CPU time measurement is enabled;
+ * {@code -1} otherwise.
+ *
+ * @throws NullPointerException if {@code ids} is {@code null}
+ * @throws IllegalArgumentException if any element in the input array
+ * {@code ids} is {@code <=} {@code 0}.
+ * @throws java.lang.UnsupportedOperationException if the Java
+ * virtual machine implementation does not support CPU time
+ * measurement.
+ *
+ * @see ThreadMXBean#getThreadCpuTime(long)
+ * @see #getThreadUserTime
+ * @see ThreadMXBean#isThreadCpuTimeSupported
+ * @see ThreadMXBean#isThreadCpuTimeEnabled
+ * @see ThreadMXBean#setThreadCpuTimeEnabled
+ */
+ public long[] getThreadCpuTime(long[] ids);
+
+ /**
+ * Returns the CPU time that each thread whose ID is in the input array
+ * {@code ids} has executed in user mode in nanoseconds.
+ * The returned values are of nanoseconds precision but
+ * not necessarily nanoseconds accuracy.
+ * <p>
+ * This method is equivalent to calling the
+ * {@link ThreadMXBean#getThreadUserTime(long)}
+ * method for each thread ID in the input array {@code ids} and setting the
+ * returned value in the corresponding element of the returned array.
+ *
+ * @param ids an array of thread IDs.
+ * @return an array of long values, each of which is the amount of user
+ * mode CPU time the thread whose ID is in the corresponding element of
+ * the input array of IDs has used,
+ * if the thread of a specified ID exists, the thread is alive,
+ * and CPU time measurement is enabled;
+ * {@code -1} otherwise.
+ *
+ * @throws NullPointerException if {@code ids} is {@code null}
+ * @throws IllegalArgumentException if any element in the input array
+ * {@code ids} is {@code <=} {@code 0}.
+ * @throws java.lang.UnsupportedOperationException if the Java
+ * virtual machine implementation does not support CPU time
+ * measurement.
+ *
+ * @see ThreadMXBean#getThreadUserTime(long)
+ * @see #getThreadCpuTime
+ * @see ThreadMXBean#isThreadCpuTimeSupported
+ * @see ThreadMXBean#isThreadCpuTimeEnabled
+ * @see ThreadMXBean#setThreadCpuTimeEnabled
+ */
+ public long[] getThreadUserTime(long[] ids);
+
+ /**
+ * Returns an approximation of the total amount of memory, in bytes,
+ * allocated in heap memory for the thread of the specified ID.
+ * The returned value is an approximation because some Java virtual machine
+ * implementations may use object allocation mechanisms that result in a
+ * delay between the time an object is allocated and the time its size is
+ * recorded.
+ * <p>
+ * If the thread of the specified ID is not alive or does not exist,
+ * this method returns {@code -1}. If thread memory allocation measurement
+ * is disabled, this method returns {@code -1}.
+ * A thread is alive if it has been started and has not yet died.
+ * <p>
+ * If thread memory allocation measurement is enabled after the thread has
+ * started, the Java virtual machine implementation may choose any time up
+ * to and including the time that the capability is enabled as the point
+ * where thread memory allocation measurement starts.
+ *
+ * @param id the thread ID of a thread
+ * @return an approximation of the total memory allocated, in bytes, in
+ * heap memory for a thread of the specified ID
+ * if the thread of the specified ID exists, the thread is alive,
+ * and thread memory allocation measurement is enabled;
+ * {@code -1} otherwise.
+ *
+ * @throws IllegalArgumentException if {@code id} {@code <=} {@code 0}.
+ * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * machine implementation does not support thread memory allocation
+ * measurement.
+ *
+ * @see #isThreadAllocatedMemorySupported
+ * @see #isThreadAllocatedMemoryEnabled
+ * @see #setThreadAllocatedMemoryEnabled
+ */
+ public long getThreadAllocatedBytes(long id);
+
+ /**
+ * Returns an approximation of the total amount of memory, in bytes,
+ * allocated in heap memory for each thread whose ID is in the input
+ * array {@code ids}.
+ * The returned values are approximations because some Java virtual machine
+ * implementations may use object allocation mechanisms that result in a
+ * delay between the time an object is allocated and the time its size is
+ * recorded.
+ * <p>
+ * This method is equivalent to calling the
+ * {@link #getThreadAllocatedBytes(long)}
+ * method for each thread ID in the input array {@code ids} and setting the
+ * returned value in the corresponding element of the returned array.
+ *
+ * @param ids an array of thread IDs.
+ * @return an array of long values, each of which is an approximation of
+ * the total memory allocated, in bytes, in heap memory for the thread
+ * whose ID is in the corresponding element of the input array of IDs.
+ *
+ * @throws NullPointerException if {@code ids} is {@code null}
+ * @throws IllegalArgumentException if any element in the input array
+ * {@code ids} is {@code <=} {@code 0}.
+ * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * machine implementation does not support thread memory allocation
+ * measurement.
+ *
+ * @see #getThreadAllocatedBytes(long)
+ * @see #isThreadAllocatedMemorySupported
+ * @see #isThreadAllocatedMemoryEnabled
+ * @see #setThreadAllocatedMemoryEnabled
+ */
+ public long[] getThreadAllocatedBytes(long[] ids);
+
+ /**
+ * Tests if the Java virtual machine implementation supports thread memory
+ * allocation measurement.
+ *
+ * @return
+ * {@code true}
+ * if the Java virtual machine implementation supports thread memory
+ * allocation measurement;
+ * {@code false} otherwise.
+ */
+ public boolean isThreadAllocatedMemorySupported();
+
+ /**
+ * Tests if thread memory allocation measurement is enabled.
+ *
+ * @return {@code true} if thread memory allocation measurement is enabled;
+ * {@code false} otherwise.
+ *
+ * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * machine does not support thread memory allocation measurement.
+ *
+ * @see #isThreadAllocatedMemorySupported
+ */
+ public boolean isThreadAllocatedMemoryEnabled();
+
+ /**
+ * Enables or disables thread memory allocation measurement. The default
+ * is platform dependent.
+ *
+ * @param enable {@code true} to enable;
+ * {@code false} to disable.
+ *
+ * @throws java.lang.UnsupportedOperationException if the Java virtual
+ * machine does not support thread memory allocation measurement.
+ *
+ * @throws java.lang.SecurityException if a security manager
+ * exists and the caller does not have
+ * ManagementPermission("control").
+ *
+ * @see #isThreadAllocatedMemorySupported
+ */
+ public void setThreadAllocatedMemoryEnabled(boolean enable);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/UnixOperatingSystemMXBean.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+/**
+ * Platform-specific management interface for the Unix
+ * operating system on which the Java virtual machine is running.
+ *
+ * @author Mandy Chung
+ * @since 1.5
+ */
+@jdk.Exported
+public interface UnixOperatingSystemMXBean extends
+ com.sun.management.OperatingSystemMXBean {
+
+ /**
+ * Returns the number of open file descriptors.
+ *
+ * @return the number of open file descriptors.
+ */
+ public long getOpenFileDescriptorCount();
+
+ /**
+ * Returns the maximum number of file descriptors.
+ *
+ * @return the maximum number of file descriptors.
+ */
+ public long getMaxFileDescriptorCount();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management;
+
+import com.sun.management.internal.VMOptionCompositeData;
+import javax.management.openmbean.CompositeData;
+
+/**
+ * Information about a VM option including its value and
+ * where the value came from which is referred as its
+ * {@link VMOption.Origin <i>origin</i>}.
+ * <p>
+ * Each VM option has a default value. A VM option can
+ * be set at VM creation time typically as a command line
+ * argument to the launcher or an argument passed to the
+ * VM created using the JNI invocation interface.
+ * In addition, a VM option may be set via an environment
+ * variable or a configuration file. A VM option can also
+ * be set dynamically via a management interface after
+ * the VM was started.
+ *
+ * A {@code VMOption} contains the value of a VM option
+ * and the origin of that value at the time this {@code VMOption}
+ * object was constructed. The value of the VM option
+ * may be changed after the {@code VMOption} object was constructed,
+ *
+ * @see <a href="{@docRoot}/../../../../technotes/guides/vm/index.html">
+ * Java Virtual Machine</a>
+ * @author Mandy Chung
+ * @since 1.6
+ */
+@jdk.Exported
+public class VMOption {
+ private String name;
+ private String value;
+ private boolean writeable;
+ private Origin origin;
+
+ /**
+ * Origin of the value of a VM option. It tells where the
+ * value of a VM option came from.
+ *
+ * @since 1.6
+ */
+ @jdk.Exported
+ public enum Origin {
+ /**
+ * The VM option has not been set and its value
+ * is the default value.
+ */
+ DEFAULT,
+ /**
+ * The VM option was set at VM creation time typically
+ * as a command line argument to the launcher or
+ * an argument passed to the VM created using the
+ * JNI invocation interface.
+ */
+ VM_CREATION,
+ /**
+ * The VM option was set via an environment variable.
+ */
+ ENVIRON_VAR,
+ /**
+ * The VM option was set via a configuration file.
+ */
+ CONFIG_FILE,
+ /**
+ * The VM option was set via the management interface after the VM
+ * was started.
+ */
+ MANAGEMENT,
+ /**
+ * The VM option was set via the VM ergonomic support.
+ */
+ ERGONOMIC,
+ /**
+ * The VM option was set using the attach framework.
+ * @since 1.9
+ */
+ ATTACH_ON_DEMAND,
+ /**
+ * The VM option was set via some other mechanism.
+ */
+ OTHER
+ }
+
+ /**
+ * Constructs a {@code VMOption}.
+ *
+ * @param name Name of a VM option.
+ * @param value Value of a VM option.
+ * @param writeable {@code true} if a VM option can be set dynamically,
+ * or {@code false} otherwise.
+ * @param origin where the value of a VM option came from.
+ *
+ * @throws NullPointerException if the name or value is {@code null}
+ */
+ public VMOption(String name, String value, boolean writeable, Origin origin) {
+ this.name = name;
+ this.value = value;
+ this.writeable = writeable;
+ this.origin = origin;
+ }
+
+ /**
+ * Constructs a {@code VMOption} object from a
+ * {@link CompositeData CompositeData}.
+ */
+ private VMOption(CompositeData cd) {
+ // validate the input composite data
+ VMOptionCompositeData.validateCompositeData(cd);
+
+ this.name = VMOptionCompositeData.getName(cd);
+ this.value = VMOptionCompositeData.getValue(cd);
+ this.writeable = VMOptionCompositeData.isWriteable(cd);
+ this.origin = VMOptionCompositeData.getOrigin(cd);
+ }
+
+ /**
+ * Returns the name of this VM option.
+ *
+ * @return the name of this VM option.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the value of this VM option at the time when
+ * this {@code VMOption} was created. The value could have been changed.
+ *
+ * @return the value of the VM option at the time when
+ * this {@code VMOption} was created.
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Returns the origin of the value of this VM option. That is,
+ * where the value of this VM option came from.
+ *
+ * @return where the value of this VM option came from.
+ */
+ public Origin getOrigin() {
+ return origin;
+ }
+
+ /**
+ * Tests if this VM option is writeable. If this VM option is writeable,
+ * it can be set by the {@link HotSpotDiagnosticMXBean#setVMOption
+ * HotSpotDiagnosticMXBean.setVMOption} method.
+ *
+ * @return {@code true} if this VM option is writeable; {@code false}
+ * otherwise.
+ */
+ public boolean isWriteable() {
+ return writeable;
+ }
+
+ public String toString() {
+ return "VM option: " + getName() +
+ " value: " + value + " " +
+ " origin: " + origin + " " +
+ (writeable ? "(read-write)" : "(read-only)");
+ }
+
+ /**
+ * Returns a {@code VMOption} object represented by the
+ * given {@code CompositeData}. The given {@code CompositeData}
+ * must contain the following attributes:
+ *
+ * <blockquote>
+ * <table border>
+ * <tr>
+ * <th align=left>Attribute Name</th>
+ * <th align=left>Type</th>
+ * </tr>
+ * <tr>
+ * <td>name</td>
+ * <td>{@code java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td>value</td>
+ * <td>{@code java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td>origin</td>
+ * <td>{@code java.lang.String}</td>
+ * </tr>
+ * <tr>
+ * <td>writeable</td>
+ * <td>{@code java.lang.Boolean}</td>
+ * </tr>
+ * </table>
+ * </blockquote>
+ *
+ * @param cd {@code CompositeData} representing a {@code VMOption}
+ *
+ * @throws IllegalArgumentException if {@code cd} does not
+ * represent a {@code VMOption} with the attributes described
+ * above.
+ *
+ * @return a {@code VMOption} object represented by {@code cd}
+ * if {@code cd} is not {@code null};
+ * {@code null} otherwise.
+ */
+ public static VMOption from(CompositeData cd) {
+ if (cd == null) {
+ return null;
+ }
+
+ if (cd instanceof VMOptionCompositeData) {
+ return ((VMOptionCompositeData) cd).getVMOption();
+ } else {
+ return new VMOption(cd);
+ }
+
+ }
+
+ // for sun.management.MappedMXBeanType
+ static CompositeData toCompositeData(VMOption option) {
+ return VMOptionCompositeData.toCompositeData(option);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandArgumentInfo.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+/**
+ * Diagnostic Command Argument information. It contains the description
+ * of one parameter of the diagnostic command. A parameter can either be an
+ * option or an argument. Options are identified by the option name while
+ * arguments are identified by their position in the command line. The generic
+ * syntax of a diagnostic command is:
+ * <blockquote>
+ * <command name> [<option>=<value>] [<argument_value>]
+ * </blockquote>
+ * Example:
+ * <blockquote>
+ * command_name option1=value1 option2=value argumentA argumentB argumentC
+ * </blockquote>
+ * In this command line, the diagnostic command receives five parameters, two
+ * options named {@code option1} and {@code option2}, and three arguments.
+ * argumentA's position is 0, argumentB's position is 1 and argumentC's
+ * position is 2.
+ *
+ * @since 1.8
+ */
+
+class DiagnosticCommandArgumentInfo {
+ private final String name;
+ private final String description;
+ private final String type;
+ private final String defaultValue;
+ private final boolean mandatory;
+ private final boolean option;
+ private final boolean multiple;
+ private final int position;
+
+ /**
+ * Returns the argument name.
+ *
+ * @return the argument name
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the argument description.
+ *
+ * @return the argument description
+ */
+ String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the argument type.
+ *
+ * @return the argument type
+ */
+ String getType() {
+ return type;
+ }
+
+ /**
+ * Returns the default value as a String if a default value
+ * is defined, null otherwise.
+ *
+ * @return the default value as a String if a default value
+ * is defined, null otherwise.
+ */
+ String getDefault() {
+ return defaultValue;
+ }
+
+ /**
+ * Returns {@code true} if the argument is mandatory,
+ * {@code false} otherwise.
+ *
+ * @return {@code true} if the argument is mandatory,
+ * {@code false} otherwise
+ */
+ boolean isMandatory() {
+ return mandatory;
+ }
+
+ /**
+ * Returns {@code true} if the argument is an option,
+ * {@code false} otherwise. Options have to be specified using the
+ * <key>=<value> syntax on the command line, while other
+ * arguments are specified with a single <value> field and are
+ * identified by their position on command line.
+ *
+ * @return {@code true} if the argument is an option,
+ * {@code false} otherwise
+ */
+ boolean isOption() {
+ return option;
+ }
+
+ /**
+ * Returns {@code true} if the argument can be specified multiple times,
+ * {@code false} otherwise.
+ *
+ * @return {@code true} if the argument can be specified multiple times,
+ * {@code false} otherwise
+ */
+ boolean isMultiple() {
+ return multiple;
+ }
+
+ /**
+ * Returns the expected position of this argument if it is not an option,
+ * -1 otherwise. Argument position if defined from left to right,
+ * starting at zero and ignoring the diagnostic command name and
+ * options.
+ *
+ * @return the expected position of this argument if it is not an option,
+ * -1 otherwise.
+ */
+ int getPosition() {
+ return position;
+ }
+
+ DiagnosticCommandArgumentInfo(String name, String description,
+ String type, String defaultValue,
+ boolean mandatory, boolean option,
+ boolean multiple, int position) {
+ this.name = name;
+ this.description = description;
+ this.type = type;
+ this.defaultValue = defaultValue;
+ this.mandatory = mandatory;
+ this.option = option;
+ this.multiple = multiple;
+ this.position = position;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import com.sun.management.DiagnosticCommandMBean;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.security.Permission;
+import java.util.*;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MalformedObjectNameException;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import sun.management.ManagementFactoryHelper;
+import sun.management.NotificationEmitterSupport;
+import sun.management.VMManagement;
+
+/**
+ * Implementation class for the diagnostic commands subsystem.
+ *
+ * @since 1.8
+ */
+public class DiagnosticCommandImpl extends NotificationEmitterSupport
+ implements DiagnosticCommandMBean {
+
+ private final VMManagement jvm;
+ private volatile Map<String, Wrapper> wrappers = null;
+ private static final String strClassName = "".getClass().getName();
+ private static final String strArrayClassName = String[].class.getName();
+ private final boolean isSupported;
+ private static DiagnosticCommandImpl diagCommandMBean = null;
+
+ static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() {
+ VMManagement jvm = ManagementFactoryHelper.getVMManagement();
+
+ // Remote Diagnostic Commands may not be supported
+ if (diagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) {
+ diagCommandMBean = new DiagnosticCommandImpl(jvm);
+ }
+ return diagCommandMBean;
+ }
+
+ @Override
+ public Object getAttribute(String attribute) throws AttributeNotFoundException,
+ MBeanException, ReflectionException {
+ throw new AttributeNotFoundException(attribute);
+ }
+
+ @Override
+ public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
+ InvalidAttributeValueException, MBeanException, ReflectionException {
+ throw new AttributeNotFoundException(attribute.getName());
+ }
+
+ @Override
+ public AttributeList getAttributes(String[] attributes) {
+ return new AttributeList();
+ }
+
+ @Override
+ public AttributeList setAttributes(AttributeList attributes) {
+ return new AttributeList();
+ }
+
+ private class Wrapper {
+
+ String name;
+ String cmd;
+ DiagnosticCommandInfo info;
+ Permission permission;
+
+ Wrapper(String name, String cmd, DiagnosticCommandInfo info)
+ throws InstantiationException {
+ this.name = name;
+ this.cmd = cmd;
+ this.info = info;
+ this.permission = null;
+ Exception cause = null;
+ if (info.getPermissionClass() != null) {
+ try {
+ Class<?> c = Class.forName(info.getPermissionClass());
+ if (info.getPermissionAction() == null) {
+ try {
+ Constructor<?> constructor = c.getConstructor(String.class);
+ permission = (Permission) constructor.newInstance(info.getPermissionName());
+
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException ex) {
+ cause = ex;
+ }
+ }
+ if (permission == null) {
+ try {
+ Constructor<?> constructor = c.getConstructor(String.class, String.class);
+ permission = (Permission) constructor.newInstance(
+ info.getPermissionName(),
+ info.getPermissionAction());
+ } catch (InstantiationException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException ex) {
+ cause = ex;
+ }
+ }
+ } catch (ClassNotFoundException ex) { }
+ if (permission == null) {
+ InstantiationException iex =
+ new InstantiationException("Unable to instantiate required permission");
+ iex.initCause(cause);
+ }
+ }
+ }
+
+ public String execute(String[] args) {
+ if (permission != null) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(permission);
+ }
+ }
+ if(args == null) {
+ return executeDiagnosticCommand(cmd);
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append(cmd);
+ for(int i=0; i<args.length; i++) {
+ if(args[i] == null) {
+ throw new IllegalArgumentException("Invalid null argument");
+ }
+ sb.append(" ");
+ sb.append(args[i]);
+ }
+ return executeDiagnosticCommand(sb.toString());
+ }
+ }
+ }
+
+ DiagnosticCommandImpl(VMManagement jvm) {
+ this.jvm = jvm;
+ isSupported = jvm.isRemoteDiagnosticCommandsSupported();
+ }
+
+ private static class OperationInfoComparator implements Comparator<MBeanOperationInfo> {
+ @Override
+ public int compare(MBeanOperationInfo o1, MBeanOperationInfo o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ }
+
+ @Override
+ public MBeanInfo getMBeanInfo() {
+ SortedSet<MBeanOperationInfo> operations = new TreeSet<>(new OperationInfoComparator());
+ Map<String, Wrapper> wrappersmap;
+ if (!isSupported) {
+ wrappersmap = Collections.emptyMap();
+ } else {
+ try {
+ String[] command = getDiagnosticCommands();
+ DiagnosticCommandInfo[] info = getDiagnosticCommandInfo(command);
+ MBeanParameterInfo stringArgInfo[] = new MBeanParameterInfo[]{
+ new MBeanParameterInfo("arguments", strArrayClassName,
+ "Array of Diagnostic Commands Arguments and Options")
+ };
+ wrappersmap = new HashMap<>();
+ for (int i = 0; i < command.length; i++) {
+ String name = transform(command[i]);
+ try {
+ Wrapper w = new Wrapper(name, command[i], info[i]);
+ wrappersmap.put(name, w);
+ operations.add(new MBeanOperationInfo(
+ w.name,
+ w.info.getDescription(),
+ (w.info.getArgumentsInfo() == null
+ || w.info.getArgumentsInfo().isEmpty())
+ ? null : stringArgInfo,
+ strClassName,
+ MBeanOperationInfo.ACTION_INFO,
+ commandDescriptor(w)));
+ } catch (InstantiationException ex) {
+ // If for some reasons the creation of a diagnostic command
+ // wrappers fails, the diagnostic command is just ignored
+ // and won't appear in the DynamicMBean
+ }
+ }
+ } catch (IllegalArgumentException | UnsupportedOperationException e) {
+ wrappersmap = Collections.emptyMap();
+ }
+ }
+ wrappers = Collections.unmodifiableMap(wrappersmap);
+ HashMap<String, Object> map = new HashMap<>();
+ map.put("immutableInfo", "false");
+ map.put("interfaceClassName","com.sun.management.DiagnosticCommandMBean");
+ map.put("mxbean", "false");
+ Descriptor desc = new ImmutableDescriptor(map);
+ return new MBeanInfo(
+ this.getClass().getName(),
+ "Diagnostic Commands",
+ null, // attributes
+ null, // constructors
+ operations.toArray(new MBeanOperationInfo[operations.size()]), // operations
+ getNotificationInfo(), // notifications
+ desc);
+ }
+
+ @Override
+ public Object invoke(String actionName, Object[] params, String[] signature)
+ throws MBeanException, ReflectionException {
+ if (!isSupported) {
+ throw new UnsupportedOperationException();
+ }
+ if (wrappers == null) {
+ getMBeanInfo();
+ }
+ Wrapper w = wrappers.get(actionName);
+ if (w != null) {
+ if (w.info.getArgumentsInfo().isEmpty()
+ && (params == null || params.length == 0)
+ && (signature == null || signature.length == 0)) {
+ return w.execute(null);
+ } else if((params != null && params.length == 1)
+ && (signature != null && signature.length == 1
+ && signature[0] != null
+ && signature[0].compareTo(strArrayClassName) == 0)) {
+ return w.execute((String[]) params[0]);
+ }
+ }
+ throw new ReflectionException(new NoSuchMethodException(actionName));
+ }
+
+ private static String transform(String name) {
+ StringBuilder sb = new StringBuilder();
+ boolean toLower = true;
+ boolean toUpper = false;
+ for (int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if (c == '.' || c == '_') {
+ toLower = false;
+ toUpper = true;
+ } else {
+ if (toUpper) {
+ toUpper = false;
+ sb.append(Character.toUpperCase(c));
+ } else if(toLower) {
+ sb.append(Character.toLowerCase(c));
+ } else {
+ sb.append(c);
+ }
+ }
+ }
+ return sb.toString();
+ }
+
+ private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException {
+ HashMap<String, Object> map = new HashMap<>();
+ map.put("dcmd.name", w.info.getName());
+ map.put("dcmd.description", w.info.getDescription());
+ map.put("dcmd.vmImpact", w.info.getImpact());
+ map.put("dcmd.permissionClass", w.info.getPermissionClass());
+ map.put("dcmd.permissionName", w.info.getPermissionName());
+ map.put("dcmd.permissionAction", w.info.getPermissionAction());
+ map.put("dcmd.enabled", w.info.isEnabled());
+ StringBuilder sb = new StringBuilder();
+ sb.append("help ");
+ sb.append(w.info.getName());
+ map.put("dcmd.help", executeDiagnosticCommand(sb.toString()));
+ if (w.info.getArgumentsInfo() != null && !w.info.getArgumentsInfo().isEmpty()) {
+ HashMap<String, Object> allargmap = new HashMap<>();
+ for (DiagnosticCommandArgumentInfo arginfo : w.info.getArgumentsInfo()) {
+ HashMap<String, Object> argmap = new HashMap<>();
+ argmap.put("dcmd.arg.name", arginfo.getName());
+ argmap.put("dcmd.arg.type", arginfo.getType());
+ argmap.put("dcmd.arg.description", arginfo.getDescription());
+ argmap.put("dcmd.arg.isMandatory", arginfo.isMandatory());
+ argmap.put("dcmd.arg.isMultiple", arginfo.isMultiple());
+ boolean isOption = arginfo.isOption();
+ argmap.put("dcmd.arg.isOption", isOption);
+ if(!isOption) {
+ argmap.put("dcmd.arg.position", arginfo.getPosition());
+ } else {
+ argmap.put("dcmd.arg.position", -1);
+ }
+ allargmap.put(arginfo.getName(), new ImmutableDescriptor(argmap));
+ }
+ map.put("dcmd.arguments", new ImmutableDescriptor(allargmap));
+ }
+ return new ImmutableDescriptor(map);
+ }
+
+ private final static String notifName =
+ "javax.management.Notification";
+
+ private final static String[] diagFramNotifTypes = {
+ "jmx.mbean.info.changed"
+ };
+
+ private MBeanNotificationInfo[] notifInfo = null;
+
+ @Override
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ synchronized (this) {
+ if (notifInfo == null) {
+ notifInfo = new MBeanNotificationInfo[1];
+ notifInfo[0] =
+ new MBeanNotificationInfo(diagFramNotifTypes,
+ notifName,
+ "Diagnostic Framework Notification");
+ }
+ }
+ return notifInfo;
+ }
+
+ private static long seqNumber = 0;
+ private static long getNextSeqNumber() {
+ return ++seqNumber;
+ }
+
+ private void createDiagnosticFrameworkNotification() {
+
+ if (!hasListeners()) {
+ return;
+ }
+ ObjectName on = null;
+ try {
+ on = ObjectName.getInstance(PlatformMBeanProviderImpl.DIAGNOSTIC_COMMAND_MBEAN_NAME);
+ } catch (MalformedObjectNameException e) { }
+ Notification notif = new Notification("jmx.mbean.info.changed",
+ on,
+ getNextSeqNumber());
+ notif.setUserData(getMBeanInfo());
+ sendNotification(notif);
+ }
+
+ @Override
+ public synchronized void addNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback) {
+ boolean before = hasListeners();
+ super.addNotificationListener(listener, filter, handback);
+ boolean after = hasListeners();
+ if (!before && after) {
+ setNotificationEnabled(true);
+ }
+ }
+
+ @Override
+ public synchronized void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener);
+ boolean after = hasListeners();
+ if (before && !after) {
+ setNotificationEnabled(false);
+ }
+ }
+
+ @Override
+ public synchronized void removeNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws ListenerNotFoundException {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener, filter, handback);
+ boolean after = hasListeners();
+ if (before && !after) {
+ setNotificationEnabled(false);
+ }
+ }
+
+ private native void setNotificationEnabled(boolean enabled);
+ private native String[] getDiagnosticCommands();
+ private native DiagnosticCommandInfo[] getDiagnosticCommandInfo(String[] commands);
+ private native String executeDiagnosticCommand(String command);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import java.util.List;
+
+/**
+ * Diagnostic command information. It contains the description of a
+ * diagnostic command.
+ *
+ * @since 1.8
+ */
+
+class DiagnosticCommandInfo {
+ private final String name;
+ private final String description;
+ private final String impact;
+ private final String permissionClass;
+ private final String permissionName;
+ private final String permissionAction;
+ private final boolean enabled;
+ private final List<DiagnosticCommandArgumentInfo> arguments;
+
+ /**
+ * Returns the diagnostic command name.
+ *
+ * @return the diagnostic command name
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the diagnostic command description.
+ *
+ * @return the diagnostic command description
+ */
+ String getDescription() {
+ return description;
+ }
+
+ /**
+ * Returns the potential impact of the diagnostic command execution
+ * on the Java virtual machine behavior.
+ *
+ * @return the potential impact of the diagnostic command execution
+ * on the Java virtual machine behavior
+ */
+ String getImpact() {
+ return impact;
+ }
+
+ /**
+ * Returns the name of the permission class required to be allowed
+ * to invoke the diagnostic command, or null if no permission
+ * is required.
+ *
+ * @return the name of the permission class name required to be allowed
+ * to invoke the diagnostic command, or null if no permission
+ * is required
+ */
+ String getPermissionClass() {
+ return permissionClass;
+ }
+
+ /**
+ * Returns the permission name required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required.
+ *
+ * @return the permission name required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required
+ */
+ String getPermissionName() {
+ return permissionName;
+ }
+
+ /**
+ * Returns the permission action required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required or
+ * if the permission has no action specified.
+ *
+ * @return the permission action required to be allowed to invoke the
+ * diagnostic command, or null if no permission is required or
+ * if the permission has no action specified
+ */
+ String getPermissionAction() {
+ return permissionAction;
+ }
+
+ /**
+ * Returns {@code true} if the diagnostic command is enabled,
+ * {@code false} otherwise. The enabled/disabled
+ * status of a diagnostic command can evolve during
+ * the lifetime of the Java virtual machine.
+ *
+ * @return {@code true} if the diagnostic command is enabled,
+ * {@code false} otherwise
+ */
+ boolean isEnabled() {
+ return enabled;
+ }
+
+ /**
+ * Returns the list of the diagnostic command arguments description.
+ * If the diagnostic command has no arguments, it returns an empty list.
+ *
+ * @return a list of the diagnostic command arguments description
+ */
+ List<DiagnosticCommandArgumentInfo> getArgumentsInfo() {
+ return arguments;
+ }
+
+ DiagnosticCommandInfo(String name, String description,
+ String impact, String permissionClass,
+ String permissionName, String permissionAction,
+ boolean enabled,
+ List<DiagnosticCommandArgumentInfo> arguments)
+ {
+ this.name = name;
+ this.description = description;
+ this.impact = impact;
+ this.permissionClass = permissionClass;
+ this.permissionName = permissionName;
+ this.permissionAction = permissionAction;
+ this.enabled = enabled;
+ this.arguments = arguments;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/Flag.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import java.util.*;
+import com.sun.management.VMOption;
+import com.sun.management.VMOption.Origin;
+import java.security.AccessController;
+
+/**
+ * Flag class is a helper class for constructing a VMOption.
+ * It has the static methods for getting the Flag objects, each
+ * corresponds to one VMOption.
+ *
+ */
+class Flag {
+ private String name;
+ private Object value;
+ private Origin origin;
+ private boolean writeable;
+ private boolean external;
+
+ Flag(String name, Object value, boolean writeable,
+ boolean external, Origin origin) {
+ this.name = name;
+ this.value = value == null ? "" : value ;
+ this.origin = origin;
+ this.writeable = writeable;
+ this.external = external;
+ }
+
+ Object getValue() {
+ return value;
+ }
+
+ boolean isWriteable() {
+ return writeable;
+ }
+
+ boolean isExternal() {
+ return external;
+ }
+
+ VMOption getVMOption() {
+ return new VMOption(name, value.toString(), writeable, origin);
+ }
+
+ static Flag getFlag(String name) {
+ String[] names = new String[1];
+ names[0] = name;
+
+ List<Flag> flags = getFlags(names, 1);
+ if (flags.isEmpty()) {
+ return null;
+ } else {
+ // flags should have only one element
+ return flags.get(0);
+ }
+ }
+
+ static List<Flag> getAllFlags() {
+ int numFlags = getInternalFlagCount();
+
+ // Get all internal flags with names = null
+ return getFlags(null, numFlags);
+ }
+
+ private static List<Flag> getFlags(String[] names, int numFlags) {
+ Flag[] flags = new Flag[numFlags];
+ int count = getFlags(names, flags, numFlags);
+
+ List<Flag> result = new ArrayList<>();
+ for (Flag f : flags) {
+ if (f != null) {
+ result.add(f);
+ }
+ }
+ return result;
+ }
+
+ private static native String[] getAllFlagNames();
+ // getFlags sets each element in the given flags array
+ // with a Flag object only if the name is valid and the
+ // type is supported. The flags array may contain null elements.
+ private static native int getFlags(String[] names, Flag[] flags, int count);
+ private static native int getInternalFlagCount();
+
+ // These set* methods are synchronized on the class object
+ // to avoid multiple threads updating the same flag at the same time.
+ static synchronized native void setLongValue(String name, long value);
+ static synchronized native void setDoubleValue(String name, double value);
+ static synchronized native void setBooleanValue(String name, boolean value);
+ static synchronized native void setStringValue(String name, String value);
+
+ static {
+ AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("management");
+ return null;
+ }
+ });
+ initialize();
+ }
+ private static native void initialize();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import com.sun.management.GarbageCollectionNotificationInfo;
+import com.sun.management.GcInfo;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import sun.management.LazyCompositeData;
+import static sun.management.LazyCompositeData.getString;
+import sun.management.Util;
+
+/**
+ * A CompositeData for GarbageCollectionNotificationInfo for the local management support.
+ * This class avoids the performance penalty paid to the
+ * construction of a CompositeData use in the local case.
+ */
+public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData {
+ private final GarbageCollectionNotificationInfo gcNotifInfo;
+
+ public GarbageCollectionNotifInfoCompositeData(GarbageCollectionNotificationInfo info) {
+ this.gcNotifInfo = info;
+ }
+
+ public GarbageCollectionNotificationInfo getGarbageCollectionNotifInfo() {
+ return gcNotifInfo;
+ }
+
+ public static CompositeData toCompositeData(GarbageCollectionNotificationInfo info) {
+ GarbageCollectionNotifInfoCompositeData gcnicd =
+ new GarbageCollectionNotifInfoCompositeData(info);
+ return gcnicd.getCompositeData();
+ }
+
+ private CompositeType getCompositeTypeByBuilder() {
+ final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {
+ public GcInfoBuilder run() {
+ try {
+ Class<?> cl = Class.forName("com.sun.management.GcInfo");
+ Field f = cl.getDeclaredField("builder");
+ f.setAccessible(true);
+ return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo());
+ } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+ return null;
+ }
+ }
+ });
+ CompositeType gict = null;
+ synchronized(compositeTypeByBuilder) {
+ gict = compositeTypeByBuilder.get(builder);
+ if(gict == null) {
+ OpenType<?>[] gcNotifInfoItemTypes = new OpenType<?>[] {
+ SimpleType.STRING,
+ SimpleType.STRING,
+ SimpleType.STRING,
+ builder.getGcInfoCompositeType(),
+ };
+ try {
+ final String typeName =
+ "sun.management.GarbageCollectionNotifInfoCompositeType";
+ gict = new CompositeType(typeName,
+ "CompositeType for GC notification info",
+ gcNotifInfoItemNames,
+ gcNotifInfoItemNames,
+ gcNotifInfoItemTypes);
+ compositeTypeByBuilder.put(builder,gict);
+ } catch (OpenDataException e) {
+ // shouldn't reach here
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return gict;
+ }
+
+ protected CompositeData getCompositeData() {
+ // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
+ // gcNotifInfoItemNames!
+ final Object[] gcNotifInfoItemValues;
+ gcNotifInfoItemValues = new Object[] {
+ gcNotifInfo.getGcName(),
+ gcNotifInfo.getGcAction(),
+ gcNotifInfo.getGcCause(),
+ GcInfoCompositeData.toCompositeData(gcNotifInfo.getGcInfo())
+ };
+
+ CompositeType gict = getCompositeTypeByBuilder();
+
+ try {
+ return new CompositeDataSupport(gict,
+ gcNotifInfoItemNames,
+ gcNotifInfoItemValues);
+ } catch (OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ // private static MappedMXBeanType gcInfoMapType;
+ private static final String GC_NAME = "gcName";
+ private static final String GC_ACTION = "gcAction";
+ private static final String GC_CAUSE = "gcCause";
+ private static final String GC_INFO = "gcInfo";
+ private static final String[] gcNotifInfoItemNames = {
+ GC_NAME,
+ GC_ACTION,
+ GC_CAUSE,
+ GC_INFO
+ };
+ private static HashMap<GcInfoBuilder,CompositeType> compositeTypeByBuilder =
+ new HashMap<>();
+
+ public static String getGcName(CompositeData cd) {
+ String gcname = getString(cd, GC_NAME);
+ if (gcname == null) {
+ throw new IllegalArgumentException("Invalid composite data: " +
+ "Attribute " + GC_NAME + " has null value");
+ }
+ return gcname;
+ }
+
+ public static String getGcAction(CompositeData cd) {
+ String gcaction = getString(cd, GC_ACTION);
+ if (gcaction == null) {
+ throw new IllegalArgumentException("Invalid composite data: " +
+ "Attribute " + GC_ACTION + " has null value");
+ }
+ return gcaction;
+ }
+
+ public static String getGcCause(CompositeData cd) {
+ String gccause = getString(cd, GC_CAUSE);
+ if (gccause == null) {
+ throw new IllegalArgumentException("Invalid composite data: " +
+ "Attribute " + GC_CAUSE + " has null value");
+ }
+ return gccause;
+ }
+
+ public static GcInfo getGcInfo(CompositeData cd) {
+ CompositeData gcInfoData = (CompositeData) cd.get(GC_INFO);
+ return GcInfo.from(gcInfoData);
+ }
+
+ /** Validate if the input CompositeData has the expected
+ * CompositeType (i.e. contain all attributes with expected
+ * names and types).
+ */
+ public static void validateCompositeData(CompositeData cd) {
+ if (cd == null) {
+ throw new NullPointerException("Null CompositeData");
+ }
+
+ if (!isTypeMatched( getBaseGcNotifInfoCompositeType(), cd.getCompositeType())) {
+ throw new IllegalArgumentException(
+ "Unexpected composite type for GarbageCollectionNotificationInfo");
+ }
+ }
+
+ // This is only used for validation.
+ private static CompositeType baseGcNotifInfoCompositeType = null;
+ private static synchronized CompositeType getBaseGcNotifInfoCompositeType() {
+ if (baseGcNotifInfoCompositeType == null) {
+ try {
+ OpenType<?>[] baseGcNotifInfoItemTypes = new OpenType<?>[] {
+ SimpleType.STRING,
+ SimpleType.STRING,
+ SimpleType.STRING,
+ GcInfoCompositeData.getBaseGcInfoCompositeType()
+ };
+ baseGcNotifInfoCompositeType =
+ new CompositeType("sun.management.BaseGarbageCollectionNotifInfoCompositeType",
+ "CompositeType for Base GarbageCollectionNotificationInfo",
+ gcNotifInfoItemNames,
+ gcNotifInfoItemNames,
+ baseGcNotifInfoItemTypes);
+ } catch (OpenDataException e) {
+ // shouldn't reach here
+ throw new RuntimeException(e);
+ }
+ }
+ return baseGcNotifInfoCompositeType;
+ }
+
+ private static final long serialVersionUID = -1805123446483771292L;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectorExtImpl.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import com.sun.management.GarbageCollectionNotificationInfo;
+import com.sun.management.GarbageCollectorMXBean;
+import com.sun.management.GcInfo;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryPoolMXBean;
+import java.util.List;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.openmbean.CompositeData;
+import sun.management.GarbageCollectorImpl;
+
+/**
+ * Implementation class for the garbage collector.
+ * Standard and committed hotspot-specific metrics if any.
+ *
+ * ManagementFactory.getGarbageCollectorMXBeans() returns a list
+ * of instances of this class.
+ */
+public class GarbageCollectorExtImpl extends GarbageCollectorImpl
+ implements GarbageCollectorMXBean {
+
+ public GarbageCollectorExtImpl(String name) {
+ super(name);
+ }
+
+ // The memory pools are static and won't be changed.
+ // TODO: If the hotspot implementation begins to have pools
+ // dynamically created and removed, this needs to be modified.
+ private String[] poolNames = null;
+ private synchronized String[] getAllPoolNames() {
+ if (poolNames == null) {
+ List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
+ poolNames = new String[pools.size()];
+ int i = 0;
+ for (MemoryPoolMXBean m : pools) {
+ poolNames[i++] = m.getName();
+ }
+ }
+ return poolNames;
+ }
+
+ public GcInfo getLastGcInfo() {
+ GcInfo info = getGcInfoBuilder().getLastGcInfo();
+ return info;
+ }
+
+ private final static String notifName =
+ "javax.management.Notification";
+
+ private final static String[] gcNotifTypes = {
+ GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION
+ };
+
+ private MBeanNotificationInfo[] notifInfo = null;
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ synchronized (this) {
+ if (notifInfo == null) {
+ notifInfo = new MBeanNotificationInfo[1];
+ notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes,
+ notifName,
+ "GC Notification");
+ }
+ }
+ return notifInfo;
+ }
+
+ private static long seqNumber = 0;
+ private static long getNextSeqNumber() {
+ return ++seqNumber;
+ }
+
+ protected void createGCNotification(long timestamp,
+ String gcName,
+ String gcAction,
+ String gcCause,
+ GcInfo gcInfo) {
+ if (!hasListeners()) {
+ return;
+ }
+ Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION,
+ getObjectName(),
+ getNextSeqNumber(),
+ timestamp,
+ gcName);
+ GarbageCollectionNotificationInfo info =
+ new GarbageCollectionNotificationInfo(gcName,
+ gcAction,
+ gcCause,
+ gcInfo);
+
+ CompositeData cd =
+ GarbageCollectionNotifInfoCompositeData.toCompositeData(info);
+ notif.setUserData(cd);
+ sendNotification(notif);
+ }
+
+ public synchronized void addNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ {
+ boolean before = hasListeners();
+ super.addNotificationListener(listener, filter, handback);
+ boolean after = hasListeners();
+ if (!before && after) {
+ setNotificationEnabled(this, true);
+ }
+ }
+
+ public synchronized void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener);
+ boolean after = hasListeners();
+
+ if (before && !after) {
+ setNotificationEnabled(this,false);
+ }
+ }
+
+ public synchronized void removeNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws ListenerNotFoundException
+ {
+ boolean before = hasListeners();
+ super.removeNotificationListener(listener,filter,handback);
+ boolean after = hasListeners();
+ if (before && !after) {
+ setNotificationEnabled(this,false);
+ }
+ }
+
+ private GcInfoBuilder gcInfoBuilder;
+ // Invoked also by the VM
+ private synchronized GcInfoBuilder getGcInfoBuilder() {
+ if(gcInfoBuilder == null) {
+ gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames());
+ }
+ return gcInfoBuilder;
+ }
+
+ private native void setNotificationEnabled(GarbageCollectorMXBean gc,
+ boolean enabled);
+
+ // Invoked by the VM
+ private static java.lang.management.GarbageCollectorMXBean
+ createGarbageCollector(String name, String type) {
+
+ return new GarbageCollectorExtImpl(name);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoBuilder.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.management.internal;
+
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.MemoryUsage;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import com.sun.management.GcInfo;
+import sun.management.Util;
+
+/**
+ * Helper class to build composite data.
+ */
+public class GcInfoBuilder {
+ private final GarbageCollectorMXBean gc;
+ private final String[] poolNames;
+ private String[] allItemNames;
+
+ // GC-specific composite type:
+ // Each GarbageCollectorMXBean may have different GC-specific attributes
+ // the CompositeType for the GcInfo could be different.
+ private CompositeType gcInfoCompositeType;
+
+ // GC-specific items
+ private final int gcExtItemCount;
+ private final String[] gcExtItemNames;
+ private final String[] gcExtItemDescs;
+ private final char[] gcExtItemTypes;
+
+ GcInfoBuilder(GarbageCollectorMXBean gc, String[] poolNames) {
+ this.gc = gc;
+ this.poolNames = poolNames;
+ this.gcExtItemCount = getNumGcExtAttributes(gc);
+ this.gcExtItemNames = new String[gcExtItemCount];
+ this.gcExtItemDescs = new String[gcExtItemCount];
+ this.gcExtItemTypes = new char[gcExtItemCount];
+
+ // Fill the information about extension attributes
+ fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames,
+ gcExtItemTypes, gcExtItemDescs);
+
+ // lazily build the CompositeType for the GcInfo
+ // including the GC-specific extension attributes
+ this.gcInfoCompositeType = null;
+ }
+
+ GcInfo getLastGcInfo() {
+ MemoryUsage[] usageBeforeGC = new MemoryUsage[poolNames.length];
+ MemoryUsage[] usageAfterGC = new MemoryUsage[poolNames.length];
+ Object[] values = new Object[gcExtItemCount];
+
+ return getLastGcInfo0(gc, gcExtItemCount, values, gcExtItemTypes,
+ usageBeforeGC, usageAfterGC);
+ }
+
+ public String[] getPoolNames() {
+ return poolNames;
+ }
+
+ int getGcExtItemCount() {
+ return gcExtItemCount;
+ }
+
+ // Returns the CompositeType for the GcInfo including
+ // the extension attributes
+ synchronized CompositeType getGcInfoCompositeType() {
+ if (gcInfoCompositeType != null)
+ return gcInfoCompositeType;
+
+ // First, fill with the attributes in the GcInfo
+ String[] gcInfoItemNames = GcInfoCompositeData.getBaseGcInfoItemNames();
+ OpenType<?>[] gcInfoItemTypes = GcInfoCompositeData.getBaseGcInfoItemTypes();
+ int numGcInfoItems = gcInfoItemNames.length;
+
+ int itemCount = numGcInfoItems + gcExtItemCount;
+ allItemNames = new String[itemCount];
+ String[] allItemDescs = new String[itemCount];
+ OpenType<?>[] allItemTypes = new OpenType<?>[itemCount];
+
+ System.arraycopy(gcInfoItemNames, 0, allItemNames, 0, numGcInfoItems);
+ System.arraycopy(gcInfoItemNames, 0, allItemDescs, 0, numGcInfoItems);
+ System.arraycopy(gcInfoItemTypes, 0, allItemTypes, 0, numGcInfoItems);
+
+ // Then fill with the extension GC-specific attributes, if any.
+ if (gcExtItemCount > 0) {
+ fillGcAttributeInfo(gc, gcExtItemCount, gcExtItemNames,
+ gcExtItemTypes, gcExtItemDescs);
+ System.arraycopy(gcExtItemNames, 0, allItemNames,
+ numGcInfoItems, gcExtItemCount);
+ System.arraycopy(gcExtItemDescs, 0, allItemDescs,
+ numGcInfoItems, gcExtItemCount);
+ for (int i = numGcInfoItems, j = 0; j < gcExtItemCount; i++, j++) {
+ switch (gcExtItemTypes[j]) {
+ case 'Z':
+ allItemTypes[i] = SimpleType.BOOLEAN;
+ break;
+ case 'B':
+ allItemTypes[i] = SimpleType.BYTE;
+ break;
+ case 'C':
+ allItemTypes[i] = SimpleType.CHARACTER;
+ break;
+ case 'S':
+ allItemTypes[i] = SimpleType.SHORT;
+ break;
+ case 'I':
+ allItemTypes[i] = SimpleType.INTEGER;
+ break;
+ case 'J':
+ allItemTypes[i] = SimpleType.LONG;
+ break;
+ case 'F':
+ allItemTypes[i] = SimpleType.FLOAT;
+ break;
+ case 'D':
+ allItemTypes[i] = SimpleType.DOUBLE;
+ break;
+ default:
+ throw new AssertionError(
+ "Unsupported type [" + gcExtItemTypes[i] + "]");
+ }
+ }
+ }
+
+ CompositeType gict = null;
+ try {
+ final String typeName =
+ "sun.management." + gc.getName() + ".GcInfoCompositeType";
+
+ gict = new CompositeType(typeName,
+ "CompositeType for GC info for " +
+ gc.getName(),
+ allItemNames,
+ allItemDescs,
+ allItemTypes);
+ } catch (OpenDataException e) {
+ // shouldn't reach here
+ throw new RuntimeException(e);
+ }
+ gcInfoCompositeType = gict;
+
+ return gcInfoCompositeType;
+ }
+
+ synchronized String[] getItemNames() {
+ if (allItemNames == null) {
+ // initialize when forming the composite type
+ getGcInfoCompositeType();
+ }
+ return allItemNames;
+ }
+
+ // Retrieve information about extension attributes
+ private native int getNumGcExtAttributes(GarbageCollectorMXBean gc);
+ private native void fillGcAttributeInfo(GarbageCollectorMXBean gc,
+ int numAttributes,
+ String[] attributeNames,
+ char[] types,
+ String[] descriptions);
+
+ /**
+ * Returns the last GcInfo
+ *
+ * @param gc GarbageCollectorMXBean that the gc info is associated with.
+ * @param numExtAtts number of extension attributes
+ * @param extAttValues Values of extension attributes to be filled.
+ * @param before Memory usage before GC to be filled.
+ * @param after Memory usage after GC to be filled.
+ */
+ private native GcInfo getLastGcInfo0(GarbageCollectorMXBean gc,
+ int numExtAtts,
+ Object[] extAttValues,
+ char[] extAttTypes,
+ MemoryUsage[] before,
+ MemoryUsage[] after);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import java.lang.management.MemoryUsage;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.io.InvalidObjectException;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.OpenDataException;
+import com.sun.management.GcInfo;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.management.LazyCompositeData;
+import static sun.management.LazyCompositeData.getLong;
+import sun.management.MappedMXBeanType;
+import sun.management.Util;
+
+/**
+ * A CompositeData for GcInfo for the local management support.
+ * This class avoids the performance penalty paid to the
+ * construction of a CompositeData use in the local case.
+ */
+public class GcInfoCompositeData extends LazyCompositeData {
+ private final GcInfo info;
+ private final GcInfoBuilder builder;
+ private final Object[] gcExtItemValues;
+
+ public GcInfoCompositeData(GcInfo info,
+ GcInfoBuilder builder,
+ Object[] gcExtItemValues) {
+ this.info = info;
+ this.builder = builder;
+ this.gcExtItemValues = gcExtItemValues;
+ }
+
+ public GcInfo getGcInfo() {
+ return info;
+ }
+
+ public static CompositeData toCompositeData(final GcInfo info) {
+ final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() {
+ public GcInfoBuilder run() {
+ try {
+ Class<?> cl = Class.forName("com.sun.management.GcInfo");
+ Field f = cl.getDeclaredField("builder");
+ f.setAccessible(true);
+ return (GcInfoBuilder)f.get(info);
+ } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+ return null;
+ }
+ }
+ });
+ final Object[] extAttr = AccessController.doPrivileged (new PrivilegedAction<Object[]>() {
+ public Object[] run() {
+ try {
+ Class<?> cl = Class.forName("com.sun.management.GcInfo");
+ Field f = cl.getDeclaredField("extAttributes");
+ f.setAccessible(true);
+ return (Object[])f.get(info);
+ } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
+ return null;
+ }
+ }
+ });
+ GcInfoCompositeData gcicd =
+ new GcInfoCompositeData(info,builder,extAttr);
+ return gcicd.getCompositeData();
+ }
+
+ protected CompositeData getCompositeData() {
+ // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
+ // baseGcInfoItemNames!
+ final Object[] baseGcInfoItemValues;
+
+ try {
+ baseGcInfoItemValues = new Object[] {
+ info.getId(),
+ info.getStartTime(),
+ info.getEndTime(),
+ info.getDuration(),
+ memoryUsageMapType.toOpenTypeData(info.getMemoryUsageBeforeGc()),
+ memoryUsageMapType.toOpenTypeData(info.getMemoryUsageAfterGc()),
+ };
+ } catch (OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+
+ // Get the item values for the extension attributes
+ final int gcExtItemCount = builder.getGcExtItemCount();
+ if (gcExtItemCount == 0 &&
+ gcExtItemValues != null && gcExtItemValues.length != 0) {
+ throw new AssertionError("Unexpected Gc Extension Item Values");
+ }
+
+ if (gcExtItemCount > 0 && (gcExtItemValues == null ||
+ gcExtItemCount != gcExtItemValues.length)) {
+ throw new AssertionError("Unmatched Gc Extension Item Values");
+ }
+
+ Object[] values = new Object[baseGcInfoItemValues.length +
+ gcExtItemCount];
+ System.arraycopy(baseGcInfoItemValues, 0, values, 0,
+ baseGcInfoItemValues.length);
+
+ if (gcExtItemCount > 0) {
+ System.arraycopy(gcExtItemValues, 0, values,
+ baseGcInfoItemValues.length, gcExtItemCount);
+ }
+
+ try {
+ return new CompositeDataSupport(builder.getGcInfoCompositeType(),
+ builder.getItemNames(),
+ values);
+ } catch (OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ private static final String ID = "id";
+ private static final String START_TIME = "startTime";
+ private static final String END_TIME = "endTime";
+ private static final String DURATION = "duration";
+ private static final String MEMORY_USAGE_BEFORE_GC = "memoryUsageBeforeGc";
+ private static final String MEMORY_USAGE_AFTER_GC = "memoryUsageAfterGc";
+
+ private static final String[] baseGcInfoItemNames = {
+ ID,
+ START_TIME,
+ END_TIME,
+ DURATION,
+ MEMORY_USAGE_BEFORE_GC,
+ MEMORY_USAGE_AFTER_GC,
+ };
+
+
+ private static MappedMXBeanType memoryUsageMapType;
+ static {
+ try {
+ Method m = GcInfo.class.getMethod("getMemoryUsageBeforeGc");
+ memoryUsageMapType =
+ MappedMXBeanType.getMappedType(m.getGenericReturnType());
+ } catch (NoSuchMethodException | OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ static String[] getBaseGcInfoItemNames() {
+ return baseGcInfoItemNames;
+ }
+
+ private static OpenType<?>[] baseGcInfoItemTypes = null;
+ static synchronized OpenType<?>[] getBaseGcInfoItemTypes() {
+ if (baseGcInfoItemTypes == null) {
+ OpenType<?> memoryUsageOpenType = memoryUsageMapType.getOpenType();
+ baseGcInfoItemTypes = new OpenType<?>[] {
+ SimpleType.LONG,
+ SimpleType.LONG,
+ SimpleType.LONG,
+ SimpleType.LONG,
+
+ memoryUsageOpenType,
+ memoryUsageOpenType,
+ };
+ }
+ return baseGcInfoItemTypes;
+ }
+
+ public static long getId(CompositeData cd) {
+ return getLong(cd, ID);
+ }
+ public static long getStartTime(CompositeData cd) {
+ return getLong(cd, START_TIME);
+ }
+ public static long getEndTime(CompositeData cd) {
+ return getLong(cd, END_TIME);
+ }
+
+ public static Map<String, MemoryUsage>
+ getMemoryUsageBeforeGc(CompositeData cd) {
+ try {
+ TabularData td = (TabularData) cd.get(MEMORY_USAGE_BEFORE_GC);
+ return cast(memoryUsageMapType.toJavaTypeData(td));
+ } catch (InvalidObjectException | OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static Map<String, MemoryUsage> cast(Object x) {
+ return (Map<String, MemoryUsage>) x;
+ }
+ public static Map<String, MemoryUsage>
+ getMemoryUsageAfterGc(CompositeData cd) {
+ try {
+ TabularData td = (TabularData) cd.get(MEMORY_USAGE_AFTER_GC);
+ //return (Map<String,MemoryUsage>)
+ return cast(memoryUsageMapType.toJavaTypeData(td));
+ } catch (InvalidObjectException | OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Returns true if the input CompositeData has the expected
+ * CompositeType (i.e. contain all attributes with expected
+ * names and types). Otherwise, return false.
+ */
+ public static void validateCompositeData(CompositeData cd) {
+ if (cd == null) {
+ throw new NullPointerException("Null CompositeData");
+ }
+
+ if (!isTypeMatched(getBaseGcInfoCompositeType(),
+ cd.getCompositeType())) {
+ throw new IllegalArgumentException(
+ "Unexpected composite type for GcInfo");
+ }
+ }
+
+ // This is only used for validation.
+ private static CompositeType baseGcInfoCompositeType = null;
+ static synchronized CompositeType getBaseGcInfoCompositeType() {
+ if (baseGcInfoCompositeType == null) {
+ try {
+ baseGcInfoCompositeType =
+ new CompositeType("sun.management.BaseGcInfoCompositeType",
+ "CompositeType for Base GcInfo",
+ getBaseGcInfoItemNames(),
+ getBaseGcInfoItemNames(),
+ getBaseGcInfoItemTypes());
+ } catch (OpenDataException e) {
+ // shouldn't reach here
+ throw new RuntimeException(e);
+ }
+ }
+ return baseGcInfoCompositeType;
+ }
+
+ private static final long serialVersionUID = -5716428894085882742L;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.management.ObjectName;
+
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+import sun.management.Util;
+
+/**
+ * Implementation of the diagnostic MBean for Hotspot VM.
+ */
+public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
+ public HotSpotDiagnostic() {
+ }
+
+ @Override
+ public void dumpHeap(String outputFile, boolean live) throws IOException {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkWrite(outputFile);
+ Util.checkControlAccess();
+ }
+
+ dumpHeap0(outputFile, live);
+ }
+
+ private native void dumpHeap0(String outputFile, boolean live) throws IOException;
+
+ @Override
+ public List<VMOption> getDiagnosticOptions() {
+ List<Flag> allFlags = Flag.getAllFlags();
+ List<VMOption> result = new ArrayList<>();
+ for (Flag flag : allFlags) {
+ if (flag.isWriteable() && flag.isExternal()) {
+ result.add(flag.getVMOption());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public VMOption getVMOption(String name) {
+ if (name == null) {
+ throw new NullPointerException("name cannot be null");
+ }
+
+ Flag f = Flag.getFlag(name);
+ if (f == null) {
+ throw new IllegalArgumentException("VM option \"" +
+ name + "\" does not exist");
+ }
+ return f.getVMOption();
+ }
+
+ @Override
+ public void setVMOption(String name, String value) {
+ if (name == null) {
+ throw new NullPointerException("name cannot be null");
+ }
+ if (value == null) {
+ throw new NullPointerException("value cannot be null");
+ }
+
+ Util.checkControlAccess();
+ Flag flag = Flag.getFlag(name);
+ if (flag == null) {
+ throw new IllegalArgumentException("VM option \"" +
+ name + "\" does not exist");
+ }
+ if (!flag.isWriteable()){
+ throw new IllegalArgumentException("VM Option \"" +
+ name + "\" is not writeable");
+ }
+
+ // Check the type of the value
+ Object v = flag.getValue();
+ if (v instanceof Long) {
+ try {
+ long l = Long.parseLong(value);
+ Flag.setLongValue(name, l);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid value:" +
+ " VM Option \"" + name + "\"" +
+ " expects numeric value", e);
+ }
+ } else if (v instanceof Double) {
+ try {
+ double d = Double.parseDouble(value);
+ Flag.setDoubleValue(name, d);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid value:" +
+ " VM Option \"" + name + "\"" +
+ " expects numeric value", e);
+ }
+ } else if (v instanceof Boolean) {
+ if (!value.equalsIgnoreCase("true") &&
+ !value.equalsIgnoreCase("false")) {
+ throw new IllegalArgumentException("Invalid value:" +
+ " VM Option \"" + name + "\"" +
+ " expects \"true\" or \"false\".");
+ }
+ Flag.setBooleanValue(name, Boolean.parseBoolean(value));
+ } else if (v instanceof String) {
+ Flag.setStringValue(name, value);
+ } else {
+ throw new IllegalArgumentException("VM Option \"" +
+ name + "\" is of an unsupported type: " +
+ v.getClass().getName());
+ }
+ }
+
+ @Override
+ public ObjectName getObjectName() {
+ return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.management.internal;
+
+import com.sun.management.ThreadMXBean;
+import sun.management.ManagementFactoryHelper;
+import sun.management.ThreadImpl;
+import sun.management.VMManagement;
+
+/**
+ *
+ */
+public class HotSpotThreadImpl extends ThreadImpl implements ThreadMXBean {
+ public HotSpotThreadImpl(VMManagement vm) {
+ super(ManagementFactoryHelper.getVMManagement());
+ }
+
+ @Override
+ public boolean isThreadAllocatedMemorySupported() {
+ return super.isThreadAllocatedMemorySupported();
+ }
+
+ @Override
+ public boolean isThreadAllocatedMemoryEnabled() {
+ return super.isThreadAllocatedMemoryEnabled();
+ }
+
+ @Override
+ public long[] getThreadCpuTime(long[] ids) {
+ return super.getThreadCpuTime(ids);
+ }
+
+ @Override
+ public long[] getThreadUserTime(long[] ids) {
+ return super.getThreadUserTime(ids);
+ }
+
+ @Override
+ public long getThreadAllocatedBytes(long id) {
+ return super.getThreadAllocatedBytes(id);
+ }
+
+ @Override
+ public long[] getThreadAllocatedBytes(long[] ids) {
+ return super.getThreadAllocatedBytes(ids);
+ }
+
+ @Override
+ public void setThreadAllocatedMemoryEnabled(boolean enable) {
+ super.setThreadAllocatedMemoryEnabled(enable);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.management.internal;
+
+import com.sun.management.DiagnosticCommandMBean;
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.ThreadMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import javax.management.DynamicMBean;
+import sun.management.ManagementFactoryHelper;
+import sun.management.spi.PlatformMBeanProvider;
+
+public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider {
+ final static String DIAGNOSTIC_COMMAND_MBEAN_NAME =
+ "com.sun.management:type=DiagnosticCommand";
+
+ private final List<PlatformComponent<?>> mxbeanList;
+ private static HotSpotDiagnostic hsDiagMBean = null;
+ private static OperatingSystemMXBean osMBean = null;
+
+ static {
+ AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+ System.loadLibrary("management_ext");
+ return null;
+ });
+ }
+
+ public PlatformMBeanProviderImpl() {
+ mxbeanList = Collections.unmodifiableList(init());
+ }
+
+ @Override
+ public List<PlatformComponent<?>> getPlatformComponentList() {
+ return mxbeanList;
+ }
+
+ private List<PlatformComponent<?>> init() {
+ ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>();
+ /**
+ * Garbage Collector in the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
+ private final Set<String> garbageCollectorMXBeanInterfaceNames
+ = Collections.unmodifiableSet(
+ Stream.of("java.lang.management.MemoryManagerMXBean",
+ "java.lang.management.GarbageCollectorMXBean",
+ "com.sun.management.GarbageCollectorMXBean")
+ .collect(Collectors.toSet()));
+
+ @Override
+ public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
+ return Stream.of(MemoryManagerMXBean.class,
+ java.lang.management.GarbageCollectorMXBean.class,
+ com.sun.management.GarbageCollectorMXBean.class)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return garbageCollectorMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*";
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return false; // zero or more instances
+ }
+
+ @Override
+ public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
+ List<java.lang.management.GarbageCollectorMXBean> list
+ = ManagementFactoryHelper.getGarbageCollectorMXBeans();
+ Map<String, MemoryManagerMXBean> map;
+ if (list.isEmpty()) {
+ map = Collections.emptyMap();
+ } else {
+ map = new HashMap<>(list.size());
+ for (MemoryManagerMXBean gcm : list) {
+ map.put(gcm.getObjectName().getCanonicalName(),
+ gcm);
+ }
+ }
+
+ return map;
+ }
+ });
+
+ /**
+ * Threading system of the Java virtual machine.
+ */
+ initMBeanList.add(new PlatformComponent<java.lang.management.ThreadMXBean>() {
+ private final Set<String> threadMXBeanInterfaceNames
+ = Collections.unmodifiableSet(
+ Stream.of("java.lang.management.ThreadMXBean",
+ "com.sun.management.ThreadMXBean")
+ .collect(Collectors.toSet()));
+ private ThreadMXBean threadMBean = null;
+
+ @Override
+ public Set<Class<? extends java.lang.management.ThreadMXBean>> mbeanInterfaces() {
+ return Stream.of(java.lang.management.ThreadMXBean.class,
+ com.sun.management.ThreadMXBean.class)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return threadMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.THREAD_MXBEAN_NAME;
+ }
+
+ @Override
+ public synchronized Map<String, java.lang.management.ThreadMXBean> nameToMBeanMap() {
+ if (threadMBean == null) {
+ threadMBean = new HotSpotThreadImpl(ManagementFactoryHelper.getVMManagement());
+ }
+ return Collections.singletonMap(
+ ManagementFactory.THREAD_MXBEAN_NAME,
+ threadMBean);
+ }
+ });
+
+ /**
+ * OperatingSystemMXBean
+ */
+ initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() {
+ private final Set<String> operatingSystemMXBeanInterfaceNames
+ = Collections.unmodifiableSet(
+ Stream.of("java.lang.management.OperatingSystemMXBean",
+ "com.sun.management.OperatingSystemMXBean",
+ "com.sun.management.UnixOperatingSystemMXBean")
+ .collect(Collectors.toSet()));
+
+ @Override
+ public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() {
+ return Stream.of(java.lang.management.OperatingSystemMXBean.class,
+ com.sun.management.OperatingSystemMXBean.class,
+ com.sun.management.UnixOperatingSystemMXBean.class)
+ .collect(Collectors.toSet());
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return operatingSystemMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, java.lang.management.OperatingSystemMXBean> nameToMBeanMap() {
+ return Collections.<String, java.lang.management.OperatingSystemMXBean>singletonMap(
+ ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
+ getOperatingSystemMXBean());
+ }
+ });
+
+ /**
+ * Diagnostic support for the HotSpot Virtual Machine.
+ */
+ initMBeanList.add(new PlatformComponent<com.sun.management.HotSpotDiagnosticMXBean>() {
+ private final Set<String> hotSpotDiagnosticMXBeanInterfaceNames =
+ Collections.unmodifiableSet(Collections.<String>singleton(
+ "com.sun.management.HotSpotDiagnosticMXBean"));
+
+ @Override
+ public Set<Class<? extends com.sun.management.HotSpotDiagnosticMXBean>> mbeanInterfaces() {
+ return Collections.singleton(com.sun.management.HotSpotDiagnosticMXBean.class);
+ }
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return hotSpotDiagnosticMXBeanInterfaceNames;
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return "com.sun.management:type=HotSpotDiagnostic";
+ }
+
+ @Override
+ public Map<String, com.sun.management.HotSpotDiagnosticMXBean> nameToMBeanMap() {
+ return Collections.<String, com.sun.management.HotSpotDiagnosticMXBean>singletonMap(
+ "com.sun.management:type=HotSpotDiagnostic",
+ getDiagnosticMXBean());
+ }
+ });
+
+ /**
+ * Diagnostic command MBean
+ */
+ DiagnosticCommandMBean diagMBean = DiagnosticCommandImpl.getDiagnosticCommandMBean();
+ if (diagMBean != null) {
+ initMBeanList.add(new PlatformComponent<DynamicMBean>() {
+ final Set<String> dynamicMBeanInterfaceNames
+ = Collections.unmodifiableSet(Collections.<String>singleton(
+ "javax.management.DynamicMBean"));
+
+ @Override
+ public Set<String> mbeanInterfaceNames() {
+ return dynamicMBeanInterfaceNames;
+ }
+
+ @Override
+ public Set<Class<? extends DynamicMBean>> mbeanInterfaces() {
+ // DynamicMBean cannot be used to find an MBean by ManagementFactory
+ return Collections.emptySet();
+ }
+
+ @Override
+ public String getObjectNamePattern() {
+ return DIAGNOSTIC_COMMAND_MBEAN_NAME;
+ }
+
+ @Override
+ public Map<String, DynamicMBean> nameToMBeanMap() {
+ return Collections.<String, DynamicMBean>singletonMap(
+ DIAGNOSTIC_COMMAND_MBEAN_NAME,
+ diagMBean);
+ }
+ });
+ }
+
+ initMBeanList.trimToSize();
+ return initMBeanList;
+ }
+
+ private static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() {
+ if (hsDiagMBean == null) {
+ hsDiagMBean = new HotSpotDiagnostic();
+ }
+ return hsDiagMBean;
+ }
+
+ private static synchronized OperatingSystemMXBean getOperatingSystemMXBean() {
+ if (osMBean == null) {
+ osMBean = new OperatingSystemImpl(ManagementFactoryHelper.getVMManagement());
+ }
+ return osMBean;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/VMOptionCompositeData.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import com.sun.management.VMOption;
+import com.sun.management.VMOption.Origin;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.OpenDataException;
+import sun.management.LazyCompositeData;
+import sun.management.MappedMXBeanType;
+
+/**
+ * A CompositeData for VMOption for the local management support.
+ * This class avoids the performance penalty paid to the
+ * construction of a CompositeData use in the local case.
+ */
+public class VMOptionCompositeData extends LazyCompositeData {
+ private final VMOption option;
+
+ private VMOptionCompositeData(VMOption option) {
+ this.option = option;
+ }
+
+ public VMOption getVMOption() {
+ return option;
+ }
+
+ public static CompositeData toCompositeData(VMOption option) {
+ VMOptionCompositeData vcd = new VMOptionCompositeData(option);
+ return vcd.getCompositeData();
+ }
+
+ protected CompositeData getCompositeData() {
+ // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
+ // vmOptionItemNames!
+ final Object[] vmOptionItemValues = {
+ option.getName(),
+ option.getValue(),
+ option.isWriteable(),
+ option.getOrigin().toString(),
+ };
+
+ try {
+ return new CompositeDataSupport(vmOptionCompositeType,
+ vmOptionItemNames,
+ vmOptionItemValues);
+ } catch (OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ private static final CompositeType vmOptionCompositeType;
+ static {
+ try {
+ vmOptionCompositeType = (CompositeType)
+ MappedMXBeanType.toOpenType(VMOption.class);
+ } catch (OpenDataException e) {
+ // Should never reach here
+ throw new AssertionError(e);
+ }
+ }
+
+ static CompositeType getVMOptionCompositeType() {
+ return vmOptionCompositeType;
+ }
+
+ private static final String NAME = "name";
+ private static final String VALUE = "value";
+ private static final String WRITEABLE = "writeable";
+ private static final String ORIGIN = "origin";
+
+ private static final String[] vmOptionItemNames = {
+ NAME,
+ VALUE,
+ WRITEABLE,
+ ORIGIN,
+ };
+
+ public static String getName(CompositeData cd) {
+ return getString(cd, NAME);
+ }
+ public static String getValue(CompositeData cd) {
+ return getString(cd, VALUE);
+ }
+ public static Origin getOrigin(CompositeData cd) {
+ String o = getString(cd, ORIGIN);
+ return Enum.valueOf(Origin.class, o);
+ }
+ public static boolean isWriteable(CompositeData cd) {
+ return getBoolean(cd, WRITEABLE);
+ }
+
+ /** Validate if the input CompositeData has the expected
+ * CompositeType (i.e. contain all attributes with expected
+ * names and types).
+ */
+ public static void validateCompositeData(CompositeData cd) {
+ if (cd == null) {
+ throw new NullPointerException("Null CompositeData");
+ }
+
+ if (!isTypeMatched(vmOptionCompositeType, cd.getCompositeType())) {
+ throw new IllegalArgumentException(
+ "Unexpected composite type for VMOption");
+ }
+ }
+
+ private static final long serialVersionUID = -2395573975093578470L;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/classes/com/sun/management/package-info.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * This package contains Oracle Corporation's platform extension to
+ * the implementation of the
+ * <a href="{@docRoot}/../../../../api/java/lang/management/package-summary.html">
+ * java.lang.management</a> API and also defines the management
+ * interface for some other components for the platform.
+ *
+ * <p>
+ * All platform MBeans are registered in the <em>platform MBeanServer</em>
+ * which can be obtained via the
+ * <a href="{@docRoot}/../../../../api/java/lang/management/ManagementFactory.html#getPlatformMBeanServer()">
+ * java.lang.management.ManagementFactory.getPlatformMBeanServer</a>
+ *
+ * @author Mandy Chung
+ * @since 1.5
+ */
+
+@jdk.Exported
+package com.sun.management;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <jni.h>
+#include "management_ext.h"
+#include "com_sun_management_internal_DiagnosticCommandImpl.h"
+
+JNIEXPORT void JNICALL Java_com_sun_management_internal_DiagnosticCommandImpl_setNotificationEnabled
+(JNIEnv *env, jobject dummy, jboolean enabled) {
+ if (jmm_version <= JMM_VERSION_1_2_2) {
+ JNU_ThrowByName(env, "java/lang/UnsupportedOperationException",
+ "JMX interface to diagnostic framework notifications is not supported by this VM");
+ return;
+ }
+ jmm_interface->SetDiagnosticFrameworkNotificationEnabled(env, enabled);
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommands
+ (JNIEnv *env, jobject dummy)
+{
+ return jmm_interface->GetDiagnosticCommands(env);
+}
+
+jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command,
+ int num_arg) {
+ int i;
+ jobject obj;
+ jobjectArray result;
+ dcmdArgInfo* dcmd_arg_info_array;
+ jclass dcmdArgInfoCls;
+ jclass arraysCls;
+ jmethodID mid;
+ jobject resultList;
+
+ dcmd_arg_info_array = (dcmdArgInfo*) malloc(num_arg * sizeof(dcmdArgInfo));
+ /* According to ISO C it is perfectly legal for malloc to return zero if called with a zero argument */
+ if (dcmd_arg_info_array == NULL && num_arg != 0) {
+ return NULL;
+ }
+ jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command,
+ dcmd_arg_info_array);
+ dcmdArgInfoCls = (*env)->FindClass(env,
+ "com/sun/management/internal/DiagnosticCommandArgumentInfo");
+ if ((*env)->ExceptionCheck(env)) {
+ free(dcmd_arg_info_array);
+ return NULL;
+ }
+
+ result = (*env)->NewObjectArray(env, num_arg, dcmdArgInfoCls, NULL);
+ if (result == NULL) {
+ free(dcmd_arg_info_array);
+ return NULL;
+ }
+ for (i=0; i<num_arg; i++) {
+ obj = JNU_NewObjectByName(env,
+ "com/sun/management/internal/DiagnosticCommandArgumentInfo",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZZI)V",
+ (*env)->NewStringUTF(env,dcmd_arg_info_array[i].name),
+ (*env)->NewStringUTF(env,dcmd_arg_info_array[i].description),
+ (*env)->NewStringUTF(env,dcmd_arg_info_array[i].type),
+ dcmd_arg_info_array[i].default_string == NULL ? NULL:
+ (*env)->NewStringUTF(env, dcmd_arg_info_array[i].default_string),
+ dcmd_arg_info_array[i].mandatory,
+ dcmd_arg_info_array[i].option,
+ dcmd_arg_info_array[i].multiple,
+ dcmd_arg_info_array[i].position);
+ if (obj == NULL) {
+ free(dcmd_arg_info_array);
+ return NULL;
+ }
+ (*env)->SetObjectArrayElement(env, result, i, obj);
+ }
+ free(dcmd_arg_info_array);
+ arraysCls = (*env)->FindClass(env, "java/util/Arrays");
+ if ((*env)->ExceptionCheck(env)) {
+ return NULL;
+ }
+ mid = (*env)->GetStaticMethodID(env, arraysCls,
+ "asList", "([Ljava/lang/Object;)Ljava/util/List;");
+ resultList = (*env)->CallStaticObjectMethod(env, arraysCls, mid, result);
+ if ((*env)->ExceptionCheck(env)) {
+ // Make sure we return NULL in case of OOM inside Java
+ return NULL;
+ }
+ return resultList;
+}
+
+/* Throws IllegalArgumentException if at least one of the diagnostic command
+ * passed in argument is not supported by the JVM
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo
+(JNIEnv *env, jobject dummy, jobjectArray commands)
+{
+ int i;
+ jclass dcmdInfoCls;
+ jobject result;
+ jobjectArray args;
+ jobject obj;
+ jmmOptionalSupport mos;
+ jint ret = jmm_interface->GetOptionalSupport(env, &mos);
+ jsize num_commands;
+ dcmdInfo* dcmd_info_array;
+
+ if (commands == NULL) {
+ JNU_ThrowNullPointerException(env, "Invalid String Array");
+ return NULL;
+ }
+ num_commands = (*env)->GetArrayLength(env, commands);
+ dcmdInfoCls = (*env)->FindClass(env,
+ "com/sun/management/internal/DiagnosticCommandInfo");
+ if ((*env)->ExceptionCheck(env)) {
+ return NULL;
+ }
+
+ result = (*env)->NewObjectArray(env, num_commands, dcmdInfoCls, NULL);
+ if (result == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return NULL;
+ }
+ if (num_commands == 0) {
+ /* Handle the 'zero commands' case specially to avoid calling 'malloc()' */
+ /* with a zero argument because that may legally return a NULL pointer. */
+ return result;
+ }
+ dcmd_info_array = (dcmdInfo*) malloc(num_commands * sizeof(dcmdInfo));
+ if (dcmd_info_array == NULL) {
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return NULL;
+ }
+ jmm_interface->GetDiagnosticCommandInfo(env, commands, dcmd_info_array);
+ for (i=0; i<num_commands; i++) {
+ args = getDiagnosticCommandArgumentInfoArray(env,
+ (*env)->GetObjectArrayElement(env,commands,i),
+ dcmd_info_array[i].num_arguments);
+ if (args == NULL) {
+ free(dcmd_info_array);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return NULL;
+ }
+ obj = JNU_NewObjectByName(env,
+ "com/sun/management/internal/DiagnosticCommandInfo",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V",
+ (*env)->NewStringUTF(env,dcmd_info_array[i].name),
+ (*env)->NewStringUTF(env,dcmd_info_array[i].description),
+ (*env)->NewStringUTF(env,dcmd_info_array[i].impact),
+ dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class),
+ dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name),
+ dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action),
+ dcmd_info_array[i].enabled,
+ args);
+ if (obj == NULL) {
+ free(dcmd_info_array);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return NULL;
+ }
+ (*env)->SetObjectArrayElement(env, result, i, obj);
+ }
+ free(dcmd_info_array);
+ return result;
+}
+
+/* Throws IllegalArgumentException if the diagnostic command
+ * passed in argument is not supported by the JVM
+ */
+JNIEXPORT jstring JNICALL
+Java_com_sun_management_internal_DiagnosticCommandImpl_executeDiagnosticCommand
+(JNIEnv *env, jobject dummy, jstring command) {
+ return jmm_interface->ExecuteDiagnosticCommand(env, command);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/Flag.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <jni.h>
+#include "management_ext.h"
+#include "com_sun_management_internal_Flag.h"
+
+static jobject default_origin = NULL;
+static jobject vm_creation_origin = NULL;
+static jobject mgmt_origin = NULL;
+static jobject envvar_origin = NULL;
+static jobject config_file_origin = NULL;
+static jobject ergo_origin = NULL;
+static jobject attach_origin = NULL;
+static jobject other_origin = NULL;
+
+JNIEXPORT jint JNICALL
+Java_com_sun_management_internal_Flag_getInternalFlagCount
+ (JNIEnv *env, jclass cls)
+{
+ jlong count = jmm_interface->GetLongAttribute(env, NULL,
+ JMM_VM_GLOBAL_COUNT);
+ return (jint) count;
+}
+
+JNIEXPORT jobjectArray JNICALL
+ Java_com_sun_management_internal_Flag_getAllFlagNames
+(JNIEnv *env, jclass cls)
+{
+ return jmm_interface->GetVMGlobalNames(env);
+}
+
+static jobject find_origin_constant(JNIEnv* env, const char* enum_name) {
+ jvalue field;
+ field = JNU_GetStaticFieldByName(env,
+ NULL,
+ "com/sun/management/VMOption$Origin",
+ enum_name,
+ "Lcom/sun/management/VMOption$Origin;");
+ return (*env)->NewGlobalRef(env, field.l);
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_Flag_initialize
+ (JNIEnv *env, jclass cls)
+{
+ default_origin = find_origin_constant(env, "DEFAULT");
+ vm_creation_origin = find_origin_constant(env, "VM_CREATION");
+ mgmt_origin = find_origin_constant(env, "MANAGEMENT");
+ envvar_origin = find_origin_constant(env, "ENVIRON_VAR");
+ config_file_origin = find_origin_constant(env, "CONFIG_FILE");
+ ergo_origin = find_origin_constant(env, "ERGONOMIC");
+ attach_origin = find_origin_constant(env, "ATTACH_ON_DEMAND");
+ other_origin = find_origin_constant(env, "OTHER");
+}
+
+JNIEXPORT jint JNICALL
+Java_com_sun_management_internal_Flag_getFlags
+ (JNIEnv *env, jclass cls, jobjectArray names, jobjectArray flags, jint count)
+{
+ jint num_flags, i, index;
+ jmmVMGlobal* globals;
+ size_t gsize;
+ const char* class_name = "com/sun/management/internal/Flag";
+ const char* signature = "(Ljava/lang/String;Ljava/lang/Object;ZZLcom/sun/management/VMOption$Origin;)V";
+ jobject origin;
+ jobject valueObj;
+ jobject flag;
+
+ if (flags == NULL) {
+ JNU_ThrowNullPointerException(env, 0);
+ return 0;
+ }
+
+ if (count <= 0) {
+ JNU_ThrowIllegalArgumentException(env, 0);
+ return 0;
+ }
+
+ gsize = (size_t)count * sizeof(jmmVMGlobal);
+ globals = (jmmVMGlobal*) malloc(gsize);
+ if (globals == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return 0;
+ }
+
+ memset(globals, 0, gsize);
+ num_flags = jmm_interface->GetVMGlobals(env, names, globals, count);
+ if (num_flags == 0) {
+ free(globals);
+ return 0;
+ }
+
+ index = 0;
+ for (i = 0; i < count; i++) {
+ if (globals[i].name == NULL) {
+ continue;
+ }
+ switch (globals[i].type) {
+ case JMM_VMGLOBAL_TYPE_JBOOLEAN:
+ valueObj = JNU_NewObjectByName(env, "java/lang/Boolean", "(Z)V",
+ globals[i].value.z);
+ break;
+ case JMM_VMGLOBAL_TYPE_JSTRING:
+ valueObj = globals[i].value.l;
+ break;
+ case JMM_VMGLOBAL_TYPE_JLONG:
+ valueObj = JNU_NewObjectByName(env, "java/lang/Long", "(J)V",
+ globals[i].value.j);
+ break;
+ case JMM_VMGLOBAL_TYPE_JDOUBLE:
+ valueObj = JNU_NewObjectByName(env, "java/lang/Double", "(D)V",
+ globals[i].value.d);
+ break;
+ default:
+ // ignore unsupported type
+ continue;
+ }
+ switch (globals[i].origin) {
+ case JMM_VMGLOBAL_ORIGIN_DEFAULT:
+ origin = default_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_COMMAND_LINE:
+ origin = vm_creation_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_MANAGEMENT:
+ origin = mgmt_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_ENVIRON_VAR:
+ origin = envvar_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_CONFIG_FILE:
+ origin = config_file_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_ERGONOMIC:
+ origin = ergo_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_ATTACH_ON_DEMAND:
+ origin = attach_origin;
+ break;
+ case JMM_VMGLOBAL_ORIGIN_OTHER:
+ origin = other_origin;
+ break;
+ default:
+ // unknown origin
+ origin = other_origin;
+ break;
+ }
+ flag = JNU_NewObjectByName(env, class_name, signature, globals[i].name,
+ valueObj, globals[i].writeable,
+ globals[i].external, origin);
+ if (flag == NULL) {
+ free(globals);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return 0;
+ }
+ (*env)->SetObjectArrayElement(env, flags, index, flag);
+ index++;
+ }
+
+ if (index != num_flags) {
+ JNU_ThrowInternalError(env, "Number of Flag objects created unmatched");
+ free(globals);
+ return 0;
+ }
+
+ free(globals);
+
+ /* return the number of Flag objects created */
+ return num_flags;
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_Flag_setLongValue
+ (JNIEnv *env, jclass cls, jstring name, jlong value)
+{
+ jvalue v;
+ v.j = value;
+
+ jmm_interface->SetVMGlobal(env, name, v);
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_Flag_setDoubleValue
+ (JNIEnv *env, jclass cls, jstring name, jdouble value)
+{
+ jvalue v;
+ v.d = value;
+
+ jmm_interface->SetVMGlobal(env, name, v);
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_Flag_setBooleanValue
+ (JNIEnv *env, jclass cls, jstring name, jboolean value)
+{
+ jvalue v;
+ v.z = value;
+
+ jmm_interface->SetVMGlobal(env, name, v);
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_Flag_setStringValue
+ (JNIEnv *env, jclass cls, jstring name, jstring value)
+{
+ jvalue v;
+ v.l = value;
+
+ jmm_interface->SetVMGlobal(env, name, v);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/GarbageCollectorExtImpl.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include "management_ext.h"
+#include "com_sun_management_internal_GarbageCollectorExtImpl.h"
+
+JNIEXPORT void JNICALL Java_com_sun_management_internal_GarbageCollectorExtImpl_setNotificationEnabled
+(JNIEnv *env, jobject dummy, jobject gc,jboolean enabled) {
+
+ if (gc == NULL) {
+ JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
+ return;
+ }
+ if((jmm_version > JMM_VERSION_1_2)
+ || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=1))) {
+ jmm_interface->SetGCNotificationEnabled(env, gc, enabled);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/GcInfoBuilder.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <jni.h>
+#include "management_ext.h"
+#include "com_sun_management_internal_GcInfoBuilder.h"
+
+JNIEXPORT jint JNICALL Java_com_sun_management_internal_GcInfoBuilder_getNumGcExtAttributes
+ (JNIEnv *env, jobject dummy, jobject gc) {
+ jlong value;
+
+ if (gc == NULL) {
+ JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
+ return 0;
+ }
+ value = jmm_interface->GetLongAttribute(env, gc,
+ JMM_GC_EXT_ATTRIBUTE_INFO_SIZE);
+ return (jint) value;
+}
+
+JNIEXPORT void JNICALL Java_com_sun_management_internal_GcInfoBuilder_fillGcAttributeInfo
+ (JNIEnv *env, jobject dummy, jobject gc,
+ jint num_attributes, jobjectArray attributeNames,
+ jcharArray types, jobjectArray descriptions) {
+
+ jmmExtAttributeInfo* ext_att_info;
+ jchar* nativeTypes;
+ jstring attName = NULL;
+ jstring desc = NULL;
+ jint ret = 0;
+ jint i;
+
+ if (gc == NULL) {
+ JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
+ return;
+ }
+
+ if (num_attributes <= 0) {
+ JNU_ThrowIllegalArgumentException(env, "Invalid num_attributes");
+ return;
+ }
+
+ ext_att_info = (jmmExtAttributeInfo*) malloc((size_t)num_attributes *
+ sizeof(jmmExtAttributeInfo));
+ if (ext_att_info == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return;
+ }
+ ret = jmm_interface->GetGCExtAttributeInfo(env, gc,
+ ext_att_info, num_attributes);
+ if (ret != num_attributes) {
+ JNU_ThrowInternalError(env, "Unexpected num_attributes");
+ free(ext_att_info);
+ return;
+ }
+
+ nativeTypes = (jchar*) malloc((size_t)num_attributes * sizeof(jchar));
+ if (nativeTypes == NULL) {
+ free(ext_att_info);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return;
+ }
+ for (i = 0; i < num_attributes; i++) {
+ nativeTypes[i] = ext_att_info[i].type;
+ attName = (*env)->NewStringUTF(env, ext_att_info[i].name);
+ desc = (*env)->NewStringUTF(env, ext_att_info[i].description);
+ (*env)->SetObjectArrayElement(env, attributeNames, i, attName);
+ (*env)->SetObjectArrayElement(env, descriptions, i, desc);
+ }
+ (*env)->SetCharArrayRegion(env, types, 0, num_attributes, nativeTypes);
+
+ if (ext_att_info != NULL) {
+ free(ext_att_info);
+ }
+ if (nativeTypes != NULL) {
+ free(nativeTypes);
+ }
+}
+
+static void setLongValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jlong value) {
+ static const char* class_name = "java/lang/Long";
+ static const char* signature = "(J)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setBooleanValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jboolean value) {
+ static const char* class_name = "java/lang/Boolean";
+ static const char* signature = "(Z)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setByteValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jbyte value) {
+ static const char* class_name = "java/lang/Byte";
+ static const char* signature = "(B)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setIntValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jint value) {
+ static const char* class_name = "java/lang/Integer";
+ static const char* signature = "(I)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setShortValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jshort value) {
+ static const char* class_name = "java/lang/Short";
+ static const char* signature = "(S)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setDoubleValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jdouble value) {
+ static const char* class_name = "java/lang/Double";
+ static const char* signature = "(D)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setFloatValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jfloat value) {
+ static const char* class_name = "java/lang/Float";
+ static const char* signature = "(D)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+static void setCharValueAtObjectArray(JNIEnv *env, jobjectArray array,
+ jsize index, jchar value) {
+ static const char* class_name = "java/lang/Character";
+ static const char* signature = "(C)V";
+ jobject obj = JNU_NewObjectByName(env, class_name, signature, value);
+
+ (*env)->SetObjectArrayElement(env, array, index, obj);
+}
+
+JNIEXPORT jobject JNICALL Java_com_sun_management_internal_GcInfoBuilder_getLastGcInfo0
+ (JNIEnv *env, jobject builder, jobject gc,
+ jint ext_att_count, jobjectArray ext_att_values, jcharArray ext_att_types,
+ jobjectArray usageBeforeGC, jobjectArray usageAfterGC) {
+
+ jmmGCStat gc_stat;
+ jchar* nativeTypes;
+ jsize i;
+ jvalue v;
+
+ if (gc == NULL) {
+ JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean");
+ return 0;
+ }
+
+ if (ext_att_count <= 0) {
+ JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count");
+ return 0;
+ }
+
+ gc_stat.usage_before_gc = usageBeforeGC;
+ gc_stat.usage_after_gc = usageAfterGC;
+ gc_stat.gc_ext_attribute_values_size = ext_att_count;
+ if (ext_att_count > 0) {
+ gc_stat.gc_ext_attribute_values = (jvalue*) malloc((size_t)ext_att_count *
+ sizeof(jvalue));
+ if (gc_stat.gc_ext_attribute_values == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return 0;
+ }
+ } else {
+ gc_stat.gc_ext_attribute_values = NULL;
+ }
+
+
+ jmm_interface->GetLastGCStat(env, gc, &gc_stat);
+ if (gc_stat.gc_index == 0) {
+ if (gc_stat.gc_ext_attribute_values != NULL) {
+ free(gc_stat.gc_ext_attribute_values);
+ }
+ return 0;
+ }
+
+ // convert the ext_att_types to native types
+ nativeTypes = (jchar*) malloc((size_t)ext_att_count * sizeof(jchar));
+ if (nativeTypes == NULL) {
+ if (gc_stat.gc_ext_attribute_values != NULL) {
+ free(gc_stat.gc_ext_attribute_values);
+ }
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return 0;
+ }
+ (*env)->GetCharArrayRegion(env, ext_att_types, 0, ext_att_count, nativeTypes);
+ for (i = 0; i < ext_att_count; i++) {
+ v = gc_stat.gc_ext_attribute_values[i];
+ switch (nativeTypes[i]) {
+ case 'Z':
+ setBooleanValueAtObjectArray(env, ext_att_values, i, v.z);
+ break;
+ case 'B':
+ setByteValueAtObjectArray(env, ext_att_values, i, v.b);
+ break;
+ case 'C':
+ setCharValueAtObjectArray(env, ext_att_values, i, v.c);
+ break;
+ case 'S':
+ setShortValueAtObjectArray(env, ext_att_values, i, v.s);
+ break;
+ case 'I':
+ setIntValueAtObjectArray(env, ext_att_values, i, v.i);
+ break;
+ case 'J':
+ setLongValueAtObjectArray(env, ext_att_values, i, v.j);
+ break;
+ case 'F':
+ setFloatValueAtObjectArray(env, ext_att_values, i, v.f);
+ break;
+ case 'D':
+ setDoubleValueAtObjectArray(env, ext_att_values, i, v.d);
+ break;
+ default:
+ if (gc_stat.gc_ext_attribute_values != NULL) {
+ free(gc_stat.gc_ext_attribute_values);
+ }
+ if (nativeTypes != NULL) {
+ free(nativeTypes);
+ }
+ JNU_ThrowInternalError(env, "Unsupported attribute type");
+ return 0;
+ }
+ }
+ if (gc_stat.gc_ext_attribute_values != NULL) {
+ free(gc_stat.gc_ext_attribute_values);
+ }
+ if (nativeTypes != NULL) {
+ free(nativeTypes);
+ }
+
+ return JNU_NewObjectByName(env,
+ "com/sun/management/GcInfo",
+ "(Lcom/sun/management/internal/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V",
+ builder,
+ gc_stat.gc_index,
+ gc_stat.start_time,
+ gc_stat.end_time,
+ usageBeforeGC,
+ usageAfterGC,
+ ext_att_values);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/HotSpotDiagnostic.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+#include "jvm.h"
+#include "management_ext.h"
+#include "com_sun_management_internal_HotSpotDiagnostic.h"
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_HotSpotDiagnostic_dumpHeap0
+ (JNIEnv *env, jobject dummy, jstring outputfile, jboolean live)
+{
+ jmm_interface->DumpHeap0(env, outputfile, live);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <jni.h>
+#include "jvm.h"
+#include "management_ext.h"
+
+#define ERR_MSG_SIZE 128
+
+const JmmInterface* jmm_interface = NULL;
+JavaVM* jvm = NULL;
+jint jmm_version = 0;
+
+JNIEXPORT jint JNICALL
+ JNI_OnLoad(JavaVM *vm, void *reserved) {
+ JNIEnv* env;
+
+ jvm = vm;
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return JNI_ERR;
+ }
+
+ jmm_interface = (JmmInterface*) JVM_GetManagement(JMM_VERSION_1_0);
+ if (jmm_interface == NULL) {
+ JNU_ThrowInternalError(env, "Unsupported Management version");
+ return JNI_ERR;
+ }
+
+ jmm_version = jmm_interface->GetVersion(env);
+ return (*env)->GetVersion(env);
+}
+
+void throw_internal_error(JNIEnv* env, const char* msg) {
+ char errmsg[128];
+
+ sprintf(errmsg, "errno: %d error: %s\n", errno, msg);
+ JNU_ThrowInternalError(env, errmsg);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.h Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+
+#include "jni_util.h"
+#include "jmm.h"
+
+#ifndef _MANAGEMENT_EXT_H_
+#define _MANAGEMENT_EXT_H_
+
+extern const JmmInterface* jmm_interface;
+extern jint jmm_version;
+extern void throw_internal_error(JNIEnv* env, const char* msg);
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/solaris/native/libmanagement_ext/UnixOperatingSystem.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <fcntl.h>
+#include <kstat.h>
+#include <procfs.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/sysinfo.h>
+#include <sys/lwp.h>
+#include <pthread.h>
+#include <utmpx.h>
+#include <dlfcn.h>
+#include <sys/loadavg.h>
+#include <jni.h>
+#include "jvm.h"
+#include "com_sun_management_internal_OperatingSystemImpl.h"
+
+typedef struct {
+ kstat_t *kstat;
+ uint64_t last_idle;
+ uint64_t last_total;
+ double last_ratio;
+} cpuload_t;
+
+static cpuload_t *cpu_loads = NULL;
+static unsigned int num_cpus;
+static kstat_ctl_t *kstat_ctrl = NULL;
+
+static void map_cpu_kstat_counters() {
+ kstat_t *kstat;
+ int i;
+
+ // Get number of CPU(s)
+ if ((num_cpus = sysconf(_SC_NPROCESSORS_ONLN)) == -1) {
+ num_cpus = 1;
+ }
+
+ // Data structure for saving CPU load
+ if ((cpu_loads = calloc(num_cpus,sizeof(cpuload_t))) == NULL) {
+ return;
+ }
+
+ // Get kstat cpu_stat counters for every CPU
+ // (loop over kstat to find our cpu_stat(s)
+ i = 0;
+ for (kstat = kstat_ctrl->kc_chain; kstat != NULL; kstat = kstat->ks_next) {
+ if (strncmp(kstat->ks_module, "cpu_stat", 8) == 0) {
+
+ if (kstat_read(kstat_ctrl, kstat, NULL) == -1) {
+ // Failed to initialize kstat for this CPU so ignore it
+ continue;
+ }
+
+ if (i == num_cpus) {
+ // Found more cpu_stats than reported CPUs
+ break;
+ }
+
+ cpu_loads[i++].kstat = kstat;
+ }
+ }
+}
+
+static int init_cpu_kstat_counters() {
+ static int initialized = 0;
+
+ // Concurrence in this method is prevented by the lock in
+ // the calling method get_cpu_load();
+ if(!initialized) {
+ if ((kstat_ctrl = kstat_open()) != NULL) {
+ map_cpu_kstat_counters();
+ initialized = 1;
+ }
+ }
+ return initialized ? 0 : -1;
+}
+
+static void update_cpu_kstat_counters() {
+ if(kstat_chain_update(kstat_ctrl) != 0) {
+ free(cpu_loads);
+ map_cpu_kstat_counters();
+ }
+}
+
+int read_cpustat(cpuload_t *load, cpu_stat_t *cpu_stat) {
+ if (load->kstat == NULL) {
+ // no handle.
+ return -1;
+ }
+ if (kstat_read(kstat_ctrl, load->kstat, cpu_stat) == -1) {
+ // disabling for now, a kstat chain update is likely to happen next time
+ load->kstat = NULL;
+ return -1;
+ }
+ return 0;
+}
+
+double get_single_cpu_load(unsigned int n) {
+ cpuload_t *load;
+ cpu_stat_t cpu_stat;
+ uint_t *usage;
+ uint64_t c_idle;
+ uint64_t c_total;
+ uint64_t d_idle;
+ uint64_t d_total;
+ int i;
+
+ if (n >= num_cpus) {
+ return -1.0;
+ }
+
+ load = &cpu_loads[n];
+ if (read_cpustat(load, &cpu_stat) < 0) {
+ return -1.0;
+ }
+
+ usage = cpu_stat.cpu_sysinfo.cpu;
+ c_idle = usage[CPU_IDLE];
+
+ for (c_total = 0, i = 0; i < CPU_STATES; i++) {
+ c_total += usage[i];
+ }
+
+ // Calculate diff against previous snapshot
+ d_idle = c_idle - load->last_idle;
+ d_total = c_total - load->last_total;
+
+ /** update if weve moved */
+ if (d_total > 0) {
+ // Save current values for next time around
+ load->last_idle = c_idle;
+ load->last_total = c_total;
+ load->last_ratio = (double) (d_total - d_idle) / d_total;
+ }
+
+ return load->last_ratio;
+}
+
+int get_info(const char *path, void *info, size_t s, off_t o) {
+ int fd;
+ int ret = 0;
+ if ((fd = open(path, O_RDONLY)) < 0) {
+ return -1;
+ }
+ if (pread(fd, info, s, o) != s) {
+ ret = -1;
+ }
+ close(fd);
+ return ret;
+}
+
+#define MIN(a, b) ((a < b) ? a : b)
+
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Return the cpu load (0-1) for proc number 'which' (or average all if which == -1)
+ */
+double get_cpu_load(int which) {
+ double load =.0;
+
+ pthread_mutex_lock(&lock);
+ if(init_cpu_kstat_counters()==0) {
+
+ update_cpu_kstat_counters();
+
+ if (which == -1) {
+ unsigned int i;
+ double t;
+
+ for (t = .0, i = 0; i < num_cpus; i++) {
+ t += get_single_cpu_load(i);
+ }
+
+ // Cap total systemload to 1.0
+ load = MIN((t / num_cpus), 1.0);
+ } else {
+ load = MIN(get_single_cpu_load(which), 1.0);
+ }
+ } else {
+ load = -1.0;
+ }
+ pthread_mutex_unlock(&lock);
+
+ return load;
+}
+
+/**
+ * Return the cpu load (0-1) for the current process (i.e the JVM)
+ * or -1.0 if the get_info() call failed
+ */
+double get_process_load(void) {
+ psinfo_t info;
+
+ // Get the percentage of "recent cpu usage" from all the lwp:s in the JVM:s
+ // process. This is returned as a value between 0.0 and 1.0 multiplied by 0x8000.
+ if (get_info("/proc/self/psinfo",&info.pr_pctcpu, sizeof(info.pr_pctcpu), offsetof(psinfo_t, pr_pctcpu)) == 0) {
+ return (double) info.pr_pctcpu / 0x8000;
+ }
+ return -1.0;
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ return get_cpu_load(-1);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ return get_process_load();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import sun.management.BaseOperatingSystemImpl;
+import sun.management.VMManagement;
+/**
+ * Implementation class for the operating system.
+ * Standard and committed hotspot-specific metrics if any.
+ *
+ * ManagementFactory.getOperatingSystemMXBean() returns an instance
+ * of this class.
+ */
+class OperatingSystemImpl extends BaseOperatingSystemImpl
+ implements com.sun.management.UnixOperatingSystemMXBean {
+
+ OperatingSystemImpl(VMManagement vm) {
+ super(vm);
+ }
+
+ public long getCommittedVirtualMemorySize() {
+ return getCommittedVirtualMemorySize0();
+ }
+
+ public long getTotalSwapSpaceSize() {
+ return getTotalSwapSpaceSize0();
+ }
+
+ public long getFreeSwapSpaceSize() {
+ return getFreeSwapSpaceSize0();
+ }
+
+ public long getProcessCpuTime() {
+ return getProcessCpuTime0();
+ }
+
+ public long getFreePhysicalMemorySize() {
+ return getFreePhysicalMemorySize0();
+ }
+
+ public long getTotalPhysicalMemorySize() {
+ return getTotalPhysicalMemorySize0();
+ }
+
+ public long getOpenFileDescriptorCount() {
+ return getOpenFileDescriptorCount0();
+ }
+
+ public long getMaxFileDescriptorCount() {
+ return getMaxFileDescriptorCount0();
+ }
+
+ public double getSystemCpuLoad() {
+ return getSystemCpuLoad0();
+ }
+
+ public double getProcessCpuLoad() {
+ return getProcessCpuLoad0();
+ }
+
+ /* native methods */
+ private native long getCommittedVirtualMemorySize0();
+ private native long getFreePhysicalMemorySize0();
+ private native long getFreeSwapSpaceSize0();
+ private native long getMaxFileDescriptorCount0();
+ private native long getOpenFileDescriptorCount0();
+ private native long getProcessCpuTime0();
+ private native double getProcessCpuLoad0();
+ private native double getSystemCpuLoad0();
+ private native long getTotalPhysicalMemorySize0();
+ private native long getTotalSwapSpaceSize0();
+
+ static {
+ initialize0();
+ }
+
+ private static native void initialize0();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,479 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "jvm.h"
+#include "management_ext.h"
+#include "com_sun_management_internal_OperatingSystemImpl.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(_ALLBSD_SOURCE)
+#include <sys/sysctl.h>
+#ifdef __APPLE__
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <mach/mach.h>
+#include <sys/proc_info.h>
+#include <libproc.h>
+#endif
+#elif !defined(_AIX)
+#include <sys/swap.h>
+#endif
+#include <sys/resource.h>
+#include <sys/times.h>
+#ifndef _ALLBSD_SOURCE
+#include <sys/sysinfo.h>
+#endif
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#if defined(_AIX)
+#include <libperfstat.h>
+#endif
+
+static jlong page_size = 0;
+
+#if defined(_ALLBSD_SOURCE) || defined(_AIX)
+#define MB (1024UL * 1024UL)
+#else
+
+/* This gets us the new structured proc interfaces of 5.6 & later */
+/* - see comment in <sys/procfs.h> */
+#define _STRUCTURED_PROC 1
+#include <sys/procfs.h>
+
+#endif /* _ALLBSD_SOURCE */
+
+static struct dirent* read_dir(DIR* dirp, struct dirent* entry) {
+#ifdef __solaris__
+ struct dirent* dbuf = readdir(dirp);
+ return dbuf;
+#else /* __linux__ || _ALLBSD_SOURCE */
+ struct dirent* p;
+ if (readdir_r(dirp, entry, &p) == 0) {
+ return p;
+ } else {
+ return NULL;
+ }
+#endif
+}
+
+// true = get available swap in bytes
+// false = get total swap in bytes
+static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) {
+#ifdef __solaris__
+ long total, avail;
+ int nswap, i, count;
+ swaptbl_t *stbl;
+ char *strtab;
+
+ // First get the number of swap resource entries
+ if ((nswap = swapctl(SC_GETNSWP, NULL)) == -1) {
+ throw_internal_error(env, "swapctl failed to get nswap");
+ return -1;
+ }
+ if (nswap == 0) {
+ return 0;
+ }
+
+ // Allocate storage for resource entries
+ stbl = (swaptbl_t*) malloc(nswap * sizeof(swapent_t) +
+ sizeof(struct swaptable));
+ if (stbl == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return -1;
+ }
+
+ // Allocate storage for the table
+ strtab = (char*) malloc((nswap + 1) * MAXPATHLEN);
+ if (strtab == NULL) {
+ free(stbl);
+ JNU_ThrowOutOfMemoryError(env, 0);
+ return -1;
+ }
+
+ for (i = 0; i < (nswap + 1); i++) {
+ stbl->swt_ent[i].ste_path = strtab + (i * MAXPATHLEN);
+ }
+ stbl->swt_n = nswap + 1;
+
+ // Get the entries
+ if ((count = swapctl(SC_LIST, stbl)) < 0) {
+ free(stbl);
+ free(strtab);
+ throw_internal_error(env, "swapctl failed to get swap list");
+ return -1;
+ }
+
+ // Sum the entries to get total and free swap
+ total = 0;
+ avail = 0;
+ for (i = 0; i < count; i++) {
+ total += stbl->swt_ent[i].ste_pages;
+ avail += stbl->swt_ent[i].ste_free;
+ }
+
+ free(stbl);
+ free(strtab);
+ return available ? ((jlong)avail * page_size) :
+ ((jlong)total * page_size);
+#elif defined(__linux__)
+ int ret;
+ FILE *fp;
+ jlong total = 0, avail = 0;
+
+ struct sysinfo si;
+ ret = sysinfo(&si);
+ if (ret != 0) {
+ throw_internal_error(env, "sysinfo failed to get swap size");
+ }
+ total = (jlong)si.totalswap * si.mem_unit;
+ avail = (jlong)si.freeswap * si.mem_unit;
+
+ return available ? avail : total;
+#elif defined(__APPLE__)
+ struct xsw_usage vmusage;
+ size_t size = sizeof(vmusage);
+ if (sysctlbyname("vm.swapusage", &vmusage, &size, NULL, 0) != 0) {
+ throw_internal_error(env, "sysctlbyname failed");
+ }
+ return available ? (jlong)vmusage.xsu_avail : (jlong)vmusage.xsu_total;
+#else /* _ALLBSD_SOURCE */
+ /*
+ * XXXBSD: there's no way available to get swap info in
+ * FreeBSD. Usage of libkvm is not an option here
+ */
+ // throw_internal_error(env, "Unimplemented in FreeBSD");
+ return (0);
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_initialize0
+ (JNIEnv *env, jclass cls)
+{
+ page_size = sysconf(_SC_PAGESIZE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0
+ (JNIEnv *env, jobject mbean)
+{
+#ifdef __solaris__
+ psinfo_t psinfo;
+ ssize_t result;
+ size_t remaining;
+ char* addr;
+ int fd;
+
+ fd = open64("/proc/self/psinfo", O_RDONLY, 0);
+ if (fd < 0) {
+ throw_internal_error(env, "Unable to open /proc/self/psinfo");
+ return -1;
+ }
+
+ addr = (char *)&psinfo;
+ for (remaining = sizeof(psinfo_t); remaining > 0;) {
+ result = read(fd, addr, remaining);
+ if (result < 0) {
+ if (errno != EINTR) {
+ close(fd);
+ throw_internal_error(env, "Unable to read /proc/self/psinfo");
+ return -1;
+ }
+ } else {
+ remaining -= result;
+ addr += result;
+ }
+ }
+
+ close(fd);
+ return (jlong) psinfo.pr_size * 1024;
+#elif defined(__linux__)
+ FILE *fp;
+ unsigned long vsize = 0;
+
+ if ((fp = fopen("/proc/self/stat", "r")) == NULL) {
+ throw_internal_error(env, "Unable to open /proc/self/stat");
+ return -1;
+ }
+
+ // Ignore everything except the vsize entry
+ if (fscanf(fp, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %lu %*[^\n]\n", &vsize) == EOF) {
+ throw_internal_error(env, "Unable to get virtual memory usage");
+ fclose(fp);
+ return -1;
+ }
+
+ fclose(fp);
+ return (jlong)vsize;
+#elif defined(__APPLE__)
+ struct task_basic_info t_info;
+ mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
+
+ kern_return_t res = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
+ if (res != KERN_SUCCESS) {
+ throw_internal_error(env, "task_info failed");
+ }
+ return t_info.virtual_size;
+#else /* _ALLBSD_SOURCE */
+ /*
+ * XXXBSD: there's no way available to do it in FreeBSD, AFAIK.
+ */
+ // throw_internal_error(env, "Unimplemented in FreeBSD");
+ return (64 * MB);
+#endif
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0
+ (JNIEnv *env, jobject mbean)
+{
+ return get_total_or_available_swap_space_size(env, JNI_FALSE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0
+ (JNIEnv *env, jobject mbean)
+{
+ return get_total_or_available_swap_space_size(env, JNI_TRUE);
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0
+ (JNIEnv *env, jobject mbean)
+{
+#ifdef __APPLE__
+ struct rusage usage;
+ if (getrusage(RUSAGE_SELF, &usage) != 0) {
+ throw_internal_error(env, "getrusage failed");
+ return -1;
+ }
+ jlong microsecs =
+ usage.ru_utime.tv_sec * 1000 * 1000 + usage.ru_utime.tv_usec +
+ usage.ru_stime.tv_sec * 1000 * 1000 + usage.ru_stime.tv_usec;
+ return microsecs * 1000;
+#else
+ jlong clk_tck, ns_per_clock_tick;
+ jlong cpu_time_ns;
+ struct tms time;
+
+ /*
+ * BSDNOTE: FreeBSD implements _SC_CLK_TCK since FreeBSD 5, so
+ * add a magic to handle it
+ */
+#if defined(__solaris__) || defined(_SC_CLK_TCK)
+ clk_tck = (jlong) sysconf(_SC_CLK_TCK);
+#elif defined(__linux__) || defined(_ALLBSD_SOURCE)
+ clk_tck = 100;
+#endif
+ if (clk_tck == -1) {
+ throw_internal_error(env,
+ "sysconf failed - not able to get clock tick");
+ return -1;
+ }
+
+ times(&time);
+ ns_per_clock_tick = (jlong) 1000 * 1000 * 1000 / (jlong) clk_tck;
+ cpu_time_ns = ((jlong)time.tms_utime + (jlong) time.tms_stime) *
+ ns_per_clock_tick;
+ return cpu_time_ns;
+#endif
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getFreePhysicalMemorySize0
+ (JNIEnv *env, jobject mbean)
+{
+#ifdef __APPLE__
+ mach_msg_type_number_t count;
+ vm_statistics_data_t vm_stats;
+ kern_return_t res;
+
+ count = HOST_VM_INFO_COUNT;
+ res = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stats, &count);
+ if (res != KERN_SUCCESS) {
+ throw_internal_error(env, "host_statistics failed");
+ return -1;
+ }
+ return (jlong)vm_stats.free_count * page_size;
+#elif defined(_ALLBSD_SOURCE)
+ /*
+ * XXBSDL no way to do it in FreeBSD
+ */
+ // throw_internal_error(env, "unimplemented in FreeBSD")
+ return (128 * MB);
+#elif defined(_AIX)
+ perfstat_memory_total_t memory_info;
+ if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) {
+ return (jlong)(memory_info.real_free * 4L * 1024L);
+ }
+ return -1;
+#else // solaris / linux
+ jlong num_avail_physical_pages = sysconf(_SC_AVPHYS_PAGES);
+ return (num_avail_physical_pages * page_size);
+#endif
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getTotalPhysicalMemorySize0
+ (JNIEnv *env, jobject mbean)
+{
+#ifdef _ALLBSD_SOURCE
+ jlong result = 0;
+ int mib[2];
+ size_t rlen;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_MEMSIZE;
+ rlen = sizeof(result);
+ if (sysctl(mib, 2, &result, &rlen, NULL, 0) != 0) {
+ throw_internal_error(env, "sysctl failed");
+ return -1;
+ }
+ return result;
+#elif defined(_AIX)
+ perfstat_memory_total_t memory_info;
+ if (-1 != perfstat_memory_total(NULL, &memory_info, sizeof(perfstat_memory_total_t), 1)) {
+ return (jlong)(memory_info.real_total * 4L * 1024L);
+ }
+ return -1;
+#else // solaris / linux
+ jlong num_physical_pages = sysconf(_SC_PHYS_PAGES);
+ return (num_physical_pages * page_size);
+#endif
+}
+
+
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getOpenFileDescriptorCount0
+ (JNIEnv *env, jobject mbean)
+{
+#ifdef __APPLE__
+ // This code is influenced by the darwin lsof source
+ pid_t my_pid;
+ struct proc_bsdinfo bsdinfo;
+ struct proc_fdinfo *fds;
+ int nfiles;
+ kern_return_t kres;
+ int res;
+ size_t fds_size;
+
+ kres = pid_for_task(mach_task_self(), &my_pid);
+ if (kres != KERN_SUCCESS) {
+ throw_internal_error(env, "pid_for_task failed");
+ return -1;
+ }
+
+ // get the maximum number of file descriptors
+ res = proc_pidinfo(my_pid, PROC_PIDTBSDINFO, 0, &bsdinfo, PROC_PIDTBSDINFO_SIZE);
+ if (res <= 0) {
+ throw_internal_error(env, "proc_pidinfo with PROC_PIDTBSDINFO failed");
+ return -1;
+ }
+
+ // allocate memory to hold the fd information (we don't acutally use this information
+ // but need it to get the number of open files)
+ fds_size = bsdinfo.pbi_nfiles * sizeof(struct proc_fdinfo);
+ fds = malloc(fds_size);
+ if (fds == NULL) {
+ JNU_ThrowOutOfMemoryError(env, "could not allocate space for file descriptors");
+ return -1;
+ }
+
+ // get the list of open files - the return value is the number of bytes
+ // proc_pidinfo filled in
+ res = proc_pidinfo(my_pid, PROC_PIDLISTFDS, 0, fds, fds_size);
+ if (res <= 0) {
+ free(fds);
+ throw_internal_error(env, "proc_pidinfo failed for PROC_PIDLISTFDS");
+ return -1;
+ }
+ nfiles = res / sizeof(struct proc_fdinfo);
+ free(fds);
+
+ return nfiles;
+#elif defined(_ALLBSD_SOURCE)
+ /*
+ * XXXBSD: there's no way available to do it in FreeBSD, AFAIK.
+ */
+ // throw_internal_error(env, "Unimplemented in FreeBSD");
+ return (100);
+#else /* solaris/linux */
+ DIR *dirp;
+ struct dirent dbuf;
+ struct dirent* dentp;
+ jlong fds = 0;
+
+#if defined(_AIX)
+/* AIX does not understand '/proc/self' - it requires the real process ID */
+#define FD_DIR aix_fd_dir
+ char aix_fd_dir[32]; /* the pid has at most 19 digits */
+ snprintf(aix_fd_dir, 32, "/proc/%d/fd", getpid());
+#else
+#define FD_DIR "/proc/self/fd"
+#endif
+
+ dirp = opendir(FD_DIR);
+ if (dirp == NULL) {
+ throw_internal_error(env, "Unable to open directory /proc/self/fd");
+ return -1;
+ }
+
+ // iterate through directory entries, skipping '.' and '..'
+ // each entry represents an open file descriptor.
+ while ((dentp = read_dir(dirp, &dbuf)) != NULL) {
+ if (isdigit(dentp->d_name[0])) {
+ fds++;
+ }
+ }
+
+ closedir(dirp);
+ // subtract by 1 which was the fd open for this implementation
+ return (fds - 1);
+#endif
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getMaxFileDescriptorCount0
+ (JNIEnv *env, jobject mbean)
+{
+ struct rlimit rlp;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlp) == -1) {
+ throw_internal_error(env, "getrlimit failed");
+ return -1;
+ }
+ return (jlong) rlp.rlim_cur;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/windows/classes/com/sun/management/internal/OperatingSystemImpl.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.management.internal;
+
+import com.sun.management.OperatingSystemMXBean;
+import sun.management.BaseOperatingSystemImpl;
+import sun.management.VMManagement;
+
+/**
+ * Implementation class for the operating system.
+ * Standard and committed hotspot-specific metrics if any.
+ *
+ * ManagementFactory.getOperatingSystemMXBean() returns an instance
+ * of this class.
+ */
+class OperatingSystemImpl extends BaseOperatingSystemImpl
+ implements OperatingSystemMXBean {
+
+ // psapiLock is a lock to make sure only one thread loading
+ // PSAPI DLL.
+ private static Object psapiLock = new Object();
+
+ OperatingSystemImpl(VMManagement vm) {
+ super(vm);
+ }
+
+ @Override
+ public long getCommittedVirtualMemorySize() {
+ synchronized (psapiLock) {
+ return getCommittedVirtualMemorySize0();
+ }
+ }
+
+ @Override
+ public long getTotalSwapSpaceSize() {
+ return getTotalSwapSpaceSize0();
+ }
+
+ @Override
+ public long getFreeSwapSpaceSize() {
+ return getFreeSwapSpaceSize0();
+ }
+
+ @Override
+ public long getProcessCpuTime() {
+ return getProcessCpuTime0();
+ }
+
+ @Override
+ public long getFreePhysicalMemorySize() {
+ return getFreePhysicalMemorySize0();
+ }
+
+ @Override
+ public long getTotalPhysicalMemorySize() {
+ return getTotalPhysicalMemorySize0();
+ }
+
+ @Override
+ public double getSystemCpuLoad() {
+ return getSystemCpuLoad0();
+ }
+
+ @Override
+ public double getProcessCpuLoad() {
+ return getProcessCpuLoad0();
+ }
+
+ /* native methods */
+ private native long getCommittedVirtualMemorySize0();
+ private native long getFreePhysicalMemorySize0();
+ private native long getFreeSwapSpaceSize0();
+ private native double getProcessCpuLoad0();
+ private native long getProcessCpuTime0();
+ private native double getSystemCpuLoad0();
+ private native long getTotalPhysicalMemorySize0();
+ private native long getTotalSwapSpaceSize0();
+
+ static {
+ initialize0();
+ }
+
+ private static native void initialize0();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,1363 @@
+/*
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jlong.h"
+#include "jvm.h"
+#include "management_ext.h"
+#include "com_sun_management_internal_OperatingSystemImpl.h"
+
+#include <psapi.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <malloc.h>
+#pragma warning (push,0)
+#include <windows.h>
+#pragma warning (pop)
+#include <stdio.h>
+#include <time.h>
+#include <stdint.h>
+#include <assert.h>
+
+/* Disable warnings due to broken header files from Microsoft... */
+#pragma warning(push, 3)
+#include <pdh.h>
+#include <pdhmsg.h>
+#include <process.h>
+#pragma warning(pop)
+
+typedef unsigned __int32 juint;
+typedef unsigned __int64 julong;
+
+static void set_low(jlong* value, jint low) {
+ *value &= (jlong)0xffffffff << 32;
+ *value |= (jlong)(julong)(juint)low;
+}
+
+static void set_high(jlong* value, jint high) {
+ *value &= (jlong)(julong)(juint)0xffffffff;
+ *value |= (jlong)high << 32;
+}
+
+static jlong jlong_from(jint h, jint l) {
+ jlong result = 0; // initialization to avoid warning
+ set_high(&result, h);
+ set_low(&result, l);
+ return result;
+}
+
+static HANDLE main_process;
+
+static void perfInit(void);
+
+JNIEXPORT void JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_initialize0
+ (JNIEnv *env, jclass cls)
+{
+ main_process = GetCurrentProcess();
+ perfInit();
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0
+ (JNIEnv *env, jobject mbean)
+{
+ PROCESS_MEMORY_COUNTERS pmc;
+ if (GetProcessMemoryInfo(main_process, &pmc, sizeof(PROCESS_MEMORY_COUNTERS)) == 0) {
+ return (jlong)-1L;
+ } else {
+ return (jlong) pmc.PagefileUsage;
+ }
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0
+ (JNIEnv *env, jobject mbean)
+{
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullTotalPageFile;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0
+ (JNIEnv *env, jobject mbean)
+{
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullAvailPageFile;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0
+ (JNIEnv *env, jobject mbean)
+{
+
+ FILETIME process_creation_time, process_exit_time,
+ process_user_time, process_kernel_time;
+
+ // Using static variables declared above
+ // Units are 100-ns intervals. Convert to ns.
+ GetProcessTimes(main_process, &process_creation_time,
+ &process_exit_time,
+ &process_kernel_time, &process_user_time);
+ return (jlong_from(process_user_time.dwHighDateTime,
+ process_user_time.dwLowDateTime) +
+ jlong_from(process_kernel_time.dwHighDateTime,
+ process_kernel_time.dwLowDateTime)) * 100;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getFreePhysicalMemorySize0
+ (JNIEnv *env, jobject mbean)
+{
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullAvailPhys;
+}
+
+JNIEXPORT jlong JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getTotalPhysicalMemorySize0
+ (JNIEnv *env, jobject mbean)
+{
+ MEMORYSTATUSEX ms;
+ ms.dwLength = sizeof(ms);
+ GlobalMemoryStatusEx(&ms);
+ return (jlong) ms.ullTotalPhys;
+}
+
+/* Performance Data Helper API (PDH) support */
+
+typedef PDH_STATUS (WINAPI *PdhAddCounterFunc)(
+ HQUERY hQuery,
+ LPCSTR szFullCounterPath,
+ DWORD dwUserData,
+ HCOUNTER *phCounter
+ );
+typedef PDH_STATUS (WINAPI *PdhOpenQueryFunc)(
+ LPCWSTR szDataSource,
+ DWORD dwUserData,
+ HQUERY *phQuery
+ );
+typedef PDH_STATUS (WINAPI *PdhCollectQueryDataFunc)(
+ HQUERY hQuery
+ );
+
+typedef PDH_STATUS (WINAPI *PdhEnumObjectItemsFunc)(
+ LPCTSTR szDataSource,
+ LPCTSTR szMachineName,
+ LPCTSTR szObjectName,
+ LPTSTR mszCounterList,
+ LPDWORD pcchCounterListLength,
+ LPTSTR mszInstanceList,
+ LPDWORD pcchInstanceListLength,
+ DWORD dwDetailLevel,
+ DWORD dwFlags
+ );
+typedef PDH_STATUS (WINAPI *PdhRemoveCounterFunc)(
+ HCOUNTER hCounter
+ );
+typedef PDH_STATUS (WINAPI *PdhLookupPerfNameByIndexFunc)(
+ LPCSTR szMachineName,
+ DWORD dwNameIndex,
+ LPSTR szNameBuffer,
+ LPDWORD pcchNameBufferSize
+ );
+typedef DWORD (WINAPI *PdhCloseQueryFunc)(
+ HQUERY hQuery
+ );
+
+typedef DWORD (WINAPI *PdhGetFormattedCounterValueFunc)(
+ HCOUNTER hCounter,
+ DWORD dwFormat,
+ LPDWORD lpdwType,
+ PPDH_FMT_COUNTERVALUE pValue
+ );
+
+static PdhAddCounterFunc PdhAddCounter_i;
+static PdhOpenQueryFunc PdhOpenQuery_i;
+static PdhCloseQueryFunc PdhCloseQuery_i;
+static PdhCollectQueryDataFunc PdhCollectQueryData_i;
+static PdhGetFormattedCounterValueFunc PdhGetFormattedCounterValue_i;
+static PdhEnumObjectItemsFunc PdhEnumObjectItems_i;
+static PdhRemoveCounterFunc PdhRemoveCounter_i;
+static PdhLookupPerfNameByIndexFunc PdhLookupPerfNameByIndex_i;
+
+/*
+ * Struct for PDH queries.
+ */
+typedef struct {
+ HQUERY query;
+ uint64_t lastUpdate; // Last time query was updated (ticks)
+} UpdateQueryS, *UpdateQueryP;
+
+// Min time between query updates (ticks)
+static const int MIN_UPDATE_INTERVAL = 500;
+
+/*
+ * Struct for a PDH query with multiple counters.
+ */
+typedef struct {
+ UpdateQueryS query;
+ HCOUNTER* counters;
+ int noOfCounters;
+} MultipleCounterQueryS, *MultipleCounterQueryP;
+
+/*
+ * Struct for a PDH query with a single counter.
+ */
+typedef struct {
+ UpdateQueryS query;
+ HCOUNTER counter;
+} SingleCounterQueryS, *SingleCounterQueryP;
+
+
+typedef struct {
+ CRITICAL_SECTION cs;
+ DWORD owningThread;
+ DWORD recursionCount;
+} PdhCriticalSectionS, *PdhCriticalSectionP;
+
+static PdhCriticalSectionS initializationLock;
+
+static void InitializePdhCriticalSection(PdhCriticalSectionP criticalSection) {
+ assert(criticalSection);
+
+ InitializeCriticalSection(&criticalSection->cs);
+ criticalSection->owningThread = 0;
+ criticalSection->recursionCount = 0;
+}
+
+static void EnterPdhCriticalSection(PdhCriticalSectionP criticalSection) {
+ assert(criticalSection);
+
+ EnterCriticalSection(&criticalSection->cs);
+ criticalSection->recursionCount++;
+ if (!criticalSection->owningThread) {
+ criticalSection->owningThread = GetCurrentThreadId();
+ }
+}
+
+static void LeavePdhCriticalSection(PdhCriticalSectionP criticalSection) {
+ assert(criticalSection);
+ assert(GetCurrentThreadId() == criticalSection->owningThread);
+ assert(criticalSection->recursionCount >= 1);
+
+ criticalSection->recursionCount--;
+ if (!criticalSection->recursionCount) {
+ criticalSection->owningThread = 0;
+ }
+ LeaveCriticalSection(&criticalSection->cs);
+}
+
+/*
+ * INFO: Using PDH APIs Correctly in a Localized Language (Q287159)
+ * http://support.microsoft.com/default.aspx?scid=kb;EN-US;q287159
+ * The index value for the base system counters and objects like processor,
+ * process, thread, memory, and so forth are always the same irrespective
+ * of the localized version of the operating system or service pack installed.
+ * To find the correct index for an object or counter, inspect the registry key/value:
+ * [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009\Counter]
+ */
+static const DWORD PDH_PROCESSOR_IDX = 238;
+static const DWORD PDH_PROCESSOR_TIME_IDX = 6;
+static const DWORD PDH_PROCESS_IDX = 230;
+static const DWORD PDH_ID_PROCESS_IDX = 784;
+
+/* useful pdh fmt's */
+static const char* const OBJECT_COUNTER_FMT = "\\%s\\%s";
+static const size_t OBJECT_COUNTER_FMT_LEN = 2;
+static const char* const OBJECT_WITH_INSTANCES_COUNTER_FMT = "\\%s(%s)\\%s";
+static const size_t OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN = 4;
+static const char* const PROCESS_OBJECT_INSTANCE_COUNTER_FMT = "\\%s(%s#%s)\\%s";
+static const size_t PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN = 5;
+
+static const char* pdhProcessImageName = NULL; /* "java" */
+static char* pdhIDProcessCounterFmt = NULL; /* "\Process(java#%d)\ID Process" */
+
+static int numberOfJavaProcessesAtInitialization = 0;
+
+/*
+ * Currently used CPU queries/counters and variables
+ */
+static SingleCounterQueryP processTotalCPULoad = NULL;
+static MultipleCounterQueryP multiCounterCPULoad = NULL;
+static double cpuFactor = .0;
+static DWORD numCpus = 0;
+
+/*
+ * Seems WinXP PDH returns PDH_MORE_DATA whenever we send in a NULL buffer.
+ * Let's just ignore it, since we make sure we have enough buffer anyway.
+ */
+static int
+pdhFail(PDH_STATUS pdhStat) {
+ return pdhStat != ERROR_SUCCESS && pdhStat != PDH_MORE_DATA;
+}
+
+static const char*
+allocateAndCopy(const char* const originalString) {
+ size_t len;
+ char* allocatedString;
+
+ assert(originalString);
+
+ len = strlen(originalString);
+
+ allocatedString = malloc(len + 1);
+
+ if (!allocatedString) {
+ return NULL;
+ }
+
+ strncpy(allocatedString, originalString, len);
+ allocatedString[len] = '\0';
+
+ return allocatedString;
+}
+
+/*
+ * Allocates memory into the supplied pointer and
+ * fills it with the localized PDH artifact description, if indexed correctly.
+ * Caller owns the memory from the point of returning from this function.
+ *
+ * @param index the PDH counter index as specified in the registry
+ * @param ppBuffer pointer to a char*.
+ * @return 0 if successful, negative on failure.
+ */
+static int
+lookupNameByIndex(DWORD index, char** ppBuffer) {
+ DWORD size;
+
+ assert(ppBuffer);
+
+ /* determine size needed */
+ if (PdhLookupPerfNameByIndex_i(NULL, index, NULL, &size) != PDH_MORE_DATA) {
+ /* invalid index? */
+ return -1;
+ }
+
+ *ppBuffer = malloc((size_t)size);
+
+ if (!*ppBuffer) {
+ return -1;
+ }
+
+ if (PdhLookupPerfNameByIndex_i(NULL, index, *ppBuffer, &size) != ERROR_SUCCESS) {
+ free(*ppBuffer);
+ *ppBuffer = NULL;
+ return -1;
+ }
+
+ /* windows vista does not null-terminate the string
+ * (although the docs says it will) */
+ (*ppBuffer)[size - 1] = '\0';
+
+ return 0;
+}
+
+/*
+* Construct a fully qualified PDH path
+*
+* @param objectName a PDH Object string representation (required)
+* @param counterName a PDH Counter string representation (required)
+* @param imageName a process image name string, ex. "java" (opt)
+* @param instance an instance string, ex. "0", "1", ... (opt)
+* @return the fully qualified PDH path.
+*
+* Caller will own the returned malloc:ed string
+*/
+static const char*
+makeFullCounterPath(const char* const objectName,
+ const char* const counterName,
+ const char* const imageName,
+ const char* const instance) {
+
+ size_t fullCounterPathLen;
+ char* fullCounterPath;
+
+ assert(objectName);
+ assert(counterName);
+
+ fullCounterPathLen = strlen(objectName);
+ fullCounterPathLen += strlen(counterName);
+
+ if (imageName) {
+ /*
+ * For paths using the "Process" Object.
+ *
+ * Examples:
+ * abstract: "\Process(imageName#instance)\Counter"
+ * actual: "\Process(java#2)\ID Process"
+ */
+ fullCounterPathLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
+ fullCounterPathLen += strlen(imageName);
+
+ /*
+ * imageName must be passed together with an associated
+ * instance "number" ("0", "1", "2", ...).
+ * This is required in order to create valid "Process" Object paths.
+ *
+ * Examples: "\Process(java#0)", \Process(java#1"), ...
+ */
+ assert(instance);
+
+ fullCounterPathLen += strlen(instance);
+
+ fullCounterPath = malloc(fullCounterPathLen + 1);
+
+ if (!fullCounterPath) {
+ return NULL;
+ }
+
+ _snprintf(fullCounterPath,
+ fullCounterPathLen,
+ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+ objectName,
+ imageName,
+ instance,
+ counterName);
+ } else {
+ if (instance) {
+ /*
+ * For paths where the Object has multiple instances.
+ *
+ * Examples:
+ * abstract: "\Object(instance)\Counter"
+ * actual: "\Processor(0)\% Privileged Time"
+ */
+ fullCounterPathLen += strlen(instance);
+ fullCounterPathLen += OBJECT_WITH_INSTANCES_COUNTER_FMT_LEN;
+ } else {
+ /*
+ * For "normal" paths.
+ *
+ * Examples:
+ * abstract: "\Object\Counter"
+ * actual: "\Memory\Available Mbytes"
+ */
+ fullCounterPathLen += OBJECT_COUNTER_FMT_LEN;
+ }
+
+ fullCounterPath = malloc(fullCounterPathLen + 1);
+
+ if (!fullCounterPath) {
+ return NULL;
+ }
+
+ if (instance) {
+ _snprintf(fullCounterPath,
+ fullCounterPathLen,
+ OBJECT_WITH_INSTANCES_COUNTER_FMT,
+ objectName,
+ instance,
+ counterName);
+ } else {
+ _snprintf(fullCounterPath,
+ fullCounterPathLen,
+ OBJECT_COUNTER_FMT,
+ objectName,
+ counterName);
+ }
+ }
+
+ fullCounterPath[fullCounterPathLen] = '\0';
+
+ return fullCounterPath;
+}
+
+/*
+ * Resolves an index for a PDH artifact to
+ * a localized, malloc:ed string representation.
+ * Caller will own the returned malloc:ed string.
+ *
+ * @param pdhArtifactIndex PDH index
+ * @return malloc:ed string representation
+ * of the requested pdh artifact (localized).
+ * NULL on failure.
+ */
+static const char*
+getPdhLocalizedArtifact(DWORD pdhArtifactIndex) {
+ char* pdhLocalizedArtifactString;
+
+ if (lookupNameByIndex(pdhArtifactIndex,
+ &pdhLocalizedArtifactString) != 0) {
+ return NULL;
+ }
+
+ return pdhLocalizedArtifactString;
+}
+
+static void
+pdhCleanup(HQUERY* const query, HCOUNTER* const counter) {
+ if (counter && *counter) {
+ PdhRemoveCounter_i(*counter);
+ *counter = NULL;
+ }
+ if (query && *query) {
+ PdhCloseQuery_i(*query);
+ *query = NULL;
+ }
+}
+
+static void
+destroySingleCounter(SingleCounterQueryP counterQuery) {
+ if (counterQuery) {
+ pdhCleanup(&counterQuery->query.query, &counterQuery->counter);
+ }
+}
+
+static void
+destroyMultiCounter(MultipleCounterQueryP multiCounterQuery) {
+ int i;
+ if (multiCounterQuery) {
+ if (multiCounterQuery->counters) {
+ for (i = 0; i < multiCounterQuery->noOfCounters; i++) {
+ pdhCleanup(NULL, &multiCounterQuery->counters[i]);
+ }
+ free(multiCounterQuery->counters);
+ multiCounterQuery->counters = NULL;
+ }
+ pdhCleanup(&multiCounterQuery->query.query, NULL);
+ }
+}
+
+static int
+openQuery(HQUERY* const query) {
+ assert(query);
+
+ if (PdhOpenQuery_i(NULL, 0, query) != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+addCounter(HQUERY query,
+ const char* const fullCounterPath,
+ HCOUNTER* const counter) {
+
+ assert(fullCounterPath);
+ assert(counter);
+
+ if (PdhAddCounter_i(query,
+ fullCounterPath,
+ 0,
+ counter) != ERROR_SUCCESS) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Sets up the supplied SingleCounterQuery to listen for the specified counter.
+ *
+ * @param counterQuery the counter query to set up.
+ * @param fullCounterPath the string specifying the full path to the counter.
+ * @returns 0 if successful, negative on failure.
+ */
+static int
+initializeSingleCounterQuery(SingleCounterQueryP counterQuery,
+ const char* const fullCounterPath) {
+ assert(counterQuery);
+ assert(fullCounterPath);
+
+ if (openQuery(&counterQuery->query.query) == 0) {
+ if (addCounter(counterQuery->query.query,
+ fullCounterPath,
+ &counterQuery->counter) == 0) {
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/*
+ * Sets up a SingleCounterQuery
+ *
+ * param counter the counter query to set up.
+ * param localizedObject string representing the PDH object to query
+ * param localizedCounter string representing the PDH counter to query
+ * param processImageName if the counter query needs the process image name ("java")
+ * param instance if the counter has instances, this is the instance ("\Processor(0)\")
+ where 0 is the instance
+ * param firstSampleOnInit for counters that need two queries to yield their values,
+ the first query can be issued just after initialization
+ *
+ * @returns 0 if successful, negative on failure.
+ */
+static int
+initializeSingleCounter(SingleCounterQueryP const counter,
+ const char* const localizedObject,
+ const char* const localizedCounter,
+ const char* const processImageName,
+ const char* const instance,
+ BOOL firstSampleOnInit) {
+ int retValue = -1;
+
+ const char* fullCounterPath = makeFullCounterPath(localizedObject,
+ localizedCounter,
+ processImageName,
+ instance);
+
+ if (fullCounterPath) {
+
+ assert(counter);
+
+ if (initializeSingleCounterQuery(counter, fullCounterPath) == 0) {
+ /*
+ * According to the MSDN documentation, rate counters must be read twice:
+ *
+ * "Obtaining the value of rate counters such as Page faults/sec requires that
+ * PdhCollectQueryData be called twice, with a specific time interval between
+ * the two calls, before calling PdhGetFormattedCounterValue. Call Sleep to
+ * implement the waiting period between the two calls to PdhCollectQueryData."
+ *
+ * Take the first sample here already to allow for the next (first) "real" sample
+ * to succeed.
+ */
+ if (firstSampleOnInit) {
+ PdhCollectQueryData_i(counter->query.query);
+ }
+
+ retValue = 0;
+ }
+ free((char*)fullCounterPath);
+ }
+
+ return retValue;
+}
+
+static void
+perfInit(void) {
+ InitializePdhCriticalSection(&initializationLock);
+}
+
+static int
+getProcessID() {
+ static int myPid = 0;
+ if (0 == myPid) {
+ myPid = _getpid();
+ }
+ return myPid;
+}
+
+/*
+ * Working against the Process object and it's related counters is inherently problematic
+ * when using the PDH API:
+ *
+ * For PDH, a process is not primarily identified by it's process id,
+ * but with a sequential number, for example \Process(java#0), \Process(java#1), ....
+ * The really bad part is that this list is reset as soon as one process exits:
+ * If \Process(java#1) exits, \Process(java#3) now becomes \Process(java#2) etc.
+ *
+ * The PDH query api requires a process identifier to be submitted when registering
+ * a query, but as soon as the list resets, the query is invalidated (since the name
+ * changed).
+ *
+ * Solution:
+ * The #number identifier for a Process query can only decrease after process creation.
+ *
+ * Therefore we create an array of counter queries for all process object instances
+ * up to and including ourselves:
+ *
+ * Ex. we come in as third process instance (java#2), we then create and register
+ * queries for the following Process object instances:
+ * java#0, java#1, java#2
+ *
+ * currentQueryIndexForProcess() keeps track of the current "correct" query
+ * (in order to keep this index valid when the list resets from underneath,
+ * ensure to call getCurrentQueryIndexForProcess() before every query involving
+ * Process object instance data).
+ */
+static int
+currentQueryIndexForProcess(void) {
+ HQUERY tmpQuery = NULL;
+ HCOUNTER handleCounter = NULL;
+ int retValue = -1;
+
+ assert(pdhProcessImageName);
+ assert(pdhIDProcessCounterFmt);
+
+ if (openQuery(&tmpQuery) == 0) {
+ int index;
+
+ /* iterate over all instance indexes and try to find our own pid */
+ for (index = 0; index < INT_MAX; ++index) {
+ char fullIDProcessCounterPath[MAX_PATH];
+ PDH_FMT_COUNTERVALUE counterValue;
+ PDH_STATUS res;
+
+ _snprintf(fullIDProcessCounterPath,
+ MAX_PATH,
+ pdhIDProcessCounterFmt,
+ index);
+
+ if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
+ break;
+ }
+
+ res = PdhCollectQueryData_i(tmpQuery);
+
+ if (PDH_INVALID_HANDLE == res || PDH_NO_DATA == res) {
+ break;
+ }
+
+ PdhGetFormattedCounterValue_i(handleCounter,
+ PDH_FMT_LONG,
+ NULL,
+ &counterValue);
+ /*
+ * This check seems to be needed for Win2k SMP boxes, since
+ * they for some reason don't return PDH_NO_DATA for non existing
+ * counters.
+ */
+ if (counterValue.CStatus != PDH_CSTATUS_VALID_DATA) {
+ break;
+ }
+
+ if ((LONG)getProcessID() == counterValue.longValue) {
+ retValue = index;
+ break;
+ }
+ }
+ }
+
+ pdhCleanup(&tmpQuery, &handleCounter);
+
+ return retValue;
+}
+
+/*
+ * If successful, returns the #index corresponding to our PID
+ * as resolved by the pdh query:
+ * "\Process(java#index)\ID Process" (or localized equivalent)
+ *
+ * This function should be called before attempting to read
+ * from any Process related counter(s), and the return value
+ * is the index to be used for indexing an array of Process object query's:
+ *
+ * Example:
+ * processTotalCPULoad[currentQueryIndex].query
+ *
+ * Returns -1 on failure.
+ */
+static int
+getCurrentQueryIndexForProcess() {
+ int currentQueryIndex = currentQueryIndexForProcess();
+
+ assert(currentQueryIndex >= 0 &&
+ currentQueryIndex < numberOfJavaProcessesAtInitialization);
+
+ return currentQueryIndex;
+}
+
+/*
+ * Returns the PDH string identifying the current process image name.
+ * Use this name as a qualifier when getting counters from the PDH Process Object
+ * representing your process.
+
+ * Example:
+ * "\Process(java#0)\Virtual Bytes" - where "java" is the PDH process
+ * image name.
+ *
+ * Please note that the process image name is not necessarily "java",
+ * hence the use of GetModuleFileName() to detect the process image name.
+ *
+ * @return the process image name to be used when retrieving
+ * PDH counters from the current process. The caller will
+ own the returned malloc:ed string. NULL if failure.
+ */
+static const char*
+getPdhProcessImageName() {
+ char moduleName[MAX_PATH];
+ char* processImageName;
+ char* dotPos;
+
+ // Find our module name and use it to extract the image name used by PDH
+ DWORD getmfnReturn = GetModuleFileName(NULL, moduleName, sizeof(moduleName));
+
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ return NULL;
+ }
+
+ if (getmfnReturn >= MAX_PATH || 0 == getmfnReturn) {
+ return NULL;
+ }
+
+ processImageName = strrchr(moduleName, '\\'); //drop path
+ processImageName++; //skip slash
+ dotPos = strrchr(processImageName, '.'); //drop .exe
+ dotPos[0] = '\0';
+
+ return allocateAndCopy(processImageName);
+}
+
+/*
+ * Sets up the supplied MultipleCounterQuery to check on the processors via PDH CPU counters.
+ * TODO: Refactor and prettify as with the the SingleCounter queries
+ * if more MultipleCounterQueries are discovered/needed.
+ *
+ * @param multiCounterCPULoad a pointer to a MultipleCounterQueryS, will be filled in with
+ * the necessary info to check the PDH processor counters.
+ * @return 0 if successful, negative on failure.
+ */
+static int
+initializeMultipleCounterForCPUs(MultipleCounterQueryP multiCounterCPULoad) {
+ DWORD cSize = 0;
+ DWORD iSize = 0;
+ DWORD pCount;
+ DWORD index;
+ char* processor = NULL; //'Processor' == PDH_PROCESSOR_IDX
+ char* time = NULL; //'Time' == PDH_PROCESSOR_TIME_IDX
+ char* instances = NULL;
+ char* tmp;
+ int retValue = -1;
+ PDH_STATUS pdhStat;
+
+ if (lookupNameByIndex(PDH_PROCESSOR_IDX, &processor) != 0) {
+ goto end;
+ }
+
+ if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX, &time) != 0) {
+ goto end;
+ }
+
+ //ok, now we have enough to enumerate all processors.
+ pdhStat = PdhEnumObjectItems_i(
+ NULL, // reserved
+ NULL, // local machine
+ processor, // object to enumerate
+ NULL, // pass in NULL buffers
+ &cSize, // and 0 length to get
+ NULL, // required size
+ &iSize, // of the buffers in chars
+ PERF_DETAIL_WIZARD, // counter detail level
+ 0);
+
+ if (pdhFail(pdhStat)) {
+ goto end;
+ }
+
+ instances = calloc(iSize, 1);
+
+ if (!instances) {
+ goto end;
+ }
+
+ cSize = 0;
+
+ pdhStat = PdhEnumObjectItems_i(
+ NULL, // reserved
+ NULL, // local machine
+ processor, // object to enumerate
+ NULL, // pass in NULL buffers
+ &cSize,
+ instances, // now allocated to be filled in
+ &iSize, // and size is known
+ PERF_DETAIL_WIZARD, // counter detail level
+ 0);
+
+ if (pdhFail(pdhStat)) {
+ goto end;
+ }
+
+ // enumerate the Processor instances ("\Processor(0)", "\Processor(1)", ..., "\Processor(_Total)")
+ for (pCount = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], pCount++);
+
+ assert(pCount == numCpus+1);
+
+ //ok, we now have the number of Processor instances - allocate an HCOUNTER for each
+ multiCounterCPULoad->counters = (HCOUNTER*)malloc(pCount * sizeof(HCOUNTER));
+
+ if (!multiCounterCPULoad->counters) {
+ goto end;
+ }
+
+ multiCounterCPULoad->noOfCounters = pCount;
+
+ if (openQuery(&multiCounterCPULoad->query.query) != 0) {
+ goto end;
+ }
+
+ // fetch instance and register its corresponding HCOUNTER with the query
+ for (index = 0, tmp = instances; *tmp != '\0'; tmp = &tmp[strlen(tmp)+1], ++index) {
+ const char* const fullCounterPath = makeFullCounterPath(processor, time, NULL, tmp);
+
+ if (!fullCounterPath) {
+ goto end;
+ }
+
+ retValue = addCounter(multiCounterCPULoad->query.query,
+ fullCounterPath,
+ &multiCounterCPULoad->counters[index]);
+
+ free((char*)fullCounterPath);
+
+ if (retValue != 0) {
+ goto end;
+ }
+ }
+
+ // Query once to initialize the counters which require at least two samples
+ // (like the % CPU usage) to calculate correctly.
+ PdhCollectQueryData_i(multiCounterCPULoad->query.query);
+
+ end:
+ if (processor) {
+ free(processor);
+ }
+
+ if (time) {
+ free(time);
+ }
+
+ if (instances) {
+ free(instances);
+ }
+
+ return retValue;
+}
+
+/*
+ * Dynamically sets up function pointers to the PDH library.
+ *
+ * @param h HMODULE for the PDH library
+ * @return 0 on success, negative on failure.
+ */
+static int
+bindPdhFunctionPointers(HMODULE h) {
+ assert(h);
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ /* The 'A' at the end means the ANSI (not the UNICODE) vesions of the methods */
+ PdhAddCounter_i = (PdhAddCounterFunc)GetProcAddress(h, "PdhAddCounterA");
+ PdhOpenQuery_i = (PdhOpenQueryFunc)GetProcAddress(h, "PdhOpenQueryA");
+ PdhCloseQuery_i = (PdhCloseQueryFunc)GetProcAddress(h, "PdhCloseQuery");
+ PdhCollectQueryData_i = (PdhCollectQueryDataFunc)GetProcAddress(h, "PdhCollectQueryData");
+ PdhGetFormattedCounterValue_i = (PdhGetFormattedCounterValueFunc)GetProcAddress(h, "PdhGetFormattedCounterValue");
+ PdhEnumObjectItems_i = (PdhEnumObjectItemsFunc)GetProcAddress(h, "PdhEnumObjectItemsA");
+ PdhRemoveCounter_i = (PdhRemoveCounterFunc)GetProcAddress(h, "PdhRemoveCounter");
+ PdhLookupPerfNameByIndex_i = (PdhLookupPerfNameByIndexFunc)GetProcAddress(h, "PdhLookupPerfNameByIndexA");
+
+ if (!PdhAddCounter_i || !PdhOpenQuery_i ||
+ !PdhCloseQuery_i || !PdhCollectQueryData_i ||
+ !PdhGetFormattedCounterValue_i || !PdhEnumObjectItems_i ||
+ !PdhRemoveCounter_i || !PdhLookupPerfNameByIndex_i)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Returns the counter value as a double for the specified query.
+ * Will collect the query data and update the counter values as necessary.
+ *
+ * @param query the query to update (if needed).
+ * @param c the counter to read.
+ * @param value where to store the formatted value.
+ * @param format the format to use (i.e. PDH_FMT_DOUBLE, PDH_FMT_LONG etc)
+ * @return 0 if no error
+ * -1 if PdhCollectQueryData fails
+ * -2 if PdhGetFormattedCounterValue fails
+ */
+static int
+getPerformanceData(UpdateQueryP query, HCOUNTER c, PDH_FMT_COUNTERVALUE* value, DWORD format) {
+ clock_t now = clock();
+
+ /*
+ * Need to limit how often we update the query
+ * to minimize the Heisenberg effect.
+ * (PDH behaves erratically if the counters are
+ * queried too often, especially counters that
+ * store and use values from two consecutive updates,
+ * like cpu load.)
+ */
+ if (now - query->lastUpdate > MIN_UPDATE_INTERVAL) {
+ if (PdhCollectQueryData_i(query->query) != ERROR_SUCCESS) {
+ return -1;
+ }
+ query->lastUpdate = now;
+ }
+
+ if (PdhGetFormattedCounterValue_i(c, format, NULL, value) != ERROR_SUCCESS) {
+ return -2;
+ }
+
+ return 0;
+}
+
+static int
+allocateAndInitializePdhConstants() {
+ const char* pdhLocalizedProcessObject = NULL;
+ const char* pdhLocalizedIDProcessCounter = NULL;
+ size_t pdhIDProcessCounterFmtLen;
+ int currentQueryIndex;
+ int retValue = -1;
+
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ assert(!pdhProcessImageName);
+ pdhProcessImageName = getPdhProcessImageName();
+ if (!pdhProcessImageName) {
+ goto end;
+ }
+
+ pdhLocalizedProcessObject = getPdhLocalizedArtifact(PDH_PROCESS_IDX);
+ if (!pdhLocalizedProcessObject) {
+ goto end;
+ }
+
+ pdhLocalizedIDProcessCounter = getPdhLocalizedArtifact(PDH_ID_PROCESS_IDX);
+ if (!pdhLocalizedIDProcessCounter) {
+ goto end;
+ }
+
+ assert(!pdhIDProcessCounterFmt);
+
+ pdhIDProcessCounterFmtLen = strlen(pdhProcessImageName);
+ pdhIDProcessCounterFmtLen += strlen(pdhLocalizedProcessObject);
+ pdhIDProcessCounterFmtLen += strlen(pdhLocalizedIDProcessCounter);
+ pdhIDProcessCounterFmtLen += PROCESS_OBJECT_INSTANCE_COUNTER_FMT_LEN;
+ pdhIDProcessCounterFmtLen += 2; // "%d"
+
+ assert(pdhIDProcessCounterFmtLen < MAX_PATH);
+ pdhIDProcessCounterFmt = malloc(pdhIDProcessCounterFmtLen + 1);
+ if (!pdhIDProcessCounterFmt) {
+ goto end;
+ }
+
+ /* "\Process(java#%d)\ID Process" */
+ _snprintf(pdhIDProcessCounterFmt,
+ pdhIDProcessCounterFmtLen,
+ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+ pdhLocalizedProcessObject,
+ pdhProcessImageName,
+ "%d",
+ pdhLocalizedIDProcessCounter);
+
+ pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';
+
+ assert(0 == numberOfJavaProcessesAtInitialization);
+ currentQueryIndex = currentQueryIndexForProcess();
+ if (-1 == currentQueryIndex) {
+ goto end;
+ }
+
+ numberOfJavaProcessesAtInitialization = currentQueryIndex + 1;
+ assert(numberOfJavaProcessesAtInitialization >= 1);
+
+ retValue = 0;
+
+ end:
+
+ if (pdhLocalizedProcessObject) {
+ free((char*)pdhLocalizedProcessObject);
+ }
+
+ if (pdhLocalizedIDProcessCounter) {
+ free((char*)pdhLocalizedIDProcessCounter);
+ }
+
+ return retValue;
+}
+
+static void
+deallocatePdhConstants() {
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ if (pdhProcessImageName) {
+ free((char*)pdhProcessImageName);
+ pdhProcessImageName = NULL;
+ }
+
+ if (pdhIDProcessCounterFmt) {
+ free(pdhIDProcessCounterFmt);
+ pdhIDProcessCounterFmt = NULL;
+ }
+
+ numberOfJavaProcessesAtInitialization = 0;
+}
+
+static int
+initializeCPUCounters() {
+ SYSTEM_INFO si;
+ char* localizedProcessObject;
+ char* localizedProcessorTimeCounter;
+ int i;
+ int retValue = -1;
+
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ assert(0 == numCpus);
+ GetSystemInfo(&si);
+ numCpus = si.dwNumberOfProcessors;
+ assert(numCpus >= 1);
+
+ /* Initialize the denominator for the jvm load calculations */
+ assert(.0 == cpuFactor);
+ cpuFactor = numCpus * 100;
+
+ if (lookupNameByIndex(PDH_PROCESS_IDX,
+ &localizedProcessObject) == 0) {
+
+ if (lookupNameByIndex(PDH_PROCESSOR_TIME_IDX,
+ &localizedProcessorTimeCounter) == 0) {
+
+ assert(processTotalCPULoad);
+ assert(pdhProcessImageName);
+
+ for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
+ char instanceIndexBuffer[32];
+ retValue = initializeSingleCounter(&processTotalCPULoad[i],
+ localizedProcessObject,
+ localizedProcessorTimeCounter,
+ pdhProcessImageName,
+ itoa(i, instanceIndexBuffer, 10),
+ TRUE);
+ if (retValue != 0) {
+ break;
+ }
+ }
+ free(localizedProcessorTimeCounter);
+ }
+ free(localizedProcessObject);
+ }
+
+ if (retValue != 0) {
+ return -1;
+ }
+
+ assert(multiCounterCPULoad);
+ return initializeMultipleCounterForCPUs(multiCounterCPULoad);
+}
+
+static void
+deallocateCPUCounters() {
+ int i;
+
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ if (processTotalCPULoad) {
+ for (i = 0; i < numberOfJavaProcessesAtInitialization; ++i) {
+ destroySingleCounter(&processTotalCPULoad[i]);
+ }
+ free(processTotalCPULoad);
+ processTotalCPULoad = NULL;
+ }
+
+ if (multiCounterCPULoad) {
+ destroyMultiCounter(multiCounterCPULoad);
+ free(multiCounterCPULoad);
+ multiCounterCPULoad = NULL;
+ }
+
+ cpuFactor = .0;
+ numCpus = 0;
+}
+
+static void
+pdhInitErrorHandler(HMODULE h) {
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+
+ deallocatePdhConstants();
+
+ if (h) {
+ FreeLibrary(h);
+ }
+}
+
+/*
+ * Helper to initialize the PDH library, function pointers and constants.
+ *
+ * @return 0 if successful, negative on failure.
+ */
+static int
+pdhInit() {
+ static BOOL initialized = FALSE;
+ int retValue;
+
+ if (initialized) {
+ return 0;
+ }
+
+ retValue = 0;
+
+ EnterPdhCriticalSection(&initializationLock); {
+ if (!initialized) {
+ HMODULE h = NULL;
+ if ((h = LoadLibrary("pdh.dll")) == NULL) {
+ retValue = -1;
+ } else if (bindPdhFunctionPointers(h) < 0) {
+ retValue = -1;
+ } else if (allocateAndInitializePdhConstants() < 0) {
+ retValue = -1;
+ }
+
+ if (0 == retValue) {
+ initialized = TRUE;
+ } else {
+ pdhInitErrorHandler(h);
+ }
+ }
+ } LeavePdhCriticalSection(&initializationLock);
+
+ return retValue;
+}
+
+static int
+allocateCPUCounters() {
+ assert(GetCurrentThreadId() == initializationLock.owningThread);
+ assert(numberOfJavaProcessesAtInitialization >= 1);
+ assert(!processTotalCPULoad);
+ assert(!multiCounterCPULoad);
+
+ /*
+ * Create an array of Process object queries, for each instance
+ * up to and including our own (java#0, java#1, java#2, ...).
+ */
+ processTotalCPULoad = calloc(numberOfJavaProcessesAtInitialization,
+ sizeof(SingleCounterQueryS));
+
+ if (!processTotalCPULoad) {
+ return -1;
+ }
+
+ multiCounterCPULoad = calloc(1, sizeof(MultipleCounterQueryS));
+
+ if (!multiCounterCPULoad) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+initializePdhCPUCounters() {
+ static BOOL initialized = FALSE;
+ int retValue;
+
+ if (initialized) {
+ return 0;
+ }
+
+ retValue = 0;
+
+ EnterPdhCriticalSection(&initializationLock); {
+ if (!initialized) {
+ if (pdhInit() < 0) {
+ retValue = -1;
+ } else if (allocateCPUCounters() < 0) {
+ retValue = -1;
+ } else if (initializeCPUCounters() < 0) {
+ retValue = -1;
+ }
+
+ if (0 == retValue) {
+ initialized = TRUE;
+ } else {
+ deallocateCPUCounters();
+ }
+ }
+ } LeavePdhCriticalSection(&initializationLock);
+
+ return retValue;
+}
+
+static int
+perfCPUInit() {
+ return initializePdhCPUCounters();
+}
+
+static double
+perfGetProcessCPULoad() {
+ PDH_FMT_COUNTERVALUE cv;
+ int currentQueryIndex;
+
+ if (perfCPUInit() < 0) {
+ // warn?
+ return -1.0;
+ }
+
+ currentQueryIndex = getCurrentQueryIndexForProcess();
+
+ if (getPerformanceData(&processTotalCPULoad[currentQueryIndex].query,
+ processTotalCPULoad[currentQueryIndex].counter,
+ &cv,
+ PDH_FMT_DOUBLE | PDH_FMT_NOCAP100) == 0) {
+ double d = cv.doubleValue / cpuFactor;
+ d = min(1, d);
+ d = max(0, d);
+ return d;
+ }
+ return -1.0;
+}
+
+static double
+perfGetCPULoad(int which) {
+ PDH_FMT_COUNTERVALUE cv;
+ HCOUNTER c;
+
+ if (perfCPUInit() < 0) {
+ // warn?
+ return -1.0;
+ }
+
+ if (-1 == which) {
+ c = multiCounterCPULoad->counters[multiCounterCPULoad->noOfCounters - 1];
+ } else {
+ if (which < multiCounterCPULoad->noOfCounters) {
+ c = multiCounterCPULoad->counters[which];
+ } else {
+ return -1.0;
+ }
+ }
+ if (getPerformanceData(&multiCounterCPULoad->query, c, &cv, PDH_FMT_DOUBLE ) == 0) {
+ return cv.doubleValue / 100;
+ }
+ return -1.0;
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ return perfGetCPULoad(-1);
+}
+
+JNIEXPORT jdouble JNICALL
+Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0
+(JNIEnv *env, jobject dummy)
+{
+ return perfGetProcessCPULoad();
+}
--- a/jdk/test/ProblemList.txt Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/ProblemList.txt Fri May 01 03:56:04 2015 -0700
@@ -136,13 +136,6 @@
############################################################################
-# jdk_management
-
-# 8058492
-java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all
-
-############################################################################
-
# jdk_jmx
# 8030957
@@ -353,9 +346,6 @@
# 8068645
com/sun/jdi/CatchPatternTest.sh generic-all
-# 8069402
-com/sun/jdi/ConnectedVMs.java generic-all
-
# 8067354
com/sun/jdi/GetLocalVariables4Test.sh windows-all
@@ -380,13 +370,7 @@
# 8072131
sun/tools/jmap/heapconfig/JMapHeapConfigTest.java macosx-all
-# 8027668
-sun/tools/jstatd/TestJstatdDefaults.java generic-all
-sun/tools/jstatd/TestJstatdServer.java generic-all
-sun/tools/jstatd/TestJstatdPort.java generic-all
-sun/tools/jstatd/TestJstatdPortAndServer.java generic-all
-
-# 8046285 8027668
+# 8046285
sun/tools/jstatd/TestJstatdExternalRegistry.java generic-all
# 6456333
--- a/jdk/test/com/sun/jdi/InstanceFilter.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/com/sun/jdi/InstanceFilter.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -104,7 +104,10 @@
return;
}
if (theThis == null) {
- // This happens when the thread has exited.
+ // This happens when the thread has exited or when a
+ // static method is called. Setting an instance
+ // filter does not prevent this event from being
+ // emitted with a this that is null.
methodEntryRequest.disable();
return;
}
@@ -138,6 +141,10 @@
EventRequestManager mgr = vm().eventRequestManager();
methodEntryRequest = mgr.createMethodEntryRequest();
methodEntryRequest.addInstanceFilter(theInstance);
+ // Thread filter is needed to prevent MethodEntry events
+ // to be emitted by the debugee when a static method
+ // is called on any thread.
+ methodEntryRequest.addThreadFilter(bpe.thread());
methodEntryRequest.enable();
listenUntilVMDisconnect();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/InvokeVarArgs.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8075331
+ * @summary Verify that we can call varargs methods
+ * @run build TestScaffold VMConnection TargetAdapter TargetListener
+ * @run compile -g InvokeVarArgs.java
+ * @run driver InvokeVarArgs
+ */
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import java.util.Arrays;
+
+interface MyInterface {
+}
+
+class SomeClass implements MyInterface {
+}
+
+class InvokeVarArgsTarg {
+
+ public static void main(String args[]) {
+ new InvokeVarArgsTarg().run();
+ }
+
+ SomeClass someClass1 = new SomeClass();
+ SomeClass someClass2 = new SomeClass();
+
+ MyInterface[] array = new MyInterface[]{someClass1, someClass2};
+ SomeClass[] array2 = new SomeClass[]{someClass1, someClass2};
+
+ public void run() {
+ System.out.println("size(array) : " + size(array));
+ System.out.println("size(array2) : " + size(array2));
+ }
+
+ int size(Object... value) {
+ return value.length;
+ }
+}
+
+public class InvokeVarArgs extends TestScaffold {
+
+ public static void main(String args[]) throws Exception {
+ new InvokeVarArgs(args).startTests();
+ }
+
+ InvokeVarArgs(String args[]) throws Exception {
+ super(args);
+ }
+
+ protected void runTests() throws Exception {
+
+ BreakpointEvent bpe = startTo("InvokeVarArgsTarg", "run", "()V");
+ StackFrame frame = bpe.thread().frame(0);
+ ObjectReference targetObj = frame.thisObject();
+ ReferenceType targetType = (ReferenceType) targetObj.type();
+ Value arrayVal = targetObj.getValue(targetType.fieldByName("array"));
+ Value array2Val = targetObj.getValue(targetType.fieldByName("array2"));
+ Method sizeMethod = targetType.methodsByName("size", "([Ljava/lang/Object;)I").get(0);
+
+ IntegerValue size = (IntegerValue) targetObj.invokeMethod(bpe.thread(), sizeMethod, Arrays.asList(new Value[]{arrayVal}), 0);
+ if (size.value() != 2) {
+ throw new Exception("size(array) should be 2, but was " + size.value());
+ }
+
+ size = (IntegerValue) targetObj.invokeMethod(bpe.thread(), sizeMethod, Arrays.asList(new Value[]{array2Val}), 0);
+ if (size.value() != 2) {
+ throw new Exception("size(array2) should be 2, but was " + size.value());
+ }
+
+ listenUntilVMDisconnect();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/CheckSomeMXBeanImplPackage.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.PlatformManagedObject;
+
+/*
+ * @test
+ * @bug 8042901
+ * @summary If jdk.management is present, GarbageCollectorMXBean and ThreadMXBean
+ * must be from com.sun.management.internal
+ * @author Shanliang Jiang
+ */
+public class CheckSomeMXBeanImplPackage {
+ private static String implPackageName = "com.sun.management.internal";
+
+ public static void main(String[] args) throws Exception {
+ boolean present = false;
+ try {
+ Class.forName("com.sun.management.GarbageCollectorMXBean");
+ present = true;
+ } catch (ClassNotFoundException cnfe) {}
+
+ if (present) {
+ Class <? extends PlatformManagedObject> klazz =
+ java.lang.management.GarbageCollectorMXBean.class;
+ for (Object obj :
+ ManagementFactory.getPlatformMXBeans(klazz)) {
+ check(klazz.getName(), obj);
+ }
+
+ klazz = com.sun.management.GarbageCollectorMXBean.class;
+ for (Object obj :
+ ManagementFactory.getPlatformMXBeans(klazz)) {
+ check(klazz.getName(), obj);
+ }
+
+ klazz = java.lang.management.ThreadMXBean.class;
+ check(klazz.getName(),
+ ManagementFactory.getPlatformMXBean(klazz));
+
+ klazz = com.sun.management.ThreadMXBean.class;
+ check(klazz.getName(),
+ ManagementFactory.getPlatformMXBean(klazz));
+
+ System.out.println("--- PASSED!");
+ } else {
+ System.out.println("--- Skip the test, jdk.management module is not present!");
+ }
+ }
+
+ private static void check(String mbeanName, Object impl) {
+ if (!impl.getClass().getName().startsWith(implPackageName)) {
+ throw new RuntimeException(mbeanName+" implementation package "
+ + "should be: " + implPackageName
+ + ", but got: " + impl.getClass());
+ } else {
+ System.out.println("--- Good, "+mbeanName+" got right implementation: " + impl);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/management/VMOptionOpenDataTest.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import com.sun.management.VMOption;
+import java.io.InvalidObjectException;
+import java.util.Objects;
+import javax.management.openmbean.OpenDataException;
+import sun.management.MappedMXBeanType;
+
+/*
+ * @test
+ * @bug 8042901
+ * @summary Check that MappedMXBeanType.toOpenTypeData supports VMOption
+ * @author Shanliang Jiang
+ */
+public class VMOptionOpenDataTest {
+ public static void main(String[] args) throws Exception {
+ System.out.println("--- VMOptionOpenDataTest-main: Checking that "
+ + "MappedMXBeanType.toOpenTypeData supports VMOption");
+ Exception failed = null;
+ try {
+ VMOption vo = new VMOption("toto", "titi", true, VMOption.Origin.OTHER);
+ System.out.println("--- Construct a VMOption object: \"" + vo + "\"");
+
+ Object open = MappedMXBeanType.toOpenTypeData(vo, VMOption.class);
+ System.out.println("--- Map it to an open type: \"" + open +" \"");
+
+ Object back = MappedMXBeanType.toJavaTypeData(open, VMOption.class);
+ System.out.println("--- Map it back to java type: \"" + back +" \"");
+
+ if (back == null) {
+ failed = new RuntimeException("Failed, mapping back got null.");
+ } else if (!(back instanceof VMOption)) {
+ failed = new RuntimeException("Failed, not mapped back to a VMOption: "
+ +back.getClass());
+ } else {
+ VMOption mapBack = (VMOption)back;
+ if (!Objects.equals(vo.getName(), mapBack.getName()) ||
+ !Objects.equals(vo.getOrigin(), mapBack.getOrigin()) ||
+ !Objects.equals(vo.getValue(), mapBack.getValue()) ||
+ vo.isWriteable() != mapBack.isWriteable()) {
+ failed = new RuntimeException(
+ "Failed, failed to map back the original VMOtion.");
+ }
+ }
+ } catch (OpenDataException | InvalidObjectException ode) {
+ failed = ode;
+ }
+ if (failed == null) {
+ System.out.println("--- PASSED!");
+ } else {
+ System.out.println("--- Failed: "+failed.getMessage());
+ throw failed;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Class/getSimpleName/GetSimpleNameTest.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8057919
+ * @summary Class.getSimpleName() should work for non-JLS compliant class names
+ */
+import jdk.internal.org.objectweb.asm.*;
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
+
+public class GetSimpleNameTest {
+ static class NestedClass {}
+ class InnerClass {}
+
+ static Class<?> f1() {
+ class LocalClass {}
+ return LocalClass.class;
+ }
+
+ public static void main(String[] args) throws Exception {
+ assertEquals(NestedClass.class.getSimpleName(), "NestedClass");
+ assertEquals( InnerClass.class.getSimpleName(), "InnerClass");
+ assertEquals( f1().getSimpleName(), "LocalClass");
+
+ java.io.Serializable anon = new java.io.Serializable() {};
+ assertEquals(anon.getClass().getSimpleName(), "");
+
+ // Java class names, prepended enclosing class name.
+ testNested("p.Outer$Nested", "p.Outer", "Nested");
+ testInner( "p.Outer$Inner", "p.Inner", "Inner");
+ testLocal( "p.Outer$1Local", "p.Outer", "Local");
+ testAnon( "p.Outer$1", "p.Outer", "");
+
+ // Non-Java class names, prepended enclosing class name.
+ testNested("p.$C1$Nested", "p.$C1$", "Nested");
+ testInner( "p.$C1$Inner", "p.$C1$", "Inner");
+ testLocal( "p.$C1$Local", "p.$C1$", "Local");
+ testAnon( "p.$C1$1", "p.$C1$", "");
+
+ // Non-Java class names, unrelated class names.
+ testNested("p1.$Nested$", "p2.$C1$", "Nested");
+ testInner( "p1.$Inner$", "p2.$C1$", "Inner");
+ testLocal( "p1.$Local$", "p2.$C1$", "Local");
+ testAnon( "p1.$anon$", "p2.$C1$", "");
+ }
+
+ static void testNested(String innerName, String outerName, String simpleName) throws Exception {
+ BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
+ CustomCL cl = new CustomCL(innerName, outerName, bg.getNestedClasses(true), bg.getNestedClasses(false));
+ assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
+ }
+
+ static void testInner(String innerName, String outerName, String simpleName) throws Exception {
+ BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
+ CustomCL cl = new CustomCL(innerName, outerName, bg.getInnerClasses(true), bg.getInnerClasses(false));
+ assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
+ }
+
+ static void testLocal(String innerName, String outerName, String simpleName) throws Exception {
+ BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
+ CustomCL cl = new CustomCL(innerName, outerName, bg.getLocalClasses(true), bg.getLocalClasses(false));
+ assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
+ }
+
+ static void testAnon(String innerName, String outerName, String simpleName) throws Exception {
+ BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName);
+ CustomCL cl = new CustomCL(innerName, outerName, bg.getAnonymousClasses(true), bg.getAnonymousClasses(false));
+ assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName);
+ }
+
+ static void assertEquals(Object o1, Object o2) {
+ if (!java.util.Objects.equals(o1, o2)) {
+ throw new AssertionError(o1 + " != " + o2);
+ }
+ }
+
+ static class CustomCL extends ClassLoader {
+ final String innerName;
+ final String outerName;
+
+ final byte[] innerClassFile;
+ final byte[] outerClassFile;
+
+ CustomCL(String innerName, String outerName, byte[] innerClassFile, byte[] outerClassFile) {
+ this.innerName = innerName;
+ this.outerName = outerName;
+ this.innerClassFile = innerClassFile;
+ this.outerClassFile = outerClassFile;
+ }
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ if (innerName.equals(name)) {
+ return defineClass(innerName, innerClassFile, 0, innerClassFile.length);
+ } else if (outerName.equals(name)) {
+ return defineClass(outerName, outerClassFile, 0, outerClassFile.length);
+ } else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ }
+
+ static class BytecodeGenerator {
+ final String innerName;
+ final String outerName;
+ final String simpleName;
+
+ BytecodeGenerator(String innerName, String outerName, String simpleName) {
+ this.innerName = intl(innerName);
+ this.outerName = intl(outerName);
+ this.simpleName = simpleName;
+ }
+
+ static String intl(String name) { return name.replace('.', '/'); }
+
+ static void makeDefaultCtor(ClassWriter cw) {
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+ mv.visitCode();
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+
+ void makeCtxk(ClassWriter cw, boolean isInner) {
+ if (isInner) {
+ cw.visitOuterClass(outerName, "f", "()V");
+ } else {
+ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f", "()V", null, null);
+ mv.visitCode();
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(0, 0);
+ mv.visitEnd();
+ }
+ }
+
+ byte[] getNestedClasses(boolean isInner) {
+ String name = (isInner ? innerName : outerName);
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);
+
+ cw.visitInnerClass(innerName, outerName, simpleName, ACC_PUBLIC | ACC_STATIC);
+
+ makeDefaultCtor(cw);
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ byte[] getInnerClasses(boolean isInner) {
+ String name = (isInner ? innerName : outerName);
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);
+
+ cw.visitInnerClass(innerName, outerName, simpleName, ACC_PUBLIC);
+
+ makeDefaultCtor(cw);
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ byte[] getLocalClasses(boolean isInner) {
+ String name = (isInner ? innerName : outerName);
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);
+
+ cw.visitInnerClass(innerName, null, simpleName, ACC_PUBLIC | ACC_STATIC);
+ makeCtxk(cw, isInner);
+
+ makeDefaultCtor(cw);
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+
+ byte[] getAnonymousClasses(boolean isInner) {
+ String name = (isInner ? innerName : outerName);
+ ClassWriter cw = new ClassWriter(0);
+ cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null);
+
+ cw.visitInnerClass(innerName, null, null, ACC_PUBLIC | ACC_STATIC);
+ makeCtxk(cw, isInner);
+
+ makeDefaultCtor(cw);
+ cw.visitEnd();
+ return cw.toByteArray();
+ }
+ }
+}
--- a/jdk/test/java/lang/Thread/ThreadStateController.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/Thread/ThreadStateController.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
import java.util.concurrent.locks.LockSupport;
import jdk.testlibrary.LockFreeLogManager;
+import jdk.testlibrary.Utils;
/**
* ThreadStateController allows a thread to request this thread to transition
@@ -73,7 +74,7 @@
public static void pause(long ms) {
try {
- Thread.sleep(ms);
+ Thread.sleep(Utils.adjustTimeout(ms));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
@@ -135,7 +136,7 @@
try {
// this thread has escaped the BLOCKED state
// release the lock and a short wait before continue
- lock.wait(10);
+ lock.wait(Utils.adjustTimeout(10));
} catch (InterruptedException e) {
// ignore
interrupted.incrementAndGet();
@@ -165,7 +166,7 @@
getId(), getName(), iterations.get(), interrupted.get());
try {
stateChange(nextState);
- lock.wait(10000);
+ lock.wait(Integer.MAX_VALUE);
log("%d: %s wakes up from timed waiting (iterations %d interrupted %d)%n",
getId(), getName(), iterations.get(), interrupted.get());
} catch (InterruptedException e) {
@@ -185,7 +186,8 @@
case S_TIMED_PARKED: {
log("%d: %s is going to timed park (iterations %d)%n",
getId(), getName(), iterations.get());
- long deadline = System.currentTimeMillis() + 10000*1000;
+ long deadline = System.currentTimeMillis() +
+ Utils.adjustTimeout(10000*1000);
stateChange(nextState);
LockSupport.parkUntil(deadline);
break;
@@ -195,7 +197,7 @@
getId(), getName(), iterations.get(), interrupted.get());
try {
stateChange(nextState);
- Thread.sleep(1000000);
+ Thread.sleep(Utils.adjustTimeout(1000000));
} catch (InterruptedException e) {
// finish sleeping
interrupted.incrementAndGet();
--- a/jdk/test/java/lang/instrument/NMTHelper.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/NMTHelper.java Fri May 01 03:56:04 2015 -0700
@@ -27,8 +27,9 @@
import java.util.regex.Pattern;
import java.util.Arrays;
import java.util.stream.Collectors;
-import sun.management.ManagementFactoryHelper;
-import com.sun.management.DiagnosticCommandMBean;
+import java.lang.management.ManagementFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
public class NMTHelper
{
@@ -53,7 +54,12 @@
}
private static String executeDcmd(String cmd, String ... args) {
- DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
+ ObjectName oname = null;
+ try {
+ oname = ObjectName.getInstance("com.sun.management:type=DiagnosticCommand");
+ } catch (MalformedObjectNameException mone) {
+ throw new RuntimeException(mone);
+ }
Object[] dcmdArgs = {args};
String[] signature = {String[].class.getName()};
@@ -63,7 +69,8 @@
System.out.println("Output from Dcmd '" + cmdString + "' is being written to file " + f);
try (FileWriter fw = new FileWriter(f)) {
fw.write("> " + cmdString + ":");
- String result = (String) dcmd.invoke(cmd, dcmdArgs, signature);
+ String result = (String)ManagementFactory.getPlatformMBeanServer().
+ invoke(oname, cmd, dcmdArgs, signature);
fw.write(result);
return result;
} catch(Exception ex) {
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh Fri May 01 03:56:04 2015 -0700
@@ -77,7 +77,7 @@
cat output.log
-MESG="Exception"
+MESG="Test failed"
grep "$MESG" output.log
result=$?
if [ "$result" = 0 ]; then
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,8 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
-import sun.management.ManagementFactoryHelper;
+import javax.management.JMX;
+import javax.management.ObjectName;
/**
* When an exception is thrown, the JVM collects just enough information
@@ -46,12 +47,15 @@
* could be freed, since class redefinition didn't know about the backtraces.
*/
public class RedefineMethodInBacktraceApp {
+ static boolean failed = false;
+
public static void main(String args[]) throws Exception {
System.out.println("Hello from RedefineMethodInBacktraceApp!");
-
new RedefineMethodInBacktraceApp().doTest();
- System.exit(0);
+ if (failed) {
+ throw new Exception("ERROR: RedefineMethodInBacktraceApp failed.");
+ }
}
public static CountDownLatch stop = new CountDownLatch(1);
@@ -63,13 +67,18 @@
}
private void doMethodInBacktraceTest() throws Exception {
- Throwable t = getThrowableFromMethodToRedefine();
+ Throwable t1 = getThrowableFromMethodToRedefine();
+ Throwable t2 = getThrowableFromMethodToDelete();
doRedefine(RedefineMethodInBacktraceTarget.class);
doClassUnloading();
- touchRedefinedMethodInBacktrace(t);
+ System.out.println("checking backtrace for throwable from methodToRedefine");
+ touchRedefinedMethodInBacktrace(t1);
+
+ System.out.println("checking backtrace for throwable from methodToDelete");
+ touchRedefinedMethodInBacktrace(t2);
}
private void doMethodInBacktraceTestB() throws Exception {
@@ -95,8 +104,11 @@
String[] threadPrintArgs = {};
Object[] dcmdArgs = {threadPrintArgs};
String[] signature = {String[].class.getName()};
- DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean();
- System.out.println(dcmd.invoke("threadPrint", dcmdArgs, signature));
+ System.out.println(ManagementFactory.getPlatformMBeanServer().invoke(
+ ObjectName.getInstance("com.sun.management:type=DiagnosticCommand"),
+ "threadPrint",
+ dcmdArgs,
+ signature));
// release the thread
stop.countDown();
@@ -115,6 +127,10 @@
if (!(thrownFromMethodToRedefine instanceof RuntimeException)) {
throw e;
}
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("\nTest failed: unexpected exception: " + e.toString());
+ failed = true;
}
method = null;
c = null;
@@ -122,15 +138,49 @@
return thrownFromMethodToRedefine;
}
+ private static Throwable getThrowableFromMethodToDelete() throws Exception {
+ Class<RedefineMethodInBacktraceTarget> c =
+ RedefineMethodInBacktraceTarget.class;
+ Method method = c.getMethod("callMethodToDelete");
+
+ Throwable thrownFromMethodToDelete = null;
+ try {
+ method.invoke(null);
+ } catch (InvocationTargetException e) {
+ thrownFromMethodToDelete = e.getCause();
+ if (!(thrownFromMethodToDelete instanceof RuntimeException)) {
+ throw e;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("\nTest failed: unexpected exception: " + e.toString());
+ failed = true;
+ }
+ return thrownFromMethodToDelete;
+ }
+
+
private static void doClassUnloading() {
// This will clean out old, unused redefined methods.
System.gc();
}
private static void touchRedefinedMethodInBacktrace(Throwable throwable) {
+ throwable.printStackTrace();
// Make sure that we can convert the backtrace, which is referring to
// the redefined method, to a StrackTraceElement[] without crashing.
- throwable.getStackTrace();
+ StackTraceElement[] stackTrace = throwable.getStackTrace();
+ for (int i = 0; i < stackTrace.length; i++) {
+ StackTraceElement frame = stackTrace[i];
+ if (frame.getClassName() == null) {
+ System.out.println("\nTest failed: trace[" + i + "].getClassName() returned null");
+ failed = true;
+ }
+ if (frame.getMethodName() == null) {
+ System.out.println("\nTest failed: trace[" + i + "].getMethodName() returned null");
+ failed = true;
+ }
+ }
}
private static void doRedefine(Class<?> clazz) throws Exception {
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java Fri May 01 03:56:04 2015 -0700
@@ -29,4 +29,13 @@
public static void methodToRedefine() {
throw new RuntimeException("Test exception");
}
+
+ public static void callMethodToDelete() {
+ methodToDelete();
+ }
+
+ private static void methodToDelete() {
+ throw new RuntimeException("Test exception in methodToDelete");
+ }
+
}
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java Fri May 01 03:56:04 2015 -0700
@@ -37,4 +37,16 @@
// ignore, test will fail
}
}
+
+ public static void callMethodToDelete() {
+ try {
+ // signal that we are here
+ RedefineMethodInBacktraceApp.called.countDown();
+
+ // wait until test is done
+ RedefineMethodInBacktraceApp.stop.await();
+ } catch (InterruptedException ex) {
+ // ignore, test will fail
+ }
+ }
}
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java Fri May 01 03:56:04 2015 -0700
@@ -28,4 +28,7 @@
public class RedefineMethodInBacktraceTargetB {
public static void methodToRedefine() {
}
+
+ public static void callMethodToDelete() {
+ }
}
--- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java Fri May 01 03:56:04 2015 -0700
@@ -29,4 +29,8 @@
public static void methodToRedefine() {
throw new RuntimeException("Test exception 2");
}
+
+ public static void callMethodToDelete() {
+ throw new RuntimeException("Test exception 2 in callMethodToDelete");
+ }
}
--- a/jdk/test/java/lang/management/ThreadMXBean/FindDeadlocks.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/management/ThreadMXBean/FindDeadlocks.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
/*
* @test
* @bug 5086470
+ * @key intermittent
* @summary Basic Test for the following methods:
* - ThreadMXBean.findDeadlockedThreads()
* - ThreadMXBean.findMonitorDeadlockedThreads()
--- a/jdk/test/java/lang/management/ThreadMXBean/Semaphore.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @bug 4530538
- * @summary A semaphore utility class.
- * @author Mandy Chung
- */
-
-public class Semaphore {
- private Object go = new Object();
- private int semaCount;
- private int waiters = 0;
-
- public Semaphore() {
- semaCount = 0;
- }
-
- public Semaphore(int initialCount) {
- semaCount = initialCount;
- }
-
- public void semaP() {
- synchronized (go) {
- waiters++;
- while (semaCount == 0) {
- try {
- go.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- throw new InternalError();
- }
- }
- semaCount--;
- waiters--;
- }
- }
- public void semaV() {
- synchronized (go) {
- semaCount++;
- go.notify();
- }
- }
-
- public int getWaiterCount() {
- synchronized (go) {
- return waiters;
- }
- }
-
- public Object getLock() {
- return go;
- }
-}
--- a/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,12 @@
/*
* @test
- * @bug 5058327
- * @summary Test if getThreadInfo(long[]) returns a ThreadInfo[]
- * with null elements with no exception.
+ * @bug 5058327 8074368
+ * @summary Tests the correct behaviour of getThreadInfo(long[]) for non-existent
+ * thread IDs and the empty thread id array.
*
* @author Mandy Chung
+ * @author Jaroslav Bachorik
*
* @build ThreadInfoArray
* @run main ThreadInfoArray
@@ -35,15 +36,30 @@
import java.lang.management.*;
import javax.management.*;
-import java.util.*;
import static java.lang.management.ManagementFactory.*;
public class ThreadInfoArray {
public static void main(String[] argv) throws Exception {
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ ObjectName on = new ObjectName(THREAD_MXBEAN_NAME);
+
ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
+ ThreadMXBean proxy = newPlatformMXBeanProxy(mbs,
+ on.toString(),
+ ThreadMXBean.class);
+ checkNullElement(mbean, proxy, mbs, on);
+ checkEmptyArray(mbean, proxy, mbs, on);
+ System.out.println("Test passed");
+ }
+
+ private static void checkNullElement(ThreadMXBean mbean, ThreadMXBean proxy,
+ MBeanServer mbs, ObjectName on)
+ throws Exception {
+ System.out.println("--- Check null element");
// ID for a new thread
long [] ids = {new Thread().getId()};
+ // direct call
ThreadInfo[] tinfos = mbean.getThreadInfo(ids);
if (tinfos[0] != null) {
@@ -52,8 +68,6 @@
}
// call getThreadInfo through MBeanServer
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- ObjectName on = new ObjectName(THREAD_MXBEAN_NAME);
Object[] params = {ids};
String[] sigs = {"[J"};
Object[] result = (Object[]) mbs.invoke(on, "getThreadInfo", params, sigs);
@@ -64,14 +78,57 @@
}
// call getThreadInfo through proxy
- ThreadMXBean proxy = newPlatformMXBeanProxy(mbs,
- on.toString(),
- ThreadMXBean.class);
tinfos = proxy.getThreadInfo(ids);
if (tinfos[0] != null) {
throw new RuntimeException("TEST FAILED: " +
"Expected to have a null element");
}
- System.out.println("Test passed");
+ System.out.println("--- PASSED");
+ }
+
+ private static void checkEmptyArray(ThreadMXBean mbean, ThreadMXBean proxy,
+ MBeanServer mbs, ObjectName on)
+ throws Exception {
+ System.out.println("--- Check empty TID array");
+
+ long[] ids = new long[0];
+ // direct call
+ assertEmptyArray(mbean.getThreadInfo(ids), "Expected empty ThreadInfo array");
+ assertEmptyArray(mbean.getThreadInfo(ids, 1), "Expected empty ThreadInfo array");
+ assertEmptyArray(mbean.getThreadInfo(ids, true, true), "Expected empty ThreadInfo array");
+
+ // call getThreadInfo through MBeanServer
+ assertEmptyArray(
+ (Object[]) mbs.invoke(
+ on, "getThreadInfo", new Object[]{ids}, new String[]{"[J"}
+ ),
+ "Expected empty ThreadInfo array via MBeanServer"
+ );
+ assertEmptyArray(
+ (Object[]) mbs.invoke(
+ on, "getThreadInfo", new Object[]{ids, 1},
+ new String[]{"[J", "int"}
+ ),
+ "Expected empty ThreadInfo array via MBeanServer"
+ );
+ assertEmptyArray(
+ (Object[]) mbs.invoke(
+ on, "getThreadInfo", new Object[]{ids, true, true},
+ new String[]{"[J", "boolean", "boolean"}
+ ),
+ "Expected empty ThreadInfo array via MBeanServer"
+ );
+
+ // call getThreadInfo through proxy
+ assertEmptyArray(proxy.getThreadInfo(ids), "Expected empty ThreadInfo array");
+ assertEmptyArray(proxy.getThreadInfo(ids, 1), "Expected empty ThreadInfo array");
+ assertEmptyArray(proxy.getThreadInfo(ids, true, true), "Expected empty ThreadInfo array");
+ System.out.println("--- PASSED");
+ }
+
+ private static void assertEmptyArray(Object[] arr, String message) throws Exception {
+ if (arr.length > 0) {
+ throw new RuntimeException("TEST FAILED: " + message);
+ }
}
}
--- a/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,60 +64,61 @@
Thread.currentThread().getState();
ThreadStateController thread = new ThreadStateController("StateChanger", globalLock);
thread.setDaemon(true);
-
- // before myThread starts
- thread.checkThreadState(NEW);
+ try {
+ // before myThread starts
+ thread.checkThreadState(NEW);
- thread.start();
- thread.transitionTo(RUNNABLE);
- thread.checkThreadState(RUNNABLE);
- checkLockInfo(thread, RUNNABLE, null, null);
+ thread.start();
+ thread.transitionTo(RUNNABLE);
+ thread.checkThreadState(RUNNABLE);
+ checkLockInfo(thread, RUNNABLE, null, null);
- thread.suspend();
- ThreadStateController.pause(10);
- thread.checkThreadState(RUNNABLE);
- checkSuspendedThreadState(thread, RUNNABLE);
- thread.resume();
+ thread.suspend();
+ ThreadStateController.pause(10);
+ thread.checkThreadState(RUNNABLE);
+ checkSuspendedThreadState(thread, RUNNABLE);
+ thread.resume();
- synchronized (globalLock) {
- thread.transitionTo(BLOCKED);
- thread.checkThreadState(BLOCKED);
- checkLockInfo(thread, BLOCKED,
- globalLock, Thread.currentThread());
- }
+ synchronized (globalLock) {
+ thread.transitionTo(BLOCKED);
+ thread.checkThreadState(BLOCKED);
+ checkLockInfo(thread, BLOCKED,
+ globalLock, Thread.currentThread());
+ }
- thread.transitionTo(WAITING);
- thread.checkThreadState(WAITING);
- checkLockInfo(thread, Thread.State.WAITING,
- globalLock, null);
+ thread.transitionTo(WAITING);
+ thread.checkThreadState(WAITING);
+ checkLockInfo(thread, Thread.State.WAITING,
+ globalLock, null);
- thread.transitionTo(TIMED_WAITING);
- thread.checkThreadState(TIMED_WAITING);
- checkLockInfo(thread, TIMED_WAITING,
- globalLock, null);
+ thread.transitionTo(TIMED_WAITING);
+ thread.checkThreadState(TIMED_WAITING);
+ checkLockInfo(thread, TIMED_WAITING,
+ globalLock, null);
- thread.transitionToPark(true /* timed park */);
- thread.checkThreadState(TIMED_WAITING);
- checkLockInfo(thread, TIMED_WAITING, null, null);
+ thread.transitionToPark(true /* timed park */);
+ thread.checkThreadState(TIMED_WAITING);
+ checkLockInfo(thread, TIMED_WAITING, null, null);
- thread.transitionToPark(false /* indefinite park */);
- thread.checkThreadState(WAITING);
- checkLockInfo(thread, WAITING, null, null);
+ thread.transitionToPark(false /* indefinite park */);
+ thread.checkThreadState(WAITING);
+ checkLockInfo(thread, WAITING, null, null);
- thread.transitionToSleep();
- thread.checkThreadState(TIMED_WAITING);
- checkLockInfo(thread, TIMED_WAITING, null, null);
-
- thread.transitionTo(TERMINATED);
- thread.checkThreadState(TERMINATED);
+ thread.transitionToSleep();
+ thread.checkThreadState(TIMED_WAITING);
+ checkLockInfo(thread, TIMED_WAITING, null, null);
- try {
- System.out.println(thread.getLog());
- } catch (InterruptedException e) {
- e.printStackTrace();
- System.out.println("TEST FAILED: Unexpected exception.");
- throw new RuntimeException(e);
+ thread.transitionTo(TERMINATED);
+ thread.checkThreadState(TERMINATED);
+ } finally {
+ try {
+ System.out.println(thread.getLog());
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ System.out.println("TEST FAILED: Unexpected exception.");
+ throw new RuntimeException(e);
+ }
}
System.out.println("Test passed.");
}
--- a/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,25 +28,26 @@
* ThreadInfo.getThreadState()
* @author Mandy Chung
*
- * @run build Semaphore Utils
+ * @run build Utils
* @run main ThreadStackTrace
*/
import java.lang.management.*;
+import java.util.concurrent.Phaser;
public class ThreadStackTrace {
- private static ThreadMXBean mbean
+ private static final ThreadMXBean mbean
= ManagementFactory.getThreadMXBean();
private static boolean notified = false;
- private static Object lockA = new Object();
- private static Object lockB = new Object();
+ private static final Object lockA = new Object();
+ private static final Object lockB = new Object();
private static volatile boolean testFailed = false;
- private static String[] blockedStack = {"run", "test", "A", "B", "C", "D"};
- private static int bsDepth = 6;
- private static int methodB = 4;
- private static String[] examinerStack = {"run", "examine1", "examine2"};
- private static int esDepth = 3;
- private static int methodExamine1= 2;
+ private static final String[] blockedStack = {"run", "test", "A", "B", "C", "D"};
+ private static final int bsDepth = 6;
+ private static final int methodB = 4;
+ private static final String[] examinerStack = {"run", "examine1", "examine2"};
+ private static final int esDepth = 3;
+ private static final int methodExamine1= 2;
private static void checkNullThreadInfo(Thread t) throws Exception {
ThreadInfo ti = mbean.getThreadInfo(t.getId());
@@ -69,8 +70,10 @@
trace = true;
}
- Examiner examiner = new Examiner("Examiner");
- BlockedThread blocked = new BlockedThread("BlockedThread");
+ final Phaser p = new Phaser(2);
+
+ Examiner examiner = new Examiner("Examiner", p);
+ BlockedThread blocked = new BlockedThread("BlockedThread", p);
examiner.setThread(blocked);
checkNullThreadInfo(examiner);
@@ -79,8 +82,8 @@
// Start the threads and check them in Blocked and Waiting states
examiner.start();
- // block until examiner begins doing its real work
- examiner.waitForStarted();
+ // #1 - block until examiner begins doing its real work
+ p.arriveAndAwaitAdvance();
System.out.println("Checking stack trace for the examiner thread " +
"is waiting to begin.");
@@ -145,35 +148,11 @@
}
static class BlockedThread extends Thread {
- private Semaphore handshake = new Semaphore();
-
- BlockedThread(String name) {
- super(name);
- }
- boolean hasWaitersForBlocked() {
- return (handshake.getWaiterCount() > 0);
- }
-
- void waitUntilBlocked() {
- handshake.semaP();
+ private final Phaser phaser;
- // give a chance for the examiner thread to really wait
- Utils.goSleep(20);
- }
-
- void waitUntilLockAReleased() {
- handshake.semaP();
-
- // give a chance for the examiner thread to really wait
- Utils.goSleep(50);
- }
-
- private void notifyWaiter() {
- // wait until the examiner waits on the semaphore
- while (handshake.getWaiterCount() == 0) {
- Utils.goSleep(20);
- }
- handshake.semaV();
+ BlockedThread(String name, Phaser phaser) {
+ super(name);
+ this.phaser = phaser;
}
private void test() {
@@ -185,25 +164,24 @@
private void B() {
C();
- // notify the examiner about to block on lockB
- notifyWaiter();
+ // #4 - notify the examiner about to block on lockB
+ phaser.arriveAndAwaitAdvance();
- synchronized (lockB) {
- };
+ synchronized (lockB) {};
}
private void C() {
D();
}
private void D() {
- // Notify that examiner about to enter lockA
- notifyWaiter();
+ // #2 - Notify that examiner about to enter lockA
+ phaser.arriveAndAwaitAdvance();
synchronized (lockA) {
notified = false;
while (!notified) {
try {
- // notify the examiner about to release lockA
- notifyWaiter();
+ // #3 - notify the examiner about to release lockA
+ phaser.arriveAndAwaitAdvance();
// Wait and let examiner thread check the mbean
lockA.wait();
} catch (InterruptedException e) {
@@ -216,6 +194,7 @@
}
}
+ @Override
public void run() {
test();
} // run()
@@ -223,28 +202,17 @@
static class Examiner extends Thread {
private static BlockedThread blockedThread;
- private Semaphore handshake = new Semaphore();
+ private final Phaser phaser;
- Examiner(String name) {
+ Examiner(String name, Phaser phaser) {
super(name);
+ this.phaser = phaser;
}
public void setThread(BlockedThread thread) {
blockedThread = thread;
}
- public synchronized void waitForStarted() {
- // wait until the examiner is about to block
- handshake.semaP();
-
- // wait until the examiner is waiting for blockedThread's notification
- while (!blockedThread.hasWaitersForBlocked()) {
- Utils.goSleep(50);
- }
- // give a chance for the examiner thread to really wait
- Utils.goSleep(20);
- }
-
private Thread itself;
private void examine1() {
synchronized (lockB) {
@@ -254,8 +222,9 @@
Utils.checkThreadState(itself, Thread.State.RUNNABLE);
checkStack(itself, examinerStack, methodExamine1);
- // wait until blockedThread is blocked on lockB
- blockedThread.waitUntilBlocked();
+ // #4 - wait until blockedThread is blocked on lockB
+ phaser.arriveAndAwaitAdvance();
+ Utils.waitForThreadState(blockedThread, State.BLOCKED);
System.out.println("Checking stack trace for " +
"BlockedThread - should be blocked on lockB.");
@@ -271,15 +240,12 @@
private void examine2() {
synchronized (lockA) {
- // wait until main thread gets signalled of the semaphore
- while (handshake.getWaiterCount() == 0) {
- Utils.goSleep(20);
- }
-
- handshake.semaV(); // notify the main thread
+ // #1 - examiner ready to do the real work
+ phaser.arriveAndAwaitAdvance();
try {
- // Wait until BlockedThread is about to block on lockA
- blockedThread.waitUntilBlocked();
+ // #2 - Wait until BlockedThread is about to block on lockA
+ phaser.arriveAndAwaitAdvance();
+ Utils.waitForThreadState(blockedThread, State.BLOCKED);
System.out.println("Checking examiner's its own stack trace");
Utils.checkThreadState(itself, Thread.State.RUNNABLE);
@@ -297,9 +263,10 @@
}
}
- // release lockA and let BlockedThread to get the lock
+ // #3 - release lockA and let BlockedThread to get the lock
// and wait on lockA
- blockedThread.waitUntilLockAReleased();
+ phaser.arriveAndAwaitAdvance();
+ Utils.waitForThreadState(blockedThread, State.WAITING);
synchronized (lockA) {
try {
@@ -321,6 +288,7 @@
Utils.goSleep(50);
} // examine2()
+ @Override
public void run() {
itself = Thread.currentThread();
examine1();
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java Fri May 01 03:56:04 2015 -0700
@@ -227,7 +227,8 @@
* <span>The default redirects of STDOUT and STDERR are started</span>
* <p>
* It is possible to wait for the process to get to a warmed-up state
- * via {@linkplain Predicate} condition on the STDOUT
+ * via {@linkplain Predicate} condition on the STDOUT. The warm-up will
+ * wait indefinitely.
* </p>
* @param name The process name
* @param processBuilder The process builder
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/PlatformMBeanProviderConstructorCheck.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.AccessControlException;
+import java.security.Permission;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.List;
+
+/*
+ * @test
+ * @bug 8042901
+ * @summary Check permission for PlatformMBeanProvider Constructor
+ * @author Shanliang Jiang
+ */
+public class PlatformMBeanProviderConstructorCheck {
+ public static void main(String[] args) throws Exception {
+ Policy origPolicy = Policy.getPolicy();
+ SecurityManager origSM = System.getSecurityManager();
+ try {
+ System.out.println("---PlatformMBeanProviderConstructorCheck starting...");
+
+ Policy.setPolicy(new MyPolicy());
+ System.setSecurityManager(new SecurityManager());
+
+ System.out.println("---PlatformMBeanProviderConstructorCheck Testing without permission...");
+ try {
+ new MyProvider();
+ throw new RuntimeException("Does not get expected AccessControlException!");
+ } catch (AccessControlException ace) {
+ System.out.println("---PlatformMBeanProviderConstructorCheck got the expected exception: "
+ + ace);
+ }
+
+ System.out.println("---PlatformMBeanProviderConstructorCheck Testing with permission...");
+ MyPolicy.allowed = true;
+ new MyProvider();
+
+ System.out.println("---PlatformMBeanProviderConstructorCheck PASSED!");
+ } finally {
+ System.setSecurityManager(origSM);
+ Policy.setPolicy(origPolicy);
+ }
+ }
+
+ private static class MyPolicy extends Policy {
+ private static String permName = "sun.management.spi.PlatformMBeanProvider.subclass";
+ private static boolean allowed = false;
+
+ @Override
+ public boolean implies(ProtectionDomain domain, Permission permission) {
+ if (permName.equals(permission.getName())) {
+ System.out.println("---MyPolicy-implies checks permission for "
+ +permName+" and returns "+allowed);
+
+ return allowed;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ private static class MyProvider extends sun.management.spi.PlatformMBeanProvider {
+ @Override
+ public List<PlatformComponent<?>> getPlatformComponentList() {
+ return null;
+ }
+ }
+}
--- a/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -120,9 +120,7 @@
return true;
}
return false;
- },
- 5,
- TimeUnit.SECONDS
+ }
);
System.out.println("Attaching test manager:");
@@ -142,9 +140,7 @@
clientPrc = ProcessTools.startProcess(
"TestManager",
client,
- (String line) -> line.startsWith("Starting TestManager for PID"),
- 10,
- TimeUnit.SECONDS
+ (String line) -> line.startsWith("Starting TestManager for PID")
);
int clientExitCode = clientPrc.waitFor();
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java Wed Jul 05 20:31:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-import java.io.IOException;
-import jdk.testlibrary.ProcessTools;
-
-public class JMXStartStopDoSomething {
- public static void doSomething() throws IOException{
- int r = System.in.read();
- System.out.println("read: " + r);
- }
-
- public static void main(String args[]) throws Exception {
- System.out.println("main enter");
- System.out.flush();
- doSomething();
- System.out.println("main exit");
- }
-}
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Fri May 01 03:56:04 2015 -0700
@@ -35,20 +35,16 @@
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
-import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
import javax.management.*;
import javax.management.remote.*;
import javax.net.ssl.SSLHandshakeException;
import jdk.testlibrary.ProcessTools;
-import jdk.testlibrary.JDKToolLauncher;
import sun.management.Agent;
import sun.management.AgentConfigurationError;
@@ -56,46 +52,20 @@
* @test
* @bug 7110104
* @library /lib/testlibrary
- * @build jdk.testlibrary.* JMXStartStopTest JMXStartStopDoSomething
+ * @build jdk.testlibrary.* JMXStartStopTest PortAllocator TestApp ManagementAgentJcmd
* @run main/othervm/timeout=600 -XX:+UsePerfData JMXStartStopTest
* @summary Makes sure that enabling/disabling the management agent through JCMD
* achieves the desired results
* @key randomness
*/
public class JMXStartStopTest {
+ private static final String TEST_APP_NAME = "TestApp";
private static final String TEST_SRC = System.getProperty("test.src");
private static final boolean verbose = false;
- /**
- * Dynamically allocates distinct ports from the ephemeral range 49152-65535
- */
- private static class PortAllocator {
-
- private final static int LOWER_BOUND = 49152;
- private final static int UPPER_BOUND = 65535;
-
- private final static Random RND = new Random(System.currentTimeMillis());
-
- private static int[] allocatePorts(final int numPorts) {
- int[] ports = new int[numPorts];
- for (int i = 0; i < numPorts; i++) {
- int port = -1;
- while (port == -1) {
- port = RND.nextInt(UPPER_BOUND - LOWER_BOUND + 1) + LOWER_BOUND;
- for (int j = 0; j < i; j++) {
- if (ports[j] == port) {
- port = -1;
- break;
- }
- }
- }
- ports[i] = port;
- }
- return ports;
- }
- }
+ private static ManagementAgentJcmd jcmd = new ManagementAgentJcmd(TEST_APP_NAME, verbose);
private static void dbg_print(String msg) {
if (verbose) {
@@ -318,14 +288,14 @@
}
}
- private static class Something {
+ private static class TestAppRun {
private Process p;
private final ProcessBuilder pb;
private final String name;
private final AtomicBoolean started = new AtomicBoolean(false);
private volatile long pid = -1;
- public Something(ProcessBuilder pb, String name) {
+ public TestAppRun(ProcessBuilder pb, String name) {
this.pb = pb;
this.name = name;
}
@@ -335,16 +305,14 @@
try {
AtomicBoolean error = new AtomicBoolean(false);
p = ProcessTools.startProcess(
- "JMXStartStopDoSomething{" + name + "}",
+ TEST_APP_NAME + "{" + name + "}",
pb,
(line) -> {
boolean ok = line.equals("main enter");
error.set(line.contains("BindException"));
return ok || error.get();
- },
- 5,
- TimeUnit.SECONDS
+ }
);
if (error.get()) {
throw new BindException("Starting process failed due to " +
@@ -352,8 +320,10 @@
}
pid = p.getPid();
} catch (TimeoutException e) {
- p.destroy();
- p.waitFor();
+ if (p != null) {
+ p.destroy();
+ p.waitFor();
+ }
throw e;
}
}
@@ -382,105 +352,32 @@
}
/**
- * Runs the test application "JMXStartStopDoSomething"
+ * Runs the test application "TestApp"
* @param name Test run name
* @param args Additional arguments
- * @return Returns a {@linkplain Something} instance representing the run
+ * @return Returns a {@linkplain TestAppRun} instance representing the run
* @throws IOException
* @throws InterruptedException
* @throws TimeoutException
*/
- private static Something doSomething(String name, String ... args)
+ private static TestAppRun doTest(String name, String ... args)
throws Exception {
List<String> pbArgs = new ArrayList<>(Arrays.asList(
"-cp",
- System.getProperty("test.class.path")
+ System.getProperty("test.class.path"),
+ "-XX:+UsePerfData"
));
pbArgs.addAll(Arrays.asList(args));
- pbArgs.add("JMXStartStopDoSomething");
+ pbArgs.add(TEST_APP_NAME);
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
pbArgs.toArray(new String[pbArgs.size()])
);
- Something s = new Something(pb, name);
+ TestAppRun s = new TestAppRun(pb, name);
s.start();
return s;
}
- /**
- * Run the "jcmd" command
- *
- * @param command Command with parameters; space separated string
- * @throws IOException
- * @throws InterruptedException
- */
- private static void jcmd(String ... command) throws IOException, InterruptedException {
- if (command.length == 0) {
- jcmd(null, c->{});
- } else {
- jcmd(null, command);
- }
- }
-
- /**
- * Run the "jcmd" command
- *
- * @param c {@linkplain Consumer} instance
- * @param command Command with parameters; space separated string
- * @throws IOException
- * @throws InterruptedException
- */
- private static void jcmd(Consumer<String> c, String ... command) throws IOException, InterruptedException {
- jcmd("JMXStartStopDoSomething", c, command);
- }
-
- /**
- * Run the "jcmd" command
- *
- * @param target The target application name (or PID)
- * @param c {@linkplain Consumer} instance
- * @param command Command with parameters; space separated string
- * @throws IOException
- * @throws InterruptedException
- */
- private static void jcmd(String target, final Consumer<String> c, String ... command) throws IOException, InterruptedException {
- dbg_print("[jcmd] " + (command.length > 0 ? command[0] : "list"));
-
- JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jcmd");
- l.addToolArg(target);
- for (String cmd : command) {
- l.addToolArg(cmd);
- }
-
- AtomicBoolean portUnavailable = new AtomicBoolean(false);
- Process p = ProcessTools.startProcess(
- "jcmd",
- new ProcessBuilder(l.getCommand()),
- line -> {
- if (line.contains("BindException") ||
- line.contains(Agent.getText(AgentConfigurationError.CONNECTOR_SERVER_IO_ERROR))) {
- portUnavailable.set(true);
- } else {
- c.accept(line);
- }
- }
- );
-
- p.waitFor();
- dbg_print("[jcmd] --------");
- if (portUnavailable.get()) {
- String cmd = Arrays.asList(l.getCommand()).stream()
- .collect(
- Collectors.joining(" ", "", ": Unable to bind address")
- );
- throw new BindException(cmd);
- }
- }
-
- private static final String CMD_STOP = "ManagementAgent.stop";
- private static final String CMD_START = "ManagementAgent.start";
- private static final String CMD_START_LOCAL = "ManagementAgent.start_local";
-
static void test_01() throws Exception {
// Run an app with JMX enabled stop it and
// restart on other port
@@ -488,7 +385,7 @@
System.out.println("**** Test one ****");
int ports[] = PortAllocator.allocatePorts(2);
- Something s = doSomething(
+ TestAppRun s = doTest(
"test_01",
"-Dcom.sun.management.jmxremote.port=" + ports[0],
"-Dcom.sun.management.jmxremote.authenticate=false",
@@ -497,10 +394,10 @@
try {
testConnect(ports[0]);
- jcmd(CMD_STOP);
+ jcmd.stop();
testNoConnect(ports[0]);
- jcmd(CMD_START, "jmxremote.port=" + ports[1]);
+ jcmd.start("jmxremote.port=" + ports[1]);
testConnect(ports[1]);
} finally {
s.stop();
@@ -514,12 +411,13 @@
System.out.println("**** Test two ****");
int[] ports = PortAllocator.allocatePorts(1);
- Something s = doSomething("test_02");
+ TestAppRun s = doTest("test_02");
try {
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
testConnect(ports[0]);
} finally {
@@ -535,18 +433,20 @@
System.out.println("**** Test three ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething("test_03");
+ TestAppRun s = doTest("test_03");
try {
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
// Second agent shouldn't start
- jcmd(CMD_START,
- "jmxremote.port=" + ports[1],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
// First agent should connect
testConnect(ports[0]);
@@ -565,13 +465,14 @@
System.out.println("**** Test four ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething("test_04");
+ TestAppRun s = doTest("test_04");
try {
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.rmi.port=" + ports[1],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.rmi.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
testConnect(ports[0], ports[1]);
} finally {
@@ -585,9 +486,9 @@
System.out.println("**** Test five ****");
int[] ports = PortAllocator.allocatePorts(1);
- Something s = doSomething("test_05");
+ TestAppRun s = doTest("test_05");
try {
- jcmd(CMD_START_LOCAL);
+ jcmd.startLocal();
testNoConnect(ports[0]);
testConnectLocal(s.getPid());
@@ -605,26 +506,27 @@
System.out.println("**** Test six ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething("test_06");
+ TestAppRun s = doTest("test_06");
try {
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
testConnect(ports[0], ports[1]);
final AtomicBoolean checks = new AtomicBoolean(false);
- jcmd(
- line -> {
- if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
- checks.set(true);
- }
- },
- CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ line -> {
+ if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
+ checks.set(true);
+ }
+ },
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
if (!checks.get()) {
throw new Exception("Starting agent on port " + ports[0] + " should "
@@ -644,27 +546,28 @@
System.out.println("**** Test seven ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething("test_07");
+ TestAppRun s = doTest("test_07");
try {
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
testConnect(ports[0], ports[1]);
final AtomicBoolean checks = new AtomicBoolean(false);
- jcmd(
- line -> {
- if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
- checks.set(true);
- }
- },
- CMD_START,
- "jmxremote.port=" + ports[1],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ line -> {
+ if (line.contains("java.lang.RuntimeException: Invalid agent state")) {
+ checks.set(true);
+ }
+ },
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
if (!checks.get()) {
throw new Exception("Starting agent on poprt " + ports[1] + " should "
@@ -684,17 +587,18 @@
System.out.println("**** Test eight ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething("test_08");
+ TestAppRun s = doTest("test_08");
try {
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false");
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
testConnect(ports[0], ports[1]);
- jcmd(CMD_STOP);
- jcmd(CMD_STOP);
+ jcmd.stop();
+ jcmd.stop();
} finally {
s.stop();
}
@@ -707,7 +611,7 @@
System.out.println("**** Test nine ****");
- Something s = doSomething("test_09");
+ TestAppRun s = doTest("test_09");
try (ServerSocket ss = new ServerSocket(0)) {
int localPort = ss.getLocalPort();
@@ -723,13 +627,12 @@
final AtomicBoolean retry = new AtomicBoolean(false);
try {
- jcmd(
+ jcmd.start(
line -> {
if (line.contains(Agent.getText(AgentConfigurationError.AGENT_EXCEPTION))) {
retry.set(true);
}
},
- CMD_START,
"jmxremote.port=" + ports[0],
"jmxremote.rmi.port=" + localPort,
"jmxremote.authenticate=false",
@@ -764,18 +667,17 @@
System.out.println("**** Test ten ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething(
+ TestAppRun s = doTest(
"test_10",
"-Dcom.sun.management.jmxremote.authenticate=false",
"-Dcom.sun.management.jmxremote.ssl=true");
try {
testNoConnect(ports[0]);
- jcmd(
- CMD_START,
- "jmxremote.port=" + ports[1],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false"
+ jcmd.start(
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
);
testConnect(ports[1]);
} finally {
@@ -791,7 +693,7 @@
System.out.println("**** Test eleven ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething(
+ TestAppRun s = doTest(
"test_11",
"-Dcom.sun.management.jmxremote.port=" + ports[0],
"-Dcom.sun.management.jmxremote.authenticate=false",
@@ -800,15 +702,14 @@
try {
testNoConnect(ports[0]);
- jcmd(CMD_STOP);
+ jcmd.stop();
testNoConnect(ports[0]);
- jcmd(
- CMD_START,
- "jmxremote.port=" + ports[1],
- "jmxremote.authenticate=false",
- "jmxremote.ssl=false"
+ jcmd.start(
+ "jmxremote.port=" + ports[1],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
);
testConnect(ports[1]);
@@ -828,7 +729,7 @@
System.out.println("**** Test twelve ****");
int[] ports = PortAllocator.allocatePorts(2);
- Something s = doSomething("test_12",
+ TestAppRun s = doTest("test_12",
"-Dcom.sun.management.config.file="
+ TEST_SRC + File.separator + "management_cl.properties",
"-Dcom.sun.management.jmxremote.authenticate=false"
@@ -837,15 +738,15 @@
try {
testNoConnect(ports[0]);
- jcmd(CMD_STOP);
+ jcmd.stop();
testNoConnect(ports[0]);
- jcmd(CMD_START,
- "config.file=" + TEST_SRC + File.separator
- + "management_jcmd.properties",
- "jmxremote.authenticate=false",
- "jmxremote.port=" + ports[1]
+ jcmd.start(
+ "config.file=" + TEST_SRC + File.separator
+ + "management_jcmd.properties",
+ "jmxremote.authenticate=false",
+ "jmxremote.port=" + ports[1]
);
testConnect(ports[1]);
@@ -863,7 +764,7 @@
System.out.println("**** Test thirteen ****");
int[] ports = PortAllocator.allocatePorts(1);
- Something s = doSomething(
+ TestAppRun s = doTest(
"test_13",
"-Dcom.sun.management.jmxremote.port=" + ports[0],
"-Dcom.sun.management.jmxremote.authenticate=false",
@@ -872,16 +773,16 @@
try {
testNoConnect(ports[0]);
- jcmd(CMD_STOP);
- jcmd(CMD_START,
- "jmxremote.ssl=false",
- "jmxremote.port=" + ports[0]
+ jcmd.stop();
+ jcmd.start(
+ "jmxremote.ssl=false",
+ "jmxremote.port=" + ports[0]
);
testConnect(ports[0]);
- jcmd(CMD_STOP);
- jcmd(CMD_START,
- "jmxremote.port=" + ports[0]
+ jcmd.stop();
+ jcmd.start(
+ "jmxremote.port=" + ports[0]
);
testNoConnect(ports[0]);
@@ -897,14 +798,14 @@
System.out.println("**** Test fourteen ****");
int[] ports = PortAllocator.allocatePorts(1);
- Something s = doSomething(
+ TestAppRun s = doTest(
"test_14",
"-Dcom.sun.management.jmxremote.port=" + ports[0],
"-Dcom.sun.management.jmxremote.authenticate=false",
"-Dcom.sun.management.jmxremote.ssl=false");
try {
testConnect(ports[0]);
- jcmd(CMD_STOP);
+ jcmd.stop();
testConnectLocal(s.getPid());
} finally {
s.stop();
@@ -918,11 +819,11 @@
System.out.println("**** Test fifteen ****");
int[] ports = PortAllocator.allocatePorts(1);
- Something s = doSomething("test_15");
+ TestAppRun s = doTest("test_15");
try {
testNoConnect(ports[0]);
- jcmd(CMD_START + "_local");
+ jcmd.startLocal();
testConnectLocal(s.getPid());
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStatusTest.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.BindException;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+import jdk.testlibrary.ProcessTools;
+
+/**
+ * @test
+ * @bug 8023093
+ * @summary Performs a sanity test for the ManagementAgent.status diagnostic command.
+ * Management agent may be disable, started (only local connections) and started.
+ * The test asserts that the expected text is being printed.
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.* PortAllocator TestApp ManagementAgentJcmd
+ * @run testng/othervm -XX:+UsePerfData JMXStatusTest
+ */
+public class JMXStatusTest {
+ private final static String TEST_APP_NAME = "TestApp";
+
+ private final static Pattern DISABLE_AGENT_STATUS = Pattern.compile(
+ "Agent\\s*\\: disabled$"
+ );
+
+ private final static Pattern LOCAL_AGENT_STATUS = Pattern.compile(
+ "Agent\\s*\\:\\s*enabled\\n+" +
+ "Connection Type\\s*\\:\\s*local\\n+" +
+ "Protocol\\s*\\:\\s*[a-z]+\\n+" +
+ "Host\\s*\\:\\s*.+\\n+" +
+ "URL\\s*\\:\\s*service\\:jmx\\:.+",
+ Pattern.MULTILINE
+ );
+
+ private final static Pattern REMOTE_AGENT_STATUS = Pattern.compile(
+ "Agent\\s*\\: enabled\\n+" +
+ "Connection Type\\s*\\: remote\\n+" +
+ "Protocol\\s*\\: [a-z]+\\n+" +
+ "Host\\s*\\: .+\\n+" +
+ "URL\\s*\\: service\\:jmx\\:.+\\n+" +
+ "Properties\\s*\\:\\n+(\\s*\\S+\\s*=\\s*\\S+\\n*)+",
+ Pattern.MULTILINE
+ );
+
+ private static ProcessBuilder testAppPb;
+ private Process testApp;
+
+ private ManagementAgentJcmd jcmd;
+
+ @BeforeClass
+ public static void setupClass() throws Exception {
+ testAppPb = ProcessTools.createJavaProcessBuilder(
+ "-cp", System.getProperty("test.class.path"),
+ "-XX:+UsePerfData",
+ TEST_APP_NAME
+ );
+ }
+
+ @BeforeTest
+ public void setup() {
+ jcmd = new ManagementAgentJcmd(TEST_APP_NAME, false);
+ }
+
+ @BeforeMethod
+ public void startTestApp() throws Exception {
+ testApp = ProcessTools.startProcess(
+ TEST_APP_NAME, testAppPb,
+ (Predicate<String>)l->l.trim().equals("main enter")
+ );
+ }
+
+ @AfterMethod
+ public void stopTestApp() throws Exception {
+ testApp.getOutputStream().write(1);
+ testApp.getOutputStream().flush();
+ testApp.waitFor();
+ testApp = null;
+ }
+
+ @Test
+ public void testAgentDisabled() throws Exception {
+ String status = jcmd.status();
+ assertStatusMatches(DISABLE_AGENT_STATUS, status);
+ }
+
+ @Test
+ public void testAgentLocal() throws Exception {
+ jcmd.startLocal();
+ String status = jcmd.status();
+
+ assertStatusMatches(LOCAL_AGENT_STATUS, status);
+ }
+
+ @Test
+ public void testAgentRemote() throws Exception {
+ while (true) {
+ try {
+ int[] ports = PortAllocator.allocatePorts(1);
+ jcmd.start(
+ "jmxremote.port=" + ports[0],
+ "jmxremote.authenticate=false",
+ "jmxremote.ssl=false"
+ );
+ String status = jcmd.status();
+
+ assertStatusMatches(REMOTE_AGENT_STATUS, status);
+ return;
+ } catch (BindException e) {
+ System.out.println("Failed to allocate ports. Retrying ...");
+ }
+ }
+ }
+
+ private void assertStatusMatches(Pattern expected, String value) {
+ assertStatusMatches(expected, value, "");
+ }
+
+ private void assertStatusMatches(Pattern expected, String value, String msg) {
+ int idx = value.indexOf('\n');
+ if (idx > -1) {
+ value = value.substring(idx + 1).trim();
+ assertTrue(expected.matcher(value).find(), msg);
+ } else {
+ fail("The management agent status must contain more then one line of text");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/ManagementAgentJcmd.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.io.IOException;
+import java.net.BindException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import sun.management.Agent;
+import sun.management.AgentConfigurationError;
+
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.ProcessTools;
+
+/**
+ * A helper class for issuing ManagementAgent.* diagnostic commands and capturing
+ * their output.
+ */
+final class ManagementAgentJcmd {
+ private static final String CMD_STOP = "ManagementAgent.stop";
+ private static final String CMD_START = "ManagementAgent.start";
+ private static final String CMD_START_LOCAL = "ManagementAgent.start_local";
+ private static final String CMD_STATUS = "ManagementAgent.status";
+
+ private final String id;
+ private final boolean verbose;
+
+ public ManagementAgentJcmd(String targetApp, boolean verbose) {
+ this.id = targetApp;
+ this.verbose = verbose;
+ }
+
+ /**
+ * `jcmd`
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public String list() throws IOException, InterruptedException {
+ return jcmd();
+ }
+
+ /**
+ * `jcmd <app> ManagementAgent.stop`
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public String stop() throws IOException, InterruptedException {
+ return jcmd(CMD_STOP);
+ }
+
+ /**
+ * `jcmd <app> ManagementAgent.start_local`
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public String startLocal() throws IOException, InterruptedException {
+ return jcmd(CMD_START_LOCAL);
+ }
+
+ /**
+ * `jcmd <app> ManagementAgent.start <args>`
+ * @return The JCMD output
+ * @param params The arguments to <b>ManagementAgent.start</b> command
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public String start(String ... params) throws IOException, InterruptedException {
+ return start(c->{}, params);
+ }
+
+ /**
+ * `jcmd <pp> ManagementAgent.start <args>`
+ * @param c A string consumer used to inspect the jcmd output line-by-line
+ * @param params The arguments to <b>ManagementAgent.start</b> command
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ public String start(Consumer<String> c, String ... params) throws IOException, InterruptedException {
+ List<String> args = new ArrayList<>();
+ args.add(CMD_START);
+ args.addAll(Arrays.asList(params));
+ return jcmd(c, args.toArray(new String[args.size()]));
+ }
+
+ public String status() throws IOException, InterruptedException {
+ return jcmd(CMD_STATUS);
+ }
+
+ /**
+ * Run the "jcmd" command
+ *
+ * @param command Command + arguments
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private String jcmd(String ... command) throws IOException, InterruptedException {
+ if (command.length == 0) {
+ return jcmd(null, c->{});
+ } else {
+ return jcmd(c->{}, command);
+ }
+ }
+
+ /**
+ * Run the "jcmd" command
+ *
+ * @param c {@linkplain Consumer} instance
+ * @param command Command + arguments
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private String jcmd(Consumer<String> c, String ... command) throws IOException, InterruptedException {
+ return jcmd(id, c, command);
+ }
+
+ /**
+ * Run the "jcmd" command
+ *
+ * @param target The target application name (or PID)
+ * @param c {@linkplain Consumer} instance
+ * @param command Command + arguments
+ * @return The JCMD output
+ * @throws IOException
+ * @throws InterruptedException
+ */
+ private String jcmd(String target, final Consumer<String> c, String ... command) throws IOException, InterruptedException {
+ dbg_print("[jcmd] " + (command.length > 0 ? command[0] : "list"));
+
+ JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jcmd");
+ l.addToolArg(target);
+ for (String cmd : command) {
+ l.addToolArg(cmd);
+ }
+
+ StringBuilder output = new StringBuilder();
+
+ AtomicBoolean portUnavailable = new AtomicBoolean(false);
+ Process p = ProcessTools.startProcess(
+ "jcmd",
+ new ProcessBuilder(l.getCommand()),
+ line -> {
+ if (line.contains("BindException") ||
+ line.contains(Agent.getText(AgentConfigurationError.CONNECTOR_SERVER_IO_ERROR))) {
+ portUnavailable.set(true);
+ } else {
+ output.append(line).append('\n');
+ c.accept(line);
+ }
+ }
+ );
+
+ p.waitFor();
+ dbg_print("[jcmd] --------");
+ if (portUnavailable.get()) {
+ String cmd = Arrays.asList(l.getCommand()).stream()
+ .collect(
+ Collectors.joining(" ", "", ": Unable to bind address")
+ );
+ throw new BindException(cmd);
+ }
+
+ return output.toString();
+ }
+
+ private void dbg_print(String msg) {
+ if (verbose) {
+ System.out.println("DBG: " + msg);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/PortAllocator.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.util.Random;
+
+/**
+ * Dynamically allocates distinct ports from the ephemeral range 49152-65535
+ */
+class PortAllocator {
+ private final static int LOWER_BOUND = 49152;
+ private final static int UPPER_BOUND = 65535;
+
+ private final static Random RND = new Random(System.currentTimeMillis());
+
+ static int[] allocatePorts(final int numPorts) {
+ int[] ports = new int[numPorts];
+ for (int i = 0; i < numPorts; i++) {
+ int port = -1;
+ while (port == -1) {
+ port = RND.nextInt(UPPER_BOUND - LOWER_BOUND + 1) + LOWER_BOUND;
+ for (int j = 0; j < i; j++) {
+ if (ports[j] == port) {
+ port = -1;
+ break;
+ }
+ }
+ }
+ ports[i] = port;
+ }
+ return ports;
+ }
+}
--- a/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt Fri May 01 03:56:04 2015 -0700
@@ -4,7 +4,7 @@
on host 1
4. run
- ${TESTJAVA}/bin/java -server JMXStartStopDoSomething \
+ ${TESTJAVA}/bin/java -server TestApp \
-Dcom.sun.management.jmxremote.port=50234 \
-Dcom.sun.management.jmxremote.rmi.port=50235 \
-Dcom.sun.management.jmxremote.authenticate=false \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/TestApp.java Fri May 01 03:56:04 2015 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+
+public class TestApp {
+ public static void doSomething() throws IOException{
+ int r = System.in.read();
+ System.out.println("read: " + r);
+ }
+
+ public static void main(String args[]) throws Exception {
+ System.out.println("main enter");
+ System.out.flush();
+ doSomething();
+ System.out.println("main exit");
+ }
+}
--- a/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,8 @@
* questions.
*/
-import sun.management.ManagementFactoryHelper;
-
+import java.lang.management.ManagementFactory;
import com.sun.management.HotSpotDiagnosticMXBean;
-
import jdk.testlibrary.OutputAnalyzer;
import static jdk.testlibrary.Platform.isSolaris;
import static jdk.testlibrary.Asserts.assertEquals;
@@ -114,13 +112,15 @@
}
private static void verifyIsEnabled(String flag) {
- HotSpotDiagnosticMXBean hotspotDiagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+ HotSpotDiagnosticMXBean hotspotDiagnostic =
+ ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
String flagValue = hotspotDiagnostic.getVMOption(flag).getValue();
assertEquals(flagValue, "true", "Expected '" + flag + "' flag be enabled");
}
private static void verifyIsDisabled(String flag) {
- HotSpotDiagnosticMXBean hotspotDiagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+ HotSpotDiagnosticMXBean hotspotDiagnostic =
+ ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
String flagValue = hotspotDiagnostic.getVMOption(flag).getValue();
assertEquals(flagValue, "false", "Expected '" + flag + "' flag be disabled");
}
--- a/jdk/test/sun/tools/jps/JpsHelper.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/tools/jps/JpsHelper.java Fri May 01 03:56:04 2015 -0700
@@ -151,6 +151,7 @@
*/
public static OutputAnalyzer jps(List<String> vmArgs, List<String> toolArgs) throws Exception {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
+ launcher.addVMArg("-XX:+UsePerfData");
if (vmArgs != null) {
for (String vmArg : vmArgs) {
launcher.addVMArg(vmArg);
--- a/jdk/test/sun/tools/jstatd/JstatdTest.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/tools/jstatd/JstatdTest.java Fri May 01 03:56:04 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
*/
import java.io.File;
-import java.io.IOException;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
@@ -130,38 +129,18 @@
private OutputAnalyzer runJps() throws Exception {
JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
launcher.addVMArg("-XX:+UsePerfData");
- // Run jps with -v flag to obtain -Dparent.pid.<pid>
- launcher.addToolArg("-v");
launcher.addToolArg(getDestination());
String[] cmd = launcher.getCommand();
log("Start jps", cmd);
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
- OutputAnalyzer output = waitForJstatdRMI(processBuilder);
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
System.out.println(output.getOutput());
return output;
}
- private OutputAnalyzer waitForJstatdRMI(ProcessBuilder pb) throws Exception {
- OutputAnalyzer output = ProcessTools.executeProcess(pb);
-
- String remoteHost = (serverName != null) ? serverName : "JStatRemoteHost";
- while (output.getExitValue() != 0) {
- String out = output.getOutput();
-
- if (out.contains("RMI Registry not available") ||
- out.contains("RMI Server " + remoteHost + " not available")) {
- Thread.sleep(100);
- output = ProcessTools.executeProcess(pb);
- } else {
- output.shouldHaveExitValue(0);
- }
- }
- return output;
- }
-
/**
* Verifies output form jps contains pids and programs' name information.
* The function will discard any lines that come before the first line with pid.
@@ -211,7 +190,7 @@
log("Start jstat", cmd);
ProcessBuilder processBuilder = new ProcessBuilder(cmd);
- OutputAnalyzer output = waitForJstatdRMI(processBuilder);
+ OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
System.out.println(output.getOutput());
return output;
@@ -277,8 +256,6 @@
assertTrue(policy.exists() && policy.isFile(),
"Security policy " + policy.getAbsolutePath() + " does not exist or not a file");
launcher.addVMArg("-Djava.security.policy=" + policy.getAbsolutePath());
- // -Dparent.pid.<pid> will help to identify jstad process started by this test
- launcher.addVMArg("-Dparent.pid." + ProcessTools.getProcessId());
if (port != null) {
launcher.addToolArg("-p");
launcher.addToolArg(port);
@@ -287,6 +264,9 @@
launcher.addToolArg("-n");
launcher.addToolArg(serverName);
}
+ if (withExternalRegistry) {
+ launcher.addToolArg("-nr");
+ }
String[] cmd = launcher.getCommand();
log("Start jstatd", cmd);
@@ -295,7 +275,7 @@
private ProcessThread tryToSetupJstatdProcess() throws Throwable {
ProcessThread jstatdThread = new ProcessThread("Jstatd-Thread",
- getJstatdCmd());
+ JstatdTest::isJstadReady, getJstatdCmd());
try {
jstatdThread.start();
// Make sure jstatd is up and running
@@ -315,18 +295,26 @@
return jstatdThread;
}
+ private static boolean isJstadReady(String line) {
+ return line.startsWith("jstatd started (bound to ");
+ }
+
public void doTest() throws Throwable {
+ if (useDefaultPort) {
+ verifyNoRmiRegistryOnDefaultPort();
+ }
+
ProcessThread jstatdThread = null;
try {
while (jstatdThread == null) {
- if (!useDefaultPort || withExternalRegistry) {
+ if (!useDefaultPort) {
port = String.valueOf(Utils.getFreePort());
}
if (withExternalRegistry) {
Registry registry = startRegistry();
if (registry == null) {
- // The port is already in use. Cancel and try with new one.
+ // The port is already in use. Cancel and try with a new one.
continue;
}
}
@@ -348,4 +336,14 @@
"jstatd process exited with unexpected exit code");
}
+ private void verifyNoRmiRegistryOnDefaultPort() throws Exception {
+ try {
+ Registry registry = LocateRegistry.getRegistry();
+ registry.list();
+ throw new Exception("There is already RMI registry on the default port: " + registry);
+ } catch (RemoteException e) {
+ // No RMI registry on default port is detected
+ }
+ }
+
}
--- a/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java Wed Jul 05 20:31:05 2017 +0200
+++ b/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java Fri May 01 03:56:04 2015 -0700
@@ -32,6 +32,7 @@
public static void main(String[] args) throws Throwable {
JstatdTest test = new JstatdTest();
+ test.setUseDefaultPort(false);
test.setWithExternalRegistry(true);
test.doTest();
}