# HG changeset patch
# User jiangli
# Date 1368131271 14400
# Node ID d3c98423c146625cd1b11e9190ac9eba3928e85e
# Parent 7243490a684726330004cacb1e76dbd269327411# Parent a258a8351528e83e9788a15e6587551e5e2f1a03
Merge
diff -r a258a8351528 -r d3c98423c146 agent/src/os/bsd/ps_core.c
--- a/agent/src/os/bsd/ps_core.c Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/os/bsd/ps_core.c Thu May 09 16:27:51 2013 -0400
@@ -199,10 +199,10 @@
//---------------------------------------------------------------
// Part of the class sharing workaround:
//
-// With class sharing, pages are mapped from classes[_g].jsa file.
+// With class sharing, pages are mapped from classes.jsa file.
// The read-only class sharing pages are mapped as MAP_SHARED,
// PROT_READ pages. These pages are not dumped into core dump.
-// With this workaround, these pages are read from classes[_g].jsa.
+// With this workaround, these pages are read from classes.jsa.
// FIXME: !HACK ALERT!
// The format of sharing achive file header is needed to read shared heap
@@ -298,14 +298,12 @@
lib_info* lib = ph->libs;
while (lib != NULL) {
// we are iterating over shared objects from the core dump. look for
- // libjvm[_g].so.
+ // libjvm.so.
const char *jvm_name = 0;
#ifdef __APPLE__
- if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0 ||
- (jvm_name = strstr(lib->name, "/libjvm_g.dylib")) != 0)
+ if ((jvm_name = strstr(lib->name, "/libjvm.dylib")) != 0)
#else
- if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
- (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0)
+ if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0)
#endif // __APPLE__
{
char classes_jsa[PATH_MAX];
@@ -389,7 +387,7 @@
}
ph->core->classes_jsa_fd = fd;
- // add read-only maps from classes[_g].jsa to the list of maps
+ // add read-only maps from classes.jsa to the list of maps
for (m = 0; m < NUM_SHARED_MAPS; m++) {
if (header._space[m]._read_only) {
base = (uintptr_t) header._space[m]._base;
diff -r a258a8351528 -r d3c98423c146 agent/src/os/linux/ps_core.c
--- a/agent/src/os/linux/ps_core.c Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/os/linux/ps_core.c Thu May 09 16:27:51 2013 -0400
@@ -195,10 +195,10 @@
//---------------------------------------------------------------
// Part of the class sharing workaround:
//
-// With class sharing, pages are mapped from classes[_g].jsa file.
+// With class sharing, pages are mapped from classes.jsa file.
// The read-only class sharing pages are mapped as MAP_SHARED,
// PROT_READ pages. These pages are not dumped into core dump.
-// With this workaround, these pages are read from classes[_g].jsa.
+// With this workaround, these pages are read from classes.jsa.
// FIXME: !HACK ALERT!
// The format of sharing achive file header is needed to read shared heap
@@ -284,10 +284,9 @@
lib_info* lib = ph->libs;
while (lib != NULL) {
// we are iterating over shared objects from the core dump. look for
- // libjvm[_g].so.
+ // libjvm.so.
const char *jvm_name = 0;
- if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0 ||
- (jvm_name = strstr(lib->name, "/libjvm_g.so")) != 0) {
+ if ((jvm_name = strstr(lib->name, "/libjvm.so")) != 0) {
char classes_jsa[PATH_MAX];
struct FileMapHeader header;
size_t n = 0;
@@ -371,7 +370,7 @@
}
ph->core->classes_jsa_fd = fd;
- // add read-only maps from classes[_g].jsa to the list of maps
+ // add read-only maps from classes.jsa to the list of maps
for (m = 0; m < NUM_SHARED_MAPS; m++) {
if (header._space[m]._read_only) {
base = (uintptr_t) header._space[m]._base;
diff -r a258a8351528 -r d3c98423c146 agent/src/os/solaris/proc/saproc.cpp
--- a/agent/src/os/solaris/proc/saproc.cpp Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/os/solaris/proc/saproc.cpp Thu May 09 16:27:51 2013 -0400
@@ -589,8 +589,7 @@
JNIEnv* env = dbg->env;
jobject this_obj = dbg->this_obj;
const char* jvm_name = 0;
- if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL ||
- (jvm_name = strstr(obj_name, "libjvm_g.so")) != NULL) {
+ if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL) {
jvm_name = obj_name;
} else {
return 0;
@@ -598,7 +597,7 @@
struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);
- // initialize classes[_g].jsa file descriptor field.
+ // initialize classes.jsa file descriptor field.
dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, -1);
// check whether class sharing is on by reading variable "UseSharedSpaces"
@@ -641,7 +640,7 @@
print_debug("looking for %s\n", classes_jsa);
- // open the classes[_g].jsa
+ // open the classes.jsa
int fd = libsaproc_open(classes_jsa, O_RDONLY);
if (fd < 0) {
char errMsg[ERR_MSG_SIZE];
@@ -651,7 +650,7 @@
print_debug("opened shared archive file %s\n", classes_jsa);
}
- // parse classes[_g].jsa
+ // parse classes.jsa
struct FileMapHeader* pheader = (struct FileMapHeader*) malloc(sizeof(struct FileMapHeader));
if (pheader == NULL) {
close(fd);
@@ -798,8 +797,8 @@
if (! isProcess) {
/*
* With class sharing, shared perm. gen heap is allocated in with MAP_SHARED|PROT_READ.
- * These pages are mapped from the file "classes[_g].jsa". MAP_SHARED pages are not dumped
- * in Solaris core.To read shared heap pages, we have to read classes[_g].jsa file.
+ * These pages are mapped from the file "classes.jsa". MAP_SHARED pages are not dumped
+ * in Solaris core.To read shared heap pages, we have to read classes.jsa file.
*/
Pobject_iter(ph, init_classsharing_workaround, &dbg);
exception = env->ExceptionOccurred();
diff -r a258a8351528 -r d3c98423c146 agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
--- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Thu May 09 16:27:51 2013 -0400
@@ -24,20 +24,29 @@
package sun.jvm.hotspot;
-import java.io.PrintStream;
-import java.net.*;
-import java.rmi.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.bsd.*;
-import sun.jvm.hotspot.debugger.proc.*;
-import sun.jvm.hotspot.debugger.remote.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-import sun.jvm.hotspot.debugger.linux.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
+import java.rmi.RemoteException;
+
+import sun.jvm.hotspot.debugger.Debugger;
+import sun.jvm.hotspot.debugger.DebuggerException;
+import sun.jvm.hotspot.debugger.JVMDebugger;
+import sun.jvm.hotspot.debugger.MachineDescription;
+import sun.jvm.hotspot.debugger.MachineDescriptionAMD64;
+import sun.jvm.hotspot.debugger.MachineDescriptionIA64;
+import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86;
+import sun.jvm.hotspot.debugger.MachineDescriptionSPARC32Bit;
+import sun.jvm.hotspot.debugger.MachineDescriptionSPARC64Bit;
+import sun.jvm.hotspot.debugger.NoSuchSymbolException;
+import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal;
+import sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal;
+import sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal;
+import sun.jvm.hotspot.debugger.remote.RemoteDebugger;
+import sun.jvm.hotspot.debugger.remote.RemoteDebuggerClient;
+import sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer;
+import sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.types.TypeDataBase;
+import sun.jvm.hotspot.utilities.PlatformInfo;
+import sun.jvm.hotspot.utilities.UnsupportedPlatformException;
/**
This class wraps much of the basic functionality and is the
* highest-level factory for VM data structures. It makes it simple
@@ -475,7 +484,7 @@
}
private void setupJVMLibNamesSolaris() {
- jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so", "gamma_g" };
+ jvmLibNames = new String[] { "libjvm.so" };
}
//
@@ -507,7 +516,7 @@
}
private void setupJVMLibNamesWin32() {
- jvmLibNames = new String[] { "jvm.dll", "jvm_g.dll" };
+ jvmLibNames = new String[] { "jvm.dll" };
}
//
@@ -547,7 +556,7 @@
}
private void setupJVMLibNamesLinux() {
- jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" };
+ jvmLibNames = new String[] { "libjvm.so" };
}
//
@@ -572,7 +581,7 @@
}
private void setupJVMLibNamesBsd() {
- jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" };
+ jvmLibNames = new String[] { "libjvm.so" };
}
//
@@ -595,7 +604,7 @@
}
private void setupJVMLibNamesDarwin() {
- jvmLibNames = new String[] { "libjvm.dylib", "libjvm_g.dylib" };
+ jvmLibNames = new String[] { "libjvm.dylib" };
}
/** Convenience routine which should be called by per-platform
diff -r a258a8351528 -r d3c98423c146 agent/src/share/classes/sun/jvm/hotspot/LinuxVtblAccess.java
--- a/agent/src/share/classes/sun/jvm/hotspot/LinuxVtblAccess.java Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/LinuxVtblAccess.java Thu May 09 16:27:51 2013 -0400
@@ -24,9 +24,9 @@
package sun.jvm.hotspot;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.types.basic.*;
+import sun.jvm.hotspot.debugger.SymbolLookup;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.basic.BasicVtblAccess;
public class LinuxVtblAccess extends BasicVtblAccess {
private String vt;
@@ -35,8 +35,7 @@
String[] dllNames) {
super(symbolLookup, dllNames);
- if (symbolLookup.lookup("libjvm.so", "__vt_10JavaThread") != null ||
- symbolLookup.lookup("libjvm_g.so", "__vt_10JavaThread") != null) {
+ if (symbolLookup.lookup("libjvm.so", "__vt_10JavaThread") != null) {
// old C++ ABI
vt = "__vt_";
} else {
diff -r a258a8351528 -r d3c98423c146 agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/bsd/BsdDebuggerLocal.java Thu May 09 16:27:51 2013 -0400
@@ -24,17 +24,28 @@
package sun.jvm.hotspot.debugger.bsd;
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.utilities.*;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.DebuggerBase;
+import sun.jvm.hotspot.debugger.DebuggerException;
+import sun.jvm.hotspot.debugger.DebuggerUtilities;
+import sun.jvm.hotspot.debugger.MachineDescription;
+import sun.jvm.hotspot.debugger.NotInHeapException;
+import sun.jvm.hotspot.debugger.OopHandle;
+import sun.jvm.hotspot.debugger.ReadResult;
+import sun.jvm.hotspot.debugger.ThreadProxy;
+import sun.jvm.hotspot.debugger.UnalignedAddressException;
+import sun.jvm.hotspot.debugger.UnmappedAddressException;
+import sun.jvm.hotspot.debugger.cdbg.CDebugger;
+import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;
+import sun.jvm.hotspot.debugger.cdbg.LoadObject;
+import sun.jvm.hotspot.runtime.JavaThread;
+import sun.jvm.hotspot.runtime.Threads;
import sun.jvm.hotspot.runtime.VM;
-import sun.jvm.hotspot.runtime.Threads;
-import sun.jvm.hotspot.runtime.JavaThread;
-import java.lang.reflect.*;
+import sun.jvm.hotspot.utilities.PlatformInfo;
/**
An implementation of the JVMDebugger interface. The basic debug
facilities are implemented through ptrace interface in the JNI code
@@ -246,10 +257,8 @@
/* called from attach methods */
private void findABIVersion() throws DebuggerException {
String libjvmName = isDarwin ? "libjvm.dylib" : "libjvm.so";
- String libjvm_gName = isDarwin? "libjvm_g.dylib" : "libjvm_g.so";
String javaThreadVt = isDarwin ? "_vt_10JavaThread" : "__vt_10JavaThread";
- if (lookupByName0(libjvmName, javaThreadVt) != 0 ||
- lookupByName0(libjvm_gName, javaThreadVt) != 0) {
+ if (lookupByName0(libjvmName, javaThreadVt) != 0) {
// old C++ ABI
useGCC32ABI = false;
} else {
diff -r a258a8351528 -r d3c98423c146 agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java Tue May 07 10:36:20 2013 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java Thu May 09 16:27:51 2013 -0400
@@ -24,14 +24,25 @@
package sun.jvm.hotspot.debugger.linux;
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.x86.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.utilities.*;
-import java.lang.reflect.*;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.debugger.DebuggerBase;
+import sun.jvm.hotspot.debugger.DebuggerException;
+import sun.jvm.hotspot.debugger.DebuggerUtilities;
+import sun.jvm.hotspot.debugger.MachineDescription;
+import sun.jvm.hotspot.debugger.NotInHeapException;
+import sun.jvm.hotspot.debugger.OopHandle;
+import sun.jvm.hotspot.debugger.ReadResult;
+import sun.jvm.hotspot.debugger.ThreadProxy;
+import sun.jvm.hotspot.debugger.UnalignedAddressException;
+import sun.jvm.hotspot.debugger.UnmappedAddressException;
+import sun.jvm.hotspot.debugger.cdbg.CDebugger;
+import sun.jvm.hotspot.debugger.cdbg.ClosestSymbol;
+import sun.jvm.hotspot.debugger.cdbg.LoadObject;
+import sun.jvm.hotspot.utilities.PlatformInfo;
/**
An implementation of the JVMDebugger interface. The basic debug
facilities are implemented through ptrace interface in the JNI code
@@ -238,8 +249,7 @@
/* called from attach methods */
private void findABIVersion() throws DebuggerException {
- if (lookupByName0("libjvm.so", "__vt_10JavaThread") != 0 ||
- lookupByName0("libjvm_g.so", "__vt_10JavaThread") != 0) {
+ if (lookupByName0("libjvm.so", "__vt_10JavaThread") != 0) {
// old C++ ABI
useGCC32ABI = false;
} else {
diff -r a258a8351528 -r d3c98423c146 make/windows/makefiles/compile.make
--- a/make/windows/makefiles/compile.make Tue May 07 10:36:20 2013 -0400
+++ b/make/windows/makefiles/compile.make Thu May 09 16:27:51 2013 -0400
@@ -52,7 +52,7 @@
# improving the quality of crash log stack traces involving jvm.dll.
# These are always used in all compiles
-CXX_FLAGS=/nologo /W3 /WX
+CXX_FLAGS=$(EXTRA_CFLAGS) /nologo /W3 /WX
# Let's add debug information when Full Debug Symbols is enabled
!if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
diff -r a258a8351528 -r d3c98423c146 make/windows/makefiles/defs.make
--- a/make/windows/makefiles/defs.make Tue May 07 10:36:20 2013 -0400
+++ b/make/windows/makefiles/defs.make Thu May 09 16:27:51 2013 -0400
@@ -193,7 +193,7 @@
MAKE_ARGS += JDK_BUILD_NUMBER=$(COOKED_BUILD_NUMBER)
endif
-NMAKE= MAKEFLAGS= MFLAGS= nmake -NOLOGO
+NMAKE= MAKEFLAGS= MFLAGS= EXTRA_CFLAGS="$(EXTRA_CFLAGS)" nmake -NOLOGO
ifndef SYSTEM_UNAME
SYSTEM_UNAME := $(shell uname)
export SYSTEM_UNAME
diff -r a258a8351528 -r d3c98423c146 src/cpu/sparc/vm/jni_sparc.h
--- a/src/cpu/sparc/vm/jni_sparc.h Tue May 07 10:36:20 2013 -0400
+++ b/src/cpu/sparc/vm/jni_sparc.h Thu May 09 16:27:51 2013 -0400
@@ -23,7 +23,12 @@
* questions.
*/
-#if defined(__GNUC__) && (__GNUC__ >= 4)
+// Note: please do not change these without also changing jni_md.h in the JDK
+// repository
+#ifndef __has_attribute
+ #define __has_attribute(x) 0
+#endif
+#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
diff -r a258a8351528 -r d3c98423c146 src/cpu/x86/vm/jni_x86.h
--- a/src/cpu/x86/vm/jni_x86.h Tue May 07 10:36:20 2013 -0400
+++ b/src/cpu/x86/vm/jni_x86.h Thu May 09 16:27:51 2013 -0400
@@ -28,7 +28,13 @@
#if defined(SOLARIS) || defined(LINUX) || defined(_ALLBSD_SOURCE)
-#if defined(__GNUC__) && (__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2)
+
+// Note: please do not change these without also changing jni_md.h in the JDK
+// repository
+#ifndef __has_attribute
+ #define __has_attribute(x) 0
+#endif
+#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
diff -r a258a8351528 -r d3c98423c146 src/cpu/zero/vm/jni_zero.h
--- a/src/cpu/zero/vm/jni_zero.h Tue May 07 10:36:20 2013 -0400
+++ b/src/cpu/zero/vm/jni_zero.h Thu May 09 16:27:51 2013 -0400
@@ -25,7 +25,13 @@
*/
-#if defined(__GNUC__) && (__GNUC__ >= 4)
+
+// Note: please do not change these without also changing jni_md.h in the JDK
+// repository
+#ifndef __has_attribute
+ #define __has_attribute(x) 0
+#endif
+#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
#define JNIEXPORT __attribute__((visibility("default")))
#define JNIIMPORT __attribute__((visibility("default")))
#else
diff -r a258a8351528 -r d3c98423c146 src/share/vm/classfile/bytecodeAssembler.cpp
--- a/src/share/vm/classfile/bytecodeAssembler.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/classfile/bytecodeAssembler.cpp Thu May 09 16:27:51 2013 -0400
@@ -75,8 +75,8 @@
int idx = i + _orig->length();
switch (entry._tag) {
case BytecodeCPEntry::UTF8:
+ entry._u.utf8->increment_refcount();
cp->symbol_at_put(idx, entry._u.utf8);
- entry._u.utf8->increment_refcount();
break;
case BytecodeCPEntry::KLASS:
cp->unresolved_klass_at_put(
diff -r a258a8351528 -r d3c98423c146 src/share/vm/classfile/systemDictionary.cpp
--- a/src/share/vm/classfile/systemDictionary.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/classfile/systemDictionary.cpp Thu May 09 16:27:51 2013 -0400
@@ -830,7 +830,7 @@
Klass *kk;
{
MutexLocker mu(SystemDictionary_lock, THREAD);
- kk = find_class(name, ik->class_loader_data());
+ kk = find_class(d_index, d_hash, name, ik->class_loader_data());
}
if (kk != NULL) {
// No clean up is needed if the shared class has been entered
diff -r a258a8351528 -r d3c98423c146 src/share/vm/classfile/vmSymbols.hpp
--- a/src/share/vm/classfile/vmSymbols.hpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/classfile/vmSymbols.hpp Thu May 09 16:27:51 2013 -0400
@@ -517,13 +517,18 @@
template(sun_management_ManagementFactory, "sun/management/ManagementFactory") \
template(sun_management_Sensor, "sun/management/Sensor") \
template(sun_management_Agent, "sun/management/Agent") \
+ template(sun_management_DiagnosticCommandImpl, "sun/management/DiagnosticCommandImpl") \
template(sun_management_GarbageCollectorImpl, "sun/management/GarbageCollectorImpl") \
+ template(sun_management_ManagementFactoryHelper, "sun/management/ManagementFactoryHelper") \
+ template(getDiagnosticCommandMBean_name, "getDiagnosticCommandMBean") \
+ template(getDiagnosticCommandMBean_signature, "()Lcom/sun/management/DiagnosticCommandMBean;") \
template(getGcInfoBuilder_name, "getGcInfoBuilder") \
template(getGcInfoBuilder_signature, "()Lsun/management/GcInfoBuilder;") \
template(com_sun_management_GcInfo, "com/sun/management/GcInfo") \
template(com_sun_management_GcInfo_constructor_signature, "(Lsun/management/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V") \
template(createGCNotification_name, "createGCNotification") \
template(createGCNotification_signature, "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/sun/management/GcInfo;)V") \
+ template(createDiagnosticFrameworkNotification_name, "createDiagnosticFrameworkNotification") \
template(createMemoryPoolMBean_name, "createMemoryPoolMBean") \
template(createMemoryManagerMBean_name, "createMemoryManagerMBean") \
template(createGarbageCollectorMBean_name, "createGarbageCollectorMBean") \
diff -r a258a8351528 -r d3c98423c146 src/share/vm/memory/allocation.inline.hpp
--- a/src/share/vm/memory/allocation.inline.hpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/memory/allocation.inline.hpp Thu May 09 16:27:51 2013 -0400
@@ -132,7 +132,7 @@
int alignment = os::vm_allocation_granularity();
_size = align_size_up(_size, alignment);
- _addr = os::reserve_memory(_size, NULL, alignment);
+ _addr = os::reserve_memory(_size, NULL, alignment, F);
if (_addr == NULL) {
vm_exit_out_of_memory(_size, OOM_MMAP_ERROR, "Allocator (reserve)");
}
diff -r a258a8351528 -r d3c98423c146 src/share/vm/prims/jvmtiClassFileReconstituter.cpp
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Thu May 09 16:27:51 2013 -0400
@@ -341,6 +341,44 @@
memcpy(writeable_address(length), annos->adr_at(0), length);
}
+// BootstrapMethods_attribute {
+// u2 attribute_name_index;
+// u4 attribute_length;
+// u2 num_bootstrap_methods;
+// { u2 bootstrap_method_ref;
+// u2 num_bootstrap_arguments;
+// u2 bootstrap_arguments[num_bootstrap_arguments];
+// } bootstrap_methods[num_bootstrap_methods];
+// }
+void JvmtiClassFileReconstituter::write_bootstrapmethod_attribute() {
+ Array* operands = cpool()->operands();
+ write_attribute_name_index("BootstrapMethods");
+ int num_bootstrap_methods = ConstantPool::operand_array_length(operands);
+
+ // calculate length of attribute
+ int length = sizeof(u2); // num_bootstrap_methods
+ for (int n = 0; n < num_bootstrap_methods; n++) {
+ u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
+ length += sizeof(u2); // bootstrap_method_ref
+ length += sizeof(u2); // num_bootstrap_arguments
+ length += sizeof(u2) * num_bootstrap_arguments; // bootstrap_arguments[num_bootstrap_arguments]
+ }
+ write_u4(length);
+
+ // write attribute
+ write_u2(num_bootstrap_methods);
+ for (int n = 0; n < num_bootstrap_methods; n++) {
+ u2 bootstrap_method_ref = cpool()->operand_bootstrap_method_ref_index_at(n);
+ u2 num_bootstrap_arguments = cpool()->operand_argument_count_at(n);
+ write_u2(bootstrap_method_ref);
+ write_u2(num_bootstrap_arguments);
+ for (int arg = 0; arg < num_bootstrap_arguments; arg++) {
+ u2 bootstrap_argument = cpool()->operand_argument_index_at(n, arg);
+ write_u2(bootstrap_argument);
+ }
+ }
+}
+
// Write InnerClasses attribute
// JVMSpec| InnerClasses_attribute {
@@ -513,6 +551,11 @@
AnnotationArray* param_anno = method->parameter_annotations();
AnnotationArray* default_anno = method->annotation_default();
+ // skip generated default interface methods
+ if (method->is_overpass()) {
+ return;
+ }
+
write_u2(access_flags.get_flags() & JVM_RECOGNIZED_METHOD_MODIFIERS);
write_u2(const_method->name_index());
write_u2(const_method->signature_index());
@@ -592,6 +635,9 @@
if (anno != NULL) {
++attr_count; // has RuntimeVisibleAnnotations attribute
}
+ if (cpool()->operands() != NULL) {
+ ++attr_count;
+ }
write_u2(attr_count);
@@ -610,6 +656,9 @@
if (anno != NULL) {
write_annotations_attribute("RuntimeVisibleAnnotations", anno);
}
+ if (cpool()->operands() != NULL) {
+ write_bootstrapmethod_attribute();
+ }
}
// Write the method information portion of ClassFile structure
@@ -619,8 +668,19 @@
HandleMark hm(thread());
Array* methods = ikh()->methods();
int num_methods = methods->length();
+ int num_overpass = 0;
- write_u2(num_methods);
+ // count the generated default interface methods
+ // these will not be re-created by write_method_info
+ // and should not be included in the total count
+ for (int index = 0; index < num_methods; index++) {
+ Method* method = methods->at(index);
+ if (method->is_overpass()) {
+ num_overpass++;
+ }
+ }
+
+ write_u2(num_methods - num_overpass);
if (JvmtiExport::can_maintain_original_method_order()) {
int index;
int original_index;
diff -r a258a8351528 -r d3c98423c146 src/share/vm/prims/jvmtiClassFileReconstituter.hpp
--- a/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Thu May 09 16:27:51 2013 -0400
@@ -127,6 +127,7 @@
void write_signature_attribute(u2 generic_signaure_index);
void write_attribute_name_index(const char* name);
void write_annotations_attribute(const char* attr_name, AnnotationArray* annos);
+ void write_bootstrapmethod_attribute();
address writeable_address(size_t size);
void write_u1(u1 x);
diff -r a258a8351528 -r d3c98423c146 src/share/vm/prims/perf.cpp
--- a/src/share/vm/prims/perf.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/prims/perf.cpp Thu May 09 16:27:51 2013 -0400
@@ -142,20 +142,20 @@
}
switch(variability) {
- case 1: /* V_Constant */
+ case PerfData::V_Constant:
pl = PerfDataManager::create_long_constant(NULL_NS, (char *)name_utf,
(PerfData::Units)units, value,
CHECK_NULL);
break;
- case 2: /* V_Variable */
- pl = PerfDataManager::create_long_variable(NULL_NS, (char *)name_utf,
+ case PerfData::V_Monotonic:
+ pl = PerfDataManager::create_long_counter(NULL_NS, (char *)name_utf,
(PerfData::Units)units, value,
CHECK_NULL);
break;
- case 3: /* V_Monotonic Counter */
- pl = PerfDataManager::create_long_counter(NULL_NS, (char *)name_utf,
+ case PerfData::V_Variable:
+ pl = PerfDataManager::create_long_variable(NULL_NS, (char *)name_utf,
(PerfData::Units)units, value,
CHECK_NULL);
break;
diff -r a258a8351528 -r d3c98423c146 src/share/vm/runtime/os.cpp
--- a/src/share/vm/runtime/os.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/runtime/os.cpp Thu May 09 16:27:51 2013 -0400
@@ -1457,6 +1457,18 @@
return result;
}
+
+char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint,
+ MEMFLAGS flags) {
+ char* result = pd_reserve_memory(bytes, addr, alignment_hint);
+ if (result != NULL) {
+ MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+ MemTracker::record_virtual_memory_type((address)result, flags);
+ }
+
+ return result;
+}
+
char* os::attempt_reserve_memory_at(size_t bytes, char* addr) {
char* result = pd_attempt_reserve_memory_at(bytes, addr);
if (result != NULL) {
diff -r a258a8351528 -r d3c98423c146 src/share/vm/runtime/os.hpp
--- a/src/share/vm/runtime/os.hpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/runtime/os.hpp Thu May 09 16:27:51 2013 -0400
@@ -255,6 +255,8 @@
static int vm_allocation_granularity();
static char* reserve_memory(size_t bytes, char* addr = 0,
size_t alignment_hint = 0);
+ static char* reserve_memory(size_t bytes, char* addr,
+ size_t alignment_hint, MEMFLAGS flags);
static char* reserve_memory_aligned(size_t size, size_t alignment);
static char* attempt_reserve_memory_at(size_t bytes, char* addr);
static void split_reserved_memory(char *base, size_t size,
diff -r a258a8351528 -r d3c98423c146 src/share/vm/runtime/serviceThread.cpp
--- a/src/share/vm/runtime/serviceThread.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/runtime/serviceThread.cpp Thu May 09 16:27:51 2013 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -29,6 +29,8 @@
#include "runtime/mutexLocker.hpp"
#include "prims/jvmtiImpl.hpp"
#include "services/gcNotifier.hpp"
+#include "services/diagnosticArgument.hpp"
+#include "services/diagnosticFramework.hpp"
ServiceThread* ServiceThread::_instance = NULL;
@@ -83,6 +85,7 @@
bool sensors_changed = false;
bool has_jvmti_events = false;
bool has_gc_notification_event = false;
+ bool has_dcmd_notification_event = false;
JvmtiDeferredEvent jvmti_event;
{
// Need state transition ThreadBlockInVM so that this thread
@@ -98,7 +101,8 @@
MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
while (!(sensors_changed = LowMemoryDetector::has_pending_requests()) &&
!(has_jvmti_events = JvmtiDeferredEventQueue::has_events()) &&
- !(has_gc_notification_event = GCNotifier::has_event())) {
+ !(has_gc_notification_event = GCNotifier::has_event()) &&
+ !(has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification())) {
// wait until one of the sensors has pending requests, or there is a
// pending JVMTI event or JMX GC notification to post
Service_lock->wait(Mutex::_no_safepoint_check_flag);
@@ -120,6 +124,10 @@
if(has_gc_notification_event) {
GCNotifier::sendNotification(CHECK);
}
+
+ if(has_dcmd_notification_event) {
+ DCmdFactory::send_notification(CHECK);
+ }
}
}
diff -r a258a8351528 -r d3c98423c146 src/share/vm/services/attachListener.cpp
--- a/src/share/vm/services/attachListener.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/services/attachListener.cpp Thu May 09 16:27:51 2013 -0400
@@ -157,7 +157,7 @@
Thread* THREAD = Thread::current();
// All the supplied jcmd arguments are stored as a single
// string (op->arg(0)). This is parsed by the Dcmd framework.
- DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD);
+ DCmd::parse_and_execute(DCmd_Source_AttachAPI, out, op->arg(0), ' ', THREAD);
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, out);
out->cr();
diff -r a258a8351528 -r d3c98423c146 src/share/vm/services/diagnosticCommand.cpp
--- a/src/share/vm/services/diagnosticCommand.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/services/diagnosticCommand.cpp Thu May 09 16:27:51 2013 -0400
@@ -34,26 +34,33 @@
void DCmdRegistrant::register_dcmds(){
// Registration of the diagnostic commands
- // First boolean argument specifies if the command is enabled
- // Second boolean argument specifies if the command is hidden
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
+ // First argument specifies which interfaces will export the command
+ // Second argument specifies if the command is enabled
+ // Third argument specifies if the command is hidden
+ uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI
+ | DCmd_Source_MBean;
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
#if INCLUDE_SERVICES // Heap dumping/inspection supported
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
#endif // INCLUDE_SERVICES
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true, false));
- //Enhanced JMX Agent Support
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false));
- DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(true,false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false));
+
+ // Enhanced JMX Agent Support
+ // These commands won't be exported via the DiagnosticCommandMBean until an
+ // appropriate permission is created for them
+ uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI;
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false));
+ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false));
}
@@ -72,29 +79,37 @@
_dcmdparser.add_dcmd_argument(&_cmd);
};
-void HelpDCmd::execute(TRAPS) {
+void HelpDCmd::execute(DCmdSource source, TRAPS) {
if (_all.value()) {
- GrowableArray* cmd_list = DCmdFactory::DCmd_list();
+ GrowableArray* cmd_list = DCmdFactory::DCmd_list(source);
for (int i = 0; i < cmd_list->length(); i++) {
- DCmdFactory* factory = DCmdFactory::factory(cmd_list->at(i),
+ DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),
strlen(cmd_list->at(i)));
- if (!factory->is_hidden()) {
- output()->print_cr("%s%s", factory->name(),
- factory->is_enabled() ? "" : " [disabled]");
- output()->print_cr("\t%s", factory->description());
- output()->cr();
- }
+ output()->print_cr("%s%s", factory->name(),
+ factory->is_enabled() ? "" : " [disabled]");
+ output()->print_cr("\t%s", factory->description());
+ output()->cr();
factory = factory->next();
}
} else if (_cmd.has_value()) {
DCmd* cmd = NULL;
- DCmdFactory* factory = DCmdFactory::factory(_cmd.value(),
+ DCmdFactory* factory = DCmdFactory::factory(source, _cmd.value(),
strlen(_cmd.value()));
if (factory != NULL) {
output()->print_cr("%s%s", factory->name(),
factory->is_enabled() ? "" : " [disabled]");
output()->print_cr(factory->description());
output()->print_cr("\nImpact: %s", factory->impact());
+ JavaPermission p = factory->permission();
+ if(p._class != NULL) {
+ if(p._action != NULL) {
+ output()->print_cr("\nPermission: %s(%s, %s)",
+ p._class, p._name == NULL ? "null" : p._name, p._action);
+ } else {
+ output()->print_cr("\nPermission: %s(%s)",
+ p._class, p._name == NULL ? "null" : p._name);
+ }
+ }
output()->cr();
cmd = factory->create_resource_instance(output());
if (cmd != NULL) {
@@ -106,14 +121,12 @@
}
} else {
output()->print_cr("The following commands are available:");
- GrowableArray* cmd_list = DCmdFactory::DCmd_list();
+ GrowableArray* cmd_list = DCmdFactory::DCmd_list(source);
for (int i = 0; i < cmd_list->length(); i++) {
- DCmdFactory* factory = DCmdFactory::factory(cmd_list->at(i),
+ DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i),
strlen(cmd_list->at(i)));
- if (!factory->is_hidden()) {
- output()->print_cr("%s%s", factory->name(),
- factory->is_enabled() ? "" : " [disabled]");
- }
+ output()->print_cr("%s%s", factory->name(),
+ factory->is_enabled() ? "" : " [disabled]");
factory = factory->_next;
}
output()->print_cr("\nFor more information about a specific command use 'help '.");
@@ -131,7 +144,7 @@
}
}
-void VersionDCmd::execute(TRAPS) {
+void VersionDCmd::execute(DCmdSource source, TRAPS) {
output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
Abstract_VM_Version::vm_release());
JDK_Version jdk_version = JDK_Version::current();
@@ -150,7 +163,7 @@
_dcmdparser.add_dcmd_option(&_all);
}
-void PrintVMFlagsDCmd::execute(TRAPS) {
+void PrintVMFlagsDCmd::execute(DCmdSource source, TRAPS) {
if (_all.value()) {
CommandLineFlags::printFlags(output(), true);
} else {
@@ -169,7 +182,7 @@
}
}
-void PrintSystemPropertiesDCmd::execute(TRAPS) {
+void PrintSystemPropertiesDCmd::execute(DCmdSource source, TRAPS) {
// load sun.misc.VMSupport
Symbol* klass = vmSymbols::sun_misc_VMSupport();
Klass* k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
@@ -219,7 +232,7 @@
_dcmdparser.add_dcmd_option(&_date);
}
-void VMUptimeDCmd::execute(TRAPS) {
+void VMUptimeDCmd::execute(DCmdSource source, TRAPS) {
if (_date.value()) {
output()->date_stamp(true, "", ": ");
}
@@ -239,11 +252,15 @@
}
}
-void SystemGCDCmd::execute(TRAPS) {
- Universe::heap()->collect(GCCause::_java_lang_system_gc);
+void SystemGCDCmd::execute(DCmdSource source, TRAPS) {
+ if (!DisableExplicitGC) {
+ Universe::heap()->collect(GCCause::_java_lang_system_gc);
+ } else {
+ output()->print_cr("Explicit GC is disabled, no GC has been performed.");
+ }
}
-void RunFinalizationDCmd::execute(TRAPS) {
+void RunFinalizationDCmd::execute(DCmdSource source, TRAPS) {
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
true, CHECK);
instanceKlassHandle klass(THREAD, k);
@@ -263,7 +280,7 @@
_dcmdparser.add_dcmd_argument(&_filename);
}
-void HeapDumpDCmd::execute(TRAPS) {
+void HeapDumpDCmd::execute(DCmdSource source, TRAPS) {
// Request a full GC before heap dump if _all is false
// This helps reduces the amount of unreachable objects in the dump
// and makes it easier to browse.
@@ -301,7 +318,7 @@
_dcmdparser.add_dcmd_option(&_all);
}
-void ClassHistogramDCmd::execute(TRAPS) {
+void ClassHistogramDCmd::execute(DCmdSource source, TRAPS) {
VM_GC_HeapInspection heapop(output(),
!_all.value() /* request full gc if false */,
true /* need_prologue */);
@@ -337,7 +354,7 @@
_dcmdparser.add_dcmd_argument(&_columns);
}
-void ClassStatsDCmd::execute(TRAPS) {
+void ClassStatsDCmd::execute(DCmdSource source, TRAPS) {
if (!UnlockDiagnosticVMOptions) {
output()->print_cr("GC.class_stats command requires -XX:+UnlockDiagnosticVMOptions");
return;
@@ -384,7 +401,7 @@
_dcmdparser.add_dcmd_option(&_locks);
}
-void ThreadDumpDCmd::execute(TRAPS) {
+void ThreadDumpDCmd::execute(DCmdSource source, TRAPS) {
// thread stacks
VM_PrintThreads op1(output(), _locks.value());
VMThread::execute(&op1);
@@ -526,7 +543,8 @@
}
}
-void JMXStartRemoteDCmd::execute(TRAPS) {
+
+void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
@@ -593,7 +611,7 @@
// do nothing
}
-void JMXStartLocalDCmd::execute(TRAPS) {
+void JMXStartLocalDCmd::execute(DCmdSource source, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
@@ -611,7 +629,7 @@
}
-void JMXStopRemoteDCmd::execute(TRAPS) {
+void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
diff -r a258a8351528 -r d3c98423c146 src/share/vm/services/diagnosticCommand.hpp
--- a/src/share/vm/services/diagnosticCommand.hpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/services/diagnosticCommand.hpp Thu May 09 16:27:51 2013 -0400
@@ -51,7 +51,7 @@
}
static const char* impact() { return "Low"; }
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
class VersionDCmd : public DCmd {
@@ -62,8 +62,13 @@
return "Print JVM version information.";
}
static const char* impact() { return "Low"; }
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.util.PropertyPermission",
+ "java.vm.version", "read"};
+ return p;
+ }
static int num_arguments() { return 0; }
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
class CommandLineDCmd : public DCmd {
@@ -74,8 +79,13 @@
return "Print the command line used to start this VM instance.";
}
static const char* impact() { return "Low"; }
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
static int num_arguments() { return 0; }
- virtual void execute(TRAPS) {
+ virtual void execute(DCmdSource source, TRAPS) {
Arguments::print_on(_output);
}
};
@@ -91,8 +101,13 @@
static const char* impact() {
return "Low";
}
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.util.PropertyPermission",
+ "*", "read"};
+ return p;
+ }
static int num_arguments() { return 0; }
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
// See also: print_flag in attachListener.cpp
@@ -108,8 +123,13 @@
static const char* impact() {
return "Low";
}
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
class VMUptimeDCmd : public DCmdWithParser {
@@ -125,7 +145,7 @@
return "Low";
}
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
class SystemGCDCmd : public DCmd {
@@ -139,7 +159,7 @@
return "Medium: Depends on Java heap size and content.";
}
static int num_arguments() { return 0; }
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
class RunFinalizationDCmd : public DCmd {
@@ -153,7 +173,7 @@
return "Medium: Depends on Java content.";
}
static int num_arguments() { return 0; }
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
#if INCLUDE_SERVICES // Heap dumping supported
@@ -174,8 +194,13 @@
return "High: Depends on Java heap size and content. "
"Request a full GC unless the '-all' option is specified.";
}
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
#endif // INCLUDE_SERVICES
@@ -194,8 +219,13 @@
static const char* impact() {
return "High: Depends on Java heap size and content.";
}
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
class ClassStatsDCmd : public DCmdWithParser {
@@ -216,7 +246,7 @@
return "High: Depends on Java heap size and content.";
}
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
// See also: thread_dump in attachListener.cpp
@@ -232,8 +262,13 @@
static const char* impact() {
return "Medium: Depends on the number of threads.";
}
+ static const JavaPermission permission() {
+ JavaPermission p = {"java.lang.management.ManagementPermission",
+ "monitor", NULL};
+ return p;
+ }
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
// Enhanced JMX Agent support
@@ -281,7 +316,7 @@
static int num_arguments();
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
@@ -302,7 +337,7 @@
return "Start local management agent.";
}
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
@@ -321,7 +356,7 @@
return "Stop remote management agent.";
}
- virtual void execute(TRAPS);
+ virtual void execute(DCmdSource source, TRAPS);
};
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
diff -r a258a8351528 -r d3c98423c146 src/share/vm/services/diagnosticFramework.cpp
--- a/src/share/vm/services/diagnosticFramework.cpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/services/diagnosticFramework.cpp Thu May 09 16:27:51 2013 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -359,7 +359,7 @@
while (arg != NULL) {
array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
arg->type(), arg->default_string(), arg->is_mandatory(),
- false, idx));
+ false, arg->allow_multiple(), idx));
idx++;
arg = arg->next();
}
@@ -367,32 +367,42 @@
while (arg != NULL) {
array->append(new DCmdArgumentInfo(arg->name(), arg->description(),
arg->type(), arg->default_string(), arg->is_mandatory(),
- true));
+ true, arg->allow_multiple()));
arg = arg->next();
}
return array;
}
DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL;
+bool DCmdFactory::_has_pending_jmx_notification = false;
-void DCmd::parse_and_execute(outputStream* out, const char* cmdline,
- char delim, TRAPS) {
+void DCmd::parse_and_execute(DCmdSource source, outputStream* out,
+ const char* cmdline, char delim, TRAPS) {
if (cmdline == NULL) return; // Nothing to do!
DCmdIter iter(cmdline, '\n');
+ int count = 0;
while (iter.has_next()) {
+ if(source == DCmd_Source_MBean && count > 0) {
+ // When diagnostic commands are invoked via JMX, each command line
+ // must contains one and only one command because of the Permission
+ // checks performed by the DiagnosticCommandMBean
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "Invalid syntax");
+ }
CmdLine line = iter.next();
if (line.is_stop()) {
break;
}
if (line.is_executable()) {
- DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK);
+ DCmd* command = DCmdFactory::create_local_DCmd(source, line, out, CHECK);
assert(command != NULL, "command error must be handled before this line");
DCmdMark mark(command);
command->parse(&line, delim, CHECK);
- command->execute(CHECK);
+ command->execute(source, CHECK);
}
+ count++;
}
}
@@ -420,15 +430,78 @@
return _dcmdparser.argument_info_array();
}
-Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
+void DCmdFactory::push_jmx_notification_request() {
+ MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
+ _has_pending_jmx_notification = true;
+ Service_lock->notify_all();
+}
+
+void DCmdFactory::send_notification(TRAPS) {
+ DCmdFactory::send_notification_internal(THREAD);
+ // Clearing pending exception to avoid premature termination of
+ // the service thread
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ }
+}
+void DCmdFactory::send_notification_internal(TRAPS) {
+ ResourceMark rm(THREAD);
+ HandleMark hm(THREAD);
+ bool notif = false;
+ {
+ MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
+ notif = _has_pending_jmx_notification;
+ _has_pending_jmx_notification = false;
+ }
+ if (notif) {
+
+ Klass* k = Management::sun_management_ManagementFactoryHelper_klass(CHECK);
+ instanceKlassHandle mgmt_factory_helper_klass(THREAD, k);
-DCmdFactory* DCmdFactory::factory(const char* name, size_t len) {
+ JavaValue result(T_OBJECT);
+ JavaCalls::call_static(&result,
+ mgmt_factory_helper_klass,
+ vmSymbols::getDiagnosticCommandMBean_name(),
+ vmSymbols::getDiagnosticCommandMBean_signature(),
+ CHECK);
+
+ instanceOop m = (instanceOop) result.get_jobject();
+ instanceHandle dcmd_mbean_h(THREAD, m);
+
+ Klass* k2 = Management::sun_management_DiagnosticCommandImpl_klass(CHECK);
+ instanceKlassHandle dcmd_mbean_klass(THREAD, k2);
+
+ if (!dcmd_mbean_h->is_a(k2)) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
+ "ManagementFactory.getDiagnosticCommandMBean didn't return a DiagnosticCommandMBean instance");
+ }
+
+ JavaValue result2(T_VOID);
+ JavaCallArguments args2(dcmd_mbean_h);
+
+ JavaCalls::call_virtual(&result2,
+ dcmd_mbean_klass,
+ vmSymbols::createDiagnosticFrameworkNotification_name(),
+ vmSymbols::void_method_signature(),
+ &args2,
+ CHECK);
+ }
+}
+
+Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
+bool DCmdFactory::_send_jmx_notification = false;
+
+DCmdFactory* DCmdFactory::factory(DCmdSource source, const char* name, size_t len) {
MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
DCmdFactory* factory = _DCmdFactoryList;
while (factory != NULL) {
if (strlen(factory->name()) == len &&
strncmp(name, factory->name(), len) == 0) {
- return factory;
+ if(factory->export_flags() & source) {
+ return factory;
+ } else {
+ return NULL;
+ }
}
factory = factory->_next;
}
@@ -439,11 +512,16 @@
MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
factory->_next = _DCmdFactoryList;
_DCmdFactoryList = factory;
+ if (_send_jmx_notification && !factory->_hidden
+ && (factory->_export_flags & DCmd_Source_MBean)) {
+ DCmdFactory::push_jmx_notification_request();
+ }
return 0; // Actually, there's no checks for duplicates
}
-DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) {
- DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len());
+DCmd* DCmdFactory::create_global_DCmd(DCmdSource source, CmdLine &line,
+ outputStream* out, TRAPS) {
+ DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len());
if (f != NULL) {
if (f->is_enabled()) {
THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
@@ -455,8 +533,9 @@
"Unknown diagnostic command");
}
-DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) {
- DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len());
+DCmd* DCmdFactory::create_local_DCmd(DCmdSource source, CmdLine &line,
+ outputStream* out, TRAPS) {
+ DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len());
if (f != NULL) {
if (!f->is_enabled()) {
THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
@@ -468,12 +547,12 @@
"Unknown diagnostic command");
}
-GrowableArray* DCmdFactory::DCmd_list() {
+GrowableArray* DCmdFactory::DCmd_list(DCmdSource source) {
MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
GrowableArray* array = new GrowableArray();
DCmdFactory* factory = _DCmdFactoryList;
while (factory != NULL) {
- if (!factory->is_hidden()) {
+ if (!factory->is_hidden() && (factory->export_flags() & source)) {
array->append(factory->name());
}
factory = factory->next();
@@ -481,15 +560,16 @@
return array;
}
-GrowableArray* DCmdFactory::DCmdInfo_list() {
+GrowableArray* DCmdFactory::DCmdInfo_list(DCmdSource source ) {
MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag);
GrowableArray* array = new GrowableArray();
DCmdFactory* factory = _DCmdFactoryList;
while (factory != NULL) {
- if (!factory->is_hidden()) {
+ if (!factory->is_hidden() && (factory->export_flags() & source)) {
array->append(new DCmdInfo(factory->name(),
factory->description(), factory->impact(),
- factory->num_arguments(), factory->is_enabled()));
+ factory->permission(), factory->num_arguments(),
+ factory->is_enabled()));
}
factory = factory->next();
}
diff -r a258a8351528 -r d3c98423c146 src/share/vm/services/diagnosticFramework.hpp
--- a/src/share/vm/services/diagnosticFramework.hpp Tue May 07 10:36:20 2013 -0400
+++ b/src/share/vm/services/diagnosticFramework.hpp Thu May 09 16:27:51 2013 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -34,6 +34,22 @@
#include "utilities/ostream.hpp"
+enum DCmdSource {
+ DCmd_Source_Internal = 0x01U, // invocation from the JVM
+ DCmd_Source_AttachAPI = 0x02U, // invocation via the attachAPI
+ DCmd_Source_MBean = 0x04U // invocation via a MBean
+};
+
+// Warning: strings referenced by the JavaPermission struct are passed to
+// the native part of the JDK. Avoid use of dynamically allocated strings
+// that could be de-allocated before the JDK native code had time to
+// convert them into Java Strings.
+struct JavaPermission {
+ const char* _class;
+ const char* _name;
+ const char* _action;
+};
+
// CmdLine is the class used to handle a command line containing a single
// diagnostic command and its arguments. It provides methods to access the
// command name and the beginning of the arguments. The class is also
@@ -113,26 +129,30 @@
// used to export the description to the JMX interface of the framework.
class DCmdInfo : public ResourceObj {
protected:
- const char* _name;
- const char* _description;
- const char* _impact;
- int _num_arguments;
- bool _is_enabled;
+ const char* _name; /* Name of the diagnostic command */
+ const char* _description; /* Short description */
+ const char* _impact; /* Impact on the JVM */
+ JavaPermission _permission; /* Java Permission required to execute this command if any */
+ int _num_arguments; /* Number of supported options or arguments */
+ bool _is_enabled; /* True if the diagnostic command can be invoked, false otherwise */
public:
DCmdInfo(const char* name,
const char* description,
const char* impact,
+ JavaPermission permission,
int num_arguments,
bool enabled) {
this->_name = name;
this->_description = description;
this->_impact = impact;
+ this->_permission = permission;
this->_num_arguments = num_arguments;
this->_is_enabled = enabled;
}
const char* name() const { return _name; }
const char* description() const { return _description; }
const char* impact() const { return _impact; }
+ JavaPermission permission() const { return _permission; }
int num_arguments() const { return _num_arguments; }
bool is_enabled() const { return _is_enabled; }
@@ -144,16 +164,20 @@
// framework.
class DCmdArgumentInfo : public ResourceObj {
protected:
- const char* _name;
- const char* _description;
- const char* _type;
- const char* _default_string;
- bool _mandatory;
- bool _option;
- int _position;
+ const char* _name; /* Option/Argument name*/
+ const char* _description; /* Short description */
+ const char* _type; /* Type: STRING, BOOLEAN, etc. */
+ const char* _default_string; /* Default value in a parsable string */
+ bool _mandatory; /* True if the option/argument is mandatory */
+ bool _option; /* True if it is an option, false if it is an argument */
+ /* (see diagnosticFramework.hpp for option/argument definitions) */
+ bool _multiple; /* True is the option can be specified several time */
+ int _position; /* Expected position for this argument (this field is */
+ /* meaningless for options) */
public:
DCmdArgumentInfo(const char* name, const char* description, const char* type,
- const char* default_string, bool mandatory, bool option) {
+ const char* default_string, bool mandatory, bool option,
+ bool multiple) {
this->_name = name;
this->_description = description;
this->_type = type;
@@ -161,11 +185,12 @@
this->_option = option;
this->_mandatory = mandatory;
this->_option = option;
+ this->_multiple = multiple;
this->_position = -1;
}
DCmdArgumentInfo(const char* name, const char* description, const char* type,
const char* default_string, bool mandatory, bool option,
- int position) {
+ bool multiple, int position) {
this->_name = name;
this->_description = description;
this->_type = type;
@@ -173,6 +198,7 @@
this->_option = option;
this->_mandatory = mandatory;
this->_option = option;
+ this->_multiple = multiple;
this->_position = position;
}
const char* name() const { return _name; }
@@ -181,11 +207,29 @@
const char* default_string() const { return _default_string; }
bool is_mandatory() const { return _mandatory; }
bool is_option() const { return _option; }
+ bool is_multiple() const { return _multiple; }
int position() const { return _position; }
};
// The DCmdParser class can be used to create an argument parser for a
// diagnostic command. It is not mandatory to use it to parse arguments.
+// The DCmdParser parses a CmdLine instance according to the parameters that
+// have been declared by its associated 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
+// position of an argument is defined relative to all arguments passed on the
+// command line, options are not considered when defining an argument position.
+// The generic syntax of a diagnostic command is:
+//
+// [