# HG changeset patch
# User lana
# Date 1363137760 25200
# Node ID 11d5942ef9c7726a525ec45dbd6ff5fd93ebd013
# Parent 65b797426a3bec6e91b64085a0cfb94adadb634a# Parent d4a32a6f8c820aa976e2f7d1de79bb6380b8c256
Merge
diff -r d4a32a6f8c82 -r 11d5942ef9c7 .hgtags
--- a/.hgtags Mon Feb 25 07:22:06 2013 +0100
+++ b/.hgtags Tue Mar 12 18:22:40 2013 -0700
@@ -316,3 +316,9 @@
412d722168bc23f8e6d98995202728678561417f hs25-b18
cdb46031e7184d37301288f5719121a63c7054b5 jdk8-b77
9f19f4a7d48a4ebe7f616b6068971ea5f8b075fa hs25-b19
+d5e12e7d2f719144d84903d9151455661c47b476 jdk8-b78
+555ec35a250783110aa070dbc8a8603f6cabe41f hs25-b20
+6691814929b606fe0e7954fd6e485dd876505c83 jdk8-b79
+df5396524152118535c36da5801d828b560d19a2 hs25-b21
+4a198b201f3ce84433fa94a3ca65d061473e7c4c jdk8-b80
+dd6350b4abc4a6c19c89dd982cc0e4f3d119885c hs25-b22
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/make/Makefile
--- a/agent/make/Makefile Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/make/Makefile Tue Mar 12 18:22:40 2013 -0700
@@ -19,7 +19,7 @@
# 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 guards against adding broken .java files to the directory
@@ -42,8 +42,6 @@
sun.jvm.hotspot \
sun.jvm.hotspot.asm \
sun.jvm.hotspot.asm.sparc \
-sun.jvm.hotspot.bugspot \
-sun.jvm.hotspot.bugspot.tree \
sun.jvm.hotspot.c1 \
sun.jvm.hotspot.ci \
sun.jvm.hotspot.code \
@@ -84,7 +82,6 @@
sun.jvm.hotspot.gc_interface \
sun.jvm.hotspot.interpreter \
sun.jvm.hotspot.jdi \
-sun.jvm.hotspot.livejvm \
sun.jvm.hotspot.memory \
sun.jvm.hotspot.opto \
sun.jvm.hotspot.oops \
@@ -130,8 +127,6 @@
sun/jvm/hotspot/*.java \
sun/jvm/hotspot/asm/*.java \
sun/jvm/hotspot/asm/sparc/*.java \
-sun/jvm/hotspot/bugspot/*.java \
-sun/jvm/hotspot/bugspot/tree/*.java \
sun/jvm/hotspot/c1/*.java \
sun/jvm/hotspot/ci/*.java \
sun/jvm/hotspot/code/*.java \
@@ -168,7 +163,6 @@
sun/jvm/hotspot/gc_implementation/shared/*.java \
sun/jvm/hotspot/interpreter/*.java \
sun/jvm/hotspot/jdi/*.java \
-sun/jvm/hotspot/livejvm/*.java \
sun/jvm/hotspot/memory/*.java \
sun/jvm/hotspot/oops/*.java \
sun/jvm/hotspot/opto/*.java \
@@ -205,7 +199,7 @@
sun/jvm/hotspot/utilities/memo/*.java \
sun/jvm/hotspot/utilities/soql/*.java \
com/sun/java/swing/action/*.java \
-com/sun/java/swing/ui/*.java
+com/sun/java/swing/ui/*.java
#END FILELIST
ifneq "x$(ALT_BOOTDIR)" "x"
@@ -231,7 +225,7 @@
OUTPUT_DIR = $(BUILD_DIR)/classes
DOC_DIR = $(BUILD_DIR)/doc
-# gnumake 3.78.1 does not accept the *s,
+# gnumake 3.78.1 does not accept the *s,
# so use the shell to expand them
ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST))
ALLFILES := $(shell /bin/ls $(ALLFILES))
@@ -303,7 +297,7 @@
cscope: $(ALLFILES)
rm -f java.files
echo $(ALLFILES) > java.files
- cscope -b -i java.files -f java.out
+ cscope -b -i java.files -f java.out
rm -f java.files
.PHONY: sa.jar
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/make/bugspot.bat
--- a/agent/make/bugspot.bat Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-REM
-REM Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
-REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-REM
-REM This code is free software; you can redistribute it and/or modify it
-REM under the terms of the GNU General Public License version 2 only, as
-REM published by the Free Software Foundation.
-REM
-REM This code is distributed in the hope that it will be useful, but WITHOUT
-REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-REM version 2 for more details (a copy is included in the LICENSE file that
-REM accompanied this code).
-REM
-REM You should have received a copy of the GNU General Public License version
-REM 2 along with this work; if not, write to the Free Software Foundation,
-REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-REM
-REM Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-REM or visit www.oracle.com if you need additional information or have any
-REM questions.
-REM
-REM
-
-java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/make/marks_notes.html
--- a/agent/make/marks_notes.html Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/make/marks_notes.html Tue Mar 12 18:22:40 2013 -0700
@@ -26,14 +26,12 @@
java -cp classes sun.jvm.hotspot.HSDB
-
java -cp classes sun.jvm.hotspot.bugspot.Main
Feedback
Refactoring of package hierarchy. All user interface components should be in
- the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB and
- sun.jvm.hotspot.ui.bugspot.Main for BugSpot.
+ the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB.
The src\share\vm\agent area seems like a workspace so it should be organized like
one. In particular, I'd like to suggest the following directory layout:
@@ -47,7 +45,7 @@
- Seems like there is a lot of redundant functionality. Between the HSDB and BugSpot. Perhaps
+ Seems like there is a lot of redundant functionality. Perhaps
this can be consolidated with a javax.swing.Actions architecture.
Tasklist
@@ -55,11 +53,7 @@
Stack memory pane:
It's one of the more useful JVM debugging tools in the SA. However, it
- doesn't support any interaction with the text; the Memory Panel in BugSpot
- was written afterward (with help from Shannon) and implements proper
- selection, scrolling, and drag-and-drop, but no annotations. I'm not sure how
- to integrate the annotations with the JTable that's being used for the memory
- view; if you have suggestions here please let me know.
+ doesn't support any interaction with the text.
Integrations with the NetBeans architecture (plug in). See the
Netbeans Open APIs homepage
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/bsd/MacosxDebuggerLocal.m
--- a/agent/src/os/bsd/MacosxDebuggerLocal.m Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/bsd/MacosxDebuggerLocal.m Tue Mar 12 18:22:40 2013 -0700
@@ -38,6 +38,8 @@
#import
#import
#import
+#import
+#import
jboolean debug = JNI_FALSE;
@@ -158,7 +160,7 @@
CHECK_EXCEPTION_(0);
unsigned long alignedAddress;
- unsigned long alignedLength;
+ unsigned long alignedLength = 0;
kern_return_t result;
vm_offset_t *pages;
int *mapped;
@@ -430,6 +432,73 @@
return (jint) usable_tid;
}
+
+static bool ptrace_continue(pid_t pid, int signal) {
+ // pass the signal to the process so we don't swallow it
+ int res;
+ if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) {
+ fprintf(stderr, "attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res);
+ return false;
+ }
+ return true;
+}
+
+// waits until the ATTACH has stopped the process
+// by signal SIGSTOP
+static bool ptrace_waitpid(pid_t pid) {
+ int ret;
+ int status;
+ while (true) {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
+ // will still be pending and delivered when the process is DETACHED and the process
+ // will go to sleep.
+ if (WSTOPSIG(status) == SIGSTOP) {
+ // Debuggee stopped by SIGSTOP.
+ return true;
+ }
+ if (!ptrace_continue(pid, WSTOPSIG(status))) {
+ fprintf(stderr, "attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+ return false;
+ }
+ } else {
+ fprintf(stderr, "attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ fprintf(stderr, "attach: waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ fprintf(stderr, "attach: waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ fprintf(stderr, "attach: waitpid() failed. Unexpected error %d\n",errno);
+ break;
+ }
+ return false;
+ }
+ }
+}
+
+// attach to a process/thread specified by "pid"
+static bool ptrace_attach(pid_t pid) {
+ int res;
+ if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) {
+ fprintf(stderr, "ptrace(PT_ATTACH, %d) failed with %d\n", pid, res);
+ return false;
+ } else {
+ return ptrace_waitpid(pid);
+ }
+}
+
/*
* Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
* Method: attach0
@@ -445,7 +514,8 @@
else
debug = JNI_FALSE;
if (debug) printf("attach0 called for jpid=%d\n", (int)jpid);
-
+
+ // get the task from the pid
kern_return_t result;
task_t gTask = 0;
result = task_for_pid(mach_task_self(), jpid, &gTask);
@@ -455,6 +525,13 @@
}
putTask(env, this_obj, gTask);
+ // use ptrace to stop the process
+ // on os x, ptrace only needs to be called on the process, not the individual threads
+ if (ptrace_attach(jpid) != true) {
+ mach_port_deallocate(mach_task_self(), gTask);
+ THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
+ }
+
id symbolicator = nil;
id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
if (jrsSymbolicator != nil) {
@@ -486,6 +563,21 @@
if (debug) printf("detach0 called\n");
task_t gTask = getTask(env, this_obj);
+
+ // detach from the ptraced process causing it to resume execution
+ int pid;
+ kern_return_t k_res;
+ k_res = pid_for_task(gTask, &pid);
+ if (k_res != KERN_SUCCESS) {
+ fprintf(stderr, "detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
+ }
+ else {
+ int res = ptrace(PT_DETACH, pid, 0, 0);
+ if (res < 0) {
+ fprintf(stderr, "detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res);
+ }
+ }
+
mach_port_deallocate(mach_task_self(), gTask);
id symbolicator = getSymbolicator(env, this_obj);
if (symbolicator != nil) {
@@ -538,7 +630,7 @@
/* Couldn't find entry point. error_message should contain some
* platform dependent error message.
*/
- THROW_NEW_DEBUGGER_EXCEPTION(error_message);
+ THROW_NEW_DEBUGGER_EXCEPTION_(error_message, (jlong)func);
}
return (jlong)func;
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/bsd/libproc_impl.c
--- a/agent/src/os/bsd/libproc_impl.c Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/bsd/libproc_impl.c Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -91,6 +91,14 @@
}
}
+void print_error(const char* format,...) {
+ va_list alist;
+ va_start(alist, format);
+ fputs("ERROR: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+}
+
bool is_debug() {
return _libsaproc_debug;
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/bsd/libproc_impl.h
--- a/agent/src/os/bsd/libproc_impl.h Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/bsd/libproc_impl.h Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -107,6 +107,7 @@
int pathmap_open(const char* name);
void print_debug(const char* format,...);
+void print_error(const char* format,...);
bool is_debug();
typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/bsd/ps_proc.c
--- a/agent/src/os/bsd/ps_proc.c Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/bsd/ps_proc.c Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -129,42 +129,66 @@
return (errno == 0)? true: false;
}
+static bool ptrace_continue(pid_t pid, int signal) {
+ // pass the signal to the process so we don't swallow it
+ if (ptrace(PTRACE_CONT, pid, NULL, signal) < 0) {
+ print_debug("ptrace(PTRACE_CONT, ..) failed for %d\n", pid);
+ return false;
+ }
+ return true;
+}
+
+// waits until the ATTACH has stopped the process
+// by signal SIGSTOP
+static bool ptrace_waitpid(pid_t pid) {
+ int ret;
+ int status;
+ do {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
+ // will still be pending and delivered when the process is DETACHED and the process
+ // will go to sleep.
+ if (WSTOPSIG(status) == SIGSTOP) {
+ // Debuggee stopped by SIGSTOP.
+ return true;
+ }
+ if (!ptrace_continue(pid, WSTOPSIG(status))) {
+ print_error("Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+ return false;
+ }
+ } else {
+ print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ print_debug("waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ print_debug("waitpid() failed. Unexpected error %d\n",errno);
+ }
+ return false;
+ }
+ } while(true);
+}
+
// attach to a process/thread specified by "pid"
static bool ptrace_attach(pid_t pid) {
if (ptrace(PT_ATTACH, pid, NULL, 0) < 0) {
print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
return false;
} else {
- int ret;
- int status;
- do {
- // Wait for debuggee to stop.
- ret = waitpid(pid, &status, 0);
- if (ret >= 0) {
- if (WIFSTOPPED(status)) {
- // Debuggee stopped.
- return true;
- } else {
- print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
- return false;
- }
- } else {
- switch (errno) {
- case EINTR:
- continue;
- break;
- case ECHILD:
- print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
- break;
- case EINVAL:
- print_debug("waitpid() failed. Invalid options argument.\n");
- break;
- default:
- print_debug("waitpid() failed. Unexpected error %d\n",errno);
- }
- return false;
- }
- } while(true);
+ return ptrace_waitpid(pid);
}
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/linux/LinuxDebuggerLocal.c
--- a/agent/src/os/linux/LinuxDebuggerLocal.c Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/linux/LinuxDebuggerLocal.c Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -25,6 +25,13 @@
#include
#include "libproc.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
#if defined(x86_64) && !defined(amd64)
#define amd64 1
#endif
@@ -154,6 +161,39 @@
}
}
+
+/*
+ * Verify that a named ELF binary file (core or executable) has the same
+ * bitness as ourselves.
+ * Throw an exception if there is a mismatch or other problem.
+ *
+ * If we proceed using a mismatched debugger/debuggee, the best to hope
+ * for is a missing symbol, the worst is a crash searching for debug symbols.
+ */
+void verifyBitness(JNIEnv *env, const char *binaryName) {
+ int fd = open(binaryName, O_RDONLY);
+ if (fd < 0) {
+ THROW_NEW_DEBUGGER_EXCEPTION("cannot open binary file");
+ }
+ unsigned char elf_ident[EI_NIDENT];
+ int i = read(fd, &elf_ident, sizeof(elf_ident));
+ close(fd);
+
+ if (i < 0) {
+ THROW_NEW_DEBUGGER_EXCEPTION("cannot read binary file");
+ }
+#ifndef _LP64
+ if (elf_ident[EI_CLASS] == ELFCLASS64) {
+ THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 64 bit, use 64-bit java for debugger");
+ }
+#else
+ if (elf_ident[EI_CLASS] != ELFCLASS64) {
+ THROW_NEW_DEBUGGER_EXCEPTION("debuggee is 32 bit, use 32 bit java for debugger");
+ }
+#endif
+}
+
+
/*
* Class: sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal
* Method: attach0
@@ -162,6 +202,12 @@
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_attach0__I
(JNIEnv *env, jobject this_obj, jint jpid) {
+ // For bitness checking, locate binary at /proc/jpid/exe
+ char buf[PATH_MAX];
+ snprintf((char *) &buf, PATH_MAX, "/proc/%d/exe", jpid);
+ verifyBitness(env, (char *) &buf);
+ CHECK_EXCEPTION;
+
struct ps_prochandle* ph;
if ( (ph = Pgrab(jpid)) == NULL) {
THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
@@ -187,6 +233,9 @@
coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy);
CHECK_EXCEPTION;
+ verifyBitness(env, execName_cstr);
+ CHECK_EXCEPTION;
+
if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) {
(*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
(*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/linux/libproc_impl.c
--- a/agent/src/os/linux/libproc_impl.c Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/linux/libproc_impl.c Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -92,6 +92,14 @@
}
}
+void print_error(const char* format,...) {
+ va_list alist;
+ va_start(alist, format);
+ fputs("ERROR: ", stderr);
+ vfprintf(stderr, format, alist);
+ va_end(alist);
+}
+
bool is_debug() {
return _libsaproc_debug;
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/linux/libproc_impl.h
--- a/agent/src/os/linux/libproc_impl.h Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/linux/libproc_impl.h Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -105,6 +105,7 @@
int pathmap_open(const char* name);
void print_debug(const char* format,...);
+void print_error(const char* format,...);
bool is_debug();
typedef bool (*thread_info_callback)(struct ps_prochandle* ph, pthread_t pid, lwpid_t lwpid);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/linux/ps_proc.c
--- a/agent/src/os/linux/ps_proc.c Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/linux/ps_proc.c Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include "libproc_impl.h"
@@ -142,46 +143,71 @@
}
+static bool ptrace_continue(pid_t pid, int signal) {
+ // pass the signal to the process so we don't swallow it
+ if (ptrace(PTRACE_CONT, pid, NULL, signal) < 0) {
+ print_debug("ptrace(PTRACE_CONT, ..) failed for %d\n", pid);
+ return false;
+ }
+ return true;
+}
+
+// waits until the ATTACH has stopped the process
+// by signal SIGSTOP
+static bool ptrace_waitpid(pid_t pid) {
+ int ret;
+ int status;
+ while (true) {
+ // Wait for debuggee to stop.
+ ret = waitpid(pid, &status, 0);
+ if (ret == -1 && errno == ECHILD) {
+ // try cloned process.
+ ret = waitpid(pid, &status, __WALL);
+ }
+ if (ret >= 0) {
+ if (WIFSTOPPED(status)) {
+ // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
+ // will still be pending and delivered when the process is DETACHED and the process
+ // will go to sleep.
+ if (WSTOPSIG(status) == SIGSTOP) {
+ // Debuggee stopped by SIGSTOP.
+ return true;
+ }
+ if (!ptrace_continue(pid, WSTOPSIG(status))) {
+ print_error("Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
+ return false;
+ }
+ } else {
+ print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
+ return false;
+ }
+ } else {
+ switch (errno) {
+ case EINTR:
+ continue;
+ break;
+ case ECHILD:
+ print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
+ break;
+ case EINVAL:
+ print_debug("waitpid() failed. Invalid options argument.\n");
+ break;
+ default:
+ print_debug("waitpid() failed. Unexpected error %d\n",errno);
+ break;
+ }
+ return false;
+ }
+ }
+}
+
// attach to a process/thread specified by "pid"
static bool ptrace_attach(pid_t pid) {
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
print_debug("ptrace(PTRACE_ATTACH, ..) failed for %d\n", pid);
return false;
} else {
- int ret;
- int status;
- do {
- // Wait for debuggee to stop.
- ret = waitpid(pid, &status, 0);
- if (ret == -1 && errno == ECHILD) {
- // try cloned process.
- ret = waitpid(pid, &status, __WALL);
- }
- if (ret >= 0) {
- if (WIFSTOPPED(status)) {
- // Debuggee stopped.
- return true;
- } else {
- print_debug("waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
- return false;
- }
- } else {
- switch (errno) {
- case EINTR:
- continue;
- break;
- case ECHILD:
- print_debug("waitpid() failed. Child process pid (%d) does not exist \n", pid);
- break;
- case EINVAL:
- print_debug("waitpid() failed. Invalid options argument.\n");
- break;
- default:
- print_debug("waitpid() failed. Unexpected error %d\n",errno);
- }
- return false;
- }
- } while(true);
+ return ptrace_waitpid(pid);
}
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/os/win32/windbg/sawindbg.cpp
--- a/agent/src/os/win32/windbg/sawindbg.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/os/win32/windbg/sawindbg.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -372,8 +372,7 @@
We are attaching to a process in 'read-only' mode. i.e., we do not want to
put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of
- usage this should suffice. We are not intending to use this for full-fledged
- ProcessControl implementation to be used with BugSpotAgent.
+ usage this should suffice.
Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h.
In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/asm/amd64/AMD64FloatRegister.java
--- a/agent/src/share/classes/sun/jvm/hotspot/asm/amd64/AMD64FloatRegister.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +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.
- *
- */
-
-package sun.jvm.hotspot.asm.amd64;
-
-import sun.jvm.hotspot.asm.Register;
-import sun.jvm.hotspot.utilities.Assert;
-
-public class AMD64FloatRegister extends Register {
-
- public AMD64FloatRegister(int number) {
- super(number);
- }
-
- public int getNumber() {
- return number;
- }
-
- public int getNumberOfRegisters() {
- return AMD64FloatRegisters.getNumRegisters();
- }
-
- public boolean isFloat() {
- return true;
- }
-
- public boolean isFramePointer() {
- return false;
- }
-
- public boolean isStackPointer() {
- return false;
- }
-
- public boolean isValid() {
- return number >= 0 && number < AMD64FloatRegisters.getNumRegisters();
- }
-
- public String toString() {
- return AMD64FloatRegisters.getRegisterName(number);
- }
-
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1536 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.filechooser.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.posix.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-import sun.jvm.hotspot.livejvm.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.*;
-import sun.jvm.hotspot.utilities.*;
-
-/** The BugSpot component. This is embeddable in an application by
- virtue of its being a JComponent. It (currently) requires the use
- of a menu bar which can be fetched via getMenuBar(). This is
- intended ultimately to replace HSDB. */
-
-public class BugSpot extends JPanel {
- public BugSpot() {
- super();
- Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
- public void run() {
- detachDebugger();
- }
- });
- }
-
- /** Turn on or off MDI (Multiple Document Interface) mode. When MDI
- is enabled, the BugSpot component contains a JDesktopPane and all
- windows are JInternalFrames. When disabled, only the menu bar is
- relevant. */
- public void setMDIMode(boolean onOrOff) {
- mdiMode = onOrOff;
- }
-
- /** Indicates whether MDI mode is enabled. */
- public boolean getMDIMode() {
- return mdiMode;
- }
-
- /** Build user interface widgets. This must be called before adding
- the BugSpot component to its parent. */
- public void build() {
- setLayout(new BorderLayout());
-
- menuBar = new JMenuBar();
-
- attachMenuItems = new java.util.ArrayList();
- detachMenuItems = new java.util.ArrayList();
- debugMenuItems = new java.util.ArrayList();
- suspendDebugMenuItems = new java.util.ArrayList();
- resumeDebugMenuItems = new java.util.ArrayList();
-
- //
- // File menu
- //
-
- JMenu menu = createMenu("File", 'F', 0);
- JMenuItem item;
- item = createMenuItem("Open source file...",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- openSourceFile();
- }
- },
- KeyEvent.VK_O, InputEvent.CTRL_MASK,
- 'O', 0);
- menu.add(item);
- detachMenuItems.add(item);
-
- menu.addSeparator();
-
- item = createMenuItem("Attach to process...",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showAttachDialog();
- }
- },
- 'A', 0);
- menu.add(item);
- attachMenuItems.add(item);
-
- item = createMenuItem("Detach",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- detach();
- }
- },
- 'D', 0);
- menu.add(item);
- detachMenuItems.add(item);
-
- // Disable detach menu items at first
- setMenuItemsEnabled(detachMenuItems, false);
-
- menu.addSeparator();
-
- menu.add(createMenuItem("Exit",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- detach();
- System.exit(0);
- }
- },
- 'x', 1));
-
- menuBar.add(menu);
-
- //
- // Debug menu
- //
-
- debugMenu = createMenu("Debug", 'D', 0);
- item = createMenuItem("Go",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (!attached) return;
- if (!isSuspended()) return;
- resume();
- }
- },
- KeyEvent.VK_F5, 0,
- 'G', 0);
- debugMenu.add(item);
- resumeDebugMenuItems.add(item);
-
- item = createMenuItem("Break",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- if (!attached) {
- System.err.println("Not attached");
- return;
- }
- if (isSuspended()) {
- System.err.println("Already suspended");
- return;
- }
- suspend();
- }
- },
- 'B', 0);
- debugMenu.add(item);
- suspendDebugMenuItems.add(item);
-
- debugMenu.addSeparator();
-
- item = createMenuItem("Threads...",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showThreadsDialog();
- }
- },
- 'T', 0);
- debugMenu.add(item);
- debugMenuItems.add(item);
- // FIXME: belongs under "View -> Debug Windows"
- item = createMenuItem("Memory",
- new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- showMemoryDialog();
- }
- },
- 'M', 0);
- debugMenu.add(item);
- debugMenuItems.add(item);
-
- debugMenu.setEnabled(false);
- menuBar.add(debugMenu);
-
- if (mdiMode) {
- desktop = new JDesktopPane();
- add(desktop, BorderLayout.CENTER);
- }
-
- fixedWidthFont = GraphicsUtilities.lookupFont("Courier");
-
- debugEventTimer = new javax.swing.Timer(100, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- pollForDebugEvent();
- }
- });
- }
-
- public JMenuBar getMenuBar() {
- return menuBar;
- }
-
- public void showAttachDialog() {
- setMenuItemsEnabled(attachMenuItems, false);
- final FrameWrapper attachDialog = newFrame("Attach to process");
- attachDialog.getContentPane().setLayout(new BorderLayout());
- attachDialog.setClosable(true);
- attachDialog.setResizable(true);
-
- JPanel panel = new JPanel();
- panel.setLayout(new BorderLayout());
- panel.setBorder(GraphicsUtilities.newBorder(5));
- attachDialog.setBackground(panel.getBackground());
-
- JPanel listPanel = new JPanel();
- listPanel.setLayout(new BorderLayout());
- final ProcessListPanel plist = new ProcessListPanel(getLocalDebugger());
- panel.add(plist, BorderLayout.CENTER);
- JCheckBox check = new JCheckBox("Update list continuously");
- check.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- plist.start();
- } else {
- plist.stop();
- }
- }
- });
- listPanel.add(plist, BorderLayout.CENTER);
- listPanel.add(check, BorderLayout.SOUTH);
- panel.add(listPanel, BorderLayout.CENTER);
- attachDialog.getContentPane().add(panel, BorderLayout.CENTER);
- attachDialog.setClosingActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- plist.stop();
- setMenuItemsEnabled(attachMenuItems, true);
- }
- });
-
- ActionListener attacher = new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- plist.stop();
- attachDialog.setVisible(false);
- removeFrame(attachDialog);
- ProcessInfo info = plist.getSelectedProcess();
- if (info != null) {
- attach(info.getPid());
- }
- }
- };
-
- Box hbox = Box.createHorizontalBox();
- hbox.add(Box.createGlue());
- JButton button = new JButton("OK");
- button.addActionListener(attacher);
- hbox.add(button);
- hbox.add(Box.createHorizontalStrut(20));
- button = new JButton("Cancel");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- plist.stop();
- attachDialog.setVisible(false);
- removeFrame(attachDialog);
- setMenuItemsEnabled(attachMenuItems, true);
- }
- });
- hbox.add(button);
- hbox.add(Box.createGlue());
- panel = new JPanel();
- panel.setBorder(GraphicsUtilities.newBorder(5));
- panel.add(hbox);
-
- attachDialog.getContentPane().add(panel, BorderLayout.SOUTH);
-
- addFrame(attachDialog);
- attachDialog.pack();
- attachDialog.setSize(400, 300);
- GraphicsUtilities.centerInContainer(attachDialog.getComponent(),
- getParentDimension(attachDialog.getComponent()));
- attachDialog.setVisible(true);
- }
-
- public void showThreadsDialog() {
- final FrameWrapper threadsDialog = newFrame("Threads");
- threadsDialog.getContentPane().setLayout(new BorderLayout());
- threadsDialog.setClosable(true);
- threadsDialog.setResizable(true);
-
- ThreadListPanel threads = new ThreadListPanel(getCDebugger(), getAgent().isJavaMode());
- threads.addListener(new ThreadListPanel.Listener() {
- public void setFocus(ThreadProxy thread, JavaThread jthread) {
- setCurrentThread(thread);
- // FIXME: print this to GUI, bring some windows to foreground
- System.err.println("Focus changed to thread " + thread);
- }
- });
- threads.setBorder(GraphicsUtilities.newBorder(5));
- threadsDialog.getContentPane().add(threads);
- addFrame(threadsDialog);
- threadsDialog.pack();
- GraphicsUtilities.reshapeToAspectRatio(threadsDialog.getComponent(),
- 3.0f,
- 0.9f,
- getParentDimension(threadsDialog.getComponent()));
- GraphicsUtilities.centerInContainer(threadsDialog.getComponent(),
- getParentDimension(threadsDialog.getComponent()));
- threadsDialog.setVisible(true);
- }
-
- public void showMemoryDialog() {
- final FrameWrapper memoryDialog = newFrame("Memory");
- memoryDialog.getContentPane().setLayout(new BorderLayout());
- memoryDialog.setClosable(true);
- memoryDialog.setResizable(true);
-
- memoryDialog.getContentPane().add(new MemoryViewer(getDebugger(),
- (getDebugger().getMachineDescription().getAddressSize() == 8)),
- BorderLayout.CENTER);
- addFrame(memoryDialog);
- memoryDialog.pack();
- GraphicsUtilities.reshapeToAspectRatio(memoryDialog.getComponent(),
- 1.0f,
- 0.7f,
- getParentDimension(memoryDialog.getComponent()));
- GraphicsUtilities.centerInContainer(memoryDialog.getComponent(),
- getParentDimension(memoryDialog.getComponent()));
- memoryDialog.setVisible(true);
- }
-
- /** Changes the editor factory this debugger uses to display source
- code. Specified factory may be null, in which case the default
- factory is used. */
- public void setEditorFactory(EditorFactory fact) {
- if (fact != null) {
- editorFact = fact;
- } else {
- editorFact = new DefaultEditorFactory();
- }
- }
-
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- private WorkerThread workerThread;
- private boolean mdiMode;
- private JVMDebugger localDebugger;
- private BugSpotAgent agent = new BugSpotAgent();
- private JMenuBar menuBar;
- /** List */
- private java.util.List attachMenuItems;
- private java.util.List detachMenuItems;
- private java.util.List debugMenuItems;
- private java.util.List suspendDebugMenuItems;
- private java.util.List resumeDebugMenuItems;
- private FrameWrapper stackFrame;
- private VariablePanel localsPanel;
- private StackTracePanel stackTracePanel;
- private FrameWrapper registerFrame;
- private RegisterPanel registerPanel;
- // Used for mixed-language stack traces
- private Map threadToJavaThreadMap;
-
- private JMenu debugMenu;
-
- // MDI mode only: desktop pane
- private JDesktopPane desktop;
-
- // Attach/detach state
- private boolean attached;
-
- // Suspension (combined Java/C++) state
- private boolean suspended;
-
- // Fixed-width font
- private Font fixedWidthFont;
-
- // Breakpoint setting
- // Maps Strings to List/**/
- private Map sourceFileToLineNumberInfoMap;
- // Maps Strings (file names) to Sets of Integers (line numbers)
- private Map fileToBreakpointMap;
-
- // Debug events
- private javax.swing.Timer debugEventTimer;
-
- // Java debug events
- private boolean javaEventPending;
-
- static class BreakpointResult {
- private boolean success;
- private boolean set;
- private int lineNo;
- private String why;
-
- /** For positive results */
- BreakpointResult(boolean success, boolean set, int lineNo) {
- this(success, set, lineNo, null);
- }
-
- /** For negative results */
- BreakpointResult(boolean success, boolean set, int lineNo, String why) {
- this.success = success;
- this.set = set;
- this.lineNo = lineNo;
- this.why = why;
- }
-
- public boolean succeeded() {
- return success;
- }
-
- public boolean set() {
- return set;
- }
-
- /** Line at which the breakpoint was actually set; only valid if
- succeeded() returns true */
- public int getLine() {
- return lineNo;
- }
-
- public String getWhy() {
- return why;
- }
- }
-
-
- // Editors for source code. File name-to-Editor mapping.
- private Map editors;
- private EditorFactory editorFact = new DefaultEditorFactory();
- private EditorCommands editorComm = new EditorCommands() {
- public void windowClosed(Editor editor) {
- editors.remove(editor.getSourceFileName());
- }
-
- public void toggleBreakpointAtLine(Editor editor, int lineNumber) {
- // FIXME: handle "lazy" breakpoints where the source file has
- // been opened with some other mechanism (File -> Open) and we
- // don't have debug information pointing to that file yet
- // FIXME: NOT FINISHED
-
- BreakpointResult res =
- handleBreakpointToggle(editor, lineNumber);
- if (res.succeeded()) {
- if (res.set()) {
- editor.showBreakpointAtLine(res.getLine());
- } else {
- editor.clearBreakpointAtLine(res.getLine());
- }
- } else {
- String why = res.getWhy();
- if (why == null) {
- why = "";
- } else {
- why = ": " + why;
- }
- showMessageDialog("Unable to toggle breakpoint" + why,
- "Unable to toggle breakpoint",
- JOptionPane.WARNING_MESSAGE);
- }
- }
- };
-
- private void attach(final int pid) {
- try {
- getAgent().attach(pid);
- setMenuItemsEnabled(detachMenuItems, true);
- setMenuItemsEnabled(suspendDebugMenuItems, false);
- setMenuItemsEnabled(resumeDebugMenuItems, true);
- debugMenu.setEnabled(true);
- attached = true;
- suspended = true;
-
- if (getAgent().isJavaMode()) {
- System.err.println("Java HotSpot(TM) virtual machine detected.");
- } else {
- System.err.println("(No Java(TM) virtual machine detected)");
- }
-
- // Set up editor map
- editors = new HashMap();
-
- // Initialize breakpoints
- fileToBreakpointMap = new HashMap();
-
- // Create combined stack trace and local variable panel
- JPanel framePanel = new JPanel();
- framePanel.setLayout(new BorderLayout());
- framePanel.setBorder(GraphicsUtilities.newBorder(5));
- localsPanel = new VariablePanel();
- JTabbedPane tab = new JTabbedPane();
- tab.addTab("Locals", localsPanel);
- tab.setTabPlacement(JTabbedPane.BOTTOM);
- framePanel.add(tab, BorderLayout.CENTER);
- JPanel stackPanel = new JPanel();
- stackPanel.setLayout(new BoxLayout(stackPanel, BoxLayout.X_AXIS));
- stackPanel.add(new JLabel("Context:"));
- stackPanel.add(Box.createHorizontalStrut(5));
- stackTracePanel = new StackTracePanel();
- stackTracePanel.addListener(new StackTracePanel.Listener() {
- public void frameChanged(CFrame fr, JavaVFrame jfr) {
- setCurrentFrame(fr, jfr);
- }
- });
- stackPanel.add(stackTracePanel);
- framePanel.add(stackPanel, BorderLayout.NORTH);
- stackFrame = newFrame("Stack");
- stackFrame.getContentPane().setLayout(new BorderLayout());
- stackFrame.getContentPane().add(framePanel, BorderLayout.CENTER);
- stackFrame.setResizable(true);
- stackFrame.setClosable(false);
- addFrame(stackFrame);
- stackFrame.setSize(400, 200);
- GraphicsUtilities.moveToInContainer(stackFrame.getComponent(), 0.0f, 1.0f, 0, 20);
- stackFrame.setVisible(true);
-
- // Create register panel
- registerPanel = new RegisterPanel();
- registerPanel.setFont(fixedWidthFont);
- registerFrame = newFrame("Registers");
- registerFrame.getContentPane().setLayout(new BorderLayout());
- registerFrame.getContentPane().add(registerPanel, BorderLayout.CENTER);
- addFrame(registerFrame);
- registerFrame.setResizable(true);
- registerFrame.setClosable(false);
- registerFrame.setSize(225, 200);
- GraphicsUtilities.moveToInContainer(registerFrame.getComponent(),
- 1.0f, 0.0f, 0, 0);
- registerFrame.setVisible(true);
-
- resetCurrentThread();
- } catch (DebuggerException e) {
- final String errMsg = formatMessage(e.getMessage(), 80);
- setMenuItemsEnabled(attachMenuItems, true);
- showMessageDialog("Unable to connect to process ID " + pid + ":\n\n" + errMsg,
- "Unable to Connect",
- JOptionPane.WARNING_MESSAGE);
- getAgent().detach();
- }
- }
-
- private synchronized void detachDebugger() {
- if (!attached) {
- return;
- }
- if (isSuspended()) {
- resume(); // Necessary for JVMDI resumption
- }
- getAgent().detach();
- // FIXME: clear out breakpoints (both Java and C/C++) from target
- // process
- sourceFileToLineNumberInfoMap = null;
- fileToBreakpointMap = null;
- threadToJavaThreadMap = null;
- editors = null;
- attached = false;
- }
-
- private synchronized void detach() {
- detachDebugger();
- setMenuItemsEnabled(attachMenuItems, true);
- setMenuItemsEnabled(detachMenuItems, false);
- debugMenu.setEnabled(false);
- if (mdiMode) {
- // FIXME: is this sufficient, or will I have to do anything else
- // to the components to kill them off? What about WorkerThreads?
- desktop.removeAll();
- desktop.invalidate();
- desktop.validate();
- desktop.repaint();
- }
- // FIXME: keep track of all windows and close them even in non-MDI
- // mode
- debugEventTimer.stop();
- }
-
- // Returns a Debugger for processes on the local machine. This is
- // only used to fetch the process list.
- private Debugger getLocalDebugger() {
- if (localDebugger == null) {
- String os = PlatformInfo.getOS();
- String cpu = PlatformInfo.getCPU();
-
- if (os.equals("win32")) {
- if (!cpu.equals("x86")) {
- throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Windows");
- }
-
- localDebugger = new WindbgDebuggerLocal(new MachineDescriptionIntelX86(), true);
- } else if (os.equals("linux")) {
- if (!cpu.equals("x86")) {
- throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Linux");
- }
-
- // FIXME: figure out how to specify path to debugger module
- throw new RuntimeException("FIXME: figure out how to specify path to debugger module");
- // localDebugger = new PosixDebuggerLocal(new MachineDescriptionIntelX86(), true);
- } else {
- // FIXME: port to Solaris
- throw new DebuggerException("Unsupported OS \"" + os + "\"");
- }
-
- // FIXME: we require that the primitive type sizes be configured
- // in order to use basic functionality in class Address such as
- // the fetching of floating-point values. There are a lot of
- // assumptions in the current code that Java floats and doubles
- // are of equivalent size to C values. The configurability of the
- // primitive type sizes hasn't seemed necessary and in this kind
- // of debugging scenario (namely, debugging arbitrary C++
- // processes) it appears difficult to support that kind of
- // flexibility.
- localDebugger.configureJavaPrimitiveTypeSizes(1, 1, 2, 8, 4, 4, 8, 2);
- }
-
- return localDebugger;
- }
-
- private BugSpotAgent getAgent() {
- return agent;
- }
-
- private Debugger getDebugger() {
- return getAgent().getDebugger();
- }
-
- private CDebugger getCDebugger() {
- return getAgent().getCDebugger();
- }
-
- private void resetCurrentThread() {
- setCurrentThread((ThreadProxy) getCDebugger().getThreadList().get(0));
- }
-
- private void setCurrentThread(ThreadProxy t) {
- // Create stack trace
- // FIXME: add ability to intermix C/Java frames
- java.util.List trace = new ArrayList();
- CFrame fr = getCDebugger().topFrameForThread(t);
- while (fr != null) {
- trace.add(new StackTraceEntry(fr, getCDebugger()));
- try {
- fr = fr.sender(t);
- } catch (AddressException e) {
- e.printStackTrace();
- showMessageDialog("Error while walking stack; stack trace will be truncated\n(see console for details)",
- "Error walking stack",
- JOptionPane.WARNING_MESSAGE);
- fr = null;
- }
- }
- JavaThread jthread = javaThreadForProxy(t);
- if (jthread != null) {
- // Java mode, and we have a Java thread.
- // Find all Java frames on the stack. We currently do this in a
- // manner which involves minimal interaction between the Java
- // and C/C++ debugging systems: any C frame which has a PC in an
- // unknown location (i.e., not in any DSO) is assumed to be a
- // Java frame. We merge stack segments of unknown frames with
- // segments of Java frames beginning with native methods.
- java.util.List javaTrace = new ArrayList();
- VFrame vf = jthread.getLastJavaVFrameDbg();
- while (vf != null) {
- if (vf.isJavaFrame()) {
- javaTrace.add(new StackTraceEntry((JavaVFrame) vf));
- vf = vf.sender();
- }
- }
- // Merge stack traces
- java.util.List mergedTrace = new ArrayList();
- int c = 0;
- int j = 0;
- while (c < trace.size()) {
- StackTraceEntry entry = (StackTraceEntry) trace.get(c);
- if (entry.isUnknownCFrame()) {
- boolean gotJavaFrame = false;
- while (j < javaTrace.size()) {
- StackTraceEntry javaEntry = (StackTraceEntry) javaTrace.get(j);
- JavaVFrame jvf = javaEntry.getJavaFrame();
- Method m = jvf.getMethod();
- if (!m.isNative() || !gotJavaFrame) {
- gotJavaFrame = true;
- mergedTrace.add(javaEntry);
- ++j;
- } else {
- break; // Reached native method; have intervening C frames
- }
- }
- if (gotJavaFrame) {
- // Skip this sequence of unknown frames, as we've
- // successfully identified it as Java frames
- while (c < trace.size() && entry.isUnknownCFrame()) {
- ++c;
- if (c < trace.size()) {
- entry = (StackTraceEntry) trace.get(c);
- }
- }
- continue;
- }
- }
- // If we get here, we either have an unknown frame we didn't
- // know how to categorize or we have a known C frame. Add it
- // to the trace.
- mergedTrace.add(entry);
- ++c;
- }
- trace = mergedTrace;
- }
- stackTracePanel.setTrace(trace);
-
- registerPanel.update(t);
- }
-
- private void setCurrentFrame(CFrame fr, JavaVFrame jfr) {
- localsPanel.clear();
-
- if (fr != null) {
- localsPanel.update(fr);
-
- // FIXME: load source file if we can find it, otherwise display disassembly
- LoadObject lo = getCDebugger().loadObjectContainingPC(fr.pc());
- if (lo != null) {
- CDebugInfoDataBase db = lo.getDebugInfoDataBase();
- if (db != null) {
- LineNumberInfo info = db.lineNumberForPC(fr.pc());
- if (info != null) {
- System.err.println("PC " + fr.pc() + ": Source file \"" +
- info.getSourceFileName() +
- "\", line number " +
- info.getLineNumber() +
- ", PC range [" +
- info.getStartPC() +
- ", " +
- info.getEndPC() +
- ")");
- // OK, here we go...
- showLineNumber(null, info.getSourceFileName(), info.getLineNumber());
- } else {
- System.err.println("(No line number information for PC " + fr.pc() + ")");
- // Dump line number information for database
- db.iterate(new LineNumberVisitor() {
- public void doLineNumber(LineNumberInfo info) {
- System.err.println(" Source file \"" +
- info.getSourceFileName() +
- "\", line number " +
- info.getLineNumber() +
- ", PC range [" +
- info.getStartPC() +
- ", " +
- info.getEndPC() +
- ")");
- }
- });
- }
- }
- }
- } else {
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(jfr != null, "Must have either C or Java frame");
- }
- localsPanel.update(jfr);
- // See whether we can locate source file and line number
- // FIXME: infer pathmap entries from user's locating of this
- // source file
- // FIXME: figure out what to do for native methods. Possible to
- // go to line number for the native method declaration?
- Method m = jfr.getMethod();
- Symbol sfn = ((InstanceKlass) m.getMethodHolder()).getSourceFileName();
- if (sfn != null) {
- int bci = jfr.getBCI();
- int lineNo = m.getLineNumberFromBCI(bci);
- if (lineNo >= 0) {
- // FIXME: show disassembly otherwise
- showLineNumber(packageName(m.getMethodHolder().getName().asString()),
- sfn.asString(), lineNo);
- }
- }
- }
- }
-
- private String packageName(String str) {
- int idx = str.lastIndexOf('/');
- if (idx < 0) {
- return "";
- }
- return str.substring(0, idx).replace('/', '.');
- }
-
- private JavaThread javaThreadForProxy(ThreadProxy t) {
- if (!getAgent().isJavaMode()) {
- return null;
- }
- if (threadToJavaThreadMap == null) {
- threadToJavaThreadMap = new HashMap();
- Threads threads = VM.getVM().getThreads();
- for (JavaThread thr = threads.first(); thr != null; thr = thr.next()) {
- threadToJavaThreadMap.put(thr.getThreadProxy(), thr);
- }
- }
- return (JavaThread) threadToJavaThreadMap.get(t);
- }
-
- private static JMenu createMenu(String name, char mnemonic, int mnemonicPos) {
- JMenu menu = new JMenu(name);
- menu.setMnemonic(mnemonic);
- menu.setDisplayedMnemonicIndex(mnemonicPos);
- return menu;
- }
-
- private static JMenuItem createMenuItem(String name, ActionListener l) {
- JMenuItem item = new JMenuItem(name);
- item.addActionListener(l);
- return item;
- }
-
- private static JMenuItem createMenuItemInternal(String name, ActionListener l, int accelerator, int modifiers) {
- JMenuItem item = createMenuItem(name, l);
- item.setAccelerator(KeyStroke.getKeyStroke(accelerator, modifiers));
- return item;
- }
-
- private static JMenuItem createMenuItem(String name, ActionListener l, int accelerator) {
- return createMenuItemInternal(name, l, accelerator, 0);
- }
-
- private static JMenuItem createMenuItem(String name, ActionListener l, char mnemonic, int mnemonicPos) {
- JMenuItem item = createMenuItem(name, l);
- item.setMnemonic(mnemonic);
- item.setDisplayedMnemonicIndex(mnemonicPos);
- return item;
- }
-
- private static JMenuItem createMenuItem(String name,
- ActionListener l,
- int accelerator,
- int acceleratorMods,
- char mnemonic,
- int mnemonicPos) {
- JMenuItem item = createMenuItemInternal(name, l, accelerator, acceleratorMods);
- item.setMnemonic(mnemonic);
- item.setDisplayedMnemonicIndex(mnemonicPos);
- return item;
- }
-
- /** Punctuates the given string with \n's where necessary to not
- exceed the given number of characters per line. Strips
- extraneous whitespace. */
- private static String formatMessage(String message, int charsPerLine) {
- StringBuffer buf = new StringBuffer(message.length());
- StringTokenizer tokenizer = new StringTokenizer(message);
- int curLineLength = 0;
- while (tokenizer.hasMoreTokens()) {
- String tok = tokenizer.nextToken();
- if (curLineLength + tok.length() > charsPerLine) {
- buf.append('\n');
- curLineLength = 0;
- } else {
- if (curLineLength != 0) {
- buf.append(' ');
- ++curLineLength;
- }
- }
- buf.append(tok);
- curLineLength += tok.length();
- }
- return buf.toString();
- }
-
- private void setMenuItemsEnabled(java.util.List items, boolean enabled) {
- for (Iterator iter = items.iterator(); iter.hasNext(); ) {
- ((JMenuItem) iter.next()).setEnabled(enabled);
- }
- }
-
- private void showMessageDialog(final String message, final String title, final int jOptionPaneKind) {
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- if (mdiMode) {
- JOptionPane.showInternalMessageDialog(desktop, message, title, jOptionPaneKind);
- } else {
- JOptionPane.showMessageDialog(null, message, title, jOptionPaneKind);
- }
- }
- });
- }
-
- private FrameWrapper newFrame(String title) {
- if (mdiMode) {
- return new JInternalFrameWrapper(new JInternalFrame(title));
- } else {
- return new JFrameWrapper(new JFrame(title));
- }
- }
-
- private void addFrame(FrameWrapper frame) {
- if (mdiMode) {
- desktop.add(frame.getComponent());
- }
- }
-
- private void removeFrame(FrameWrapper frame) {
- if (mdiMode) {
- desktop.remove(frame.getComponent());
- desktop.invalidate();
- desktop.validate();
- desktop.repaint();
- }
- // FIXME: do something when not in MDI mode
- }
-
- private Dimension getParentDimension(Component c) {
- if (mdiMode) {
- return desktop.getSize();
- } else {
- return Toolkit.getDefaultToolkit().getScreenSize();
- }
- }
-
- // Default editor implementation
- class DefaultEditor implements Editor {
- private DefaultEditorFactory factory;
- private FrameWrapper editorFrame;
- private String filename;
- private SourceCodePanel code;
- private boolean shown;
- private Object userData;
-
- public DefaultEditor(DefaultEditorFactory fact, String filename, final EditorCommands comm) {
- this.filename = filename;
- this.factory = fact;
- editorFrame = newFrame(filename);
- code = new SourceCodePanel();
- // FIXME: when font changes, change font in editors as well
- code.setFont(fixedWidthFont);
- editorFrame.getContentPane().add(code);
- editorFrame.setClosable(true);
- editorFrame.setResizable(true);
- editorFrame.setClosingActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- comm.windowClosed(DefaultEditor.this);
- removeFrame(editorFrame);
- editorFrame.dispose();
- factory.editorClosed(DefaultEditor.this);
- }
- });
- editorFrame.setActivatedActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- factory.makeEditorCurrent(DefaultEditor.this);
- code.requestFocus();
- }
- });
- code.setEditorCommands(comm, this);
- }
-
- public boolean openFile() { return code.openFile(filename); }
- public String getSourceFileName() { return filename; }
- public int getCurrentLineNumber() { return code.getCurrentLineNumber(); }
- public void showLineNumber(int lineNo) {
- if (!shown) {
- addFrame(editorFrame);
- GraphicsUtilities.reshapeToAspectRatio(editorFrame.getComponent(),
- 1.0f,
- 0.85f,
- getParentDimension(editorFrame.getComponent()));
- editorFrame.setVisible(true);
- shown = true;
- }
- code.showLineNumber(lineNo);
- editorFrame.toFront();
- }
- public void highlightLineNumber(int lineNo) { code.highlightLineNumber(lineNo); }
- public void showBreakpointAtLine(int lineNo) { code.showBreakpointAtLine(lineNo); }
- public boolean hasBreakpointAtLine(int lineNo) { return code.hasBreakpointAtLine(lineNo); }
- public void clearBreakpointAtLine(int lineNo) { code.clearBreakpointAtLine(lineNo); }
- public void clearBreakpoints() { code.clearBreakpoints(); }
- public void setUserData(Object o) { userData = o; }
- public Object getUserData() { return userData; }
- public void toFront() { editorFrame.toFront();
- factory.makeEditorCurrent(this); }
- }
-
- class DefaultEditorFactory implements EditorFactory {
- private LinkedList/**/ editors = new LinkedList();
-
- public Editor openFile(String filename, EditorCommands commands) {
- DefaultEditor editor = new DefaultEditor(this, filename, editorComm);
- if (!editor.openFile()) {
- return null;
- }
- return editor;
- }
-
- public Editor getCurrentEditor() {
- if (editors.isEmpty()) {
- return null;
- }
- return (Editor) editors.getFirst();
- }
-
- void editorClosed(Editor editor) {
- editors.remove(editor);
- }
-
- void makeEditorCurrent(Editor editor) {
- editors.remove(editor);
- editors.addFirst(editor);
- }
- }
-
- // Helper class for loading .java files; show only those with
- // correct file name which are also in the correct package
- static class JavaFileFilter extends javax.swing.filechooser.FileFilter {
- private String packageName;
- private String fileName;
-
- JavaFileFilter(String packageName, String fileName) {
- this.packageName = packageName;
- this.fileName = fileName;
- }
-
- public boolean accept(File f) {
- if (f.isDirectory()) {
- return true;
- }
- // This rejects most files
- if (!f.getName().equals(fileName)) {
- return false;
- }
- // Ensure selected file is in the correct package
- PackageScanner scanner = new PackageScanner();
- String pkg = scanner.scan(f);
- if (!pkg.equals(packageName)) {
- return false;
- }
- return true;
- }
-
- public String getDescription() { return "Java source files"; }
- }
-
- // Auxiliary information used only for Java source files
- static class JavaUserData {
- private String packageName; // External format
- private String sourceFileName;
-
- /** Source file name is equivalent to that found in the .java
- file; i.e., not a full path */
- JavaUserData(String packageName, String sourceFileName) {
- this.packageName = packageName;
- this.sourceFileName = sourceFileName;
- }
-
- String packageName() { return packageName; }
- String sourceFileName() { return sourceFileName; }
- }
-
- // Opens a source file. This makes it available for the setting of
- // lazy breakpoints.
- private void openSourceFile() {
- JFileChooser chooser = new JFileChooser();
- chooser.setDialogTitle("Open source code file");
- chooser.setMultiSelectionEnabled(false);
- if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {
- return;
- }
- File chosen = chooser.getSelectedFile();
- if (chosen == null) {
- return;
- }
-
- // See whether we have a Java source file. If so, derive a package
- // name for it.
- String path = chosen.getPath();
- String name = null;
- JavaUserData data = null;
- if (path.endsWith(".java")) {
- PackageScanner scanner = new PackageScanner();
- String pkg = scanner.scan(chosen);
- // Now knowing both the package name and file name, we can put
- // this in the editor map and use it for setting breakpoints
- // later
- String fileName = chosen.getName();
- name = pkg + "." + fileName;
- data = new JavaUserData(pkg, fileName);
- } else {
- // FIXME: need pathmap mechanism
- name = path;
- }
- Editor editor = (Editor) editors.get(name);
- if (editor == null) {
- editor = editorFact.openFile(path, editorComm);
- if (editor == null) {
- showMessageDialog("Unable to open file \"" + path + "\" -- unexpected error.",
- "Unable to open file",
- JOptionPane.WARNING_MESSAGE);
- return;
- }
- editors.put(name, editor);
- if (data != null) {
- editor.setUserData(data);
- }
- } else {
- editor.toFront();
- }
- editor.showLineNumber(1);
- // Show breakpoints as well if we have any for this file
- Set set = (Set) fileToBreakpointMap.get(editor.getSourceFileName());
- if (set != null) {
- for (Iterator iter = set.iterator(); iter.hasNext(); ) {
- editor.showBreakpointAtLine(((Integer) iter.next()).intValue());
- }
- }
- }
-
- // Package name may be null, in which case the file is assumed to be
- // a C source file. Otherwise it is assumed to be a Java source file
- // and certain filtering rules will be applied.
- private void showLineNumber(String packageName, String fileName, int lineNumber) {
- String name;
- if (packageName == null) {
- name = fileName;
- } else {
- name = packageName + "." + fileName;
- }
- Editor editor = (Editor) editors.get(name);
- if (editor == null) {
- // See whether file exists
- File file = new File(fileName);
- String realFileName = fileName;
- if (!file.exists()) {
- // User must specify path to file
- JFileChooser chooser = new JFileChooser();
- chooser.setDialogTitle("Please locate " + fileName);
- chooser.setMultiSelectionEnabled(false);
- if (packageName != null) {
- chooser.setFileFilter(new JavaFileFilter(packageName, fileName));
- }
- int res = chooser.showOpenDialog(null);
- if (res != JFileChooser.APPROVE_OPTION) {
- // FIXME: show disassembly instead
- return;
- }
- // FIXME: would like to infer more from the selection; i.e.,
- // a pathmap leading up to this file
- File chosen = chooser.getSelectedFile();
- if (chosen == null) {
- return;
- }
- realFileName = chosen.getPath();
- }
- // Now instruct editor factory to open file
- editor = editorFact.openFile(realFileName, editorComm);
- if (editor == null) {
- showMessageDialog("Unable to open file \"" + realFileName + "\" -- unexpected error.",
- "Unable to open file",
- JOptionPane.WARNING_MESSAGE);
- return;
- }
- // Got an editor; put it in map
- editors.put(name, editor);
- // If Java source file, add additional information for later
- if (packageName != null) {
- editor.setUserData(new JavaUserData(packageName, fileName));
- }
- }
- // Got editor; show line
- editor.showLineNumber(lineNumber);
- editor.highlightLineNumber(lineNumber);
- // Show breakpoints as well if we have any for this file
- Set set = (Set) fileToBreakpointMap.get(editor.getSourceFileName());
- if (set != null) {
- for (Iterator iter = set.iterator(); iter.hasNext(); ) {
- editor.showBreakpointAtLine(((Integer) iter.next()).intValue());
- }
- }
- }
-
- //
- // Suspend/resume
- //
-
- private boolean isSuspended() {
- return suspended;
- }
-
- private synchronized void suspend() {
- setMenuItemsEnabled(resumeDebugMenuItems, true);
- setMenuItemsEnabled(suspendDebugMenuItems, false);
- BugSpotAgent agent = getAgent();
- if (agent.canInteractWithJava() && !agent.isJavaSuspended()) {
- agent.suspendJava();
- }
- agent.suspend();
- // FIXME: call VM.getVM().fireVMSuspended()
- resetCurrentThread();
- debugEventTimer.stop();
- suspended = true;
- }
-
- private synchronized void resume() {
- // Note: we don't wipe out the cached state like the
- // sourceFileToLineNumberInfoMap since it is too expensive to
- // recompute. Instead we recompute it if any DLLs are loaded or
- // unloaded.
- threadToJavaThreadMap = null;
- setMenuItemsEnabled(resumeDebugMenuItems, false);
- setMenuItemsEnabled(suspendDebugMenuItems, true);
- registerPanel.clear();
- // FIXME: call VM.getVM().fireVMResumed()
- BugSpotAgent agent = getAgent();
- agent.resume();
- if (agent.canInteractWithJava()) {
- if (agent.isJavaSuspended()) {
- agent.resumeJava();
- }
- if (javaEventPending) {
- javaEventPending = false;
- // Clear it out before resuming polling for events
- agent.javaEventContinue();
- }
- }
- agent.enableJavaInteraction();
- suspended = false;
- debugEventTimer.start();
- }
-
- //
- // Breakpoints
- //
-
- private synchronized BreakpointResult handleBreakpointToggle(Editor editor, int lineNumber) {
- // Currently we only use user data in editors to indicate Java
- // source files. If this changes then this code will need to
- // change.
- JavaUserData data = (JavaUserData) editor.getUserData();
- String filename = editor.getSourceFileName();
- if (data == null) {
- // C/C++ code
- // FIXME: as noted above in EditorCommands.toggleBreakpointAtLine,
- // this needs more work to handle "lazy" breakpoints in files
- // which we don't know about in the debug information yet
- CDebugger dbg = getCDebugger();
- ProcessControl prctl = dbg.getProcessControl();
- if (prctl == null) {
- return new BreakpointResult(false, false, 0, "Process control not enabled");
- }
- boolean mustSuspendAndResume = (!prctl.isSuspended());
- try {
- if (mustSuspendAndResume) {
- prctl.suspend();
- }
- // Search debug info for all DSOs
- LineNumberInfo info = getLineNumberInfo(filename, lineNumber);
- if (info != null) {
- Set bpset = (Set) fileToBreakpointMap.get(filename);
- if (bpset == null) {
- bpset = new HashSet();
- fileToBreakpointMap.put(filename, bpset);
- }
- Integer key = new Integer(info.getLineNumber());
- if (bpset.contains(key)) {
- // Clear breakpoint at this line's PC
- prctl.clearBreakpoint(info.getStartPC());
- bpset.remove(key);
- return new BreakpointResult(true, false, info.getLineNumber());
- } else {
- // Set breakpoint at this line's PC
- System.err.println("Setting breakpoint at PC " + info.getStartPC());
- prctl.setBreakpoint(info.getStartPC());
- bpset.add(key);
- return new BreakpointResult(true, true, info.getLineNumber());
- }
- } else {
- return new BreakpointResult(false, false, 0, "No debug information for this source file and line");
- }
- } finally {
- if (mustSuspendAndResume) {
- prctl.resume();
- }
- }
- } else {
- BugSpotAgent agent = getAgent();
- if (!agent.canInteractWithJava()) {
- String why;
- if (agent.isJavaInteractionDisabled()) {
- why = "Can not toggle Java breakpoints while stopped because\nof C/C++ debug events (breakpoints, single-stepping)";
- } else {
- why = "Could not talk to SA's JVMDI module to enable Java\nprogramming language breakpoints (run with -Xdebug -Xrunsa)";
- }
- return new BreakpointResult(false, false, 0, why);
- }
- Set bpset = (Set) fileToBreakpointMap.get(filename);
- if (bpset == null) {
- bpset = new HashSet();
- fileToBreakpointMap.put(filename, bpset);
- }
- boolean mustResumeAndSuspend = isSuspended();
- try {
- if (mustResumeAndSuspend) {
- agent.resume();
- }
- ServiceabilityAgentJVMDIModule.BreakpointToggleResult res =
- getAgent().toggleJavaBreakpoint(data.sourceFileName(),
- data.packageName(),
- lineNumber);
- if (res.getSuccess()) {
- Integer key = new Integer(res.getLineNumber());
- boolean addRemRes = false;
- if (res.getWasSet()) {
- addRemRes = bpset.add(key);
- System.err.println("Setting breakpoint at " + res.getMethodName() + res.getMethodSignature() +
- ", bci " + res.getBCI() + ", line " + res.getLineNumber());
- } else {
- addRemRes = bpset.remove(key);
- System.err.println("Clearing breakpoint at " + res.getMethodName() + res.getMethodSignature() +
- ", bci " + res.getBCI() + ", line " + res.getLineNumber());
- }
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(addRemRes, "Inconsistent Java breakpoint state with respect to target process");
- }
- return new BreakpointResult(true, res.getWasSet(), res.getLineNumber());
- } else {
- return new BreakpointResult(false, false, 0, res.getErrMsg());
- }
- } finally {
- if (mustResumeAndSuspend) {
- agent.suspend();
- resetCurrentThread();
- }
- }
- }
- }
-
- // Must call only when suspended
- private LineNumberInfo getLineNumberInfo(String filename, int lineNumber) {
- Map map = getSourceFileToLineNumberInfoMap();
- java.util.List infos = (java.util.List) map.get(filename);
- if (infos == null) {
- return null;
- }
- // Binary search for line number
- return searchLineNumbers(infos, lineNumber, 0, infos.size());
- }
-
- // Must call only when suspended
- private Map getSourceFileToLineNumberInfoMap() {
- if (sourceFileToLineNumberInfoMap == null) {
- // Build from debug info
- java.util.List loadObjects = getCDebugger().getLoadObjectList();
- final Map map = new HashMap();
- for (Iterator iter = loadObjects.iterator(); iter.hasNext(); ) {
- LoadObject lo = (LoadObject) iter.next();
- CDebugInfoDataBase db = lo.getDebugInfoDataBase();
- if (db != null) {
- db.iterate(new LineNumberVisitor() {
- public void doLineNumber(LineNumberInfo info) {
- String name = info.getSourceFileName();
- if (name != null) {
- java.util.List val = (java.util.List) map.get(name);
- if (val == null) {
- val = new ArrayList();
- map.put(name, val);
- }
- val.add(info);
- }
- }
- });
- }
- }
- // Sort all lists
- for (Iterator iter = map.values().iterator(); iter.hasNext(); ) {
- java.util.List list = (java.util.List) iter.next();
- Collections.sort(list, new Comparator() {
- public int compare(Object o1, Object o2) {
- LineNumberInfo l1 = (LineNumberInfo) o1;
- LineNumberInfo l2 = (LineNumberInfo) o2;
- int n1 = l1.getLineNumber();
- int n2 = l2.getLineNumber();
- if (n1 < n2) return -1;
- if (n1 == n2) return 0;
- return 1;
- }
- });
- }
- sourceFileToLineNumberInfoMap = map;
- }
- return sourceFileToLineNumberInfoMap;
- }
-
- private LineNumberInfo searchLineNumbers(java.util.List infoList, int lineNo, int lowIdx, int highIdx) {
- if (highIdx < lowIdx) return null;
- if (lowIdx == highIdx) {
- // Base case: see whether start PC is less than or equal to addr
- if (checkLineNumber(infoList, lineNo, lowIdx)) {
- return (LineNumberInfo) infoList.get(lowIdx);
- } else {
- return null;
- }
- } else if (lowIdx == highIdx - 1) {
- if (checkLineNumber(infoList, lineNo, lowIdx)) {
- return (LineNumberInfo) infoList.get(lowIdx);
- } else if (checkLineNumber(infoList, lineNo, highIdx)) {
- return (LineNumberInfo) infoList.get(highIdx);
- } else {
- return null;
- }
- }
- int midIdx = (lowIdx + highIdx) >> 1;
- LineNumberInfo info = (LineNumberInfo) infoList.get(midIdx);
- if (lineNo < info.getLineNumber()) {
- // Always move search down
- return searchLineNumbers(infoList, lineNo, lowIdx, midIdx);
- } else if (lineNo == info.getLineNumber()) {
- return info;
- } else {
- // Move search up
- return searchLineNumbers(infoList, lineNo, midIdx, highIdx);
- }
- }
-
- private boolean checkLineNumber(java.util.List infoList, int lineNo, int idx) {
- LineNumberInfo info = (LineNumberInfo) infoList.get(idx);
- return (info.getLineNumber() >= lineNo);
- }
-
- //
- // Debug events
- //
-
- private synchronized void pollForDebugEvent() {
- ProcessControl prctl = getCDebugger().getProcessControl();
- if (prctl == null) {
- return;
- }
- DebugEvent ev = prctl.debugEventPoll();
- if (ev != null) {
- DebugEvent.Type t = ev.getType();
- if (t == DebugEvent.Type.LOADOBJECT_LOAD ||
- t == DebugEvent.Type.LOADOBJECT_UNLOAD) {
- // Conservatively clear cached debug info state
- sourceFileToLineNumberInfoMap = null;
- // FIXME: would be very useful to have "stop on load/unload"
- // events
- // FIXME: must do work at these events to implement lazy
- // breakpoints
- prctl.debugEventContinue();
- } else if (t == DebugEvent.Type.BREAKPOINT) {
- // Note: Visual C++ only notifies on breakpoints it doesn't
- // know about
-
- // FIXME: put back test
- // if (!prctl.isBreakpointSet(ev.getPC())) {
- showMessageDialog("Breakpoint reached at PC " + ev.getPC(),
- "Breakpoint reached",
- JOptionPane.INFORMATION_MESSAGE);
- // }
- agent.disableJavaInteraction();
- suspend();
- prctl.debugEventContinue();
- } else if (t == DebugEvent.Type.SINGLE_STEP) {
- agent.disableJavaInteraction();
- suspend();
- prctl.debugEventContinue();
- } else if (t == DebugEvent.Type.ACCESS_VIOLATION) {
- showMessageDialog("Access violation attempting to " +
- (ev.getWasWrite() ? "write" : "read") +
- " address " + ev.getAddress() +
- " at PC " + ev.getPC(),
- "Access Violation",
- JOptionPane.WARNING_MESSAGE);
- agent.disableJavaInteraction();
- suspend();
- prctl.debugEventContinue();
- } else {
- String info = "Unknown debug event encountered";
- if (ev.getUnknownEventDetail() != null) {
- info = info + ": " + ev.getUnknownEventDetail();
- }
- showMessageDialog(info, "Unknown debug event", JOptionPane.INFORMATION_MESSAGE);
- suspend();
- prctl.debugEventContinue();
- }
- return;
- }
-
- // No C++ debug event; poll for Java debug event
- if (getAgent().canInteractWithJava()) {
- if (!javaEventPending) {
- if (getAgent().javaEventPending()) {
- suspend();
- // This does a lot of work and we want to have the page
- // cache available to us as it runs
- sun.jvm.hotspot.livejvm.Event jev = getAgent().javaEventPoll();
- if (jev != null) {
- javaEventPending = true;
- if (jev.getType() == sun.jvm.hotspot.livejvm.Event.Type.BREAKPOINT) {
- BreakpointEvent bpev = (BreakpointEvent) jev;
- showMessageDialog("Breakpoint reached in method\n" +
- bpev.methodID().method().externalNameAndSignature() +
- ",\nbci " + bpev.location(),
- "Breakpoint reached",
- JOptionPane.INFORMATION_MESSAGE);
- } else if (jev.getType() == sun.jvm.hotspot.livejvm.Event.Type.EXCEPTION) {
- ExceptionEvent exev = (ExceptionEvent) jev;
- showMessageDialog(exev.exception().getKlass().getName().asString() +
- "\nthrown in method\n" +
- exev.methodID().method().externalNameAndSignature() +
- "\nat BCI " + exev.location(),
- "Exception thrown",
- JOptionPane.INFORMATION_MESSAGE);
- } else {
- Assert.that(false, "Should not reach here");
- }
- }
- }
- }
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,799 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.io.PrintStream;
-import java.net.*;
-import java.rmi.*;
-import sun.jvm.hotspot.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.bsd.*;
-import sun.jvm.hotspot.debugger.proc.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.debugger.windbg.*;
-import sun.jvm.hotspot.debugger.linux.*;
-import sun.jvm.hotspot.debugger.sparc.*;
-import sun.jvm.hotspot.debugger.remote.*;
-import sun.jvm.hotspot.livejvm.*;
-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.*;
-
-/**
This class wraps the basic functionality for connecting to the
- * target process or debug server. It makes it simple to start up the
- * debugging system.
- *
- *
This agent (as compared to the HotSpotAgent) can connect to
- * and interact with arbitrary processes. If the target process
- * happens to be a HotSpot JVM, the Java debugging features of the
- * Serviceability Agent are enabled. Further, if the Serviceability
- * Agent's JVMDI module is loaded into the target VM, interaction
- * with the live Java program is possible, specifically the catching
- * of exceptions and setting of breakpoints.
- *
- *
The BugSpot debugger requires that the underlying Debugger
- * support C/C++ debugging via the CDebugger interface.
- *
- *
FIXME: especially with the addition of remote debugging, this
- * has turned into a mess; needs rethinking.
*/
-
-public class BugSpotAgent {
-
- private JVMDebugger debugger;
- private MachineDescription machDesc;
- private TypeDataBase db;
-
- private String os;
- private String cpu;
- private String fileSep;
-
- // The system can work in several ways:
- // - Attaching to local process
- // - Attaching to local core file
- // - Connecting to remote debug server
- // - Starting debug server for process
- // - Starting debug server for core file
-
- // These are options for the "client" side of things
- private static final int PROCESS_MODE = 0;
- private static final int CORE_FILE_MODE = 1;
- private static final int REMOTE_MODE = 2;
- private int startupMode;
-
- // This indicates whether we are really starting a server or not
- private boolean isServer;
-
- // All possible required information for connecting
- private int pid;
- private String executableName;
- private String coreFileName;
- private String debugServerID;
-
- // All needed information for server side
- private String serverID;
-
- // Indicates whether we are attached to a HotSpot JVM or not
- private boolean javaMode;
-
- // Indicates whether we have process control over a live HotSpot JVM
- // or not; non-null if so.
- private ServiceabilityAgentJVMDIModule jvmdi;
- // While handling C breakpoints interactivity with the Java program
- // is forbidden. Too many invariants are broken while the target is
- // stopped at a C breakpoint to risk making JVMDI calls.
- private boolean javaInteractionDisabled;
-
- private String[] jvmLibNames;
- private String[] saLibNames;
-
- // FIXME: make these configurable, i.e., via a dotfile; also
- // consider searching within the JDK from which this Java executable
- // comes to find them
- private static final String defaultDbxPathPrefix = "/net/jano.eng/export/disk05/hotspot/sa";
- private static final String defaultDbxSvcAgentDSOPathPrefix = "/net/jano.eng/export/disk05/hotspot/sa";
-
- private static final boolean DEBUG;
- static {
- DEBUG = System.getProperty("sun.jvm.hotspot.bugspot.BugSpotAgent.DEBUG")
- != null;
- }
-
- static void debugPrintln(String str) {
- if (DEBUG) {
- System.err.println(str);
- }
- }
-
- static void showUsage() {
- System.out.println(" You can also pass these -D options to java to specify where to find dbx and the \n" +
- " Serviceability Agent plugin for dbx:");
- System.out.println(" -DdbxPathName=\n" +
- " Default is derived from dbxPathPrefix");
- System.out.println(" or");
- System.out.println(" -DdbxPathPrefix=\n" +
- " where xxx is the path name of a dir structure that contains:\n" +
- " //bin/dbx\n" +
- " The default is " + defaultDbxPathPrefix);
- System.out.println(" and");
- System.out.println(" -DdbxSvcAgentDSOPathName=\n" +
- " Default is determined from dbxSvcAgentDSOPathPrefix");
- System.out.println(" or");
- System.out.println(" -DdbxSvcAgentDSOPathPrefix=\n" +
- " where xxx is the pathname of a dir structure that contains:\n" +
- " //bin/lib/libsvc_agent_dbx.so\n" +
- " The default is " + defaultDbxSvcAgentDSOPathPrefix);
- }
-
- public BugSpotAgent() {
- // for non-server add shutdown hook to clean-up debugger in case
- // of forced exit. For remote server, shutdown hook is added by
- // DebugServer.
- Runtime.getRuntime().addShutdownHook(new java.lang.Thread(
- new Runnable() {
- public void run() {
- synchronized (BugSpotAgent.this) {
- if (!isServer) {
- detach();
- }
- }
- }
- }));
- }
-
- //--------------------------------------------------------------------------------
- // Accessors (once the system is set up)
- //
-
- public synchronized Debugger getDebugger() {
- return debugger;
- }
-
- public synchronized CDebugger getCDebugger() {
- return getDebugger().getCDebugger();
- }
-
- public synchronized ProcessControl getProcessControl() {
- return getCDebugger().getProcessControl();
- }
-
- public synchronized TypeDataBase getTypeDataBase() {
- return db;
- }
-
- /** Indicates whether the target process is suspended
- completely. Equivalent to getProcessControl().isSuspended(). */
- public synchronized boolean isSuspended() throws DebuggerException {
- return getProcessControl().isSuspended();
- }
-
- /** Suspends the target process completely. Equivalent to
- getProcessControl().suspend(). */
- public synchronized void suspend() throws DebuggerException {
- getProcessControl().suspend();
- }
-
- /** Resumes the target process completely. Equivalent to
- getProcessControl().suspend(). */
- public synchronized void resume() throws DebuggerException {
- getProcessControl().resume();
- }
-
- /** Indicates whether we are attached to a Java HotSpot virtual
- machine */
- public synchronized boolean isJavaMode() {
- return javaMode;
- }
-
- /** Temporarily disables interaction with the target process via
- JVMDI. This is done while the target process is stopped at a C
- breakpoint. Can be called even if the JVMDI agent has not been
- initialized. */
- public synchronized void disableJavaInteraction() {
- javaInteractionDisabled = true;
- }
-
- /** Re-enables interaction with the target process via JVMDI. This
- is done while the target process is continued past a C
- braekpoint. Can be called even if the JVMDI agent has not been
- initialized. */
- public synchronized void enableJavaInteraction() {
- javaInteractionDisabled = false;
- }
-
- /** Indicates whether Java interaction has been disabled */
- public synchronized boolean isJavaInteractionDisabled() {
- return javaInteractionDisabled;
- }
-
- /** Indicates whether we can talk to the Serviceability Agent's
- JVMDI module to be able to set breakpoints */
- public synchronized boolean canInteractWithJava() {
- return (jvmdi != null) && !javaInteractionDisabled;
- }
-
- /** Suspends all Java threads in the target process. Can only be
- called if we are attached to a HotSpot JVM and can connect to
- the SA's JVMDI module. Must not be called when the target
- process has been suspended with suspend(). */
- public synchronized void suspendJava() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module");
- }
- if (jvmdi.isSuspended()) {
- throw new DebuggerException("Target process already suspended via JVMDI");
- }
- jvmdi.suspend();
- }
-
- /** Resumes all Java threads in the target process. Can only be
- called if we are attached to a HotSpot JVM and can connect to
- the SA's JVMDI module. Must not be called when the target
- process has been suspended with suspend(). */
- public synchronized void resumeJava() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module");
- }
- if (!jvmdi.isSuspended()) {
- throw new DebuggerException("Target process already resumed via JVMDI");
- }
- jvmdi.resume();
- }
-
- /** Indicates whether the target process has been suspended at the
- Java language level via the SA's JVMDI module */
- public synchronized boolean isJavaSuspended() throws DebuggerException {
- return jvmdi.isSuspended();
- }
-
- /** Toggle a Java breakpoint at the given location. */
- public synchronized ServiceabilityAgentJVMDIModule.BreakpointToggleResult
- toggleJavaBreakpoint(String srcFileName,
- String pkgName,
- int lineNo) {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not toggle Java breakpoints");
- }
- return jvmdi.toggleBreakpoint(srcFileName, pkgName, lineNo);
- }
-
- /** Access to JVMDI module's eventPending */
- public synchronized boolean javaEventPending() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not poll for Java debug events");
- }
- return jvmdi.eventPending();
- }
-
- /** Access to JVMDI module's eventPoll */
- public synchronized Event javaEventPoll() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not poll for Java debug events");
- }
- return jvmdi.eventPoll();
- }
-
- /** Access to JVMDI module's eventContinue */
- public synchronized void javaEventContinue() throws DebuggerException {
- if (!canInteractWithJava()) {
- throw new DebuggerException("Could not connect to SA's JVMDI module; can not continue past Java debug events");
- }
- jvmdi.eventContinue();
- }
-
-
- // FIXME: add other accessors. For example, suspension and
- // resumption should be done through this interface, as well as
- // interaction with the live Java process such as breakpoint setting.
- // Probably should not expose the ServiceabilityAgentJVMDIModule
- // from this interface.
-
- //--------------------------------------------------------------------------------
- // Client-side operations
- //
-
- /** This attaches to a process running on the local machine. */
- public synchronized void attach(int processID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- pid = processID;
- startupMode = PROCESS_MODE;
- isServer = false;
- go();
- }
-
- /** This opens a core file on the local machine */
- public synchronized void attach(String executableName, String coreFileName)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- if ((executableName == null) || (coreFileName == null)) {
- throw new DebuggerException("Both the core file name and executable name must be specified");
- }
- this.executableName = executableName;
- this.coreFileName = coreFileName;
- startupMode = CORE_FILE_MODE;
- isServer = false;
- go();
- }
-
- /** This attaches to a "debug server" on a remote machine; this
- remote server has already attached to a process or opened a
- core file and is waiting for RMI calls on the Debugger object to
- come in. */
- public synchronized void attach(String remoteServerID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached to a process");
- }
- if (remoteServerID == null) {
- throw new DebuggerException("Debug server id must be specified");
- }
-
- debugServerID = remoteServerID;
- startupMode = REMOTE_MODE;
- isServer = false;
- go();
- }
-
- /** This should only be called by the user on the client machine,
- not the server machine */
- public synchronized boolean detach() throws DebuggerException {
- if (isServer) {
- throw new DebuggerException("Should not call detach() for server configuration");
- }
- return detachInternal();
- }
-
- //--------------------------------------------------------------------------------
- // Server-side operations
- //
-
- /** This attaches to a process running on the local machine and
- starts a debug server, allowing remote machines to connect and
- examine this process. uniqueID is used to uniquely identify the
- debuggee */
- public synchronized void startServer(int processID, String uniqueID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- pid = processID;
- startupMode = PROCESS_MODE;
- isServer = true;
- serverID = uniqueID;
- go();
- }
-
- /** This attaches to a process running on the local machine and
- starts a debug server, allowing remote machines to connect and
- examine this process. */
- public synchronized void startServer(int processID)
- throws DebuggerException {
- startServer(processID, null);
- }
-
- /** This opens a core file on the local machine and starts a debug
- server, allowing remote machines to connect and examine this
- core file. uniqueID is used to uniquely identify the
- debuggee */
- public synchronized void startServer(String executableName, String coreFileName,
- String uniqueID)
- throws DebuggerException {
- if (debugger != null) {
- throw new DebuggerException("Already attached");
- }
- if ((executableName == null) || (coreFileName == null)) {
- throw new DebuggerException("Both the core file name and Java executable name must be specified");
- }
- this.executableName = executableName;
- this.coreFileName = coreFileName;
- startupMode = CORE_FILE_MODE;
- isServer = true;
- serverID = uniqueID;
- go();
- }
-
- /** This opens a core file on the local machine and starts a debug
- server, allowing remote machines to connect and examine this
- core file.*/
- public synchronized void startServer(String executableName, String coreFileName)
- throws DebuggerException {
- startServer(executableName, coreFileName, null);
- }
-
- /** This may only be called on the server side after startServer()
- has been called */
- public synchronized boolean shutdownServer() throws DebuggerException {
- if (!isServer) {
- throw new DebuggerException("Should not call shutdownServer() for client configuration");
- }
- return detachInternal();
- }
-
-
- //--------------------------------------------------------------------------------
- // Internals only below this point
- //
-
- private boolean detachInternal() {
- if (debugger == null) {
- return false;
- }
- if (canInteractWithJava()) {
- jvmdi.detach();
- jvmdi = null;
- }
- boolean retval = true;
- if (!isServer) {
- VM.shutdown();
- }
- // We must not call detach() if we are a client and are connected
- // to a remote debugger
- Debugger dbg = null;
- DebuggerException ex = null;
- if (isServer) {
- try {
- RMIHelper.unbind(serverID);
- }
- catch (DebuggerException de) {
- ex = de;
- }
- dbg = debugger;
- } else {
- if (startupMode != REMOTE_MODE) {
- dbg = debugger;
- }
- }
- if (dbg != null) {
- retval = dbg.detach();
- }
-
- debugger = null;
- machDesc = null;
- db = null;
- if (ex != null) {
- throw(ex);
- }
- return retval;
- }
-
- private void go() {
- setupDebugger();
- javaMode = setupVM();
- }
-
- private void setupDebugger() {
- if (startupMode != REMOTE_MODE) {
- //
- // Local mode (client attaching to local process or setting up
- // server, but not client attaching to server)
- //
-
- try {
- os = PlatformInfo.getOS();
- cpu = PlatformInfo.getCPU();
- }
- catch (UnsupportedPlatformException e) {
- throw new DebuggerException(e);
- }
- fileSep = System.getProperty("file.separator");
-
- if (os.equals("solaris")) {
- setupDebuggerSolaris();
- } else if (os.equals("win32")) {
- setupDebuggerWin32();
- } else if (os.equals("linux")) {
- setupDebuggerLinux();
- } else if (os.equals("bsd")) {
- setupDebuggerBsd();
- } else {
- // Add support for more operating systems here
- throw new DebuggerException("Operating system " + os + " not yet supported");
- }
- if (isServer) {
- RemoteDebuggerServer remote = null;
- try {
- remote = new RemoteDebuggerServer(debugger);
- }
- catch (RemoteException rem) {
- throw new DebuggerException(rem);
- }
- RMIHelper.rebind(serverID, remote);
- }
- } else {
- //
- // Remote mode (client attaching to server)
- //
-
- // Create and install a security manager
-
- // FIXME: currently commented out because we were having
- // security problems since we're "in the sun.* hierarchy" here.
- // Perhaps a permissive policy file would work around this. In
- // the long run, will probably have to move into com.sun.*.
-
- // if (System.getSecurityManager() == null) {
- // System.setSecurityManager(new RMISecurityManager());
- // }
-
- connectRemoteDebugger();
- }
- }
-
- private boolean setupVM() {
- // We need to instantiate a HotSpotTypeDataBase on both the client
- // and server machine. On the server it is only currently used to
- // configure the Java primitive type sizes (which we should
- // consider making constant). On the client it is used to
- // configure the VM.
-
- try {
- if (os.equals("solaris")) {
- db = new HotSpotTypeDataBase(machDesc, new HotSpotSolarisVtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else if (os.equals("win32")) {
- db = new HotSpotTypeDataBase(machDesc, new Win32VtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else if (os.equals("linux")) {
- db = new HotSpotTypeDataBase(machDesc, new LinuxVtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else if (os.equals("bsd")) {
- db = new HotSpotTypeDataBase(machDesc, new BsdVtblAccess(debugger, jvmLibNames),
- debugger, jvmLibNames);
- } else {
- throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess implemented yet)");
- }
- }
- catch (NoSuchSymbolException e) {
- e.printStackTrace();
- return false;
- }
-
- if (startupMode != REMOTE_MODE) {
- // Configure the debugger with the primitive type sizes just obtained from the VM
- debugger.configureJavaPrimitiveTypeSizes(db.getJBooleanType().getSize(),
- db.getJByteType().getSize(),
- db.getJCharType().getSize(),
- db.getJDoubleType().getSize(),
- db.getJFloatType().getSize(),
- db.getJIntType().getSize(),
- db.getJLongType().getSize(),
- db.getJShortType().getSize());
- }
-
- if (!isServer) {
- // Do not initialize the VM on the server (unnecessary, since it's
- // instantiated on the client)
- VM.initialize(db, debugger);
- }
-
- try {
- jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames);
- if (jvmdi.canAttach()) {
- jvmdi.attach();
- jvmdi.setCommandTimeout(6000);
- debugPrintln("Attached to Serviceability Agent's JVMDI module.");
- // Jog VM to suspended point with JVMDI module
- resume();
- suspendJava();
- suspend();
- debugPrintln("Suspended all Java threads.");
- } else {
- debugPrintln("Could not locate SA's JVMDI module; skipping attachment");
- jvmdi = null;
- }
- } catch (Exception e) {
- e.printStackTrace();
- jvmdi = null;
- }
-
- return true;
- }
-
- //--------------------------------------------------------------------------------
- // OS-specific debugger setup/connect routines
- //
-
- //
- // Solaris
- //
-
- private void setupDebuggerSolaris() {
- setupJVMLibNamesSolaris();
- ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true);
- debugger = dbg;
- attachDebugger();
-
- // Set up CPU-dependent stuff
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("sparc")) {
- int addressSize = dbg.getRemoteProcessAddressSize();
- if (addressSize == -1) {
- throw new DebuggerException("Error occurred while trying to determine the remote process's address size");
- }
-
- if (addressSize == 32) {
- machDesc = new MachineDescriptionSPARC32Bit();
- } else if (addressSize == 64) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC");
- }
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else {
- throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64");
- }
-
- dbg.setMachineDescription(machDesc);
- }
-
- private void connectRemoteDebugger() throws DebuggerException {
- RemoteDebugger remote =
- (RemoteDebugger) RMIHelper.lookup(debugServerID);
- debugger = new RemoteDebuggerClient(remote);
- machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription();
- os = debugger.getOS();
- if (os.equals("solaris")) {
- setupJVMLibNamesSolaris();
- } else if (os.equals("win32")) {
- setupJVMLibNamesWin32();
- } else if (os.equals("linux")) {
- setupJVMLibNamesLinux();
- } else if (os.equals("bsd")) {
- setupJVMLibNamesBsd();
- } else {
- throw new RuntimeException("Unknown OS type");
- }
-
- cpu = debugger.getCPU();
- }
-
- private void setupJVMLibNamesSolaris() {
- jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so", "gamma_g" };
- saLibNames = new String[] { "libsa.so", "libsa_g.so" };
- }
-
- //
- // Win32
- //
-
- private void setupDebuggerWin32() {
- setupJVMLibNamesWin32();
-
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else if (cpu.equals("ia64")) {
- machDesc = new MachineDescriptionIA64();
- } else {
- throw new DebuggerException("Win32 supported under x86, amd64 and ia64 only");
- }
-
- // Note we do not use a cache for the local debugger in server
- // mode; it will be taken care of on the client side (once remote
- // debugging is implemented).
-
- debugger = new WindbgDebuggerLocal(machDesc, !isServer);
-
- attachDebugger();
- }
-
- private void setupJVMLibNamesWin32() {
- jvmLibNames = new String[] { "jvm.dll", "jvm_g.dll" };
- saLibNames = new String[] { "sa.dll", "sa_g.dll" };
- }
-
- //
- // Linux
- //
-
- private void setupDebuggerLinux() {
- setupJVMLibNamesLinux();
-
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("ia64")) {
- machDesc = new MachineDescriptionIA64();
- } else if (cpu.equals("amd64")) {
- machDesc = new MachineDescriptionAMD64();
- } else if (cpu.equals("sparc")) {
- if (LinuxDebuggerLocal.getAddressSize()==8) {
- machDesc = new MachineDescriptionSPARC64Bit();
- } else {
- machDesc = new MachineDescriptionSPARC32Bit();
- }
- } else {
- try {
- machDesc = (MachineDescription)
- Class.forName("sun.jvm.hotspot.debugger.MachineDescription" +
- cpu.toUpperCase()).newInstance();
- } catch (Exception e) {
- throw new DebuggerException("unsupported machine type");
- }
- }
-
-
- // Note we do not use a cache for the local debugger in server
- // mode; it will be taken care of on the client side (once remote
- // debugging is implemented).
-
- debugger = new LinuxDebuggerLocal(machDesc, !isServer);
- attachDebugger();
- }
-
- private void setupJVMLibNamesLinux() {
- // same as solaris
- setupJVMLibNamesSolaris();
- }
-
- //
- // BSD
- //
-
- private void setupDebuggerBsd() {
- setupJVMLibNamesBsd();
-
- if (cpu.equals("x86")) {
- machDesc = new MachineDescriptionIntelX86();
- } else if (cpu.equals("amd64") || (cpu.equals("x86_64"))) {
- machDesc = new MachineDescriptionAMD64();
- } else {
- throw new DebuggerException("Bsd only supported on x86/x86_64. Current arch: " + cpu);
- }
-
- // Note we do not use a cache for the local debugger in server
- // mode; it will be taken care of on the client side (once remote
- // debugging is implemented).
-
- debugger = new BsdDebuggerLocal(machDesc, !isServer);
- attachDebugger();
- }
-
- private void setupJVMLibNamesBsd() {
- // same as solaris
- setupJVMLibNamesSolaris();
- }
-
- /** Convenience routine which should be called by per-platform
- debugger setup. Should not be called when startupMode is
- REMOTE_MODE. */
- private void attachDebugger() {
- if (startupMode == PROCESS_MODE) {
- debugger.attach(pid);
- } else if (startupMode == CORE_FILE_MODE) {
- debugger.attach(executableName, coreFileName);
- } else {
- throw new DebuggerException("Should not call attach() for startupMode == " + startupMode);
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/JavaLineNumberInfo.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/JavaLineNumberInfo.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import sun.jvm.hotspot.oops.*;
-
-/** Wrapper class which describes line number information for Java
- class files. The line number table is converted into this
- representation on demand. These objects are then sorted by line
- number for fast lookup when setting breakpoints in a particular
- source file. */
-
-public class JavaLineNumberInfo {
- private InstanceKlass klass;
- private Method method;
- private int startBCI;
- private int lineNumber;
-
- public JavaLineNumberInfo(InstanceKlass klass,
- Method method,
- int startBCI,
- int lineNumber) {
- this.klass = klass;
- this.method = method;
- this.startBCI = startBCI;
- this.lineNumber = lineNumber;
- }
-
- public InstanceKlass getKlass() { return klass; }
- public Method getMethod() { return method; }
- public int getStartBCI() { return startBCI; }
- public int getLineNumber() { return lineNumber; }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- * 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.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-import sun.jvm.hotspot.ui.*;
-
-/** The main class for the BugSpot debugger. */
-
-public class Main {
- public static void main(String[] args) {
- JFrame frame = new JFrame("BugSpot");
- frame.setSize(800, 600);
- BugSpot db = new BugSpot();
- db.setMDIMode(true);
- db.build();
- frame.setJMenuBar(db.getMenuBar());
- frame.getContentPane().add(db);
- frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
-
- GraphicsUtilities.reshapeToAspectRatio(frame,
- 4.0f/3.0f, 0.85f, Toolkit.getDefaultToolkit().getScreenSize());
- GraphicsUtilities.centerInContainer(frame,
- Toolkit.getDefaultToolkit().getScreenSize());
- frame.setVisible(true);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/PCFinder.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/PCFinder.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-
-/** Helper class for locating a program counter. Indicates the
- confidence of the find. */
-
-public class PCFinder {
- public static final int LOW_CONFIDENCE = 1;
- public static final int HIGH_CONFIDENCE = 2;
-
- public static class Info {
- private String name;
- private long offset;
- private int confidence;
-
- public Info(String name, long offset, int confidence) {
- this.name = name;
- this.offset = offset;
- this.confidence = confidence;
- }
-
- /** May be null */
- public String getName() { return name; }
-
- /** If this is -1, a symbol could not be found, and the offset
- should not be shown */
- public long getOffset() { return offset; }
-
- /** PCFinder.LOW_CONFIDENCE or PCFinder.HIGH_CONFIDENCE */
- public int getConfidence() { return confidence; }
- }
-
- /** Passed loadobject may be null in which case the returned Info
- object has low confidence */
- public static Info findPC(Address pc, LoadObject lo, CDebugger dbg) {
- if (lo == null) {
- return new Info(null, -1, LOW_CONFIDENCE);
- }
-
- // First try debug info
- BlockSym sym = lo.debugInfoForPC(pc);
- while (sym != null) {
- if (sym.isFunction()) {
- // Highest confidence
- return new Info(sym.toString(), pc.minus(sym.getAddress()), HIGH_CONFIDENCE);
- }
- }
-
- // Now try looking up symbol in loadobject
-
- // FIXME: must add support for mapfiles on Win32 and try looking
- // up there first if possible. Should we hide that behind
- // LoadObject.closestSymbolToPC and have the ClosestSymbol return
- // confidence? I think so. On Solaris there is no notion of a
- // mapfile, and the confidence for closestSymbolToPC will be high
- // instead of low.
-
- int confidence = HIGH_CONFIDENCE;
-
- ClosestSymbol cs = lo.closestSymbolToPC(pc);
- if (cs != null) {
- // FIXME: currently low confidence (only on Win32)
- return new Info(cs.getName() + "()", cs.getOffset(), LOW_CONFIDENCE);
- }
-
- // Unknown location
- return new Info(dbg.getNameOfFile(lo.getName()).toUpperCase() +
- "! " + pc + "()", -1, HIGH_CONFIDENCE);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/PackageScanner.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/PackageScanner.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.io.*;
-
-/** Scans a .java file for the package that it is in. */
-
-public class PackageScanner {
-
- public PackageScanner() {
- }
-
- public String scan(String filename) {
- return scan(new File(filename));
- }
-
- /** Returns the String comprising the package name of the classes in
- this .java file. Returns the (non-null) empty string if any
- error occurs or if the classes are in the unnamed package. */
- public String scan(File file) {
- BufferedReader buf = null;
- String res = "";
- try {
- buf = new BufferedReader(new FileReader(file));
- StreamTokenizer tok = new StreamTokenizer(buf);
- tok.slashStarComments(true);
- tok.slashSlashComments(true);
- if (tok.nextToken() != StreamTokenizer.TT_WORD) {
- return res;
- }
- if (!tok.sval.equals("package")) {
- return res;
- }
- if (tok.nextToken() != StreamTokenizer.TT_WORD) {
- return res;
- }
- res = tok.sval;
- return res;
- } catch (FileNotFoundException e) {
- return res;
- } catch (IOException e) {
- return res;
- } finally {
- try {
- if (buf != null) {
- buf.close();
- }
- } catch (IOException e) {
- }
- }
- }
-
- public static void main(String[] args) {
- if (args.length != 1) {
- usage();
- }
-
- System.out.println(new PackageScanner().scan(args[0]));
- }
-
- private static void usage() {
- System.err.println("Usage: java PackageScanner <.java file name>");
- System.err.println("Prints package the .java file is in to stdout.");
- System.exit(1);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/RegisterPanel.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/RegisterPanel.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.table.*;
-
-import sun.jvm.hotspot.debugger.*;
-
-/** Displays registers in a window. FIXME: this will need more work to
- understand and handle register windows. */
-
-public class RegisterPanel extends JPanel {
- private java.util.List/**/ registers;
- private AbstractTableModel dataModel;
- private boolean valid;
- private boolean editable;
- private String nullAddressString;
- private ThreadProxy curThread;
- private JTable table;
-
- static class RegisterInfo {
- private String name;
- private Address value;
-
- RegisterInfo(String name, Address value) {
- this.name = name;
- this.value = value;
- }
-
- String getName() { return name; }
- Address getValue() { return value; }
- }
-
- public RegisterPanel() {
- super();
-
- registers = new ArrayList();
-
- dataModel = new AbstractTableModel() {
- public int getColumnCount() { return 2; }
- public int getRowCount() { return registers.size(); }
- public String getColumnName(int col) {
- switch (col) {
- case 0:
- return "Register Name";
- case 1:
- return "Register Value";
- default:
- throw new RuntimeException("Index " + col + " out of bounds");
- }
- }
- public Object getValueAt(int row, int col) {
- RegisterInfo info = (RegisterInfo) registers.get(row);
-
- switch (col) {
- case 0:
- return info.getName();
- case 1:
- if (valid) {
- Address val = info.getValue();
- if (val != null) {
- return val;
- } else {
- return nullAddressString;
- }
- } else {
- return "-";
- }
- default:
- throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds");
- }
- }
- public boolean isCellEditable(int row, int col) {
- if (col == 0) return false;
- if (!valid) return false;
- if (curThread == null) return false;
- if (!curThread.canSetContext()) return false;
-
- // FIXME: add listener to watch for register changes
- // return true;
- return false;
- }
- };
-
- // Build user interface
- setLayout(new BorderLayout());
- table = new JTable(dataModel);
- table.setCellSelectionEnabled(true);
- table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
- table.setDragEnabled(true);
- JTableHeader header = table.getTableHeader();
- header.setReorderingAllowed(false);
- JScrollPane scrollPane = new JScrollPane(table);
- add(scrollPane, BorderLayout.CENTER);
- }
-
-
- /** Updates the register panel with the register set from the
- specified thread. Call this when the process has been suspended
- and the current thread has been set. FIXME: this interface will
- need to change to support register windows. */
- public void update(ThreadProxy curThread) {
- this.curThread = curThread;
- ThreadContext context = curThread.getContext();
- editable = curThread.canSetContext();
- registers.clear();
- for (int i = 0; i < context.getNumRegisters(); i++) {
- String name = context.getRegisterName(i);
- Address addr = context.getRegisterAsAddress(i);
- if ((nullAddressString == null) && (addr != null)) {
- String addrStr = addr.toString();
- StringBuffer buf = new StringBuffer();
- buf.append("0x");
- int len = addrStr.length() - 2;
- for (int j = 0; j < len; j++) {
- buf.append("0");
- }
- nullAddressString = buf.toString();
- }
- registers.add(new RegisterInfo(name, addr));
- }
- valid = true;
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- dataModel.fireTableDataChanged();
- }
- });
- }
-
- /** Clears the registers' values. Call this when the processs has
- been resumed. */
- public void clear() {
- valid = false;
- nullAddressString = null;
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- dataModel.fireTableDataChanged();
- }
- });
- }
-
- public void setFont(Font font) {
- super.setFont(font);
- if (table != null) {
- table.setFont(font);
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTraceEntry.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTraceEntry.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2001, 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-/** This class describes a frame in a stack trace. It abstracts over
- C/C++ and Java frames. */
-
-public class StackTraceEntry {
- private CFrame cFrame;
- private CDebugger dbg;
- private JavaVFrame javaFrame;
- private String value; // What is displayed in a stack trace
- // For merging C and Java stack traces.
- // For more precise stack traces, should probably have a way to
- // convert a CFrame to a sun.jvm.hotspot.runtime.Frame. For now,
- // doing similar algorithm to jdbx (which does not have intimate
- // knowledge of the VM).
- private boolean isUnknownCFrame;
-
- public StackTraceEntry(CFrame cFrame, CDebugger dbg) {
- this.cFrame = cFrame;
- this.dbg = dbg;
- computeValue();
- }
-
- public StackTraceEntry(JavaVFrame javaFrame) {
- this.javaFrame = javaFrame;
- computeValue();
- }
-
- public boolean isCFrame() { return (cFrame != null); }
- public boolean isJavaFrame() { return (javaFrame != null); }
- public CFrame getCFrame() { return cFrame; }
- public JavaVFrame getJavaFrame() { return javaFrame; }
- public boolean isUnknownCFrame() { return isUnknownCFrame; }
- public String toString() {
- return value;
- }
-
- private void computeValue() {
- isUnknownCFrame = true;
- value = "";
- if (cFrame != null) {
- PCFinder.Info info = PCFinder.findPC(cFrame.pc(), cFrame.loadObjectForPC(), dbg);
- if (info.getName() != null) {
- value = "(C) " + info.getName();
- isUnknownCFrame = false;
- if (info.getConfidence() == PCFinder.LOW_CONFIDENCE) {
- value = value + " (?)";
- }
- if (info.getOffset() >= 0) {
- value = value + " + 0x" + Long.toHexString(info.getOffset());
- }
- }
- } else if (javaFrame != null) {
- isUnknownCFrame = false;
- Method m = javaFrame.getMethod();
- value = "(J) " + m.externalNameAndSignature();
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTracePanel.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTracePanel.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import javax.swing.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.*;
-
-/** This panel contains a ListBox with all of the stack frames in a
- given thread. When a given entry is selected, an event is
- fired. */
-
-public class StackTracePanel extends JPanel {
- public interface Listener {
- public void frameChanged(CFrame fr, JavaVFrame jfr);
- }
-
- class Model extends AbstractListModel implements ComboBoxModel {
- private Object selectedItem;
- public Object getElementAt(int index) {
- if (trace == null) return null;
- return trace.get(index);
- }
- public int getSize() {
- if (trace == null) return 0;
- return trace.size();
- }
- public Object getSelectedItem() {
- return selectedItem;
- }
- public void setSelectedItem(Object item) {
- selectedItem = item;
- }
- public void dataChanged() {
- fireContentsChanged(this, 0, trace.size());
- }
- }
-
- private java.util.List trace;
- private Model model;
- private JComboBox list;
- private java.util.List listeners;
-
- public StackTracePanel() {
- super();
-
- model = new Model();
-
- // Build user interface
- setLayout(new BorderLayout());
- setBorder(GraphicsUtilities.newBorder(5));
- list = new JComboBox(model);
- list.setPrototypeDisplayValue("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
- add(list, BorderLayout.CENTER);
-
- // Add selection listener
- list.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- if (e.getStateChange() == ItemEvent.SELECTED) {
- fireFrameChanged();
- }
- }
- });
- }
-
- /** Takes a List of StackTraceEntry objects */
- public void setTrace(java.util.List trace) {
- this.trace = trace;
- model.dataChanged();
- list.setSelectedIndex(0);
- fireFrameChanged();
- }
-
- public void addListener(Listener listener) {
- if (listeners == null) {
- listeners = new ArrayList();
- }
- listeners.add(listener);
- }
-
- protected void fireFrameChanged() {
- if (listeners != null) {
- StackTraceEntry entry = (StackTraceEntry) trace.get(list.getSelectedIndex());
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- ((Listener) iter.next()).frameChanged(entry.getCFrame(), entry.getJavaFrame());
- }
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/ThreadListPanel.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/ThreadListPanel.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.util.*;
-import javax.swing.*;
-import javax.swing.table.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.*;
-
-// NOTE: this class was not placed in sun.jvm.hotspot.ui to prevent
-// mixing components designed for C and C++ debugging with the ones
-// that work with the core serviceability agent functionality (which
-// does not require that the CDebugger interface be implemented).
-
-/** The ThreadListPanel is used for C and C++ debugging and can
- visualize all threads in the target process. The caller passes in
- a CDebugger attached to the target process and can request that
- JavaThreads' associations with these underlying threads be
- displayed; this option is only valid when attached to a HotSpot
- JVM and when the {@link sun.jvm.hotspot.runtime.VM} has been
- initialized. */
-
-public class ThreadListPanel extends JPanel {
- /** Listener which can be added to receive "Set Focus" events */
- public static interface Listener {
- /** ThreadProxy will always be provided; JavaThread will only be
- present if displayJavaThreads was specified in the constructor
- for the panel and the thread was a JavaThread. */
- public void setFocus(ThreadProxy thread, JavaThread jthread);
- }
-
- static class ThreadInfo {
- private ThreadProxy thread;
- // Distinguish between PC == null and no top frame
- private boolean gotPC;
- private Address pc;
- private String location;
- private JavaThread javaThread;
- private String javaThreadName;
-
- public ThreadInfo(ThreadProxy thread, CDebugger dbg, JavaThread jthread) {
- this.thread = thread;
- this.location = "";
- CFrame fr = dbg.topFrameForThread(thread);
- if (fr != null) {
- gotPC = true;
- pc = fr.pc();
- PCFinder.Info info = PCFinder.findPC(pc, fr.loadObjectForPC(), dbg);
- if (info.getName() != null) {
- location = info.getName();
- if (info.getConfidence() == PCFinder.LOW_CONFIDENCE) {
- location = location + " (?)";
- }
- if (info.getOffset() < 0) {
- location = location + " + 0x" + Long.toHexString(info.getOffset());
- }
- }
- }
- if (jthread != null) {
- javaThread = jthread;
- javaThreadName = jthread.getThreadName();
- }
- }
-
- public ThreadProxy getThread() { return thread; }
- public boolean hasPC() { return gotPC; }
- public Address getPC() { return pc; }
- public String getLocation() { return location; }
- public boolean isJavaThread() { return (javaThread != null); }
- public JavaThread getJavaThread() { return javaThread; }
- public String getJavaThreadName() { return javaThreadName; }
- }
-
- // List
- private java.util.List threadList;
- private JTable table;
- private AbstractTableModel dataModel;
- // List
- private java.util.List listeners;
-
- /** Takes a CDebugger from which the thread list is queried.
- displayJavaThreads must only be set to true if the debugger is
- attached to a HotSpot JVM and if the VM has already been
- initialized. */
- public ThreadListPanel(CDebugger dbg, final boolean displayJavaThreads) {
- super();
-
- Map threadToJavaThreadMap = null;
- if (displayJavaThreads) {
- // Collect Java threads from virtual machine and insert them in
- // table for later querying
- threadToJavaThreadMap = new HashMap();
- Threads threads = VM.getVM().getThreads();
- for (JavaThread thr = threads.first(); thr != null; thr = thr.next()) {
- threadToJavaThreadMap.put(thr.getThreadProxy(), thr);
- }
- }
-
- java.util.List/**/ threads = dbg.getThreadList();
- threadList = new ArrayList(threads.size());
- for (Iterator iter = threads.iterator(); iter.hasNext(); ) {
- ThreadProxy thr = (ThreadProxy) iter.next();
- JavaThread jthr = null;
- if (displayJavaThreads) {
- jthr = (JavaThread) threadToJavaThreadMap.get(thr);
- }
- threadList.add(new ThreadInfo(thr, dbg, jthr));
- }
-
- // Thread ID, current PC, current symbol, Java Thread, [Java thread name]
- dataModel = new AbstractTableModel() {
- public int getColumnCount() { return (displayJavaThreads ? 5 : 3); }
- public int getRowCount() { return threadList.size(); }
- public String getColumnName(int col) {
- switch (col) {
- case 0:
- return "Thread ID";
- case 1:
- return "PC";
- case 2:
- return "Location";
- case 3:
- return "Java?";
- case 4:
- return "Java Thread Name";
- default:
- throw new RuntimeException("Index " + col + " out of bounds");
- }
- }
- public Object getValueAt(int row, int col) {
- ThreadInfo info = (ThreadInfo) threadList.get(row);
-
- switch (col) {
- case 0:
- return info.getThread();
- case 1:
- {
- if (info.hasPC()) {
- return info.getPC();
- }
- return "";
- }
- case 2:
- return info.getLocation();
- case 3:
- if (info.isJavaThread()) {
- return "Yes";
- } else {
- return "";
- }
- case 4:
- if (info.isJavaThread()) {
- return info.getJavaThreadName();
- } else {
- return "";
- }
- default:
- throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds");
- }
- }
- };
-
- // Build user interface
- setLayout(new BorderLayout());
- table = new JTable(dataModel);
- table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- JTableHeader header = table.getTableHeader();
- header.setReorderingAllowed(false);
- table.setRowSelectionAllowed(true);
- table.setColumnSelectionAllowed(false);
- JScrollPane scrollPane = new JScrollPane(table);
- add(scrollPane, BorderLayout.CENTER);
- if (threadList.size() > 0) {
- table.setRowSelectionInterval(0, 0);
- }
-
- JButton button = new JButton("Set Focus");
- button.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- int i = table.getSelectedRow();
- if (i < 0) {
- return;
- }
- ThreadInfo info = (ThreadInfo) threadList.get(i);
- for (Iterator iter = listeners.iterator(); iter.hasNext(); ) {
- ((Listener) iter.next()).setFocus(info.getThread(), info.getJavaThread());
- }
- }
- });
- JPanel focusPanel = new JPanel();
- focusPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0));
- focusPanel.setLayout(new BoxLayout(focusPanel, BoxLayout.Y_AXIS));
- focusPanel.add(Box.createGlue());
- focusPanel.add(button);
- focusPanel.add(Box.createGlue());
- add(focusPanel, BorderLayout.EAST);
-
- // FIXME: make listener model for the debugger so if the user
- // specifies a mapfile for or path to a given DSO later we can
- // update our state
- }
-
- public void addListener(Listener l) {
- if (listeners == null) {
- listeners = new ArrayList();
- }
- listeners.add(l);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/VariablePanel.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/VariablePanel.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/*
- * Copyright (c) 2001, 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot;
-
-import java.awt.*;
-import javax.swing.*;
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.bugspot.tree.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.ui.tree.*;
-import sun.jvm.hotspot.ui.treetable.*;
-
-/** Manages display of a set of local variables in a frame, or the
- contents of the "this" pointer */
-
-public class VariablePanel extends JPanel {
- private JTreeTable treeTable;
- private SimpleTreeTableModel model;
- private SimpleTreeGroupNode root;
-
- public VariablePanel() {
- super();
-
- model = new SimpleTreeTableModel();
- model.setValuesEditable(false);
- root = new SimpleTreeGroupNode();
- model.setRoot(root);
- treeTable = new JTreeTable(model);
- treeTable.setRootVisible(false);
- treeTable.setShowsRootHandles(true);
- treeTable.setShowsIcons(false);
- treeTable.setTreeEditable(false);
- treeTable.getTableHeader().setReorderingAllowed(false);
- treeTable.setCellSelectionEnabled(true);
- treeTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
- treeTable.setDragEnabled(true);
- JScrollPane sp = new JScrollPane(treeTable);
- sp.getViewport().setBackground(Color.white);
-
- setLayout(new BorderLayout());
- add(sp, BorderLayout.CENTER);
- }
-
- /** Clear the contents of this VariablePanel */
- public void clear() {
- root.removeAllChildren();
- model.fireTreeStructureChanged();
- }
-
- /** Update the contents of this VariablePanel from the given CFrame */
- public void update(CFrame fr) {
- // Collect locals
- CCollector coll = new CCollector();
- fr.iterateLocals(coll);
- update(coll);
- }
-
- /** Update the contents of this VariablePanel from the given JavaVFrame */
- public void update(JavaVFrame jfr) {
- Method m = jfr.getMethod();
- if (!m.hasLocalVariableTable()) {
- return;
- }
- int bci = jfr.getBCI();
- // Get local variable table
- LocalVariableTableElement[] locals = m.getLocalVariableTable();
- // Get locals as StackValueCollection
- StackValueCollection coll = jfr.getLocals();
- root.removeAllChildren();
- // See which locals are live
- for (int i = 0; i < locals.length; i++) {
- LocalVariableTableElement local = locals[i];
- if (local.getStartBCI() <= bci && bci < local.getStartBCI() + local.getLength()) {
- // Valid; add it
- SimpleTreeNode node = null;
- Symbol name = null;
- try {
- name = m.getConstants().getSymbolAt(local.getNameCPIndex());
- if (name == null) {
- System.err.println("Null name at slot " +
- local.getNameCPIndex() +
- " for local variable at slot " +
- local.getSlot());
- continue;
- }
- } catch (Exception e) {
- System.err.println("Unable to fetch name at slot " +
- local.getNameCPIndex() +
- " for local variable at slot " +
- local.getSlot());
- e.printStackTrace();
- continue;
- }
- sun.jvm.hotspot.oops.NamedFieldIdentifier f =
- new sun.jvm.hotspot.oops.NamedFieldIdentifier(name.asString());
- Symbol descriptor = null;
- try {
- descriptor = m.getConstants().getSymbolAt(local.getDescriptorCPIndex());
- } catch (Exception e) {
- System.err.println("Unable to fetch descriptor at slot " +
- local.getDescriptorCPIndex() +
- " for local variable " + f.getName() +
- " at slot " + local.getSlot());
- e.printStackTrace();
- continue;
- }
-
- if (descriptor != null) {
- switch (descriptor.getByteAt(0)) {
- case 'F': {
- node = new sun.jvm.hotspot.ui.tree.FloatTreeNodeAdapter(coll.floatAt(local.getSlot()), f, true);
- break;
- }
- case 'D': {
- node = new sun.jvm.hotspot.ui.tree.DoubleTreeNodeAdapter(coll.doubleAt(local.getSlot()), f, true);
- break;
- }
- case 'C': {
- node = new sun.jvm.hotspot.ui.tree.CharTreeNodeAdapter((char) coll.intAt(local.getSlot()), f, true);
- break;
- }
- case 'B':
- case 'S':
- case 'I': {
- node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.intAt(local.getSlot()), f, true);
- break;
- }
- case 'Z': {
- node = new sun.jvm.hotspot.ui.tree.BooleanTreeNodeAdapter(
- ((coll.intAt(local.getSlot()) != 0) ? true : false), f, true
- );
- break;
- }
- case 'J': {
- node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.longAt(local.getSlot()), f, true);
- break;
- }
- default: {
- try {
- node = new sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter(
- VM.getVM().getObjectHeap().newOop(coll.oopHandleAt(local.getSlot())), f, true
- );
- } catch (AddressException e) {
- node = new sun.jvm.hotspot.ui.tree.FieldTreeNodeAdapter(f, true) {
- public int getChildCount() { return 0; }
- public SimpleTreeNode getChild(int i) { return null; }
- public boolean isLeaf() { return false; }
- public int getIndexOfChild(SimpleTreeNode child) { return 0; }
- public String getValue() {
- return "";
- }
- };
- }
- break;
- }
- }
- if (node != null) {
- root.addChild(node);
- }
- }
- }
- }
-
- model.fireTreeStructureChanged();
- }
-
- /** Update the contents of this VariablePanel from the given "this"
- pointer of the given type */
- public void update(Address thisAddr, Type type) {
- // Collect fields
- CCollector coll = new CCollector();
- type.iterateObject(thisAddr, coll);
- update(coll);
- }
-
- private void update(CCollector coll) {
- root.removeAllChildren();
- for (int i = 0; i < coll.getNumChildren(); i++) {
- root.addChild(coll.getChild(i));
- }
- model.fireTreeStructureChanged();
- }
-
- static class CCollector extends DefaultObjectVisitor {
- private java.util.List children;
-
- public CCollector() {
- children = new ArrayList();
- }
-
- public int getNumChildren() {
- return children.size();
- }
-
- public SimpleTreeNode getChild(int i) {
- return (SimpleTreeNode) children.get(i);
- }
-
- public void doBit(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true));
- }
- public void doInt(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true));
- }
- public void doEnum(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val, String enumName) {
- children.add(new sun.jvm.hotspot.bugspot.tree.EnumTreeNodeAdapter(enumName, val, f, true));
- }
- public void doFloat(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, float val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.FloatTreeNodeAdapter(val, f, true));
- }
- public void doDouble(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, double val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.DoubleTreeNodeAdapter(val, f, true));
- }
- public void doPointer(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true));
- }
- public void doArray(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true));
- }
- public void doRef(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true));
- }
- public void doCompound(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) {
- children.add(new sun.jvm.hotspot.bugspot.tree.ObjectTreeNodeAdapter(val, f, true));
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/AddressTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/AddressTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a float value in a tree handled by SimpleTreeModel */
-
-public class AddressTreeNodeAdapter extends FieldTreeNodeAdapter {
- private Address val;
-
- public AddressTreeNodeAdapter(Address val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public AddressTreeNodeAdapter(Address val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- if (val != null) {
- return val.toString();
- }
- return "NULL";
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/DoubleTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/DoubleTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a double value in a tree handled by SimpleTreeModel */
-
-public class DoubleTreeNodeAdapter extends FieldTreeNodeAdapter {
- private double val;
-
- public DoubleTreeNodeAdapter(double val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public DoubleTreeNodeAdapter(double val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- return Double.toString(val);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/EnumTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/EnumTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates an enumerated value in a tree handled by SimpleTreeModel */
-
-public class EnumTreeNodeAdapter extends FieldTreeNodeAdapter {
- private long val;
- private String enumName;
-
- public EnumTreeNodeAdapter(String enumName, long val, FieldIdentifier id) {
- this(enumName, val, id, false);
- }
-
- public EnumTreeNodeAdapter(String enumName, long val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.enumName = enumName;
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- if (enumName != null) {
- return enumName;
- } else {
- return Long.toString(val);
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FieldTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FieldTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Abstract base class for all adapters for fields of C/C++ objects */
-
-public abstract class FieldTreeNodeAdapter implements SimpleTreeNode {
- private FieldIdentifier id;
- private boolean treeTableMode;
-
- /** The identifier may be null, i.e., for the root of the tree */
- public FieldTreeNodeAdapter(FieldIdentifier id, boolean treeTableMode) {
- this.id = id;
- this.treeTableMode = treeTableMode;
- }
-
- public FieldIdentifier getID() {
- return id;
- }
-
- /** Defaults to false in subclasses */
- public boolean getTreeTableMode() {
- return treeTableMode;
- }
-
- public Type getType() {
- return getID().getType();
- }
-
- public String getName() {
- if (getID() != null) {
- return getID().toString();
- }
- return "";
- }
-
- public String toString() {
- if (treeTableMode) {
- return getName();
- } else {
- if (getID() != null) {
- return getName() + ": " + getValue();
- } else {
- return getValue();
- }
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FloatTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FloatTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a float value in a tree handled by SimpleTreeModel */
-
-public class FloatTreeNodeAdapter extends FieldTreeNodeAdapter {
- private float val;
-
- public FloatTreeNodeAdapter(float val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public FloatTreeNodeAdapter(float val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- return Float.toString(val);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/LongTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/LongTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** Encapsulates a long value in a tree handled by SimpleTreeModel */
-
-public class LongTreeNodeAdapter extends FieldTreeNodeAdapter {
- private long val;
-
- public LongTreeNodeAdapter(long val, FieldIdentifier id) {
- this(val, id, false);
- }
-
- public LongTreeNodeAdapter(long val, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.val = val;
- }
-
- public int getChildCount() {
- return 0;
- }
-
- public SimpleTreeNode getChild(int index) {
- return null;
- }
-
- public boolean isLeaf() {
- return true;
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- return 0;
- }
-
- public String getValue() {
- return Long.toString(val);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/ObjectTreeNodeAdapter.java
--- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/ObjectTreeNodeAdapter.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- *
- */
-
-package sun.jvm.hotspot.bugspot.tree;
-
-import java.io.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.debugger.cdbg.*;
-import sun.jvm.hotspot.ui.tree.SimpleTreeNode;
-
-/** An adapter class which allows C/C++ objects to be displayed in a
- tree via the SimpleTreeNode interface. */
-
-public class ObjectTreeNodeAdapter extends FieldTreeNodeAdapter {
- // Address of object
- private Address addr;
-
- /** The address may be null (for object fields of objcets which are
- null). The FieldIdentifier should not be null. treeTableMode
- defaults to false. */
- public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id) {
- this(addr, id, false);
- }
-
- /** The address may be null (for object fields of objcets which are
- null). The FieldIdentifier should not be null. */
- public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id, boolean treeTableMode) {
- super(id, treeTableMode);
- this.addr = addr;
- }
-
- public int getChildCount() {
- if (addr == null) {
- return 0;
- }
-
- Counter c = new Counter();
- getType().iterateObject(addr, c);
- return c.getNumFields();
- }
-
- public SimpleTreeNode getChild(int index) {
- if (addr == null) {
- return null;
- }
-
- Fetcher f = new Fetcher(index);
- getType().iterateObject(addr, f);
- return f.getChild();
- }
-
- public boolean isLeaf() {
- return (addr == null);
- }
-
- public int getIndexOfChild(SimpleTreeNode child) {
- FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID();
- Finder f = new Finder(id);
- getType().iterateObject(addr, f);
- return f.getIndex();
- }
-
- public String getValue() {
- if (addr != null) {
- return addr.toString();
- }
- return "NULL";
- }
-
- /** Should be used only once, then have the number of fields
- fetched. */
- static class Counter extends DefaultObjectVisitor {
- private int numFields;
-
- public int getNumFields() {
- return numFields;
- }
-
- public void doBit(FieldIdentifier f, long val) { ++numFields; }
- public void doInt(FieldIdentifier f, long val) { ++numFields; }
- public void doEnum(FieldIdentifier f, long val, String enumName) { ++numFields; }
- public void doFloat(FieldIdentifier f, float val) { ++numFields; }
- public void doDouble(FieldIdentifier f, double val) { ++numFields; }
- public void doPointer(FieldIdentifier f, Address val) { ++numFields; }
- public void doArray(FieldIdentifier f, Address val) { ++numFields; }
- public void doRef(FieldIdentifier f, Address val) { ++numFields; }
- public void doCompound(FieldIdentifier f, Address addr) { ++numFields; }
- }
-
- /** Creates a new SimpleTreeNode for the given field. */
- class Fetcher extends DefaultObjectVisitor {
- private int index;
- private int curField;
- private SimpleTreeNode child;
-
- public Fetcher(int index) {
- this.index = index;
- }
-
- public SimpleTreeNode getChild() {
- return child;
- }
-
- public void doBit(FieldIdentifier f, long val) {
- if (curField == index) {
- child = new LongTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doInt(FieldIdentifier f, long val) {
- if (curField == index) {
- child = new LongTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doEnum(FieldIdentifier f, long val, String enumName) {
- if (curField == index) {
- child = new EnumTreeNodeAdapter(enumName, val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doFloat(FieldIdentifier f, float val) {
- if (curField == index) {
- child = new FloatTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doDouble(FieldIdentifier f, double val) {
- if (curField == index) {
- child = new DoubleTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doPointer(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doArray(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doRef(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new AddressTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
-
- public void doCompound(FieldIdentifier f, Address val) {
- if (curField == index) {
- child = new ObjectTreeNodeAdapter(val, f, getTreeTableMode());
- }
- ++curField;
- }
- }
-
- /** Finds the index of the given FieldIdentifier. */
- static class Finder extends DefaultObjectVisitor {
- private FieldIdentifier id;
- private int curField;
- private int index = -1;
-
- public Finder(FieldIdentifier id) {
- this.id = id;
- }
-
- /** Returns -1 if not found */
- public int getIndex() {
- return index;
- }
-
- public void doBit(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doInt(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doEnum(FieldIdentifier f, long val,
- String enumName) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doFloat(FieldIdentifier f, float val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doDouble(FieldIdentifier f, double val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doPointer(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doArray(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doRef(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- public void doCompound(FieldIdentifier f,
- Address val) { if (f.equals(id)) { index = curField; } ++curField; }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java Tue Mar 12 18:22:40 2013 -0700
@@ -60,8 +60,13 @@
return null;
}
+ // Check alignment of rbp
+ if ( dbg.getAddressValue(rbp) % ADDRESS_SIZE != 0) {
+ return null;
+ }
+
Address nextRBP = rbp.getAddressAt( 0 * ADDRESS_SIZE);
- if (nextRBP == null) {
+ if (nextRBP == null || nextRBP.lessThanOrEqual(rbp)) {
return null;
}
Address nextPC = rbp.getAddressAt( 1 * ADDRESS_SIZE);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/debugger/linux/x86/LinuxX86CFrame.java
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/x86/LinuxX86CFrame.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/x86/LinuxX86CFrame.java Tue Mar 12 18:22:40 2013 -0700
@@ -61,8 +61,13 @@
return null;
}
+ // Check alignment of ebp
+ if ( dbg.getAddressValue(ebp) % ADDRESS_SIZE != 0) {
+ return null;
+ }
+
Address nextEBP = ebp.getAddressAt( 0 * ADDRESS_SIZE);
- if (nextEBP == null) {
+ if (nextEBP == null || nextEBP.lessThanOrEqual(ebp)) {
return null;
}
Address nextPC = ebp.getAddressAt( 1 * ADDRESS_SIZE);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/BreakpointEvent.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/BreakpointEvent.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-public class BreakpointEvent extends Event {
- private Oop thread;
- private Oop clazz;
- private JNIid method;
- private int location;
-
- public BreakpointEvent(Oop thread,
- Oop clazz,
- JNIid method,
- int location) {
- super(Event.Type.BREAKPOINT);
- this.thread = thread;
- this.clazz = clazz;
- this.method = method;
- this.location = location;
- }
-
- public Oop thread() { return thread; }
- public Oop clazz() { return clazz; }
- public JNIid methodID() { return method; }
- public int location() { return location; }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/CIntegerAccessor.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/CIntegerAccessor.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.debugger.*;
-
-class CIntegerAccessor {
- private Address addr;
- private long numBytes;
- private boolean isUnsigned;
-
- CIntegerAccessor(Address addr, long numBytes, boolean isUnsigned) {
- this.addr = addr;
- this.numBytes = numBytes;
- this.isUnsigned = isUnsigned;
- }
-
- long getValue() {
- return addr.getCIntegerAt(0, numBytes, isUnsigned);
- }
-
- void setValue(long value) {
- addr.setCIntegerAt(0, numBytes, value);
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/CStringAccessor.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/CStringAccessor.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import java.io.UnsupportedEncodingException;
-import sun.jvm.hotspot.debugger.*;
-
-class CStringAccessor {
- private Address addr;
- private int bufLen;
-
- CStringAccessor(Address addr, int bufLen) {
- this.addr = addr;
- this.bufLen = bufLen;
- }
-
- String getValue() throws DebuggerException {
- int len = 0;
- while ((addr.getCIntegerAt(len, 1, true) != 0) && (len < bufLen)) {
- ++len;
- }
- byte[] res = new byte[len];
- for (int i = 0; i < len; i++) {
- res[i] = (byte) addr.getCIntegerAt(i, 1, true);
- }
- try {
- return new String(res, "US-ASCII");
- } catch (UnsupportedEncodingException e) {
- throw new DebuggerException("Unable to use US-ASCII encoding");
- }
- }
-
- void setValue(String value) throws DebuggerException {
- try {
- byte[] data = value.getBytes("US-ASCII");
- if (data.length >= bufLen) {
- throw new DebuggerException("String too long");
- }
- for (int i = 0; i < data.length; i++) {
- addr.setCIntegerAt(i, 1, data[i]);
- }
- addr.setCIntegerAt(data.length, 1, 0);
- } catch (UnsupportedEncodingException e) {
- throw new DebuggerException("Unable to use US-ASCII encoding");
- }
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/Event.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/Event.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-public class Event {
- public static class Type {
- private Type() {}
- public static final Type BREAKPOINT = new Type();
- public static final Type EXCEPTION = new Type();
- }
-
- private Type type;
-
- public Event(Type type) {
- this.type = type;
- }
-
- public Type getType() { return type; }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/ExceptionEvent.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/ExceptionEvent.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-public class ExceptionEvent extends Event {
- private Oop thread;
- private Oop clazz;
- private JNIid method;
- private int location;
- private Oop exception;
- private Oop catchClass;
- private JNIid catchMethod;
- private int catchLocation;
-
- public ExceptionEvent(Oop thread,
- Oop clazz,
- JNIid method,
- int location,
- Oop exception,
- Oop catchClass,
- JNIid catchMethod,
- int catchLocation) {
- super(Event.Type.EXCEPTION);
- this.thread = thread;
- this.clazz = clazz;
- this.method = method;
- this.location = location;
- this.exception = exception;
- this.catchClass = catchClass;
- this.catchMethod = catchMethod;
- this.catchLocation = catchLocation;
- }
-
- public Oop thread() { return thread; }
- public Oop clazz() { return clazz; }
- public JNIid methodID() { return method; }
- public int location() { return location; }
- public Oop exception() { return exception; }
- public Oop catchClass() { return catchClass; }
- public JNIid catchMethodID() { return catchMethod; }
- public int catchLocation() { return catchLocation; }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/JNIHandleAccessor.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/JNIHandleAccessor.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.utilities.*;
-
-class JNIHandleAccessor {
- private Address addr;
- private ObjectHeap heap;
-
- JNIHandleAccessor(Address addr, ObjectHeap heap) {
- this.addr = addr;
- this.heap = heap;
- }
-
- Oop getValue() {
- // Accessing the contents of the JNIHandle is a double dereference
- Address handle = addr.getAddressAt(0);
- if (handle == null) return null;
- return heap.newOop(handle.getOopHandleAt(0));
- }
-
- void setValue(Oop value) {
- Address handle = addr.getAddressAt(0);
- if (Assert.ASSERTS_ENABLED) {
- Assert.that(handle != null, "Must have valid global JNI handle for setting");
- }
- handle.setOopHandleAt(0, value.getHandle());
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/livejvm/ServiceabilityAgentJVMDIModule.java
--- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/ServiceabilityAgentJVMDIModule.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,415 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-package sun.jvm.hotspot.livejvm;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-
-/** Provides Java programming language-level interaction with a live
- Java HotSpot VM via the use of the SA's JVMDI module. This is an
- experimental mechanism. The BugSpot debugger should be converted
- to use the JVMDI/JDWP-based JDI implementation for live process
- interaction once the JDI binding for the SA is complete. */
-
-public class ServiceabilityAgentJVMDIModule {
- private Debugger dbg;
- private String[] saLibNames;
- private String saLibName;
- private boolean attached;
-
- private boolean suspended;
-
- private static final int JVMDI_EVENT_BREAKPOINT = 2;
- private static final int JVMDI_EVENT_EXCEPTION = 4;
-
- private static long timeoutMillis = 3000;
-
- // Values in target process
- // Events sent from VM to SA
- private CIntegerAccessor saAttached;
- private CIntegerAccessor saEventPending;
- private CIntegerAccessor saEventKind;
- // Exception events
- private JNIHandleAccessor saExceptionThread;
- private JNIHandleAccessor saExceptionClass;
- private JNIid saExceptionMethod;
- private CIntegerAccessor saExceptionLocation;
- private JNIHandleAccessor saExceptionException;
- private JNIHandleAccessor saExceptionCatchClass;
- private JNIid saExceptionCatchMethod;
- private CIntegerAccessor saExceptionCatchLocation;
- // Breakpoint events
- private JNIHandleAccessor saBreakpointThread;
- private JNIHandleAccessor saBreakpointClass;
- private JNIid saBreakpointMethod;
- private CIntegerAccessor saBreakpointLocation;
- // Commands sent by the SA to the VM
- private int SA_CMD_SUSPEND_ALL;
- private int SA_CMD_RESUME_ALL;
- private int SA_CMD_TOGGLE_BREAKPOINT;
- private int SA_CMD_BUF_SIZE;
- private CIntegerAccessor saCmdPending;
- private CIntegerAccessor saCmdType;
- private CIntegerAccessor saCmdResult;
- private CStringAccessor saCmdResultErrMsg;
- // Toggle breakpoint command arguments
- private CStringAccessor saCmdBkptSrcFileName;
- private CStringAccessor saCmdBkptPkgName;
- private CIntegerAccessor saCmdBkptLineNumber;
- private CIntegerAccessor saCmdBkptResWasError;
- private CIntegerAccessor saCmdBkptResLineNumber;
- private CIntegerAccessor saCmdBkptResBCI;
- private CIntegerAccessor saCmdBkptResWasSet;
- private CStringAccessor saCmdBkptResMethodName;
- private CStringAccessor saCmdBkptResMethodSig;
-
- public ServiceabilityAgentJVMDIModule(Debugger dbg, String[] saLibNames) {
- this.dbg = dbg;
- this.saLibNames = saLibNames;
- }
-
- /** Indicates whether a call to attach() should complete without an
- exception. */
- public boolean canAttach() {
- return setupLookup("SA_CMD_SUSPEND_ALL");
- }
-
- /** Attempt to initiate a connection with the JVMDI module in the
- target VM. */
- public void attach() throws DebuggerException {
- if (!canAttach()) {
- throw new DebuggerException("Unable to initiate symbol lookup in SA's JVMDI module");
- }
-
- if (attached) {
- throw new DebuggerException("Already attached");
- }
-
- // Attempt to look up well-known symbols in the target VM.
- SA_CMD_SUSPEND_ALL = lookupConstInt("SA_CMD_SUSPEND_ALL");
- SA_CMD_RESUME_ALL = lookupConstInt("SA_CMD_RESUME_ALL");
- SA_CMD_TOGGLE_BREAKPOINT = lookupConstInt("SA_CMD_TOGGLE_BREAKPOINT");
- SA_CMD_BUF_SIZE = lookupConstInt("SA_CMD_BUF_SIZE");
-
- saAttached = lookupCInt("saAttached");
- saEventPending = lookupCInt("saEventPending");
- saEventKind = lookupCInt("saEventKind");
- saCmdPending = lookupCInt("saCmdPending");
- saCmdType = lookupCInt("saCmdType");
- saCmdResult = lookupCInt("saCmdResult");
- saCmdResultErrMsg = lookupCString("saCmdResultErrMsg", SA_CMD_BUF_SIZE);
- // Toggling of breakpoints
- saCmdBkptSrcFileName = lookupCString("saCmdBkptSrcFileName", SA_CMD_BUF_SIZE);
- saCmdBkptPkgName = lookupCString("saCmdBkptPkgName", SA_CMD_BUF_SIZE);
- saCmdBkptLineNumber = lookupCInt("saCmdBkptLineNumber");
- saCmdBkptResWasError = lookupCInt("saCmdBkptResWasError");
- saCmdBkptResLineNumber = lookupCInt("saCmdBkptResLineNumber");
- saCmdBkptResBCI = lookupCInt("saCmdBkptResBCI");
- saCmdBkptResWasSet = lookupCInt("saCmdBkptResWasSet");
- saCmdBkptResMethodName = lookupCString("saCmdBkptResMethodName", SA_CMD_BUF_SIZE);
- saCmdBkptResMethodSig = lookupCString("saCmdBkptResMethodSig", SA_CMD_BUF_SIZE);
-
- // Check for existence of symbols needed later
- // FIXME: should probably cache these since we can't support the
- // -Xrun module or the VM getting unloaded anyway
- lookup("saExceptionThread");
- lookup("saExceptionClass");
- lookup("saExceptionMethod");
- lookup("saExceptionLocation");
- lookup("saExceptionException");
- lookup("saExceptionCatchClass");
- lookup("saExceptionCatchMethod");
- lookup("saExceptionCatchLocation");
- lookup("saBreakpointThread");
- lookup("saBreakpointClass");
- lookup("saBreakpointMethod");
- lookup("saBreakpointLocation");
-
- saAttached.setValue(1);
- attached = true;
- }
-
- public void detach() {
- saAttached.setValue(0);
- attached = false;
- saLibName = null;
- }
-
- /** Set the timeout value (in milliseconds) for the VM to reply to
- commands. Once this timeout has elapsed, the VM is assumed to
- have disconnected. Defaults to 3000 milliseconds (3 seconds). */
- public void setCommandTimeout(long millis) {
- timeoutMillis = millis;
- }
-
- /** Get the timeout value (in milliseconds) for the VM to reply to
- commands. Once this timeout has elapsed, the VM is assumed to
- have disconnected. Defaults to 3000 milliseconds (3 seconds). */
- public long getCommandTimeout() {
- return timeoutMillis;
- }
-
- /** Indicates whether a Java debug event is pending */
- public boolean eventPending() {
- return (saEventPending.getValue() != 0);
- }
-
- /** Poll for event; returns null if none pending. */
- public Event eventPoll() {
- if (saEventPending.getValue() == 0) {
- return null;
- }
-
- int kind = (int) saEventKind.getValue();
- switch (kind) {
- case JVMDI_EVENT_EXCEPTION: {
- JNIHandleAccessor thread = lookupJNIHandle("saExceptionThread");
- JNIHandleAccessor clazz = lookupJNIHandle("saExceptionClass");
- JNIid method = lookupJNIid("saExceptionMethod");
- CIntegerAccessor location = lookupCInt("saExceptionLocation");
- JNIHandleAccessor exception = lookupJNIHandle("saExceptionException");
- JNIHandleAccessor catchClass = lookupJNIHandle("saExceptionCatchClass");
- JNIid catchMethod = lookupJNIid("saExceptionCatchMethod");
- CIntegerAccessor catchLocation = lookupCInt("saExceptionCatchLocation");
- return new ExceptionEvent(thread.getValue(), clazz.getValue(), method,
- (int) location.getValue(), exception.getValue(),
- catchClass.getValue(), catchMethod, (int) catchLocation.getValue());
- }
-
- case JVMDI_EVENT_BREAKPOINT: {
- JNIHandleAccessor thread = lookupJNIHandle("saBreakpointThread");
- JNIHandleAccessor clazz = lookupJNIHandle("saBreakpointClass");
- JNIid method = lookupJNIid("saBreakpointMethod");
- CIntegerAccessor location = lookupCInt("saBreakpointLocation");
- return new BreakpointEvent(thread.getValue(), clazz.getValue(),
- method, (int) location.getValue());
- }
-
- default:
- throw new DebuggerException("Unsupported event type " + kind);
- }
- }
-
- /** Continue past current event */
- public void eventContinue() {
- saEventPending.setValue(0);
- }
-
- /** Suspend all Java threads in the target VM. Throws
- DebuggerException if the VM disconnected. */
- public void suspend() {
- saCmdType.setValue(SA_CMD_SUSPEND_ALL);
- saCmdPending.setValue(1);
- waitForCommandCompletion();
- suspended = true;
- }
-
- /** Resume all Java threads in the target VM. Throws
- DebuggerException if the VM disconnected. */
- public void resume() {
- saCmdType.setValue(SA_CMD_RESUME_ALL);
- saCmdPending.setValue(1);
- waitForCommandCompletion();
- suspended = false;
- }
-
- /** Indicates whether all Java threads have been suspended via this
- interface. */
- public boolean isSuspended() {
- return suspended;
- }
-
- /** Information about toggling of breakpoints */
- public static class BreakpointToggleResult {
- private boolean success;
- private String errMsg;
- private int lineNumber;
- private int bci;
- private boolean wasSet;
- private String methodName;
- private String methodSig;
-
- /** Success constructor */
- public BreakpointToggleResult(int lineNumber, int bci, boolean wasSet,
- String methodName, String methodSig) {
- this.lineNumber = lineNumber;
- this.bci = bci;
- this.wasSet = wasSet;
- this.methodName = methodName;
- this.methodSig = methodSig;
- success = true;
- }
-
- /** Failure constructor */
- public BreakpointToggleResult(String errMsg) {
- this.errMsg = errMsg;
- success = false;
- }
-
- /** Indicates whether this represents a successful return or not */
- public boolean getSuccess() { return success; }
-
- /** Valid only if getSuccess() returns false */
- public String getErrMsg() { return errMsg; }
-
- /** Line number at which breakpoint toggle occurred; valid only if
- getSuccess() returns true. */
- public int getLineNumber() { return lineNumber; }
-
- /** BCI at which breakpoint toggle occurred; valid only if
- getSuccess() returns true. */
- public int getBCI() { return bci; }
-
- /** Indicates whether the breakpoint toggle was the set of a
- breakpoint or not; valid only if getSuccess() returns true. */
- public boolean getWasSet() { return wasSet; }
-
- /** Method name in which the breakpoint toggle occurred; valid
- only if getSuccess() returns true. */
- public String getMethodName() { return methodName; }
-
- /** Method signature in which the breakpoint toggle occurred;
- valid only if getSuccess() returns true. */
- public String getMethodSignature() { return methodSig; }
- }
-
- /** Toggle a breakpoint. Throws DebuggerException if a real error
- occurred; otherwise returns non-null BreakpointToggleResult. The
- work of scanning the loaded classes is done in the target VM
- because it turns out to be significantly faster than scanning
- through the system dictionary from the SA, and interactivity
- when setting breakpoints is important. */
- public BreakpointToggleResult toggleBreakpoint(String srcFileName,
- String pkgName,
- int lineNo) {
- saCmdBkptSrcFileName.setValue(srcFileName);
- saCmdBkptPkgName.setValue(pkgName);
- saCmdBkptLineNumber.setValue(lineNo);
- saCmdType.setValue(SA_CMD_TOGGLE_BREAKPOINT);
- saCmdPending.setValue(1);
- if (waitForCommandCompletion(true)) {
- return new BreakpointToggleResult((int) saCmdBkptResLineNumber.getValue(),
- (int) saCmdBkptResBCI.getValue(),
- (saCmdBkptResWasSet.getValue() != 0),
- saCmdBkptResMethodName.getValue(),
- saCmdBkptResMethodSig.getValue());
- } else {
- return new BreakpointToggleResult(saCmdResultErrMsg.getValue());
- }
- }
-
-
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- private CIntegerAccessor lookupCInt(String symbolName) {
- return new CIntegerAccessor(lookup(symbolName), 4, false);
- }
-
- private CStringAccessor lookupCString(String symbolName, int bufLen) {
- return new CStringAccessor(lookup(symbolName), bufLen);
- }
-
- private JNIHandleAccessor lookupJNIHandle(String symbolName) {
- return new JNIHandleAccessor(lookup(symbolName), VM.getVM().getObjectHeap());
- }
-
- private JNIid lookupJNIid(String symbolName) {
- Address idAddr = lookup(symbolName).getAddressAt(0);
- if (idAddr == null) {
- return null;
- }
- return new JNIid(idAddr, VM.getVM().getObjectHeap());
- }
-
- private int lookupConstInt(String symbolName) {
- Address addr = lookup(symbolName);
- return (int) addr.getCIntegerAt(0, 4, false);
- }
-
- private boolean setupLookup(String symbolName) {
- if (saLibName == null) {
- for (int i = 0; i < saLibNames.length; i++) {
- Address addr = dbg.lookup(saLibNames[i], symbolName);
- if (addr != null) {
- saLibName = saLibNames[i];
- return true;
- }
- }
- return false;
- }
- return true;
- }
-
- private Address lookup(String symbolName) {
- if (saLibName == null) {
- for (int i = 0; i < saLibNames.length; i++) {
- Address addr = dbg.lookup(saLibNames[i], symbolName);
- if (addr != null) {
- saLibName = saLibNames[i];
- return addr;
- }
- }
- throw new DebuggerException("Unable to find symbol " + symbolName + " in any of the known names for the SA");
- }
-
- Address addr = dbg.lookup(saLibName, symbolName);
- if (addr == null) {
- throw new DebuggerException("Unable to find symbol " + symbolName + " in " + saLibName);
- }
- return addr;
- }
-
- private void waitForCommandCompletion() {
- waitForCommandCompletion(false);
- }
-
- /** Returns true if command succeeded, false if not */
- private boolean waitForCommandCompletion(boolean forBreakpoint) {
- long start = System.currentTimeMillis();
- long cur = start;
- while ((saCmdPending.getValue() != 0) &&
- (cur - start < timeoutMillis)) {
- try {
- java.lang.Thread.currentThread().sleep(10);
- } catch (InterruptedException e) {
- }
- cur = System.currentTimeMillis();
- }
- if (saCmdPending.getValue() != 0) {
- detach();
- throw new DebuggerException("VM appears to have died");
- }
- boolean succeeded = saCmdResult.getValue() == 0;
- if (!succeeded &&
- (!forBreakpoint || saCmdBkptResWasError.getValue() != 0)) {
- String err = saCmdResultErrMsg.getValue();
- throw new DebuggerException("Error executing JVMDI command: " + err);
- }
- return succeeded;
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/memory/CMSCollector.java
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/CMSCollector.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/CMSCollector.java Tue Mar 12 18:22:40 2013 -0700
@@ -61,15 +61,13 @@
CMSBitMap markBitMap = markBitMap();
long addressSize = VM.getVM().getAddressSize();
if ( markBitMap.isMarked(addr) && markBitMap.isMarked(addr.addOffsetTo(1*addressSize)) ) {
- System.err.println("Printezis bits are set...");
Address nextOneAddr = markBitMap.getNextMarkedWordAddress(addr.addOffsetTo(2*addressSize));
//return size in bytes
long size = (nextOneAddr.addOffsetTo(1*addressSize)).minus(addr);
return size;
} else {
- //missing Printezis marks
- System.err.println("Missing Printszis marks...");
- return -1;
+ //missing Printezis marks
+ return -1;
}
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/CompactibleFreeListSpace.java Tue Mar 12 18:22:40 2013 -0700
@@ -191,7 +191,6 @@
//Find the object size using Printezis bits and skip over
long size = collector().blockSizeUsingPrintezisBits(cur);
if (size == -1) {
- System.err.println("Printezis bits not set...");
break;
}
cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -469,7 +469,6 @@
case JVM_CONSTANT_UnresolvedClassInError: return "JVM_CONSTANT_UnresolvedClassInError";
case JVM_CONSTANT_MethodHandleInError:return "JVM_CONSTANT_MethodHandleInError";
case JVM_CONSTANT_MethodTypeInError: return "JVM_CONSTANT_MethodTypeInError";
- case JVM_CONSTANT_Object: return "JVM_CONSTANT_Object";
}
throw new InternalError("Unknown tag: " + tag);
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/MethodData.java Tue Mar 12 18:22:40 2013 -0700
@@ -184,7 +184,6 @@
if (trapReasonName[index] == null) {
throw new InternalError("missing reason for " + index);
}
- System.out.println(trapReasonName[index]);
}
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Tue Mar 12 18:22:40 2013 -0700
@@ -335,7 +335,6 @@
}
if (obj == null) {
//Find the object size using Printezis bits and skip over
- System.err.println("Finding object size using Printezis bits and skipping over...");
long size = 0;
if ( (cmsSpaceOld != null) && cmsSpaceOld.contains(handle) ){
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -67,7 +67,6 @@
public static final int JVM_CONSTANT_UnresolvedClassInError = 103; // Error tag due to resolution error
public static final int JVM_CONSTANT_MethodHandleInError = 104; // Error tag due to resolution error
public static final int JVM_CONSTANT_MethodTypeInError = 105; // Error tag due to resolution error
- public static final int JVM_CONSTANT_Object = 106; // Required for BoundMethodHandle arguments.
// 1.5 major/minor version numbers from JVM spec. 3rd edition
public static final short MAJOR_VERSION = 49;
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Tue Mar 12 18:22:40 2013 -0700
@@ -90,10 +90,6 @@
/** Flags indicating whether we are attached to a core, C1, or C2 build */
private boolean usingClientCompiler;
private boolean usingServerCompiler;
- /** Flag indicating whether UseTLAB is turned on */
- private boolean useTLAB;
- /** Flag indicating whether invokedynamic support is on */
- private boolean enableInvokeDynamic;
/** alignment constants */
private boolean isLP64;
private int bytesPerLong;
@@ -326,9 +322,6 @@
}
}
- useTLAB = (db.lookupIntConstant("UseTLAB").intValue() != 0);
- enableInvokeDynamic = (db.lookupIntConstant("EnableInvokeDynamic").intValue() != 0);
-
if (debugger != null) {
isLP64 = debugger.getMachineDescription().isLP64();
}
@@ -579,15 +572,6 @@
}
}
- /** Indicates whether Thread-Local Allocation Buffers are used */
- public boolean getUseTLAB() {
- return useTLAB;
- }
-
- public boolean getEnableInvokeDynamic() {
- return enableInvokeDynamic;
- }
-
public TypeDataBase getTypeDataBase() {
return db;
}
@@ -822,6 +806,12 @@
return objectAlignmentInBytes;
}
+ /** Indicates whether Thread-Local Allocation Buffers are used */
+ public boolean getUseTLAB() {
+ Flag flag = getCommandLineFlag("UseTLAB");
+ return (flag == null) ? false: flag.getBool();
+ }
+
// returns null, if not available.
public Flag[] getCommandLineFlags() {
if (commandLineFlags == null) {
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Tue Mar 12 18:22:40 2013 -0700
@@ -0,0 +1,277 @@
+/*
+ * 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.
+ *
+ * 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.jvm.hotspot.tools;
+
+import java.io.*;
+import java.util.*;
+
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.memory.*;
+import sun.jvm.hotspot.oops.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.tools.*;
+import sun.jvm.hotspot.utilities.*;
+
+/**
+ A command line tool to print class loader statistics.
+*/
+
+public class ClassLoaderStats extends Tool {
+ boolean verbose = true;
+
+ public static void main(String[] args) {
+ ClassLoaderStats cls = new ClassLoaderStats();
+ cls.start(args);
+ cls.stop();
+ }
+
+ private static class ClassData {
+ Klass klass;
+ long size;
+
+ ClassData(Klass klass, long size) {
+ this.klass = klass; this.size = size;
+ }
+ }
+
+ private static class LoaderData {
+ long numClasses;
+ long classSize;
+ List classDetail = new ArrayList(); // List
+ }
+
+ public void run() {
+ printClassLoaderStatistics();
+ }
+
+ private void printClassLoaderStatistics() {
+ final PrintStream out = System.out;
+ final PrintStream err = System.err;
+ final Map loaderMap = new HashMap();
+ // loader data for bootstrap class loader
+ final LoaderData bootstrapLoaderData = new LoaderData();
+ if (verbose) {
+ err.print("finding class loader instances ..");
+ }
+
+ VM vm = VM.getVM();
+ ObjectHeap heap = vm.getObjectHeap();
+ Klass classLoaderKlass = vm.getSystemDictionary().getClassLoaderKlass();
+ try {
+ heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
+ public boolean doObj(Oop oop) {
+ loaderMap.put(oop, new LoaderData());
+ return false;
+ }
+ }, classLoaderKlass);
+ } catch (Exception se) {
+ se.printStackTrace();
+ }
+
+ if (verbose) {
+ err.println("done.");
+ err.print("computing per loader stat ..");
+ }
+
+ SystemDictionary dict = VM.getVM().getSystemDictionary();
+ dict.classesDo(new SystemDictionary.ClassAndLoaderVisitor() {
+ public void visit(Klass k, Oop loader) {
+ if (! (k instanceof InstanceKlass)) {
+ return;
+ }
+ LoaderData ld = (loader != null) ? (LoaderData)loaderMap.get(loader)
+ : bootstrapLoaderData;
+ if (ld != null) {
+ ld.numClasses++;
+ long size = computeSize((InstanceKlass)k);
+ ld.classDetail.add(new ClassData(k, size));
+ ld.classSize += size;
+ }
+ }
+ });
+
+ if (verbose) {
+ err.println("done.");
+ err.print("please wait.. computing liveness");
+ }
+
+ // compute reverse pointer analysis (takes long time for larger app)
+ ReversePtrsAnalysis analysis = new ReversePtrsAnalysis();
+
+ if (verbose) {
+ analysis.setHeapProgressThunk(new HeapProgressThunk() {
+ public void heapIterationFractionUpdate(double fractionOfHeapVisited) {
+ err.print('.');
+ }
+ // This will be called after the iteration is complete
+ public void heapIterationComplete() {
+ err.println("done.");
+ }
+ });
+ }
+
+ try {
+ analysis.run();
+ } catch (Exception e) {
+ // e.printStackTrace();
+ if (verbose)
+ err.println("liveness analysis may be inaccurate ...");
+ }
+ ReversePtrs liveness = VM.getVM().getRevPtrs();
+
+ out.println("class_loader\tclasses\tbytes\tparent_loader\talive?\ttype");
+ out.println();
+
+ long numClassLoaders = 1L;
+ long totalNumClasses = bootstrapLoaderData.numClasses;
+ long totalClassSize = bootstrapLoaderData.classSize;
+ long numAliveLoaders = 1L;
+ long numDeadLoaders = 0L;
+
+ // print bootstrap loader details
+ out.print("");
+ out.print('\t');
+ out.print(bootstrapLoaderData.numClasses);
+ out.print('\t');
+ out.print(bootstrapLoaderData.classSize);
+ out.print('\t');
+ out.print(" null ");
+ out.print('\t');
+ // bootstrap loader is always alive
+ out.print("live");
+ out.print('\t');
+ out.println("");
+
+ for (Iterator keyItr = loaderMap.keySet().iterator(); keyItr.hasNext();) {
+ Oop loader = (Oop) keyItr.next();
+ LoaderData data = (LoaderData) loaderMap.get(loader);
+ numClassLoaders ++;
+ totalNumClasses += data.numClasses;
+ totalClassSize += data.classSize;
+
+ out.print(loader.getHandle());
+ out.print('\t');
+ out.print(data.numClasses);
+ out.print('\t');
+ out.print(data.classSize);
+ out.print('\t');
+
+ class ParentFinder extends DefaultOopVisitor {
+ public void doOop(OopField field, boolean isVMField) {
+ if (field.getID().getName().equals("parent")) {
+ parent = field.getValue(getObj());
+ }
+ }
+ private Oop parent = null;
+ public Oop getParent() { return parent; }
+ }
+
+ ParentFinder parentFinder = new ParentFinder();
+ loader.iterate(parentFinder, false);
+ Oop parent = parentFinder.getParent();
+ out.print((parent != null)? parent.getHandle().toString() : " null ");
+ out.print('\t');
+ boolean alive = (liveness != null) ? (liveness.get(loader) != null) : true;
+ out.print(alive? "live" : "dead");
+ if (alive) numAliveLoaders++; else numDeadLoaders++;
+ out.print('\t');
+ Klass loaderKlass = loader.getKlass();
+ if (loaderKlass != null) {
+ out.print(loaderKlass.getName().asString());
+ out.print('@');
+ out.print(loader.getKlass().getAddress());
+ } else {
+ out.print(" null! ");
+ }
+ out.println();
+ }
+
+ out.println();
+ // summary line
+ out.print("total = ");
+ out.print(numClassLoaders);
+ out.print('\t');
+ out.print(totalNumClasses);
+ out.print('\t');
+ out.print(totalClassSize);
+ out.print('\t');
+ out.print(" N/A ");
+ out.print('\t');
+ out.print("alive=");
+ out.print(numAliveLoaders);
+ out.print(", dead=");
+ out.print(numDeadLoaders);
+ out.print('\t');
+ out.print(" N/A ");
+ out.println();
+ }
+
+ private static long objectSize(Oop oop) {
+ return oop == null ? 0L : oop.getObjectSize();
+ }
+
+ // Don't count the shared empty arrays
+ private static long arraySize(GenericArray arr) {
+ return arr.getLength() != 0L ? arr.getSize() : 0L;
+ }
+
+ private long computeSize(InstanceKlass k) {
+ long size = 0L;
+ // the InstanceKlass object itself
+ size += k.getSize();
+
+ // Constant pool
+ ConstantPool cp = k.getConstants();
+ size += cp.getSize();
+ if (cp.getCache() != null) {
+ size += cp.getCache().getSize();
+ }
+ size += arraySize(cp.getTags());
+
+ // Interfaces
+ size += arraySize(k.getLocalInterfaces());
+ size += arraySize(k.getTransitiveInterfaces());
+
+ // Inner classes
+ size += arraySize(k.getInnerClasses());
+
+ // Fields
+ size += arraySize(k.getFields());
+
+ // Methods
+ MethodArray methods = k.getMethods();
+ int nmethods = (int) methods.getLength();
+ if (nmethods != 0L) {
+ size += methods.getSize();
+ for (int i = 0; i < nmethods; ++i) {
+ Method m = methods.at(i);
+ size += m.getSize();
+ size += m.getConstMethod().getSize();
+ }
+ }
+
+ return size;
+ }
+}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Tue Mar 12 18:22:40 2013 -0700
@@ -57,17 +57,18 @@
printGCAlgorithm(flagMap);
System.out.println();
System.out.println("Heap Configuration:");
- printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
- printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
- printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
- printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
- printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
- printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
- printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
- printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
- printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
- printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
- printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
+ printValue("MinHeapFreeRatio = ", getFlagValue("MinHeapFreeRatio", flagMap));
+ printValue("MaxHeapFreeRatio = ", getFlagValue("MaxHeapFreeRatio", flagMap));
+ printValMB("MaxHeapSize = ", getFlagValue("MaxHeapSize", flagMap));
+ printValMB("NewSize = ", getFlagValue("NewSize", flagMap));
+ printValMB("MaxNewSize = ", getFlagValue("MaxNewSize", flagMap));
+ printValMB("OldSize = ", getFlagValue("OldSize", flagMap));
+ printValue("NewRatio = ", getFlagValue("NewRatio", flagMap));
+ printValue("SurvivorRatio = ", getFlagValue("SurvivorRatio", flagMap));
+ printValMB("MetaspaceSize = ", getFlagValue("MetaspaceSize", flagMap));
+ printValMB("ClassMetaspaceSize = ", getFlagValue("ClassMetaspaceSize", flagMap));
+ printValMB("MaxMetaspaceSize = ", getFlagValue("MaxMetaspaceSize", flagMap));
+ printValMB("G1HeapRegionSize = ", HeapRegion.grainBytes());
System.out.println();
System.out.println("Heap Usage:");
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -45,7 +45,7 @@
}
protected String getCommandFlags() {
- return "-heap|-heap:format=b|-histo|-permstat|-finalizerinfo";
+ return "-heap|-heap:format=b|-histo|-clstats|-finalizerinfo";
}
protected void printFlagsUsage() {
@@ -53,14 +53,14 @@
System.out.println(" -heap\tto print java heap summary");
System.out.println(" -heap:format=b\tto dump java heap in hprof binary format");
System.out.println(" -histo\tto print histogram of java object heap");
- System.out.println(" -permstat\tto print permanent generation statistics");
+ System.out.println(" -clstats\tto print class loader statistics");
System.out.println(" -finalizerinfo\tto print information on objects awaiting finalization");
super.printFlagsUsage();
}
public static final int MODE_HEAP_SUMMARY = 0;
public static final int MODE_HISTOGRAM = 1;
- public static final int MODE_PERMSTAT = 2;
+ public static final int MODE_CLSTATS = 2;
public static final int MODE_PMAP = 3;
public static final int MODE_HEAP_GRAPH_HPROF_BIN = 4;
public static final int MODE_HEAP_GRAPH_GXL = 5;
@@ -78,8 +78,8 @@
tool = new ObjectHistogram();
break;
- case MODE_PERMSTAT:
- tool = new PermStat();
+ case MODE_CLSTATS:
+ tool = new ClassLoaderStats();
break;
case MODE_PMAP:
@@ -118,7 +118,9 @@
} else if (modeFlag.equals("-histo")) {
mode = MODE_HISTOGRAM;
} else if (modeFlag.equals("-permstat")) {
- mode = MODE_PERMSTAT;
+ mode = MODE_CLSTATS;
+ } else if (modeFlag.equals("-clstats")) {
+ mode = MODE_CLSTATS;
} else if (modeFlag.equals("-finalizerinfo")) {
mode = MODE_FINALIZERINFO;
} else {
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Tue Mar 12 18:22:40 2013 -0700
@@ -58,10 +58,6 @@
}
}
- protected boolean requiresVM() {
- return false;
- }
-
public static void main(String[] args) throws Exception {
PMap t = new PMap();
t.start(args);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Tue Mar 12 18:22:40 2013 -0700
@@ -50,29 +50,23 @@
public void run(PrintStream out) {
Debugger dbg = getAgent().getDebugger();
- run(out, dbg, getAgent().isJavaMode());
+ run(out, dbg);
}
public void run(PrintStream out, Debugger dbg) {
- run(out, dbg, true);
- }
-
- private void run(PrintStream out, Debugger dbg, final boolean isJava) {
CDebugger cdbg = dbg.getCDebugger();
if (cdbg != null) {
ConcurrentLocksPrinter concLocksPrinter = null;
- if (isJava) {
- // compute and cache java Vframes.
- initJFrameCache();
- if (concurrentLocks) {
- concLocksPrinter = new ConcurrentLocksPrinter();
- }
- // print Java level deadlocks
- try {
- DeadlockDetector.print(out);
- } catch (Exception exp) {
- out.println("can't print deadlock information: " + exp.getMessage());
- }
+ // compute and cache java Vframes.
+ initJFrameCache();
+ if (concurrentLocks) {
+ concLocksPrinter = new ConcurrentLocksPrinter();
+ }
+ // print Java level deadlocks
+ try {
+ DeadlockDetector.print(out);
+ } catch (Exception exp) {
+ out.println("can't print deadlock information: " + exp.getMessage());
}
List l = cdbg.getThreadList();
@@ -100,63 +94,59 @@
}
out.println();
} else {
- if (isJava) {
- // look for one or more java frames
- String[] names = null;
- // check interpreter frame
- Interpreter interp = VM.getVM().getInterpreter();
- if (interp.contains(pc)) {
- names = getJavaNames(th, f.localVariableBase());
- // print codelet name if we can't determine method
- if (names == null || names.length == 0) {
- out.print(" ");
- InterpreterCodelet ic = interp.getCodeletContaining(pc);
- if (ic != null) {
- String desc = ic.getDescription();
- if (desc != null) out.print(desc);
- }
- out.println();
- }
- } else {
- // look for known code blobs
- CodeCache c = VM.getVM().getCodeCache();
- if (c.contains(pc)) {
- CodeBlob cb = c.findBlobUnsafe(pc);
- if (cb.isNMethod()) {
- names = getJavaNames(th, f.localVariableBase());
- // just print compiled code, if can't determine method
- if (names == null || names.length == 0) {
- out.println("");
- }
- } else if (cb.isBufferBlob()) {
- out.println("");
- } else if (cb.isRuntimeStub()) {
- out.println("");
- } else if (cb.isDeoptimizationStub()) {
- out.println("");
- } else if (cb.isUncommonTrapStub()) {
- out.println("");
- } else if (cb.isExceptionStub()) {
- out.println("");
- } else if (cb.isSafepointStub()) {
- out.println("");
- } else {
- out.println("");
- }
- } else {
- printUnknown(out);
- }
- }
- // print java frames, if any
- if (names != null && names.length != 0) {
- // print java frame(s)
- for (int i = 0; i < names.length; i++) {
- out.println(names[i]);
- }
- }
- } else {
- printUnknown(out);
- }
+ // look for one or more java frames
+ String[] names = null;
+ // check interpreter frame
+ Interpreter interp = VM.getVM().getInterpreter();
+ if (interp.contains(pc)) {
+ names = getJavaNames(th, f.localVariableBase());
+ // print codelet name if we can't determine method
+ if (names == null || names.length == 0) {
+ out.print(" ");
+ InterpreterCodelet ic = interp.getCodeletContaining(pc);
+ if (ic != null) {
+ String desc = ic.getDescription();
+ if (desc != null) out.print(desc);
+ }
+ out.println();
+ }
+ } else {
+ // look for known code blobs
+ CodeCache c = VM.getVM().getCodeCache();
+ if (c.contains(pc)) {
+ CodeBlob cb = c.findBlobUnsafe(pc);
+ if (cb.isNMethod()) {
+ names = getJavaNames(th, f.localVariableBase());
+ // just print compiled code, if can't determine method
+ if (names == null || names.length == 0) {
+ out.println("");
+ }
+ } else if (cb.isBufferBlob()) {
+ out.println("");
+ } else if (cb.isRuntimeStub()) {
+ out.println("");
+ } else if (cb.isDeoptimizationStub()) {
+ out.println("");
+ } else if (cb.isUncommonTrapStub()) {
+ out.println("");
+ } else if (cb.isExceptionStub()) {
+ out.println("");
+ } else if (cb.isSafepointStub()) {
+ out.println("");
+ } else {
+ out.println("");
+ }
+ } else {
+ printUnknown(out);
+ }
+ }
+ // print java frames, if any
+ if (names != null && names.length != 0) {
+ // print java frame(s)
+ for (int i = 0; i < names.length; i++) {
+ out.println(names[i]);
+ }
+ }
}
f = f.sender(th);
}
@@ -164,7 +154,7 @@
exp.printStackTrace();
// continue, may be we can do a better job for other threads
}
- if (isJava && concurrentLocks) {
+ if (concurrentLocks) {
JavaThread jthread = (JavaThread) proxyToThread.get(th);
if (jthread != null) {
concLocksPrinter.print(jthread, out);
@@ -180,10 +170,6 @@
}
}
- protected boolean requiresVM() {
- return false;
- }
-
public static void main(String[] args) throws Exception {
PStack t = new PStack();
t.start(args);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/PermStat.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- *
- */
-
-package sun.jvm.hotspot.tools;
-
-import java.io.*;
-import java.util.*;
-
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.memory.*;
-import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.tools.*;
-import sun.jvm.hotspot.utilities.*;
-
-/**
- A command line tool to print perm. generation statistics.
-*/
-
-public class PermStat extends Tool {
- boolean verbose = true;
-
- public static void main(String[] args) {
- PermStat ps = new PermStat();
- ps.start(args);
- ps.stop();
- }
-
- private static class ClassData {
- Klass klass;
- long size;
-
- ClassData(Klass klass, long size) {
- this.klass = klass; this.size = size;
- }
- }
-
- private static class LoaderData {
- long numClasses;
- long classSize;
- List classDetail = new ArrayList(); // List
- }
-
- public void run() {
- printClassLoaderStatistics();
- }
-
- private void printClassLoaderStatistics() {
- final PrintStream out = System.out;
- final PrintStream err = System.err;
- final Map loaderMap = new HashMap();
- // loader data for bootstrap class loader
- final LoaderData bootstrapLoaderData = new LoaderData();
- if (verbose) {
- err.print("finding class loader instances ..");
- }
-
- VM vm = VM.getVM();
- ObjectHeap heap = vm.getObjectHeap();
- Klass classLoaderKlass = vm.getSystemDictionary().getClassLoaderKlass();
- try {
- heap.iterateObjectsOfKlass(new DefaultHeapVisitor() {
- public boolean doObj(Oop oop) {
- loaderMap.put(oop, new LoaderData());
- return false;
- }
- }, classLoaderKlass);
- } catch (Exception se) {
- se.printStackTrace();
- }
-
- if (verbose) {
- err.println("done.");
- err.print("computing per loader stat ..");
- }
-
- SystemDictionary dict = VM.getVM().getSystemDictionary();
- dict.classesDo(new SystemDictionary.ClassAndLoaderVisitor() {
- public void visit(Klass k, Oop loader) {
- if (! (k instanceof InstanceKlass)) {
- return;
- }
- LoaderData ld = (loader != null) ? (LoaderData)loaderMap.get(loader)
- : bootstrapLoaderData;
- if (ld != null) {
- ld.numClasses++;
- long size = computeSize((InstanceKlass)k);
- ld.classDetail.add(new ClassData(k, size));
- ld.classSize += size;
- }
- }
- });
-
- if (verbose) {
- err.println("done.");
- err.print("please wait.. computing liveness");
- }
-
- // compute reverse pointer analysis (takes long time for larger app)
- ReversePtrsAnalysis analysis = new ReversePtrsAnalysis();
-
- if (verbose) {
- analysis.setHeapProgressThunk(new HeapProgressThunk() {
- public void heapIterationFractionUpdate(double fractionOfHeapVisited) {
- err.print('.');
- }
- // This will be called after the iteration is complete
- public void heapIterationComplete() {
- err.println("done.");
- }
- });
- }
-
- try {
- analysis.run();
- } catch (Exception e) {
- // e.printStackTrace();
- if (verbose)
- err.println("liveness analysis may be inaccurate ...");
- }
- ReversePtrs liveness = VM.getVM().getRevPtrs();
-
- out.println("class_loader\tclasses\tbytes\tparent_loader\talive?\ttype");
- out.println();
-
- long numClassLoaders = 1L;
- long totalNumClasses = bootstrapLoaderData.numClasses;
- long totalClassSize = bootstrapLoaderData.classSize;
- long numAliveLoaders = 1L;
- long numDeadLoaders = 0L;
-
- // print bootstrap loader details
- out.print("");
- out.print('\t');
- out.print(bootstrapLoaderData.numClasses);
- out.print('\t');
- out.print(bootstrapLoaderData.classSize);
- out.print('\t');
- out.print(" null ");
- out.print('\t');
- // bootstrap loader is always alive
- out.print("live");
- out.print('\t');
- out.println("");
-
- for (Iterator keyItr = loaderMap.keySet().iterator(); keyItr.hasNext();) {
- Oop loader = (Oop) keyItr.next();
- LoaderData data = (LoaderData) loaderMap.get(loader);
- numClassLoaders ++;
- totalNumClasses += data.numClasses;
- totalClassSize += data.classSize;
-
- out.print(loader.getHandle());
- out.print('\t');
- out.print(data.numClasses);
- out.print('\t');
- out.print(data.classSize);
- out.print('\t');
-
- class ParentFinder extends DefaultOopVisitor {
- public void doOop(OopField field, boolean isVMField) {
- if (field.getID().getName().equals("parent")) {
- parent = field.getValue(getObj());
- }
- }
- private Oop parent = null;
- public Oop getParent() { return parent; }
- }
-
- ParentFinder parentFinder = new ParentFinder();
- loader.iterate(parentFinder, false);
- Oop parent = parentFinder.getParent();
- out.print((parent != null)? parent.getHandle().toString() : " null ");
- out.print('\t');
- boolean alive = (liveness != null) ? (liveness.get(loader) != null) : true;
- out.print(alive? "live" : "dead");
- if (alive) numAliveLoaders++; else numDeadLoaders++;
- out.print('\t');
- Klass loaderKlass = loader.getKlass();
- if (loaderKlass != null) {
- out.print(loaderKlass.getName().asString());
- out.print('@');
- out.print(loader.getKlass().getAddress());
- } else {
- out.print(" null! ");
- }
- out.println();
- }
-
- out.println();
- // summary line
- out.print("total = ");
- out.print(numClassLoaders);
- out.print('\t');
- out.print(totalNumClasses);
- out.print('\t');
- out.print(totalClassSize);
- out.print('\t');
- out.print(" N/A ");
- out.print('\t');
- out.print("alive=");
- out.print(numAliveLoaders);
- out.print(", dead=");
- out.print(numDeadLoaders);
- out.print('\t');
- out.print(" N/A ");
- out.println();
- }
-
- private static long objectSize(Oop oop) {
- return oop == null ? 0L : oop.getObjectSize();
- }
-
- // Don't count the shared empty arrays
- private static long arraySize(GenericArray arr) {
- return arr.getLength() != 0L ? arr.getSize() : 0L;
- }
-
- private long computeSize(InstanceKlass k) {
- long size = 0L;
- // the InstanceKlass object itself
- size += k.getSize();
-
- // Constant pool
- ConstantPool cp = k.getConstants();
- size += cp.getSize();
- if (cp.getCache() != null) {
- size += cp.getCache().getSize();
- }
- size += arraySize(cp.getTags());
-
- // Interfaces
- size += arraySize(k.getLocalInterfaces());
- size += arraySize(k.getTransitiveInterfaces());
-
- // Inner classes
- size += arraySize(k.getInnerClasses());
-
- // Fields
- size += arraySize(k.getFields());
-
- // Methods
- MethodArray methods = k.getMethods();
- int nmethods = (int) methods.getLength();
- if (nmethods != 0L) {
- size += methods.getSize();
- for (int i = 0; i < nmethods; ++i) {
- Method m = methods.at(i);
- size += m.getSize();
- size += m.getConstMethod().getSize();
- }
- }
-
- return size;
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Tue Mar 12 18:22:40 2013 -0700
@@ -27,7 +27,6 @@
import java.io.PrintStream;
import java.util.Hashtable;
import sun.jvm.hotspot.*;
-import sun.jvm.hotspot.bugspot.*;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.debugger.*;
@@ -35,7 +34,7 @@
// override run & code main as shown below.
public abstract class Tool implements Runnable {
- private BugSpotAgent agent;
+ private HotSpotAgent agent;
private int debugeeType;
// debugeeType is one of constants below
@@ -51,12 +50,7 @@
return true;
}
- // whether this tool requires debuggee to be java process or core?
- protected boolean requiresVM() {
- return true;
- }
-
- protected void setAgent(BugSpotAgent a) {
+ protected void setAgent(HotSpotAgent a) {
agent = a;
}
@@ -64,7 +58,7 @@
debugeeType = dt;
}
- protected BugSpotAgent getAgent() {
+ protected HotSpotAgent getAgent() {
return agent;
}
@@ -155,7 +149,7 @@
usage();
}
- agent = new BugSpotAgent();
+ agent = new HotSpotAgent();
try {
switch (debugeeType) {
case DEBUGEE_PID:
@@ -198,33 +192,24 @@
err.println("Debugger attached successfully.");
- boolean isJava = agent.isJavaMode();
- if (isJava) {
- VM vm = VM.getVM();
- if (vm.isCore()) {
- err.println("Core build detected.");
- } else if (vm.isClientCompiler()) {
- err.println("Client compiler detected.");
- } else if (vm.isServerCompiler()) {
- err.println("Server compiler detected.");
- } else {
- throw new RuntimeException("Fatal error: " +
- "should have been able to detect core/C1/C2 build");
- }
+ VM vm = VM.getVM();
+ if (vm.isCore()) {
+ err.println("Core build detected.");
+ } else if (vm.isClientCompiler()) {
+ err.println("Client compiler detected.");
+ } else if (vm.isServerCompiler()) {
+ err.println("Server compiler detected.");
+ } else {
+ throw new RuntimeException("Fatal error: "
+ + "should have been able to detect core/C1/C2 build");
+ }
- String version = vm.getVMRelease();
- if (version != null) {
- err.print("JVM version is ");
- err.println(version);
- }
+ String version = vm.getVMRelease();
+ if (version != null) {
+ err.print("JVM version is ");
+ err.println(version);
+ }
- run();
- } else { // not a java process or core
- if (requiresVM()) {
- err.println(getName() + " requires a java VM process/core!");
- } else {
- run();
- }
- }
+ run();
}
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java Tue Mar 12 18:22:40 2013 -0700
@@ -50,7 +50,7 @@
/**
* This base class encapsulates many of the events that are fired from
* the various panels in this directory so they can easily be plugged
- * in to different containing frameworks (HSDB, BugSpot).
+ * in to different containing frameworks (HSDB).
*/
public class SAPanel extends JPanel {
protected List listeners = new ArrayList();
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ConstantTag.java Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -51,7 +51,6 @@
private static final int JVM_CONSTANT_UnresolvedClassInError = 103; // Resolution failed
private static final int JVM_CONSTANT_MethodHandleInError = 104; // Error tag due to resolution error
private static final int JVM_CONSTANT_MethodTypeInError = 105; // Error tag due to resolution error
- private static final int JVM_CONSTANT_Object = 106; // Required for BoundMethodHandle arguments.
// JVM_CONSTANT_MethodHandle subtypes //FIXME: connect these to data structure
private static int JVM_REF_getField = 1;
@@ -96,8 +95,6 @@
public boolean isKlassIndex() { return tag == JVM_CONSTANT_ClassIndex; }
public boolean isStringIndex() { return tag == JVM_CONSTANT_StringIndex; }
- public boolean isObject() { return tag == JVM_CONSTANT_Object; }
-
public boolean isKlassReference() { return isKlassIndex() || isUnresolvedKlass(); }
public boolean isFieldOrMethod() { return isField() || isMethod() || isInterfaceMethod(); }
public boolean isSymbol() { return isUtf8(); }
@@ -123,7 +120,6 @@
case JVM_CONSTANT_StringIndex :
case JVM_CONSTANT_MethodHandle :
case JVM_CONSTANT_MethodType :
- case JVM_CONSTANT_Object :
return BasicType.T_OBJECT;
default:
throw new InternalError("unexpected tag: " + tag);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Mon Feb 25 07:22:06 2013 +0100
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Tue Mar 12 18:22:40 2013 -0700
@@ -31,7 +31,6 @@
sapkg.hotspot = Packages.sun.jvm.hotspot;
sapkg.asm = sapkg.hotspot.asm;
-sapkg.bugspot = sapkg.hotspot.bugspot;
sapkg.c1 = sapkg.hotspot.c1;
sapkg.code = sapkg.hotspot.code;
sapkg.compiler = sapkg.hotspot.compiler;
@@ -40,7 +39,6 @@
// sapkg.debugger = sapkg.hotspot.debugger;
sapkg.interpreter = sapkg.hotspot.interpreter;
-sapkg.livejvm = sapkg.hotspot.livejvm;
sapkg.jdi = sapkg.hotspot.jdi;
sapkg.memory = sapkg.hotspot.memory;
sapkg.oops = sapkg.hotspot.oops;
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/native/jvmdi/sa.cpp
--- a/agent/src/share/native/jvmdi/sa.cpp Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,601 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-#include
-#include
-#include
-#include
-#include "sa.hpp"
-#include "jni.h"
-#include "jvmdi.h"
-
-#ifndef WIN32
- #include
-#else
- typedef int int32_t;
-#endif
-
-#ifdef WIN32
- #include
- #define YIELD() Sleep(0)
- #define SLEEP() Sleep(10)
- #define vsnprintf _vsnprintf
-#else
- Error: please port YIELD() and SLEEP() macros to your platform
-#endif
-
-using namespace std;
-
-//////////////////////////////////////////////////////////////////////
-// //
-// Exported "interface" for Java language-level interaction between //
-// the SA and the VM. Note that the SA knows about the layout of //
-// certain VM data structures and that knowledge is taken advantage //
-// of in this code, although this interfaces with the VM via JVMDI. //
-// //
-//////////////////////////////////////////////////////////////////////
-
-extern "C" {
- /////////////////////////////////////
- // //
- // Events sent by the VM to the SA //
- // //
- /////////////////////////////////////
-
- // Set by the SA when it attaches. Indicates that events should be
- // posted via these exported variables, and that the VM should wait
- // for those events to be acknowledged by the SA (via its setting
- // saEventPending to 0).
- JNIEXPORT volatile int32_t saAttached = 0;
-
- // Set to nonzero value by the VM when an event has been posted; set
- // back to 0 by the SA when it has processed that event.
- JNIEXPORT volatile int32_t saEventPending = 0;
-
- // Kind of the event (from jvmdi.h)
- JNIEXPORT volatile int32_t saEventKind = 0;
-
- //
- // Exception events
- //
- JNIEXPORT jthread saExceptionThread;
- JNIEXPORT jclass saExceptionClass;
- JNIEXPORT jmethodID saExceptionMethod;
- JNIEXPORT int32_t saExceptionLocation;
- JNIEXPORT jobject saExceptionException;
- JNIEXPORT jclass saExceptionCatchClass;
- JNIEXPORT jmethodID saExceptionCatchMethod;
- JNIEXPORT int32_t saExceptionCatchLocation;
-
- //
- // Breakpoint events
- //
- JNIEXPORT jthread saBreakpointThread;
- JNIEXPORT jclass saBreakpointClass;
- JNIEXPORT jmethodID saBreakpointMethod;
- JNIEXPORT jlocation saBreakpointLocation;
-
- ///////////////////////////////////////
- // //
- // Commands sent by the SA to the VM //
- // //
- ///////////////////////////////////////
-
- extern JNIEXPORT const int32_t SA_CMD_SUSPEND_ALL = 0;
- extern JNIEXPORT const int32_t SA_CMD_RESUME_ALL = 1;
- extern JNIEXPORT const int32_t SA_CMD_TOGGLE_BREAKPOINT = 2;
- extern JNIEXPORT const int32_t SA_CMD_BUF_SIZE = 1024;
-
- // SA sets this to a nonzero value when it is requesting a command
- // to be processed; VM sets it back to 0 when the command has been
- // executed
- JNIEXPORT volatile int32_t saCmdPending = 0;
-
- // SA sets this to one of the manifest constants above to indicate
- // the kind of command to be executed
- JNIEXPORT volatile int32_t saCmdType = 0;
-
- // VM sets this to 0 if the last command succeeded or a nonzero
- // value if it failed
- JNIEXPORT volatile int32_t saCmdResult = 0;
-
- // If last command failed, this buffer will contain a descriptive
- // error message
- JNIEXPORT char saCmdResultErrMsg[SA_CMD_BUF_SIZE];
-
- //
- // Toggling of breakpoint command arguments.
- //
- // Originally there were separate set/clear breakpoint commands
- // taking a class name, method name and signature, and the iteration
- // through the debug information was done in the SA. It turns out
- // that doing this work in the target VM is significantly faster,
- // and since interactivity when setting and clearing breakpoints is
- // important, the solution which resulted in more C/C++ code was used.
- //
-
- // Source file name
- JNIEXPORT char saCmdBkptSrcFileName[SA_CMD_BUF_SIZE];
-
- // Package name ('/' as separator instead of '.')
- JNIEXPORT char saCmdBkptPkgName[SA_CMD_BUF_SIZE];
-
- // Line number
- JNIEXPORT int32_t saCmdBkptLineNumber;
-
- // Output back to SA: indicator whether the last failure of a
- // breakpoint toggle command was really an error or just a lack of
- // debug information covering the requested line. 0 if not error.
- // Valid only if saCmdResult != 0.
- JNIEXPORT int32_t saCmdBkptResWasError;
-
- // Output back to SA: resulting line number at which the breakpoint
- // was set or cleared (valid only if saCmdResult == 0)
- JNIEXPORT int32_t saCmdBkptResLineNumber;
-
- // Output back to SA: resulting byte code index at which the
- // breakpoint was set or cleared (valid only if saCmdResult == 0)
- JNIEXPORT int32_t saCmdBkptResBCI;
-
- // Output back to SA: indicator whether the breakpoint operation
- // resulted in a set or cleared breakpoint; nonzero if set, zero if
- // cleared (valid only if saCmdResult == 0)
- JNIEXPORT int32_t saCmdBkptResWasSet;
-
- // Output back to SA: method name the breakpoint was set in (valid
- // only if saCmdResult == 0)
- JNIEXPORT char saCmdBkptResMethodName[SA_CMD_BUF_SIZE];
-
- // Output back to SA: method signature (JNI style) the breakpoint
- // was set in (valid only if saCmdResult == 0)
- JNIEXPORT char saCmdBkptResMethodSig[SA_CMD_BUF_SIZE];
-}
-
-// Internal state
-static JavaVM* jvm = NULL;
-static JVMDI_Interface_1* jvmdi = NULL;
-static jthread debugThreadObj = NULL;
-static bool suspended = false;
-static vector suspendedThreads;
-static JVMDI_RawMonitor eventLock = NULL;
-
-class MonitorLocker {
-private:
- JVMDI_RawMonitor lock;
-public:
- MonitorLocker(JVMDI_RawMonitor lock) {
- this->lock = lock;
- if (lock != NULL) {
- jvmdi->RawMonitorEnter(lock);
- }
- }
- ~MonitorLocker() {
- if (lock != NULL) {
- jvmdi->RawMonitorExit(lock);
- }
- }
-};
-
-class JvmdiDeallocator {
-private:
- void* ptr;
-public:
- JvmdiDeallocator(void* ptr) {
- this->ptr = ptr;
- }
- ~JvmdiDeallocator() {
- jvmdi->Deallocate((jbyte*) ptr);
- }
-};
-
-class JvmdiRefListDeallocator {
-private:
- JNIEnv* env;
- jobject* refList;
- jint refCount;
-public:
- JvmdiRefListDeallocator(JNIEnv* env, jobject* refList, jint refCount) {
- this->env = env;
- this->refList = refList;
- this->refCount = refCount;
- }
- ~JvmdiRefListDeallocator() {
- for (int i = 0; i < refCount; i++) {
- env->DeleteGlobalRef(refList[i]);
- }
- jvmdi->Deallocate((jbyte*) refList);
- }
-};
-
-static void
-stop(char* msg) {
- fprintf(stderr, "%s", msg);
- fprintf(stderr, "\n");
- exit(1);
-}
-
-// This fills in the command result error message, sets the command
-// result to -1, and clears the pending command flag
-static void
-reportErrorToSA(const char* str, ...) {
- va_list varargs;
- va_start(varargs, str);
- vsnprintf(saCmdResultErrMsg, sizeof(saCmdResultErrMsg), str, varargs);
- va_end(varargs);
- saCmdResult = -1;
- saCmdPending = 0;
-}
-
-static bool
-packageNameMatches(char* clazzName, char* pkg) {
- int pkgLen = strlen(pkg);
- int clazzNameLen = strlen(clazzName);
-
- if (pkgLen >= clazzNameLen + 1) {
- return false;
- }
-
- if (strncmp(clazzName, pkg, pkgLen)) {
- return false;
- }
-
- // Ensure that '/' is the next character if non-empty package name
- int l = pkgLen;
- if (l > 0) {
- if (clazzName[l] != '/') {
- return false;
- }
- l++;
- }
- // Ensure that there are no more trailing slashes
- while (l < clazzNameLen) {
- if (clazzName[l++] == '/') {
- return false;
- }
- }
- return true;
-}
-
-static void
-executeOneCommand(JNIEnv* env) {
- switch (saCmdType) {
- case SA_CMD_SUSPEND_ALL: {
- if (suspended) {
- reportErrorToSA("Target process already suspended");
- return;
- }
-
- // We implement this by getting all of the threads and calling
- // SuspendThread on each one, except for the thread object
- // corresponding to this thread. Each thread for which the call
- // succeeded (i.e., did not return JVMDI_ERROR_INVALID_THREAD)
- // is added to a list which is remembered for later resumption.
- // Note that this currently has race conditions since a thread
- // might be started after we call GetAllThreads and since a
- // thread for which we got an error earlier might be resumed by
- // the VM while we are busy suspending other threads. We could
- // solve this by looping until there are no more threads we can
- // suspend, but a more robust and scalable solution is to add
- // this functionality to the JVMDI interface (i.e.,
- // "suspendAll"). Probably need to provide an exclude list for
- // such a routine.
- jint threadCount;
- jthread* threads;
- if (jvmdi->GetAllThreads(&threadCount, &threads) != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error while getting thread list");
- return;
- }
-
-
- for (int i = 0; i < threadCount; i++) {
- jthread thr = threads[i];
- if (!env->IsSameObject(thr, debugThreadObj)) {
- jvmdiError err = jvmdi->SuspendThread(thr);
- if (err == JVMDI_ERROR_NONE) {
- // Remember this thread and do not free it
- suspendedThreads.push_back(thr);
- continue;
- } else {
- fprintf(stderr, " SA: Error %d while suspending thread\n", err);
- // FIXME: stop, resume all threads, report error
- }
- }
- env->DeleteGlobalRef(thr);
- }
-
- // Free up threads
- jvmdi->Deallocate((jbyte*) threads);
-
- // Suspension is complete
- suspended = true;
- break;
- }
-
- case SA_CMD_RESUME_ALL: {
- if (!suspended) {
- reportErrorToSA("Target process already suspended");
- return;
- }
-
- saCmdResult = 0;
- bool errorOccurred = false;
- jvmdiError firstError;
- for (int i = 0; i < suspendedThreads.size(); i++) {
- jthread thr = suspendedThreads[i];
- jvmdiError err = jvmdi->ResumeThread(thr);
- env->DeleteGlobalRef(thr);
- if (err != JVMDI_ERROR_NONE) {
- if (!errorOccurred) {
- errorOccurred = true;
- firstError = err;
- }
- }
- }
- suspendedThreads.clear();
- suspended = false;
- if (errorOccurred) {
- reportErrorToSA("Error %d while resuming threads", firstError);
- return;
- }
- break;
- }
-
- case SA_CMD_TOGGLE_BREAKPOINT: {
- saCmdBkptResWasError = 1;
-
- // Search line number info for all loaded classes
- jint classCount;
- jclass* classes;
-
- jvmdiError glcRes = jvmdi->GetLoadedClasses(&classCount, &classes);
- if (glcRes != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error %d while getting loaded classes", glcRes);
- return;
- }
- JvmdiRefListDeallocator rld(env, (jobject*) classes, classCount);
-
- bool done = false;
- bool gotOne = false;
- jclass targetClass;
- jmethodID targetMethod;
- jlocation targetLocation;
- jint targetLineNumber;
-
- for (int i = 0; i < classCount && !done; i++) {
- fflush(stderr);
- jclass clazz = classes[i];
- char* srcName;
- jvmdiError sfnRes = jvmdi->GetSourceFileName(clazz, &srcName);
- if (sfnRes == JVMDI_ERROR_NONE) {
- JvmdiDeallocator de1(srcName);
- if (!strcmp(srcName, saCmdBkptSrcFileName)) {
- // Got a match. Now see whether the package name of the class also matches
- char* clazzName;
- jvmdiError sigRes = jvmdi->GetClassSignature(clazz, &clazzName);
- if (sigRes != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error %d while getting a class's signature", sigRes);
- return;
- }
- JvmdiDeallocator de2(clazzName);
- if (packageNameMatches(clazzName + 1, saCmdBkptPkgName)) {
- // Iterate through all methods
- jint methodCount;
- jmethodID* methods;
- if (jvmdi->GetClassMethods(clazz, &methodCount, &methods) != JVMDI_ERROR_NONE) {
- reportErrorToSA("Error while getting methods of class %s", clazzName);
- return;
- }
- JvmdiDeallocator de3(methods);
- for (int j = 0; j < methodCount && !done; j++) {
- jmethodID m = methods[j];
- jint entryCount;
- JVMDI_line_number_entry* table;
- jvmdiError lnRes = jvmdi->GetLineNumberTable(clazz, m, &entryCount, &table);
- if (lnRes == JVMDI_ERROR_NONE) {
- JvmdiDeallocator de4(table);
- // Look for line number greater than or equal to requested line
- for (int k = 0; k < entryCount && !done; k++) {
- JVMDI_line_number_entry& entry = table[k];
- if (entry.line_number >= saCmdBkptLineNumber &&
- (!gotOne || entry.line_number < targetLineNumber)) {
- gotOne = true;
- targetClass = clazz;
- targetMethod = m;
- targetLocation = entry.start_location;
- targetLineNumber = entry.line_number;
- done = (targetLineNumber == saCmdBkptLineNumber);
- }
- }
- } else if (lnRes != JVMDI_ERROR_ABSENT_INFORMATION) {
- reportErrorToSA("Unexpected error %d while fetching line number table", lnRes);
- return;
- }
- }
- }
- }
- } else if (sfnRes != JVMDI_ERROR_ABSENT_INFORMATION) {
- reportErrorToSA("Unexpected error %d while fetching source file name", sfnRes);
- return;
- }
- }
-
- bool wasSet = true;
- if (gotOne) {
- // Really toggle this breakpoint
- jvmdiError bpRes;
- bpRes = jvmdi->SetBreakpoint(targetClass, targetMethod, targetLocation);
- if (bpRes == JVMDI_ERROR_DUPLICATE) {
- bpRes = jvmdi->ClearBreakpoint(targetClass, targetMethod, targetLocation);
- wasSet = false;
- }
- if (bpRes != JVMDI_ERROR_NONE) {
- reportErrorToSA("Unexpected error %d while setting or clearing breakpoint at bci %d, line %d",
- bpRes, targetLocation, targetLineNumber);
- return;
- }
- } else {
- saCmdBkptResWasError = 0;
- reportErrorToSA("No debug information found covering this line");
- return;
- }
-
- // Provide result
- saCmdBkptResLineNumber = targetLineNumber;
- saCmdBkptResBCI = targetLocation;
- saCmdBkptResWasSet = (wasSet ? 1 : 0);
- {
- char* methodName;
- char* methodSig;
- if (jvmdi->GetMethodName(targetClass, targetMethod, &methodName, &methodSig)
- == JVMDI_ERROR_NONE) {
- JvmdiDeallocator mnd(methodName);
- JvmdiDeallocator msd(methodSig);
- strncpy(saCmdBkptResMethodName, methodName, SA_CMD_BUF_SIZE);
- strncpy(saCmdBkptResMethodSig, methodSig, SA_CMD_BUF_SIZE);
- } else {
- strncpy(saCmdBkptResMethodName, "", SA_CMD_BUF_SIZE);
- strncpy(saCmdBkptResMethodSig, "", SA_CMD_BUF_SIZE);
- }
- }
- break;
- }
-
- default:
- reportErrorToSA("Command %d not yet supported", saCmdType);
- return;
- }
-
- // Successful command execution
- saCmdResult = 0;
- saCmdPending = 0;
-}
-
-static void
-saCommandThread(void *arg) {
- JNIEnv* env = NULL;
- if (jvm->GetEnv((void **) &env, JNI_VERSION_1_2) != JNI_OK) {
- stop("Error while starting Serviceability Agent "
- "command thread: could not get JNI environment");
- }
-
- while (1) {
- // Wait for command
- while (!saCmdPending) {
- SLEEP();
- }
-
- executeOneCommand(env);
- }
-}
-
-static void
-saEventHook(JNIEnv *env, JVMDI_Event *event)
-{
- MonitorLocker ml(eventLock);
-
- saEventKind = event->kind;
-
- if (event->kind == JVMDI_EVENT_VM_INIT) {
- // Create event lock
- if (jvmdi->CreateRawMonitor("Serviceability Agent Event Lock", &eventLock)
- != JVMDI_ERROR_NONE) {
- stop("Unable to create Serviceability Agent's event lock");
- }
- // Start thread which receives commands from the SA.
- jclass threadClass = env->FindClass("java/lang/Thread");
- if (threadClass == NULL) stop("Unable to find class java/lang/Thread");
- jstring threadName = env->NewStringUTF("Serviceability Agent Command Thread");
- if (threadName == NULL) stop("Unable to allocate debug thread name");
- jmethodID ctor = env->GetMethodID(threadClass, "", "(Ljava/lang/String;)V");
- if (ctor == NULL) stop("Unable to find appropriate constructor for java/lang/Thread");
- // Allocate thread object
- jthread thr = (jthread) env->NewObject(threadClass, ctor, threadName);
- if (thr == NULL) stop("Unable to allocate debug thread's java/lang/Thread instance");
- // Remember which thread this is
- debugThreadObj = env->NewGlobalRef(thr);
- if (debugThreadObj == NULL) stop("Unable to allocate global ref for debug thread object");
- // Start thread
- jvmdiError err;
- if ((err = jvmdi->RunDebugThread(thr, &saCommandThread, NULL, JVMDI_THREAD_NORM_PRIORITY))
- != JVMDI_ERROR_NONE) {
- char buf[256];
- sprintf(buf, "Error %d while starting debug thread", err);
- stop(buf);
- }
- // OK, initialization is done
- return;
- }
-
- if (!saAttached) {
- return;
- }
-
- switch (event->kind) {
- case JVMDI_EVENT_EXCEPTION: {
- fprintf(stderr, "SA: Exception thrown -- ignoring\n");
- saExceptionThread = event->u.exception.thread;
- saExceptionClass = event->u.exception.clazz;
- saExceptionMethod = event->u.exception.method;
- saExceptionLocation = event->u.exception.location;
- saExceptionException = event->u.exception.exception;
- saExceptionCatchClass = event->u.exception.catch_clazz;
- saExceptionCatchClass = event->u.exception.catch_clazz;
- saExceptionCatchMethod = event->u.exception.catch_method;
- saExceptionCatchLocation = event->u.exception.catch_location;
- // saEventPending = 1;
- break;
- }
-
- case JVMDI_EVENT_BREAKPOINT: {
- saBreakpointThread = event->u.breakpoint.thread;
- saBreakpointClass = event->u.breakpoint.clazz;
- saBreakpointMethod = event->u.breakpoint.method;
- saBreakpointLocation = event->u.breakpoint.location;
- saEventPending = 1;
- break;
- }
-
- default:
- break;
- }
-
- while (saAttached && saEventPending) {
- SLEEP();
- }
-}
-
-extern "C" {
-JNIEXPORT jint JNICALL
-JVM_OnLoad(JavaVM *vm, char *options, void *reserved)
-{
- jvm = vm;
- if (jvm->GetEnv((void**) &jvmdi, JVMDI_VERSION_1) != JNI_OK) {
- return -1;
- }
- if (jvmdi->SetEventHook(&saEventHook) != JVMDI_ERROR_NONE) {
- return -1;
- }
- return 0;
-}
-};
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/native/jvmdi/sa.dsp
--- a/agent/src/share/native/jvmdi/sa.dsp Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-# Microsoft Developer Studio Project File - Name="sa" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-
-CFG=sa - Win32 Debug
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "sa.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "sa.mak" CFG="sa - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "sa - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "sa - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-MTL=midl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "sa - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "D:\jdk1.4\include" /I "D:\jdk1.4\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
-
-!ELSEIF "$(CFG)" == "sa - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "Debug"
-# PROP Intermediate_Dir "Debug"
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "D:\jdk1.4\include" /I "D:\jdk1.4\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /GZ /c
-# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-
-!ENDIF
-
-# Begin Target
-
-# Name "sa - Win32 Release"
-# Name "sa - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=.\sa.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# End Group
-# Begin Group "Resource Files"
-
-# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
-# End Group
-# End Target
-# End Project
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/native/jvmdi/sa.dsw
--- a/agent/src/share/native/jvmdi/sa.dsw Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-Microsoft Developer Studio Workspace File, Format Version 6.00
-# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
-
-###############################################################################
-
-Project: "sa"=.\sa.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-}}}
-
-###############################################################################
-
-Global:
-
-Package=<5>
-{{{
-}}}
-
-Package=<3>
-{{{
-}}}
-
-###############################################################################
-
diff -r d4a32a6f8c82 -r 11d5942ef9c7 agent/src/share/native/jvmdi/sa.hpp
--- a/agent/src/share/native/jvmdi/sa.hpp Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2002, 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.
- *
- */
-
-#include "jni.h"
-
-extern "C" {
-JNIEXPORT jint JNICALL
-JVM_OnLoad(JavaVM *vm, char *options, void *reserved);
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/Makefile
--- a/make/Makefile Mon Feb 25 07:22:06 2013 +0100
+++ b/make/Makefile Tue Mar 12 18:22:40 2013 -0700
@@ -464,9 +464,6 @@
$(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
$(install-file)
-$(EXPORT_JRE_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
- $(install-file)
-
# Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
$(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
$(install-file)
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/bsd/makefiles/defs.make
--- a/make/bsd/makefiles/defs.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/bsd/makefiles/defs.make Tue Mar 12 18:22:40 2013 -0700
@@ -157,8 +157,6 @@
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/bsd/makefiles/gcc.make
--- a/make/bsd/makefiles/gcc.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/bsd/makefiles/gcc.make Tue Mar 12 18:22:40 2013 -0700
@@ -229,6 +229,20 @@
CFLAGS += -DDONT_USE_PRECOMPILED_HEADER
endif
+ifeq ($(OS_VENDOR), Darwin)
+ # Setting these parameters makes it an error to link to macosx APIs that are
+ # newer than the given OS version and makes the linked binaries compatible even
+ # if built on a newer version of the OS.
+ # The expected format is X.Y.Z
+ ifeq ($(MACOSX_VERSION_MIN),)
+ MACOSX_VERSION_MIN=10.7.0
+ endif
+ # The macro takes the version with no dots, ex: 1070
+ CFLAGS += -DMAC_OS_X_VERSION_MAX_ALLOWED=$(subst .,,$(MACOSX_VERSION_MIN)) \
+ -mmacosx-version-min=$(MACOSX_VERSION_MIN)
+ LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
+endif
+
#------------------------------------------------------------------------
# Linker flags
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/bsd/makefiles/vm.make
--- a/make/bsd/makefiles/vm.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/bsd/makefiles/vm.make Tue Mar 12 18:22:40 2013 -0700
@@ -94,7 +94,12 @@
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
# a time and date.
-vm_version.o: CXXFLAGS += ${JRE_VERSION}
+CXXFLAGS/vm_version.o += ${JRE_VERSION}
+
+CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
+
+# File specific flags
+CXXFLAGS += $(CXXFLAGS/BYFILE)
ifdef DEFAULT_LIBPATH
CXXFLAGS += -DDEFAULT_LIBPATH="\"$(DEFAULT_LIBPATH)\""
@@ -332,9 +337,6 @@
# Serviceability agent
include $(MAKEFILES_DIR)/saproc.make
-# Whitebox testing API
-include $(MAKEFILES_DIR)/wb.make
-
#----------------------------------------------------------------------
ifeq ($(OS_VENDOR), Darwin)
@@ -342,10 +344,10 @@
dsymutil $(LIBJVM)
# no libjvm_db for macosx
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
echo "Doing vm.make build:"
else
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
endif
install: install_jvm install_jsig install_saproc
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/bsd/makefiles/wb.make
--- a/make/bsd/makefiles/wb.make Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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.
-#
-#
-
-# Rules to build whitebox testing library, used by vm.make
-WB = wb
-
-WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
-
-WB_JAR = $(GENERATED)/$(WB).jar
-
-WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
-WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
-
-WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
- $(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
-
-$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
- $(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
-
-$(WB_JAR): $(WB_JAVA_CLASSES)
- $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
-
-$(WB_JAVA_CLASSDIR):
- $(QUIETLY) mkdir -p $@
-
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/excludeSrc.make
--- a/make/excludeSrc.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/excludeSrc.make Tue Mar 12 18:22:40 2013 -0700
@@ -78,7 +78,7 @@
Src_Files_EXCLUDE += \
cmsAdaptiveSizePolicy.cpp cmsCollectorPolicy.cpp \
- cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp cmsPermGen.cpp compactibleFreeListSpace.cpp \
+ cmsGCAdaptivePolicyCounters.cpp cmsLockVerifier.cpp compactibleFreeListSpace.cpp \
concurrentMarkSweepGeneration.cpp concurrentMarkSweepThread.cpp \
freeChunk.cpp adaptiveFreeList.cpp promotionInfo.cpp vmCMSOperations.cpp collectionSetChooser.cpp \
concurrentG1Refine.cpp concurrentG1RefineThread.cpp concurrentMark.cpp concurrentMarkThread.cpp \
@@ -91,11 +91,11 @@
gcTaskManager.cpp gcTaskThread.cpp objectStartArray.cpp parallelScavengeHeap.cpp parMarkBitMap.cpp \
pcTasks.cpp psAdaptiveSizePolicy.cpp psCompactionManager.cpp psGCAdaptivePolicyCounters.cpp \
psGenerationCounters.cpp psMarkSweep.cpp psMarkSweepDecorator.cpp psOldGen.cpp psParallelCompact.cpp \
- psPermGen.cpp psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp psTasks.cpp psVirtualspace.cpp \
+ psPromotionLAB.cpp psPromotionManager.cpp psScavenge.cpp psTasks.cpp psVirtualspace.cpp \
psYoungGen.cpp vmPSOperations.cpp asParNewGeneration.cpp parCardTableModRefBS.cpp \
parGCAllocBuffer.cpp parNewGeneration.cpp mutableSpace.cpp gSpaceCounters.cpp allocationStats.cpp \
spaceCounters.cpp gcAdaptivePolicyCounters.cpp mutableNUMASpace.cpp immutableSpace.cpp \
- immutableSpace.cpp g1MemoryPool.cpp psMemoryPool.cpp yieldWorkingGroup.cpp g1Log.cpp
+ immutableSpace.cpp g1MemoryPool.cpp psMemoryPool.cpp yieldingWorkGroup.cpp g1Log.cpp
endif
ifeq ($(INCLUDE_NMT), false)
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/hotspot_version
--- a/make/hotspot_version Mon Feb 25 07:22:06 2013 +0100
+++ b/make/hotspot_version Tue Mar 12 18:22:40 2013 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=19
+HS_BUILD_NUMBER=22
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/linux/makefiles/defs.make
--- a/make/linux/makefiles/defs.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/linux/makefiles/defs.make Tue Mar 12 18:22:40 2013 -0700
@@ -258,8 +258,6 @@
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
EXPORT_MINIMAL_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/minimal
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/linux/makefiles/vm.make
--- a/make/linux/makefiles/vm.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/linux/makefiles/vm.make Tue Mar 12 18:22:40 2013 -0700
@@ -100,7 +100,13 @@
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
# a time and date.
-vm_version.o: CXXFLAGS += ${JRE_VERSION}
+CXXFLAGS/vm_version.o += ${JRE_VERSION}
+
+CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
+
+# File specific flags
+CXXFLAGS += $(CXXFLAGS/BYFILE)
+
ifndef JAVASE_EMBEDDED
ifneq (${ARCH},arm)
@@ -375,12 +381,9 @@
# Serviceability agent
include $(MAKEFILES_DIR)/saproc.make
-# Whitebox testing API
-include $(MAKEFILES_DIR)/wb.make
-
#----------------------------------------------------------------------
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceCheck
install: install_jvm install_jsig install_saproc
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/linux/makefiles/wb.make
--- a/make/linux/makefiles/wb.make Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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.
-#
-#
-
-# Rules to build whitebox testing library, used by vm.make
-WB = wb
-
-WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
-
-WB_JAR = $(GENERATED)/$(WB).jar
-
-WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
-WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
-
-WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
- $(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
-
-$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
- $(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
-
-$(WB_JAR): $(WB_JAVA_CLASSES)
- $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
-
-$(WB_JAVA_CLASSDIR):
- $(QUIETLY) mkdir -p $@
-
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/sa.files
--- a/make/sa.files Mon Feb 25 07:22:06 2013 +0100
+++ b/make/sa.files Tue Mar 12 18:22:40 2013 -0700
@@ -24,10 +24,7 @@
# This filelist macro is included in platform specific sa.make
# included all packages/*.java. package list can be generated by
-# $(GAMMADIR)/agent/make/build-pkglist. Then manually removed all
-# classes in sun.jvm.hotspot.ui (and subpackages), all ui classes
-# in sun.jvm.hotspot.bugspot/hotspot and SPARC and x86 disassembler
-# classes and sun.jvm.hotspot.utilities.soql.
+# $(GAMMADIR)/agent/make/build-pkglist.
# define AGENT_DIR before including this file in sa.make
@@ -40,8 +37,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/tree/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/ci/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \
@@ -82,7 +77,6 @@
$(AGENT_SRC_DIR)/sun/jvm/hotspot/gc_interface/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/interpreter/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/jdi/*.java \
-$(AGENT_SRC_DIR)/sun/jvm/hotspot/livejvm/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/memory/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java \
$(AGENT_SRC_DIR)/sun/jvm/hotspot/opto/*.java \
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/solaris/makefiles/defs.make
--- a/make/solaris/makefiles/defs.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/solaris/makefiles/defs.make Tue Mar 12 18:22:40 2013 -0700
@@ -187,8 +187,6 @@
endif
endif
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/solaris/makefiles/vm.make
--- a/make/solaris/makefiles/vm.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/solaris/makefiles/vm.make Tue Mar 12 18:22:40 2013 -0700
@@ -88,7 +88,13 @@
# This is VERY important! The version define must only be supplied to vm_version.o
# If not, ccache will not re-use the cache at all, since the version string might contain
# a time and date.
-vm_version.o: CXXFLAGS += ${JRE_VERSION}
+CXXFLAGS/vm_version.o += ${JRE_VERSION}
+
+CXXFLAGS/BYFILE = $(CXXFLAGS/$@)
+
+# File specific flags
+CXXFLAGS += $(CXXFLAGS/BYFILE)
+
# CFLAGS_WARN holds compiler options to suppress/enable warnings.
CFLAGS += $(CFLAGS_WARN)
@@ -341,12 +347,9 @@
# Serviceability agent
include $(MAKEFILES_DIR)/saproc.make
-# Whitebox testing API
-include $(MAKEFILES_DIR)/wb.make
-
#----------------------------------------------------------------------
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck
install: install_jvm install_jsig install_saproc
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/solaris/makefiles/wb.make
--- a/make/solaris/makefiles/wb.make Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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.
-#
-
-# Rules to build whitebox testing library, used by vm.make
-
-WB = wb
-
-WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
-
-WB_JAR = $(GENERATED)/$(WB).jar
-
-WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
-WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
-
-WB_JAVA_CLASSES = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
- $(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
-
-$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
- $(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
-
-$(WB_JAR): $(WB_JAVA_CLASSES)
- $(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
-
-$(WB_JAVA_CLASSDIR):
- $(QUIETLY) mkdir -p $@
-
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/windows/makefiles/debug.make
--- a/make/windows/makefiles/debug.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/windows/makefiles/debug.make Tue Mar 12 18:22:40 2013 -0700
@@ -33,7 +33,7 @@
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
@@ -72,4 +72,3 @@
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
!include $(WorkSpace)/make/windows/makefiles/launcher.make
-!include $(WorkSpace)/make/windows/makefiles/wb.make
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/windows/makefiles/defs.make
--- a/make/windows/makefiles/defs.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/windows/makefiles/defs.make Tue Mar 12 18:22:40 2013 -0700
@@ -277,8 +277,6 @@
endif
endif
-EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
-
ifeq ($(BUILD_WIN_SA), 1)
EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/windows/makefiles/fastdebug.make
--- a/make/windows/makefiles/fastdebug.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/windows/makefiles/fastdebug.make Tue Mar 12 18:22:40 2013 -0700
@@ -33,7 +33,7 @@
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
@@ -71,4 +71,3 @@
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
!include $(WorkSpace)/make/windows/makefiles/launcher.make
-!include $(WorkSpace)/make/windows/makefiles/wb.make
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/windows/makefiles/product.make
--- a/make/windows/makefiles/product.make Mon Feb 25 07:22:06 2013 +0100
+++ b/make/windows/makefiles/product.make Tue Mar 12 18:22:40 2013 -0700
@@ -32,7 +32,7 @@
BUILD_PCH_FILE=_build_pch_file.obj
!endif
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
!include ../local.make
!include compile.make
@@ -82,4 +82,3 @@
!include $(WorkSpace)/make/windows/makefiles/shared.make
!include $(WorkSpace)/make/windows/makefiles/sa.make
!include $(WorkSpace)/make/windows/makefiles/launcher.make
-!include $(WorkSpace)/make/windows/makefiles/wb.make
diff -r d4a32a6f8c82 -r 11d5942ef9c7 make/windows/makefiles/wb.make
--- a/make/windows/makefiles/wb.make Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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.
-#
-#
-
-# This makefile is used to build the whitebox testing lib
-# and compile the tests which use it
-
-!include $(WorkSpace)/make/windows/makefiles/rules.make
-
-WBSRCDIR = $(WorkSpace)/src/share/tools/whitebox
-
-# turn GENERATED into a windows path to get sane dependencies
-WB_CLASSES=$(GENERATED:/=\)\wb\classes
-WB_JAR=$(GENERATED:/=\)\wb.jar
-
-# call recursive make to do wildcard expansion
-.SUFFIXES : .java .class
-wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLASSES)
- $(MAKE) -f $(WorkSpace)\make\windows\makefiles\$(BUILD_FLAVOR).make $(**:.java=.class)
-
-
-{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class::
- $(COMPILE_JAVAC) -sourcepath $(WBSRCDIR) -d $(WB_CLASSES) $<
-
-$(WB_JAR): wb_java_srcs
- $(RUN_JAR) cf $@ -C $(WB_CLASSES) .
-
-# turn $@ to a unix path because mkdir in PATH is cygwin/mks mkdir
-$(WB_CLASSES):
- mkdir -p $(@:\=/)
-
-# main target to build wb
-wb: $(WB_JAR)
-
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/cpu/sparc/vm/frame_sparc.cpp
--- a/src/cpu/sparc/vm/frame_sparc.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/cpu/sparc/vm/frame_sparc.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -216,6 +216,11 @@
}
}
+ // Could just be some random pointer within the codeBlob
+ if (!_cb->code_contains(_pc)) {
+ return false;
+ }
+
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/cpu/sparc/vm/templateTable_sparc.cpp
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -340,8 +340,6 @@
__ bind(notInt);
// __ cmp(O2, JVM_CONSTANT_String);
- __ brx(Assembler::equal, true, Assembler::pt, isString);
- __ delayed()->cmp(O2, JVM_CONSTANT_Object);
__ brx(Assembler::notEqual, true, Assembler::pt, notString);
__ delayed()->ldf(FloatRegisterImpl::S, O0, O1, Ftos_f);
__ bind(isString);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/cpu/x86/vm/frame_x86.cpp
--- a/src/cpu/x86/vm/frame_x86.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/cpu/x86/vm/frame_x86.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -91,6 +91,12 @@
return false;
}
}
+
+ // Could just be some random pointer within the codeBlob
+ if (!_cb->code_contains(_pc)) {
+ return false;
+ }
+
// Entry frame checks
if (is_entry_frame()) {
// an entry frame must have a valid fp.
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/bsd/vm/os_bsd.cpp
--- a/src/os/bsd/vm/os_bsd.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/bsd/vm/os_bsd.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -2695,7 +2695,7 @@
assert(thread->is_VM_thread(), "Must be VMThread");
// read current suspend action
int action = osthread->sr.suspend_action();
- if (action == SR_SUSPEND) {
+ if (action == os::Bsd::SuspendResume::SR_SUSPEND) {
suspend_save_context(osthread, siginfo, context);
// Notify the suspend action is about to be completed. do_suspend()
@@ -2717,12 +2717,12 @@
do {
sigsuspend(&suspend_set);
// ignore all returns until we get a resume signal
- } while (osthread->sr.suspend_action() != SR_CONTINUE);
+ } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE);
resume_clear_context(osthread);
} else {
- assert(action == SR_CONTINUE, "unexpected sr action");
+ assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action");
// nothing special to do - just leave the handler
}
@@ -2776,7 +2776,7 @@
// but this seems the normal response to library errors
static bool do_suspend(OSThread* osthread) {
// mark as suspended and send signal
- osthread->sr.set_suspend_action(SR_SUSPEND);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -2785,18 +2785,18 @@
for (int i = 0; !osthread->sr.is_suspended(); i++) {
os::yield_all(i);
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
return true;
}
else {
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
return false;
}
}
static void do_resume(OSThread* osthread) {
assert(osthread->sr.is_suspended(), "thread should be suspended");
- osthread->sr.set_suspend_action(SR_CONTINUE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -2806,7 +2806,7 @@
os::yield_all(i);
}
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE);
}
////////////////////////////////////////////////////////////////////////////////
@@ -2887,7 +2887,9 @@
void signalHandler(int sig, siginfo_t* info, void* uc) {
assert(info != NULL && uc != NULL, "it must be old kernel");
+ int orig_errno = errno; // Preserve errno value over signal handler.
JVM_handle_bsd_signal(sig, info, uc, true);
+ errno = orig_errno;
}
@@ -3901,15 +3903,27 @@
jlong os::current_thread_cpu_time() {
#ifdef __APPLE__
return os::thread_cpu_time(Thread::current(), true /* user + sys */);
+#else
+ Unimplemented();
+ return 0;
#endif
}
jlong os::thread_cpu_time(Thread* thread) {
+#ifdef __APPLE__
+ return os::thread_cpu_time(thread, true /* user + sys */);
+#else
+ Unimplemented();
+ return 0;
+#endif
}
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
#ifdef __APPLE__
return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
+#else
+ Unimplemented();
+ return 0;
#endif
}
@@ -3933,6 +3947,9 @@
} else {
return ((jlong)tinfo.user_time.seconds * 1000000000) + ((jlong)tinfo.user_time.microseconds * (jlong)1000);
}
+#else
+ Unimplemented();
+ return 0;
#endif
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/bsd/vm/os_bsd.hpp
--- a/src/os/bsd/vm/os_bsd.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/bsd/vm/os_bsd.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -151,36 +151,25 @@
// for BsdThreads are no longer needed.
class SuspendResume {
private:
- volatile int _suspend_action;
+ volatile int _suspend_action;
+ volatile jint _state;
+ public:
// values for suspend_action:
- #define SR_NONE (0x00)
- #define SR_SUSPEND (0x01) // suspend request
- #define SR_CONTINUE (0x02) // resume request
+ enum {
+ SR_NONE = 0x00,
+ SR_SUSPEND = 0x01, // suspend request
+ SR_CONTINUE = 0x02, // resume request
+ SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
+ };
- volatile jint _state;
- // values for _state: + SR_NONE
- #define SR_SUSPENDED (0x20)
- public:
SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
int suspend_action() const { return _suspend_action; }
void set_suspend_action(int x) { _suspend_action = x; }
// atomic updates for _state
- void set_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
- void clear_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
+ inline void set_suspended();
+ inline void clear_suspended();
bool is_suspended() { return _state & SR_SUSPENDED; }
#undef SR_SUSPENDED
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/bsd/vm/os_bsd.inline.hpp
--- a/src/os/bsd/vm/os_bsd.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/bsd/vm/os_bsd.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_BSD_VM_OS_BSD_INLINE_HPP
#define OS_BSD_VM_OS_BSD_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
@@ -286,4 +285,21 @@
const char* optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+
+inline void os::Bsd::SuspendResume::set_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
+inline void os::Bsd::SuspendResume::clear_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
#endif // OS_BSD_VM_OS_BSD_INLINE_HPP
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/linux/vm/os_linux.cpp
--- a/src/os/linux/vm/os_linux.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/linux/vm/os_linux.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -3461,7 +3461,7 @@
assert(thread->is_VM_thread(), "Must be VMThread");
// read current suspend action
int action = osthread->sr.suspend_action();
- if (action == SR_SUSPEND) {
+ if (action == os::Linux::SuspendResume::SR_SUSPEND) {
suspend_save_context(osthread, siginfo, context);
// Notify the suspend action is about to be completed. do_suspend()
@@ -3483,12 +3483,12 @@
do {
sigsuspend(&suspend_set);
// ignore all returns until we get a resume signal
- } while (osthread->sr.suspend_action() != SR_CONTINUE);
+ } while (osthread->sr.suspend_action() != os::Linux::SuspendResume::SR_CONTINUE);
resume_clear_context(osthread);
} else {
- assert(action == SR_CONTINUE, "unexpected sr action");
+ assert(action == os::Linux::SuspendResume::SR_CONTINUE, "unexpected sr action");
// nothing special to do - just leave the handler
}
@@ -3542,7 +3542,7 @@
// but this seems the normal response to library errors
static bool do_suspend(OSThread* osthread) {
// mark as suspended and send signal
- osthread->sr.set_suspend_action(SR_SUSPEND);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_SUSPEND);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -3551,18 +3551,18 @@
for (int i = 0; !osthread->sr.is_suspended(); i++) {
os::yield_all(i);
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
return true;
}
else {
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
return false;
}
}
static void do_resume(OSThread* osthread) {
assert(osthread->sr.is_suspended(), "thread should be suspended");
- osthread->sr.set_suspend_action(SR_CONTINUE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_CONTINUE);
int status = pthread_kill(osthread->pthread_id(), SR_signum);
assert_status(status == 0, status, "pthread_kill");
@@ -3572,7 +3572,7 @@
os::yield_all(i);
}
}
- osthread->sr.set_suspend_action(SR_NONE);
+ osthread->sr.set_suspend_action(os::Linux::SuspendResume::SR_NONE);
}
////////////////////////////////////////////////////////////////////////////////
@@ -3653,7 +3653,9 @@
void signalHandler(int sig, siginfo_t* info, void* uc) {
assert(info != NULL && uc != NULL, "it must be old kernel");
+ int orig_errno = errno; // Preserve errno value over signal handler.
JVM_handle_linux_signal(sig, info, uc, true);
+ errno = orig_errno;
}
@@ -4741,49 +4743,26 @@
//
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
- static bool proc_pid_cpu_avail = true;
static bool proc_task_unchecked = true;
static const char *proc_stat_path = "/proc/%d/stat";
pid_t tid = thread->osthread()->thread_id();
- int i;
char *s;
char stat[2048];
int statlen;
char proc_name[64];
int count;
long sys_time, user_time;
- char string[64];
char cdummy;
int idummy;
long ldummy;
FILE *fp;
- // We first try accessing /proc//cpu since this is faster to
- // process. If this file is not present (linux kernels 2.5 and above)
- // then we open /proc//stat.
- if ( proc_pid_cpu_avail ) {
- sprintf(proc_name, "/proc/%d/cpu", tid);
- fp = fopen(proc_name, "r");
- if ( fp != NULL ) {
- count = fscanf( fp, "%s %lu %lu\n", string, &user_time, &sys_time);
- fclose(fp);
- if ( count != 3 ) return -1;
-
- if (user_sys_cpu_time) {
- return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
- } else {
- return (jlong)user_time * (1000000000 / clock_tics_per_sec);
- }
- }
- else proc_pid_cpu_avail = false;
- }
-
// The /proc//stat aggregates per-process usage on
// new Linux kernels 2.6+ where NPTL is supported.
// The /proc/self/task//stat still has the per-thread usage.
// See bug 6328462.
- // There can be no directory /proc/self/task on kernels 2.4 with NPTL
- // and possibly in some other cases, so we check its availability.
+ // There possibly can be cases where there is no directory
+ // /proc/self/task, so we check its availability.
if (proc_task_unchecked && os::Linux::is_NPTL()) {
// This is executed only once
proc_task_unchecked = false;
@@ -4808,7 +4787,6 @@
// We don't really need to know the command string, just find the last
// occurrence of ")" and then start parsing from there. See bug 4726580.
s = strrchr(stat, ')');
- i = 0;
if (s == NULL ) return -1;
// Skip blank chars
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/linux/vm/os_linux.hpp
--- a/src/os/linux/vm/os_linux.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/linux/vm/os_linux.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -209,39 +209,27 @@
// for LinuxThreads are no longer needed.
class SuspendResume {
private:
- volatile int _suspend_action;
+ volatile int _suspend_action;
+ volatile jint _state;
+ public:
// values for suspend_action:
- #define SR_NONE (0x00)
- #define SR_SUSPEND (0x01) // suspend request
- #define SR_CONTINUE (0x02) // resume request
+ enum {
+ SR_NONE = 0x00,
+ SR_SUSPEND = 0x01, // suspend request
+ SR_CONTINUE = 0x02, // resume request
+ SR_SUSPENDED = 0x20 // values for _state: + SR_NONE
+ };
- volatile jint _state;
- // values for _state: + SR_NONE
- #define SR_SUSPENDED (0x20)
- public:
SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; }
int suspend_action() const { return _suspend_action; }
void set_suspend_action(int x) { _suspend_action = x; }
// atomic updates for _state
- void set_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
- void clear_suspended() {
- jint temp, temp2;
- do {
- temp = _state;
- temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
- } while (temp2 != temp);
- }
+ inline void set_suspended();
+ inline void clear_suspended();
bool is_suspended() { return _state & SR_SUSPENDED; }
- #undef SR_SUSPENDED
};
private:
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/linux/vm/os_linux.inline.hpp
--- a/src/os/linux/vm/os_linux.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/linux/vm/os_linux.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_LINUX_VM_OS_LINUX_INLINE_HPP
#define OS_LINUX_VM_OS_LINUX_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
@@ -288,4 +287,21 @@
const char* optval, socklen_t optlen) {
return ::setsockopt(fd, level, optname, optval, optlen);
}
+
+inline void os::Linux::SuspendResume::set_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp | SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
+inline void os::Linux::SuspendResume::clear_suspended() {
+ jint temp, temp2;
+ do {
+ temp = _state;
+ temp2 = Atomic::cmpxchg(temp & ~SR_SUSPENDED, &_state, temp);
+ } while (temp2 != temp);
+}
+
#endif // OS_LINUX_VM_OS_LINUX_INLINE_HPP
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/solaris/vm/os_solaris.cpp
--- a/src/os/solaris/vm/os_solaris.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/solaris/vm/os_solaris.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1865,7 +1865,7 @@
// Die immediately, no exit hook, no abort hook, no cleanup.
void os::die() {
- _exit(-1);
+ ::abort(); // dump core (for debugging)
}
// unused
@@ -4317,7 +4317,9 @@
void signalHandler(int sig, siginfo_t* info, void* ucVoid) {
+ int orig_errno = errno; // Preserve errno value over signal handler.
JVM_handle_solaris_signal(sig, info, ucVoid, true);
+ errno = orig_errno;
}
/* Do not delete - if guarantee is ever removed, a signal handler (even empty)
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/solaris/vm/os_solaris.inline.hpp
--- a/src/os/solaris/vm/os_solaris.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/solaris/vm/os_solaris.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
#define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/windows/vm/decoder_windows.cpp
--- a/src/os/windows/vm/decoder_windows.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/windows/vm/decoder_windows.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "prims/jvm.h"
+#include "runtime/arguments.hpp"
#include "decoder_windows.hpp"
WindowsDecoder::WindowsDecoder() {
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/windows/vm/os_windows.cpp
--- a/src/os/windows/vm/os_windows.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/windows/vm/os_windows.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1940,7 +1940,7 @@
// a counter for each possible signal value, including signal_thread exit signal
static volatile jint pending_signals[NSIG+1] = { 0 };
-static HANDLE sig_sem;
+static HANDLE sig_sem = NULL;
void os::signal_init_pd() {
// Initialize signal structures
@@ -1970,10 +1970,11 @@
void os::signal_notify(int signal_number) {
BOOL ret;
-
- Atomic::inc(&pending_signals[signal_number]);
- ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
- assert(ret != 0, "ReleaseSemaphore() failed");
+ if (sig_sem != NULL) {
+ Atomic::inc(&pending_signals[signal_number]);
+ ret = ::ReleaseSemaphore(sig_sem, 1, NULL);
+ assert(ret != 0, "ReleaseSemaphore() failed");
+ }
}
static int check_pending_signals(bool wait_for_signal) {
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os/windows/vm/os_windows.inline.hpp
--- a/src/os/windows/vm/os_windows.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os/windows/vm/os_windows.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -25,7 +25,6 @@
#ifndef OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
#define OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
-#include "runtime/atomic.hpp"
#include "runtime/atomic.inline.hpp"
#include "runtime/os.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp
--- a/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,7 +25,6 @@
#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_INLINE_HPP
-#include "orderAccess_bsd_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp
--- a/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/bsd_x86/vm/orderAccess_bsd_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,8 +25,9 @@
#ifndef OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
#define OS_CPU_BSD_X86_VM_ORDERACCESS_BSD_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
// Implementation of class OrderAccess.
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp
--- a/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,7 +26,6 @@
#ifndef OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
#define OS_CPU_BSD_ZERO_VM_ATOMIC_BSD_ZERO_INLINE_HPP
-#include "orderAccess_bsd_zero.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_zero.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp
--- a/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,7 +25,6 @@
#ifndef OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP
#define OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP
-#include "orderAccess_linux_sparc.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_sparc.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp
--- a/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,7 +25,6 @@
#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_INLINE_HPP
-#include "orderAccess_linux_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp
--- a/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,8 +25,9 @@
#ifndef OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
#define OS_CPU_LINUX_X86_VM_ORDERACCESS_LINUX_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
// Implementation of class OrderAccess.
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp
--- a/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/linux_zero/vm/atomic_linux_zero.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -26,7 +26,6 @@
#ifndef OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
#define OS_CPU_LINUX_ZERO_VM_ATOMIC_LINUX_ZERO_INLINE_HPP
-#include "orderAccess_linux_zero.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_zero.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp
--- a/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,7 +25,6 @@
#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP
#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP
-#include "orderAccess_solaris_sparc.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_sparc.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp
--- a/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,6 +25,7 @@
#ifndef OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP
#define OS_CPU_SOLARIS_SPARC_VM_ORDERACCESS_SOLARIS_SPARC_INLINE_HPP
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
#include "vm_version_sparc.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp
--- a/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,7 +25,6 @@
#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP
#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_INLINE_HPP
-#include "orderAccess_solaris_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp
--- a/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/solaris_x86/vm/orderAccess_solaris_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,7 +25,7 @@
#ifndef OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP
#define OS_CPU_SOLARIS_X86_VM_ORDERACCESS_SOLARIS_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp
--- a/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -25,7 +25,6 @@
#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP
#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_INLINE_HPP
-#include "orderAccess_windows_x86.inline.hpp"
#include "runtime/atomic.hpp"
#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp
--- a/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/os_cpu/windows_x86/vm/orderAccess_windows_x86.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,12 +25,11 @@
#ifndef OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP
#define OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP
-#include "runtime/atomic.hpp"
+#include "runtime/atomic.inline.hpp"
#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
#include "vm_version_x86.hpp"
-#pragma warning(disable: 4035) // Disables warnings reporting missing return statement
-
// Implementation of class OrderAccess.
inline void OrderAccess::loadload() { acquire(); }
@@ -214,6 +213,4 @@
#endif // AMD64
}
-#pragma warning(default: 4035) // Enables warnings reporting missing return statement
-
#endif // OS_CPU_WINDOWS_X86_VM_ORDERACCESS_WINDOWS_X86_INLINE_HPP
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/tools/whitebox/sun/hotspot/WhiteBox.java
--- a/src/share/tools/whitebox/sun/hotspot/WhiteBox.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +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.
- *
- */
-
-package sun.hotspot;
-
-import java.lang.reflect.Method;
-import java.security.BasicPermission;
-import sun.hotspot.parser.DiagnosticCommand;
-
-public class WhiteBox {
-
- @SuppressWarnings("serial")
- public static class WhiteBoxPermission extends BasicPermission {
- public WhiteBoxPermission(String s) {
- super(s);
- }
- }
-
- private WhiteBox() {}
- private static final WhiteBox instance = new WhiteBox();
- private static native void registerNatives();
-
- /**
- * Returns the singleton WhiteBox instance.
- *
- * The returned WhiteBox object should be carefully guarded
- * by the caller, since it can be used to read and write data
- * at arbitrary memory addresses. It must never be passed to
- * untrusted code.
- */
- public synchronized static WhiteBox getWhiteBox() {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new WhiteBoxPermission("getInstance"));
- }
- return instance;
- }
-
- static {
- registerNatives();
- }
-
- // Memory
- public native long getObjectAddress(Object o);
- public native int getHeapOopSize();
-
- // Runtime
- // Make sure class name is in the correct format
- public boolean isClassAlive(String name) {
- return isClassAlive0(name.replace('.', '/'));
- }
- private native boolean isClassAlive0(String name);
-
- // G1
- public native boolean g1InConcurrentMark();
- public native boolean g1IsHumongous(Object o);
- public native long g1NumFreeRegions();
- public native int g1RegionSize();
- public native Object[] parseCommandLine(String commandline, DiagnosticCommand[] args);
-
- // NMT
- public native boolean NMTAllocTest();
- public native boolean NMTFreeTestMemory();
- public native boolean NMTWaitForDataMerge();
-
- // Compiler
- public native void deoptimizeAll();
- public native boolean isMethodCompiled(Method method);
- public native boolean isMethodCompilable(Method method);
- public native boolean isMethodQueuedForCompilation(Method method);
- public native int deoptimizeMethod(Method method);
- public native void makeMethodNotCompilable(Method method);
- public native int getMethodCompilationLevel(Method method);
- public native boolean setDontInlineMethod(Method method, boolean value);
- public native int getCompileQueuesSize();
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
--- a/src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java Mon Feb 25 07:22:06 2013 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-package sun.hotspot.parser;
-
-public class DiagnosticCommand {
-
- public enum DiagnosticArgumentType {
- JLONG, BOOLEAN, STRING, NANOTIME, STRINGARRAY, MEMORYSIZE
- }
-
- private String name;
- private String desc;
- private DiagnosticArgumentType type;
- private boolean mandatory;
- private String defaultValue;
-
- public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
- boolean mandatory, String defaultValue) {
- this.name = name;
- this.desc = desc;
- this.type = type;
- this.mandatory = mandatory;
- this.defaultValue = defaultValue;
- }
-
- public String getName() {
- return name;
- }
-
- public String getDesc() {
- return desc;
- }
-
- public DiagnosticArgumentType getType() {
- return type;
- }
-
- public boolean isMandatory() {
- return mandatory;
- }
-
- public String getDefaultValue() {
- return defaultValue;
- }
-}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/adlc/formssel.cpp
--- a/src/share/vm/adlc/formssel.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/adlc/formssel.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -753,10 +753,11 @@
!strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
!strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
!strcmp(_matrule->_rChild->_opType,"LoadN") ||
- !strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
!strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
!strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
- !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
+ !strcmp(_matrule->_rChild->_opType,"CheckCastPP") ||
+ !strcmp(_matrule->_rChild->_opType,"GetAndSetP") ||
+ !strcmp(_matrule->_rChild->_opType,"GetAndSetN")) ) return true;
else if ( is_ideal_load() == Form::idealP ) return true;
else if ( is_ideal_store() != Form::none ) return true;
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/c1/c1_FrameMap.cpp
--- a/src/share/vm/c1/c1_FrameMap.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/c1/c1_FrameMap.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -308,27 +308,6 @@
return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::obj_offset_in_bytes());
}
-void FrameMap::print_frame_layout() const {
- int svar;
- tty->print_cr("#####################################");
- tty->print_cr("Frame size in words %d", framesize());
-
- if( _num_monitors > 0) {
- tty->print_cr("monitor [0]:%d | [%2d]:%d",
- in_bytes(sp_offset_for_monitor_base(0)),
- in_bytes(sp_offset_for_monitor_base(_num_monitors)));
- }
- if( _num_spills > 0) {
- svar = _num_spills - 1;
- if(svar == 0)
- tty->print_cr("spill [0]:%d", in_bytes(sp_offset_for_spill(0)));
- else
- tty->print_cr("spill [0]:%d | [%2d]:%d", in_bytes(sp_offset_for_spill(0)),
- svar,
- in_bytes(sp_offset_for_spill(svar)));
- }
-}
-
// For OopMaps, map a local variable or spill index to an VMReg.
// This is the offset from sp() in the frame of the slot for the index,
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/c1/c1_FrameMap.hpp
--- a/src/share/vm/c1/c1_FrameMap.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/c1/c1_FrameMap.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -226,8 +226,6 @@
return make_new_address(sp_offset_for_monitor_object(monitor_index));
}
- void print_frame_layout() const;
-
// Creates Location describing desired slot and returns it via pointer
// to Location object. Returns true if the stack frame offset was legal
// (as defined by Location::legal_offset_in_bytes()), false otherwise.
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/c1/c1_LIR.cpp
--- a/src/share/vm/c1/c1_LIR.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/c1/c1_LIR.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -814,7 +814,7 @@
// only visit register parameters
int n = opJavaCall->_arguments->length();
- for (int i = 0; i < n; i++) {
+ for (int i = opJavaCall->_receiver->is_valid() ? 1 : 0; i < n; i++) {
if (!opJavaCall->_arguments->at(i)->is_pointer()) {
do_input(*opJavaCall->_arguments->adr_at(i));
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/ci/ciEnv.cpp
--- a/src/share/vm/ci/ciEnv.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/ci/ciEnv.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -597,10 +597,6 @@
assert (klass->is_instance_klass() || klass->is_array_klass(),
"must be an instance or array klass ");
return ciConstant(T_OBJECT, klass->java_mirror());
- } else if (tag.is_object()) {
- oop obj = cpool->object_at(index);
- ciObject* ciobj = get_object(obj);
- return ciConstant(T_OBJECT, ciobj);
} else if (tag.is_method_type()) {
// must execute Java code to link this CP entry into cache[i].f1
ciSymbol* signature = get_symbol(cpool->method_type_signature_at(index));
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/classfile/classLoaderData.hpp
--- a/src/share/vm/classfile/classLoaderData.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/classfile/classLoaderData.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -234,6 +234,7 @@
void add_to_deallocate_list(Metadata* m);
static ClassLoaderData* class_loader_data(oop loader);
+ static ClassLoaderData* class_loader_data_or_null(oop loader);
static ClassLoaderData* anonymous_class_loader_data(oop loader, TRAPS);
static void print_loader(ClassLoaderData *loader_data, outputStream *out);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/classfile/classLoaderData.inline.hpp
--- a/src/share/vm/classfile/classLoaderData.inline.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/classfile/classLoaderData.inline.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -25,9 +25,15 @@
#include "classfile/classLoaderData.hpp"
#include "classfile/javaClasses.hpp"
+inline ClassLoaderData* ClassLoaderData::class_loader_data_or_null(oop loader) {
+ if (loader == NULL) {
+ return ClassLoaderData::the_null_class_loader_data();
+ }
+ return java_lang_ClassLoader::loader_data(loader);
+}
+
inline ClassLoaderData* ClassLoaderData::class_loader_data(oop loader) {
- if (loader == NULL) return ClassLoaderData::the_null_class_loader_data();
- ClassLoaderData* loader_data = java_lang_ClassLoader::loader_data(loader);
+ ClassLoaderData* loader_data = class_loader_data_or_null(loader);
assert(loader_data != NULL, "Must be");
return loader_data;
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/classfile/dictionary.cpp
--- a/src/share/vm/classfile/dictionary.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/classfile/dictionary.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -347,6 +347,7 @@
assert_locked_or_safepoint(SystemDictionary_lock);
assert(obj() != NULL, "adding NULL obj");
assert(obj()->name() == class_name, "sanity check on name");
+ assert(loader_data != NULL, "Must be non-NULL");
unsigned int hash = compute_hash(class_name, loader_data);
int index = hash_to_index(hash);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/classfile/systemDictionary.cpp
--- a/src/share/vm/classfile/systemDictionary.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/classfile/systemDictionary.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -866,16 +866,22 @@
// the new entry.
Klass* SystemDictionary::find(Symbol* class_name,
- Handle class_loader,
- Handle protection_domain,
- TRAPS) {
+ Handle class_loader,
+ Handle protection_domain,
+ TRAPS) {
// UseNewReflection
// The result of this call should be consistent with the result
// of the call to resolve_instance_class_or_null().
// See evaluation 6790209 and 4474172 for more details.
class_loader = Handle(THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
- ClassLoaderData* loader_data = register_loader(class_loader, CHECK_NULL);
+ ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(class_loader());
+
+ if (loader_data == NULL) {
+ // If the ClassLoaderData has not been setup,
+ // then the class loader has no entries in the dictionary.
+ return NULL;
+ }
unsigned int d_hash = dictionary()->compute_hash(class_name, loader_data);
int d_index = dictionary()->hash_to_index(d_hash);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/classfile/verifier.cpp
--- a/src/share/vm/classfile/verifier.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/classfile/verifier.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -61,7 +61,8 @@
# include "bytes_ppc.hpp"
#endif
-#define NOFAILOVER_MAJOR_VERSION 51
+#define NOFAILOVER_MAJOR_VERSION 51
+#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION 52
// Access to external entry for VerifyClassCodes - old byte code verifier
@@ -2317,6 +2318,11 @@
types = (1 << JVM_CONSTANT_InterfaceMethodref) |
(1 << JVM_CONSTANT_Methodref);
break;
+ case Bytecodes::_invokestatic:
+ types = (_klass->major_version() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
+ (1 << JVM_CONSTANT_Methodref) :
+ ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));
+ break;
default:
types = 1 << JVM_CONSTANT_Methodref;
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -300,8 +300,7 @@
}
}
-// Wait until the next synchronous GC, a concurrent full gc request,
-// or a timeout, whichever is earlier.
+// Wait until any cms_lock event
void ConcurrentMarkSweepThread::wait_on_cms_lock(long t_millis) {
MutexLockerEx x(CGC_lock,
Mutex::_no_safepoint_check_flag);
@@ -315,15 +314,100 @@
"Should not be set");
}
+// Wait until the next synchronous GC, a concurrent full gc request,
+// or a timeout, whichever is earlier.
+void ConcurrentMarkSweepThread::wait_on_cms_lock_for_scavenge(long t_millis) {
+ // Wait time in millis or 0 value representing infinite wait for a scavenge
+ assert(t_millis >= 0, "Wait time for scavenge should be 0 or positive");
+
+ GenCollectedHeap* gch = GenCollectedHeap::heap();
+ double start_time_secs = os::elapsedTime();
+ double end_time_secs = start_time_secs + (t_millis / ((double) MILLIUNITS));
+
+ // Total collections count before waiting loop
+ unsigned int before_count;
+ {
+ MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
+ before_count = gch->total_collections();
+ }
+
+ unsigned int loop_count = 0;
+
+ while(!_should_terminate) {
+ double now_time = os::elapsedTime();
+ long wait_time_millis;
+
+ if(t_millis != 0) {
+ // New wait limit
+ wait_time_millis = (long) ((end_time_secs - now_time) * MILLIUNITS);
+ if(wait_time_millis <= 0) {
+ // Wait time is over
+ break;
+ }
+ } else {
+ // No wait limit, wait if necessary forever
+ wait_time_millis = 0;
+ }
+
+ // Wait until the next event or the remaining timeout
+ {
+ MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag);
+
+ if (_should_terminate || _collector->_full_gc_requested) {
+ return;
+ }
+ set_CMS_flag(CMS_cms_wants_token); // to provoke notifies
+ assert(t_millis == 0 || wait_time_millis > 0, "Sanity");
+ CGC_lock->wait(Mutex::_no_safepoint_check_flag, wait_time_millis);
+ clear_CMS_flag(CMS_cms_wants_token);
+ assert(!CMS_flag_is_set(CMS_cms_has_token | CMS_cms_wants_token),
+ "Should not be set");
+ }
+
+ // Extra wait time check before entering the heap lock to get the collection count
+ if(t_millis != 0 && os::elapsedTime() >= end_time_secs) {
+ // Wait time is over
+ break;
+ }
+
+ // Total collections count after the event
+ unsigned int after_count;
+ {
+ MutexLockerEx hl(Heap_lock, Mutex::_no_safepoint_check_flag);
+ after_count = gch->total_collections();
+ }
+
+ if(before_count != after_count) {
+ // There was a collection - success
+ break;
+ }
+
+ // Too many loops warning
+ if(++loop_count == 0) {
+ warning("wait_on_cms_lock_for_scavenge() has looped %u times", loop_count - 1);
+ }
+ }
+}
+
void ConcurrentMarkSweepThread::sleepBeforeNextCycle() {
while (!_should_terminate) {
if (CMSIncrementalMode) {
icms_wait();
+ if(CMSWaitDuration >= 0) {
+ // Wait until the next synchronous GC, a concurrent full gc
+ // request or a timeout, whichever is earlier.
+ wait_on_cms_lock_for_scavenge(CMSWaitDuration);
+ }
return;
} else {
- // Wait until the next synchronous GC, a concurrent full gc
- // request or a timeout, whichever is earlier.
- wait_on_cms_lock(CMSWaitDuration);
+ if(CMSWaitDuration >= 0) {
+ // Wait until the next synchronous GC, a concurrent full gc
+ // request or a timeout, whichever is earlier.
+ wait_on_cms_lock_for_scavenge(CMSWaitDuration);
+ } else {
+ // Wait until any cms_lock event or check interval not to call shouldConcurrentCollect permanently
+ wait_on_cms_lock(CMSCheckInterval);
+ }
}
// Check if we should start a CMS collection cycle
if (_collector->shouldConcurrentCollect()) {
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -130,6 +130,12 @@
// A concurrent full gc request terminates the wait.
void wait_on_cms_lock(long t_millis);
+ // Wait on CMS lock until the next synchronous GC
+ // or given timeout, whichever is earlier. A timeout value
+ // of 0 indicates that there is no upper bound on the wait time.
+ // A concurrent full gc request terminates the wait.
+ void wait_on_cms_lock_for_scavenge(long t_millis);
+
// The CMS thread will yield during the work portion of its cycle
// only when requested to. Both synchronous and asychronous requests
// are provided:
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/g1/collectionSetChooser.cpp
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -146,43 +146,6 @@
verify();
}
-uint CollectionSetChooser::calc_min_old_cset_length() {
- // The min old CSet region bound is based on the maximum desired
- // number of mixed GCs after a cycle. I.e., even if some old regions
- // look expensive, we should add them to the CSet anyway to make
- // sure we go through the available old regions in no more than the
- // maximum desired number of mixed GCs.
- //
- // The calculation is based on the number of marked regions we added
- // to the CSet chooser in the first place, not how many remain, so
- // that the result is the same during all mixed GCs that follow a cycle.
-
- const size_t region_num = (size_t) _length;
- const size_t gc_num = (size_t) G1MixedGCCountTarget;
- size_t result = region_num / gc_num;
- // emulate ceiling
- if (result * gc_num < region_num) {
- result += 1;
- }
- return (uint) result;
-}
-
-uint CollectionSetChooser::calc_max_old_cset_length() {
- // The max old CSet region bound is based on the threshold expressed
- // as a percentage of the heap size. I.e., it should bound the
- // number of old regions added to the CSet irrespective of how many
- // of them are available.
-
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- const size_t region_num = g1h->n_regions();
- const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
- size_t result = region_num * perc / 100;
- // emulate ceiling
- if (100 * result < region_num * perc) {
- result += 1;
- }
- return (uint) result;
-}
void CollectionSetChooser::add_region(HeapRegion* hr) {
assert(!hr->isHumongous(),
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/g1/collectionSetChooser.hpp
--- a/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -51,6 +51,8 @@
uint _curr_index;
// The number of candidate old regions added to the CSet chooser.
+ // Note: this is not updated when removing a region using
+ // remove_and_move_to_next() below.
uint _length;
// Keeps track of the start of the next array chunk to be claimed by
@@ -111,13 +113,8 @@
hr->live_bytes() < _region_live_threshold_bytes;
}
- // Calculate the minimum number of old regions we'll add to the CSet
- // during a mixed GC.
- uint calc_min_old_cset_length();
-
- // Calculate the maximum number of old regions we'll add to the CSet
- // during a mixed GC.
- uint calc_max_old_cset_length();
+ // Returns the number candidate old regions added
+ uint length() { return _length; }
// Serial version.
void add_region(HeapRegion *hr);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
--- a/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -117,7 +117,7 @@
if (G1Log::fine()) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf]",
+ gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf secs]",
scan_end - scan_start);
}
}
@@ -150,7 +150,7 @@
if (G1Log::fine()) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf sec]",
+ gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf secs]",
mark_end_sec - mark_start_sec);
}
@@ -234,7 +234,7 @@
if (G1Log::fine()) {
gclog_or_tty->date_stamp(PrintGCDateStamps);
gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]",
+ gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf secs]",
cleanup_end_sec - cleanup_start_sec);
}
}
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -267,7 +267,15 @@
double max_gc_time = (double) MaxGCPauseMillis / 1000.0;
double time_slice = (double) GCPauseIntervalMillis / 1000.0;
_mmu_tracker = new G1MMUTrackerQueue(time_slice, max_gc_time);
- _sigma = (double) G1ConfidencePercent / 100.0;
+
+ uintx confidence_perc = G1ConfidencePercent;
+ // Put an artificial ceiling on this so that it's not set to a silly value.
+ if (confidence_perc > 100) {
+ confidence_perc = 100;
+ warning("G1ConfidencePercent is set to a value that is too large, "
+ "it's been updated to %u", confidence_perc);
+ }
+ _sigma = (double) confidence_perc / 100.0;
// start conservatively (around 50ms is about right)
_concurrent_mark_remark_times_ms->add(0.05);
@@ -1798,6 +1806,14 @@
}
#endif // !PRODUCT
+double G1CollectorPolicy::reclaimable_bytes_perc(size_t reclaimable_bytes) {
+ // Returns the given amount of reclaimable bytes (that represents
+ // the amount of reclaimable space still to be collected) as a
+ // percentage of the current heap capacity.
+ size_t capacity_bytes = _g1->capacity();
+ return (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+}
+
bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
const char* false_action_str) {
CollectionSetChooser* cset_chooser = _collectionSetChooser;
@@ -1807,19 +1823,21 @@
ergo_format_reason("candidate old regions not available"));
return false;
}
+
+ // Is the amount of uncollected reclaimable space above G1HeapWastePercent?
size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
- size_t capacity_bytes = _g1->capacity();
- double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
+ double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
double threshold = (double) G1HeapWastePercent;
- if (perc < threshold) {
+ if (reclaimable_perc <= threshold) {
ergo_verbose4(ErgoMixedGCs,
false_action_str,
- ergo_format_reason("reclaimable percentage lower than threshold")
+ ergo_format_reason("reclaimable percentage not over threshold")
ergo_format_region("candidate old regions")
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
cset_chooser->remaining_regions(),
- reclaimable_bytes, perc, threshold);
+ reclaimable_bytes,
+ reclaimable_perc, threshold);
return false;
}
@@ -1830,10 +1848,50 @@
ergo_format_byte_perc("reclaimable")
ergo_format_perc("threshold"),
cset_chooser->remaining_regions(),
- reclaimable_bytes, perc, threshold);
+ reclaimable_bytes,
+ reclaimable_perc, threshold);
return true;
}
+uint G1CollectorPolicy::calc_min_old_cset_length() {
+ // The min old CSet region bound is based on the maximum desired
+ // number of mixed GCs after a cycle. I.e., even if some old regions
+ // look expensive, we should add them to the CSet anyway to make
+ // sure we go through the available old regions in no more than the
+ // maximum desired number of mixed GCs.
+ //
+ // The calculation is based on the number of marked regions we added
+ // to the CSet chooser in the first place, not how many remain, so
+ // that the result is the same during all mixed GCs that follow a cycle.
+
+ const size_t region_num = (size_t) _collectionSetChooser->length();
+ const size_t gc_num = (size_t) MAX2(G1MixedGCCountTarget, (uintx) 1);
+ size_t result = region_num / gc_num;
+ // emulate ceiling
+ if (result * gc_num < region_num) {
+ result += 1;
+ }
+ return (uint) result;
+}
+
+uint G1CollectorPolicy::calc_max_old_cset_length() {
+ // The max old CSet region bound is based on the threshold expressed
+ // as a percentage of the heap size. I.e., it should bound the
+ // number of old regions added to the CSet irrespective of how many
+ // of them are available.
+
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ const size_t region_num = g1h->n_regions();
+ const size_t perc = (size_t) G1OldCSetRegionThresholdPercent;
+ size_t result = region_num * perc / 100;
+ // emulate ceiling
+ if (100 * result < region_num * perc) {
+ result += 1;
+ }
+ return (uint) result;
+}
+
+
void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
double young_start_time_sec = os::elapsedTime();
@@ -1847,7 +1905,7 @@
double base_time_ms = predict_base_elapsed_time_ms(_pending_cards);
double predicted_pause_time_ms = base_time_ms;
- double time_remaining_ms = target_pause_time_ms - base_time_ms;
+ double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
"start choosing CSet",
@@ -1885,7 +1943,7 @@
_collection_set = _inc_cset_head;
_collection_set_bytes_used_before = _inc_cset_bytes_used_before;
- time_remaining_ms -= _inc_cset_predicted_elapsed_time_ms;
+ time_remaining_ms = MAX2(time_remaining_ms - _inc_cset_predicted_elapsed_time_ms, 0.0);
predicted_pause_time_ms += _inc_cset_predicted_elapsed_time_ms;
ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
@@ -1909,8 +1967,8 @@
if (!gcs_are_young()) {
CollectionSetChooser* cset_chooser = _collectionSetChooser;
cset_chooser->verify();
- const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length();
- const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length();
+ const uint min_old_cset_length = calc_min_old_cset_length();
+ const uint max_old_cset_length = calc_max_old_cset_length();
uint expensive_region_num = 0;
bool check_time_remaining = adaptive_young_list_length();
@@ -1928,6 +1986,30 @@
break;
}
+
+ // Stop adding regions if the remaining reclaimable space is
+ // not above G1HeapWastePercent.
+ size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
+ double reclaimable_perc = reclaimable_bytes_perc(reclaimable_bytes);
+ double threshold = (double) G1HeapWastePercent;
+ if (reclaimable_perc <= threshold) {
+ // We've added enough old regions that the amount of uncollected
+ // reclaimable space is at or below the waste threshold. Stop
+ // adding old regions to the CSet.
+ ergo_verbose5(ErgoCSetConstruction,
+ "finish adding old regions to CSet",
+ ergo_format_reason("reclaimable percentage not over threshold")
+ ergo_format_region("old")
+ ergo_format_region("max")
+ ergo_format_byte_perc("reclaimable")
+ ergo_format_perc("threshold"),
+ old_cset_region_length(),
+ max_old_cset_length,
+ reclaimable_bytes,
+ reclaimable_perc, threshold);
+ break;
+ }
+
double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
if (check_time_remaining) {
if (predicted_time_ms > time_remaining_ms) {
@@ -1967,7 +2049,7 @@
}
// We will add this region to the CSet.
- time_remaining_ms -= predicted_time_ms;
+ time_remaining_ms = MAX2(time_remaining_ms - predicted_time_ms, 0.0);
predicted_pause_time_ms += predicted_time_ms;
cset_chooser->remove_and_move_to_next(hr);
_g1->old_set_remove(hr);
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -619,6 +619,18 @@
bool predict_will_fit(uint young_length, double base_time_ms,
uint base_free_regions, double target_pause_time_ms);
+ // Calculate the minimum number of old regions we'll add to the CSet
+ // during a mixed GC.
+ uint calc_min_old_cset_length();
+
+ // Calculate the maximum number of old regions we'll add to the CSet
+ // during a mixed GC.
+ uint calc_max_old_cset_length();
+
+ // Returns the given amount of uncollected reclaimable space
+ // as a percentage of the current heap capacity.
+ double reclaimable_bytes_perc(size_t reclaimable_bytes);
+
public:
G1CollectorPolicy();
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/g1/g1_globals.hpp
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp Tue Mar 12 18:22:40 2013 -0700
@@ -32,7 +32,7 @@
#define G1_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct, manageable, product_rw) \
\
- product(intx, G1ConfidencePercent, 50, \
+ product(uintx, G1ConfidencePercent, 50, \
"Confidence level for MMU/pause predictions") \
\
develop(intx, G1MarkingOverheadPercent, 0, \
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
--- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -373,6 +373,8 @@
" does not exceed used.end() = " PTR_FORMAT ","
" yet last_chunk_index_to_check " INTPTR_FORMAT
" exceeds last_chunk_index " INTPTR_FORMAT,
+ last_block, last_block + last_block_size,
+ used.end(),
last_chunk_index_to_check, last_chunk_index));
assert(sp->used_region().end() > used.end(),
err_msg("Expansion did not happen: "
diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/interpreter/bytecodeTracer.cpp
--- a/src/share/vm/interpreter/bytecodeTracer.cpp Mon Feb 25 07:22:06 2013 +0100
+++ b/src/share/vm/interpreter/bytecodeTracer.cpp Tue Mar 12 18:22:40 2013 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -335,9 +335,6 @@
st->print_cr(" %s", constants->resolved_klass_at(i)->external_name());
} else if (tag.is_unresolved_klass()) {
st->print_cr(" ", i);
- } else if (tag.is_object()) {
- st->print("