# 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 @@

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(" "); - print_oop(constants->object_at(i), st); } else if (tag.is_method_type()) { int i2 = constants->method_type_index_at(i); st->print(" %d", i2); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/interpreter/linkResolver.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1241,7 +1241,6 @@ void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { assert(EnableInvokeDynamic, ""); - pool->set_has_invokedynamic(); // mark header to flag active call sites //resolve_pool(, method_name, method_signature, current_klass, pool, index, CHECK); Symbol* method_name = pool->name_ref_at(index); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/interpreter/rewriter.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 @@ -48,7 +48,6 @@ add_cp_cache_entry(i); break; case JVM_CONSTANT_String: - case JVM_CONSTANT_Object: case JVM_CONSTANT_MethodHandle : // fall through case JVM_CONSTANT_MethodType : // fall through add_resolved_references_entry(i); @@ -238,7 +237,7 @@ address p = bcp + offset; int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p); constantTag tag = _pool->tag_at(cp_index).value(); - if (tag.is_method_handle() || tag.is_method_type() || tag.is_string() || tag.is_object()) { + if (tag.is_method_handle() || tag.is_method_type() || tag.is_string()) { int ref_index = cp_entry_to_resolved_references(cp_index); if (is_wide) { (*bcp) = Bytecodes::_fast_aldc_w; diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/memory/allocation.inline.hpp --- a/src/share/vm/memory/allocation.inline.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/memory/allocation.inline.hpp 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 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP #define SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP +#include "runtime/atomic.inline.hpp" #include "runtime/os.hpp" // Explicit C-heap memory management diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/memory/cardTableModRefBS.cpp --- a/src/share/vm/memory/cardTableModRefBS.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -694,7 +694,7 @@ if (failed) { if (!failures) { tty->cr(); - tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]"); + tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]", start, end); tty->print_cr("== %sexpecting value: %d", (val_equals) ? "" : "not ", val); failures = true; diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/memory/cardTableRS.cpp --- a/src/share/vm/memory/cardTableRS.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/memory/cardTableRS.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -353,7 +353,7 @@ assert(jp >= _begin && jp < _end, err_msg("Error: jp " PTR_FORMAT " should be within " "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")", - _begin, _end)); + jp, _begin, _end)); oop obj = oopDesc::load_decode_heap_oop(p); guarantee(obj == NULL || (HeapWord*)obj >= _boundary, err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on " diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/memory/collectorPolicy.cpp --- a/src/share/vm/memory/collectorPolicy.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/memory/collectorPolicy.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -168,11 +168,11 @@ void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size, size_t init_promo_size, size_t init_survivor_size) { - const double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; + const double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0; _size_policy = new AdaptiveSizePolicy(init_eden_size, init_promo_size, init_survivor_size, - max_gc_minor_pause_sec, + max_gc_pause_sec, GCTimeRatio); } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/memory/metaspaceCounters.cpp --- a/src/share/vm/memory/metaspaceCounters.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/memory/metaspaceCounters.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -25,12 +25,14 @@ #include "precompiled.hpp" #include "memory/metaspaceCounters.hpp" #include "memory/resourceArea.hpp" - -#define METASPACE_NAME "perm" +#include "utilities/exceptions.hpp" MetaspaceCounters* MetaspaceCounters::_metaspace_counters = NULL; -MetaspaceCounters::MetaspaceCounters() { +MetaspaceCounters::MetaspaceCounters() : + _capacity(NULL), + _used(NULL), + _max_capacity(NULL) { if (UsePerfData) { size_t min_capacity = MetaspaceAux::min_chunk_size(); size_t max_capacity = MetaspaceAux::reserved_in_bytes(); @@ -41,6 +43,25 @@ } } +static PerfVariable* create_ms_variable(const char *ns, + const char *name, + size_t value, + TRAPS) { + const char *path = PerfDataManager::counter_name(ns, name); + PerfVariable *result = + PerfDataManager::create_variable(SUN_GC, path, PerfData::U_Bytes, value, + CHECK_NULL); + return result; +} + +static void create_ms_constant(const char *ns, + const char *name, + size_t value, + TRAPS) { + const char *path = PerfDataManager::counter_name(ns, name); + PerfDataManager::create_constant(SUN_GC, path, PerfData::U_Bytes, value, CHECK); +} + void MetaspaceCounters::initialize(size_t min_capacity, size_t max_capacity, size_t curr_capacity, @@ -50,93 +71,32 @@ EXCEPTION_MARK; ResourceMark rm; - // Create a name that will be recognized by jstat tools as - // the perm gen. Change this to a Metaspace name when the - // tools are fixed. - // name to recognize "sun.gc.generation.2.*" - - const char* name = METASPACE_NAME; - const int ordinal = 2; - const int spaces = 1; - - const char* cns = PerfDataManager::name_space("generation", ordinal); - - _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtClass); - strcpy(_name_space, cns); - - const char* cname = PerfDataManager::counter_name(_name_space, "name"); - PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK); - - // End of perm gen like name creation - - cname = PerfDataManager::counter_name(_name_space, "spaces"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None, - spaces, CHECK); - - cname = PerfDataManager::counter_name(_name_space, "minCapacity"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, - min_capacity, CHECK); - - cname = PerfDataManager::counter_name(_name_space, "maxCapacity"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, - max_capacity, CHECK); + const char *ms = "metaspace"; - cname = PerfDataManager::counter_name(_name_space, "capacity"); - _current_size = - PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, - curr_capacity, CHECK); - - // SpaceCounter like counters - // name to recognize "sun.gc.generation.2.space.0.*" - { - const int space_ordinal = 0; - const char* cns = PerfDataManager::name_space(_name_space, "space", - space_ordinal); - - char* space_name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtClass); - strcpy(space_name_space, cns); - - const char* cname = PerfDataManager::counter_name(space_name_space, "name"); - PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK); - - cname = PerfDataManager::counter_name(space_name_space, "maxCapacity"); - _max_capacity = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, - (jlong)max_capacity, CHECK); - - cname = PerfDataManager::counter_name(space_name_space, "capacity"); - _capacity = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, - curr_capacity, CHECK); - - cname = PerfDataManager::counter_name(space_name_space, "used"); - _used = PerfDataManager::create_variable(SUN_GC, - cname, - PerfData::U_Bytes, - used, - CHECK); - - cname = PerfDataManager::counter_name(space_name_space, "initCapacity"); - PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, - min_capacity, CHECK); - } + create_ms_constant(ms, "minCapacity", min_capacity, CHECK); + _max_capacity = create_ms_variable(ms, "maxCapacity", max_capacity, CHECK); + _capacity = create_ms_variable(ms, "capacity", curr_capacity, CHECK); + _used = create_ms_variable(ms, "used", used, CHECK); } } void MetaspaceCounters::update_capacity() { assert(UsePerfData, "Should not be called unless being used"); + assert(_capacity != NULL, "Should be initialized"); size_t capacity_in_bytes = MetaspaceAux::capacity_in_bytes(); _capacity->set_value(capacity_in_bytes); } void MetaspaceCounters::update_used() { assert(UsePerfData, "Should not be called unless being used"); + assert(_used != NULL, "Should be initialized"); size_t used_in_bytes = MetaspaceAux::used_in_bytes(); _used->set_value(used_in_bytes); } void MetaspaceCounters::update_max_capacity() { assert(UsePerfData, "Should not be called unless being used"); + assert(_max_capacity != NULL, "Should be initialized"); size_t reserved_in_bytes = MetaspaceAux::reserved_in_bytes(); _max_capacity->set_value(reserved_in_bytes); } @@ -146,18 +106,19 @@ update_used(); update_capacity(); update_max_capacity(); - _current_size->set_value(MetaspaceAux::reserved_in_bytes()); } } void MetaspaceCounters::initialize_performance_counters() { if (UsePerfData) { + assert(_metaspace_counters == NULL, "Should only be initialized once"); _metaspace_counters = new MetaspaceCounters(); } } void MetaspaceCounters::update_performance_counters() { if (UsePerfData) { + assert(_metaspace_counters != NULL, "Should be initialized"); _metaspace_counters->update_all(); } } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/memory/metaspaceCounters.hpp --- a/src/share/vm/memory/metaspaceCounters.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/memory/metaspaceCounters.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -29,11 +29,9 @@ class MetaspaceCounters: public CHeapObj { friend class VMStructs; - PerfVariable* _current_size; PerfVariable* _capacity; PerfVariable* _used; PerfVariable* _max_capacity; - char* _name_space; static MetaspaceCounters* _metaspace_counters; void initialize(size_t min_capacity, size_t max_capacity, diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/constantPool.cpp --- a/src/share/vm/oops/constantPool.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/constantPool.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -695,10 +695,6 @@ result_oop = string_at_impl(this_oop, index, cache_index, CHECK_NULL); break; - case JVM_CONSTANT_Object: - result_oop = this_oop->object_at(index); - break; - case JVM_CONSTANT_MethodHandleInError: case JVM_CONSTANT_MethodTypeInError: { @@ -1824,8 +1820,6 @@ st->print_cr(internal_name()); if (flags() != 0) { st->print(" - flags: 0x%x", flags()); - if (has_pseudo_string()) st->print(" has_pseudo_string"); - if (has_invokedynamic()) st->print(" has_invokedynamic"); if (has_preresolution()) st->print(" has_preresolution"); if (on_stack()) st->print(" on_stack"); st->cr(); @@ -1869,13 +1863,14 @@ st->print(" name_and_type_index=%d", uncached_name_and_type_ref_index_at(index)); break; case JVM_CONSTANT_String : - unresolved_string_at(index)->print_value_on(st); + if (is_pseudo_string_at(index)) { + oop anObj = pseudo_string_at(index); + anObj->print_value_on(st); + st->print(" {0x%lx}", (address)anObj); + } else { + unresolved_string_at(index)->print_value_on(st); + } break; - case JVM_CONSTANT_Object : { - oop anObj = object_at(index); - anObj->print_value_on(st); - st->print(" {0x%lx}", (address)anObj); - } break; case JVM_CONSTANT_Integer : st->print("%d", int_at(index)); break; @@ -1939,8 +1934,6 @@ void ConstantPool::print_value_on(outputStream* st) const { assert(is_constantPool(), "must be constantPool"); st->print("constant pool [%d]", length()); - if (has_pseudo_string()) st->print("/pseudo_string"); - if (has_invokedynamic()) st->print("/invokedynamic"); if (has_preresolution()) st->print("/preresolution"); if (operands() != NULL) st->print("/operands[%d]", operands()->length()); print_address_on(st); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/constantPool.hpp --- a/src/share/vm/oops/constantPool.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/constantPool.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -97,10 +97,8 @@ Array* _reference_map; enum { - _has_invokedynamic = 1, // Flags - _has_pseudo_string = 2, - _has_preresolution = 4, - _on_stack = 8 + _has_preresolution = 1, // Flags + _on_stack = 2 }; int _flags; // old fashioned bit twiddling @@ -175,12 +173,6 @@ Array* tags() const { return _tags; } Array* operands() const { return _operands; } - bool has_invokedynamic() const { return (_flags & _has_invokedynamic) != 0; } - void set_has_invokedynamic() { _flags |= _has_invokedynamic; } - - bool has_pseudo_string() const { return (_flags & _has_pseudo_string) != 0; } - void set_has_pseudo_string() { _flags |= _has_pseudo_string; } - bool has_preresolution() const { return (_flags & _has_preresolution) != 0; } void set_has_preresolution() { _flags |= _has_preresolution; } @@ -324,14 +316,6 @@ resolved_references()->obj_at_put(obj_index, str); } - void set_object_tag_at(int which) { - release_tag_at_put(which, JVM_CONSTANT_Object); - } - - void object_at_put(int which, oop obj) { - resolved_references()->obj_at_put(cp_to_object_index(which), obj); - } - // For temporary use while constructing constant pool void string_index_at_put(int which, int string_index) { tag_at_put(which, JVM_CONSTANT_StringIndex); @@ -429,12 +413,6 @@ // Version that can be used before string oop array is created. oop uncached_string_at(int which, TRAPS); - oop object_at(int which) { - assert(tag_at(which).is_object(), "Corrupted constant pool"); - int obj_index = cp_to_object_index(which); - return resolved_references()->obj_at(obj_index); - } - // A "pseudo-string" is an non-string oop that has found is way into // a String entry. // Under EnableInvokeDynamic this can happen if the user patches a live @@ -454,10 +432,18 @@ return s; } + oop pseudo_string_at(int which) { + assert(tag_at(which).is_string(), "Corrupted constant pool"); + assert(unresolved_string_at(which) == NULL, "shouldn't have symbol"); + int obj_index = cp_to_object_index(which); + oop s = resolved_references()->obj_at(obj_index); + return s; + } + void pseudo_string_at_put(int which, int obj_index, oop x) { assert(EnableInvokeDynamic, ""); - set_has_pseudo_string(); // mark header assert(tag_at(which).is_string(), "Corrupted constant pool"); + unresolved_string_at_put(which, NULL); // indicates patched string string_at_put(which, obj_index, x); // this works just fine } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/generateOopMap.cpp --- a/src/share/vm/oops/generateOopMap.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/generateOopMap.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 @@ -1853,7 +1853,6 @@ if (tag.is_klass() || tag.is_unresolved_klass() || tag.is_string() || - tag.is_object() || tag.is_method_handle() || tag.is_method_type()) { assert(bt == T_OBJECT, "Guard is incorrect"); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/instanceKlass.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -2170,7 +2170,11 @@ if (impl != NULL) { if (!impl->is_loader_alive(is_alive)) { // remove this guy - *adr_implementor() = NULL; + Klass** klass = adr_implementor(); + assert(klass != NULL, "null klass"); + if (klass != NULL) { + *klass = NULL; + } } } } @@ -3151,9 +3155,10 @@ if (protection_domain() != NULL) { guarantee(protection_domain()->is_oop(), "should be oop"); } - if (host_klass() != NULL) { - guarantee(host_klass()->is_metadata(), "should be in metaspace"); - guarantee(host_klass()->is_klass(), "should be klass"); + const Klass* host = host_klass(); + if (host != NULL) { + guarantee(host->is_metadata(), "should be in metaspace"); + guarantee(host->is_klass(), "should be klass"); } if (signers() != NULL) { guarantee(signers()->is_objArray(), "should be obj array"); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/instanceKlass.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -536,7 +536,9 @@ assert(is_anonymous(), "not anonymous"); Klass** addr = (Klass**)adr_host_klass(); assert(addr != NULL, "no reversed space"); - *addr = host; + if (addr != NULL) { + *addr = host; + } } bool is_anonymous() const { return (_misc_flags & _misc_is_anonymous) != 0; @@ -758,7 +760,10 @@ void set_implementor(Klass* k) { assert(is_interface(), "not interface"); Klass** addr = adr_implementor(); - *addr = k; + assert(addr != NULL, "null addr"); + if (addr != NULL) { + *addr = k; + } } int nof_implementors() const { diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/method.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -456,6 +456,8 @@ void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN; // method parameters + bool has_method_parameters() const + { return constMethod()->has_method_parameters(); } int method_parameters_length() const { return constMethod()->method_parameters_length(); } MethodParametersElement* method_parameters_start() const diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/symbol.cpp --- a/src/share/vm/oops/symbol.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/symbol.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 @@ -27,6 +27,7 @@ #include "classfile/altHashing.hpp" #include "classfile/classLoaderData.hpp" #include "oops/symbol.hpp" +#include "runtime/atomic.inline.hpp" #include "runtime/os.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" @@ -210,6 +211,28 @@ return AltHashing::murmur3_32(seed, (const jbyte*)as_C_string(), utf8_length()); } +void Symbol::increment_refcount() { + // Only increment the refcount if positive. If negative either + // overflow has occurred or it is a permanent symbol in a read only + // shared archive. + if (_refcount >= 0) { + Atomic::inc(&_refcount); + NOT_PRODUCT(Atomic::inc(&_total_count);) + } +} + +void Symbol::decrement_refcount() { + if (_refcount >= 0) { + Atomic::dec(&_refcount); +#ifdef ASSERT + if (_refcount < 0) { + print(); + assert(false, "reference count underflow for symbol"); + } +#endif + } +} + void Symbol::print_on(outputStream* st) const { if (this == NULL) { st->print_cr("NULL"); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/oops/symbol.hpp --- a/src/share/vm/oops/symbol.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/oops/symbol.hpp 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 @@ -27,7 +27,6 @@ #include "utilities/utf8.hpp" #include "memory/allocation.hpp" -#include "runtime/atomic.hpp" // A Symbol is a canonicalized string. // All Symbols reside in global SymbolTable and are reference counted. @@ -150,8 +149,8 @@ // Reference counting. See comments above this class for when to use. int refcount() const { return _refcount; } - inline void increment_refcount(); - inline void decrement_refcount(); + void increment_refcount(); + void decrement_refcount(); int byte_at(int index) const { assert(index >=0 && index < _length, "symbol index overflow"); @@ -232,26 +231,4 @@ return (((uintptr_t)this < (uintptr_t)other) ? -1 : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1); } - -inline void Symbol::increment_refcount() { - // Only increment the refcount if positive. If negative either - // overflow has occurred or it is a permanent symbol in a read only - // shared archive. - if (_refcount >= 0) { - Atomic::inc(&_refcount); - NOT_PRODUCT(Atomic::inc(&_total_count);) - } -} - -inline void Symbol::decrement_refcount() { - if (_refcount >= 0) { - Atomic::dec(&_refcount); -#ifdef ASSERT - if (_refcount < 0) { - print(); - assert(false, "reference count underflow for symbol"); - } -#endif - } -} #endif // SHARE_VM_OOPS_SYMBOL_HPP diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/bytecodeInfo.cpp --- a/src/share/vm/opto/bytecodeInfo.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/bytecodeInfo.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -47,7 +47,8 @@ _site_invoke_ratio(site_invoke_ratio), _max_inline_level(max_inline_level), _count_inline_bcs(method()->code_size_for_inlining()), - _subtrees(c->comp_arena(), 2, 0, NULL) + _subtrees(c->comp_arena(), 2, 0, NULL), + _msg(NULL) { NOT_PRODUCT(_count_inlines = 0;) if (_caller_jvms != NULL) { @@ -77,7 +78,8 @@ _method(callee_method), _site_invoke_ratio(site_invoke_ratio), _max_inline_level(max_inline_level), - _count_inline_bcs(method()->code_size()) + _count_inline_bcs(method()->code_size()), + _msg(NULL) { NOT_PRODUCT(_count_inlines = 0;) assert(!UseOldInlining, "do not use for old stuff"); @@ -95,8 +97,10 @@ ); } -// positive filter: should callee be inlined? returns NULL, if yes, or rejection msg -const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const { +// positive filter: should callee be inlined? +bool InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, + int caller_bci, ciCallProfile& profile, + WarmCallInfo* wci_result) { // Allows targeted inlining if(callee_method->should_inline()) { *wci_result = *(WarmCallInfo::always_hot()); @@ -104,11 +108,10 @@ CompileTask::print_inline_indent(inline_level()); tty->print_cr("Inlined method is hot: "); } - return NULL; + set_msg("force inline by CompilerOracle"); + return true; } - // positive filter: should send be inlined? returns NULL (--> yes) - // or rejection msg int size = callee_method->code_size_for_inlining(); // Check for too many throws (and not too huge) @@ -119,11 +122,13 @@ CompileTask::print_inline_indent(inline_level()); tty->print_cr("Inlined method with many throws (throws=%d):", callee_method->interpreter_throwout_count()); } - return NULL; + set_msg("many throws"); + return true; } if (!UseOldInlining) { - return NULL; // size and frequency are represented in a new way + set_msg("!UseOldInlining"); + return true; // size and frequency are represented in a new way } int default_max_inline_size = C->max_inline_size(); @@ -153,31 +158,44 @@ // Not hot. Check for medium-sized pre-existing nmethod at cold sites. if (callee_method->has_compiled_code() && callee_method->instructions_size() > inline_small_code_size) - return "already compiled into a medium method"; + set_msg("already compiled into a medium method"); + return false; } if (size > max_inline_size) { - if (max_inline_size > default_max_inline_size) - return "hot method too big"; - return "too big"; + if (max_inline_size > default_max_inline_size) { + set_msg("hot method too big"); + } else { + set_msg("too big"); + } + return false; } - return NULL; + return true; } -// negative filter: should callee NOT be inlined? returns NULL, ok to inline, or rejection msg -const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const { - // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg +// negative filter: should callee NOT be inlined? +bool InlineTree::should_not_inline(ciMethod *callee_method, + ciMethod* caller_method, + WarmCallInfo* wci_result) { + + const char* fail_msg = NULL; + + // First check all inlining restrictions which are required for correctness + if ( callee_method->is_abstract()) { + fail_msg = "abstract method"; // // note: we allow ik->is_abstract() + } else if (!callee_method->holder()->is_initialized()) { + fail_msg = "method holder not initialized"; + } else if ( callee_method->is_native()) { + fail_msg = "native method"; + } else if ( callee_method->dont_inline()) { + fail_msg = "don't inline by annotation"; + } + if (!UseOldInlining) { - const char* fail = NULL; - if ( callee_method->is_abstract()) fail = "abstract method"; - // note: we allow ik->is_abstract() - if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized"; - if ( callee_method->is_native()) fail = "native method"; - if ( callee_method->dont_inline()) fail = "don't inline by annotation"; - - if (fail) { + if (fail_msg != NULL) { *wci_result = *(WarmCallInfo::always_cold()); - return fail; + set_msg(fail_msg); + return true; } if (callee_method->has_unloaded_classes_in_signature()) { @@ -199,20 +217,23 @@ // %%% adjust wci_result->size()? } - return NULL; + return false; + } + + // one more inlining restriction + if (fail_msg == NULL && callee_method->has_unloaded_classes_in_signature()) { + fail_msg = "unloaded signature classes"; } - // First check all inlining restrictions which are required for correctness - if ( callee_method->is_abstract()) return "abstract method"; - // note: we allow ik->is_abstract() - if (!callee_method->holder()->is_initialized()) return "method holder not initialized"; - if ( callee_method->is_native()) return "native method"; - if ( callee_method->dont_inline()) return "don't inline by annotation"; - if ( callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes"; + if (fail_msg != NULL) { + set_msg(fail_msg); + return true; + } + // ignore heuristic controls on inlining if (callee_method->should_inline()) { - // ignore heuristic controls on inlining - return NULL; + set_msg("force inline by CompilerOracle"); + return false; } // Now perform checks which are heuristic @@ -220,7 +241,8 @@ if (!callee_method->force_inline()) { if (callee_method->has_compiled_code() && callee_method->instructions_size() > InlineSmallCode) { - return "already compiled into a big method"; + set_msg("already compiled into a big method"); + return true; } } @@ -231,17 +253,21 @@ const InlineTree *top = this; while (top->caller_tree() != NULL) top = top->caller_tree(); ciInstanceKlass* k = top->method()->holder(); - if (!k->is_subclass_of(C->env()->Throwable_klass())) - return "exception method"; + if (!k->is_subclass_of(C->env()->Throwable_klass())) { + set_msg("exception method"); + return true; + } } if (callee_method->should_not_inline()) { - return "disallowed by CompilerOracle"; + set_msg("disallowed by CompilerOracle"); + return true; } #ifndef PRODUCT if (ciReplay::should_not_inline(callee_method)) { - return "disallowed by ciReplay"; + set_msg("disallowed by ciReplay"); + return true; } #endif @@ -249,19 +275,23 @@ // Do not inline StringCache::profile() method used only at the beginning. if (callee_method->name() == ciSymbol::profile_name() && callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) { - return "profiling method"; + set_msg("profiling method"); + return true; } } // use frequency-based objections only for non-trivial methods - if (callee_method->code_size() <= MaxTrivialSize) return NULL; + if (callee_method->code_size() <= MaxTrivialSize) { + return false; + } // don't use counts with -Xcomp or CTW if (UseInterpreter && !CompileTheWorld) { if (!callee_method->has_compiled_code() && !callee_method->was_executed_more_than(0)) { - return "never executed"; + set_msg("never executed"); + return true; } if (is_init_with_ea(callee_method, caller_method, C)) { @@ -270,39 +300,44 @@ } else if (!callee_method->was_executed_more_than(MIN2(MinInliningThreshold, CompileThreshold >> 1))) { - return "executed < MinInliningThreshold times"; + set_msg("executed < MinInliningThreshold times"); + return true; } } - return NULL; + return false; } //-----------------------------try_to_inline----------------------------------- -// return NULL if ok, reason for not inlining otherwise +// return true if ok // Relocated from "InliningClosure::try_to_inline" -const char* InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay) { - // Old algorithm had funny accumulating BC-size counters +bool InlineTree::try_to_inline(ciMethod* callee_method, ciMethod* caller_method, + int caller_bci, ciCallProfile& profile, + WarmCallInfo* wci_result, bool& should_delay) { + + // Old algorithm had funny accumulating BC-size counters if (UseOldInlining && ClipInlining && (int)count_inline_bcs() >= DesiredMethodLimit) { if (!callee_method->force_inline() || !IncrementalInline) { - return "size > DesiredMethodLimit"; + set_msg("size > DesiredMethodLimit"); + return false; } else if (!C->inlining_incrementally()) { should_delay = true; } } - const char *msg = NULL; - msg = should_inline(callee_method, caller_method, caller_bci, profile, wci_result); - if (msg != NULL) - return msg; - - msg = should_not_inline(callee_method, caller_method, wci_result); - if (msg != NULL) - return msg; + if (!should_inline(callee_method, caller_method, caller_bci, profile, + wci_result)) { + return false; + } + if (should_not_inline(callee_method, caller_method, wci_result)) { + return false; + } if (InlineAccessors && callee_method->is_accessor()) { // accessor methods are not subject to any of the following limits. - return NULL; + set_msg("accessor"); + return true; } // suppress a few checks for accessors and trivial methods @@ -312,7 +347,8 @@ if (C->over_inlining_cutoff()) { if ((!callee_method->force_inline() && !caller_method->is_compiled_lambda_form()) || !IncrementalInline) { - return "NodeCountInliningCutoff"; + set_msg("NodeCountInliningCutoff"); + return false; } else { should_delay = true; } @@ -326,16 +362,19 @@ } else if (profile.count() == 0) { // don't inline unreached call sites - return "call site not reached"; + set_msg("call site not reached"); + return false; } } if (!C->do_inlining() && InlineAccessors) { - return "not an accessor"; + set_msg("not an accessor"); + return false; } if (inline_level() > _max_inline_level) { if (!callee_method->force_inline() || !IncrementalInline) { - return "inlining too deep"; + set_msg("inlining too deep"); + return false; } else if (!C->inlining_incrementally()) { should_delay = true; } @@ -345,15 +384,19 @@ if (!callee_method->is_compiled_lambda_form()) { // count the current method and the callee int inline_level = (method() == callee_method) ? 1 : 0; - if (inline_level > MaxRecursiveInlineLevel) - return "recursively inlining too deep"; + if (inline_level > MaxRecursiveInlineLevel) { + set_msg("recursively inlining too deep"); + return false; + } // count callers of current method and callee JVMState* jvms = caller_jvms(); while (jvms != NULL && jvms->has_method()) { if (jvms->method() == callee_method) { inline_level++; - if (inline_level > MaxRecursiveInlineLevel) - return "recursively inlining too deep"; + if (inline_level > MaxRecursiveInlineLevel) { + set_msg("recursively inlining too deep"); + return false; + } } jvms = jvms->caller(); } @@ -364,14 +407,15 @@ if (UseOldInlining && ClipInlining && (int)count_inline_bcs() + size >= DesiredMethodLimit) { if (!callee_method->force_inline() || !IncrementalInline) { - return "size > DesiredMethodLimit"; + set_msg("size > DesiredMethodLimit"); + return false; } else if (!C->inlining_incrementally()) { should_delay = true; } } // ok, inline this method - return NULL; + return true; } //------------------------------pass_initial_checks---------------------------- @@ -421,17 +465,18 @@ //------------------------------print_inlining--------------------------------- void InlineTree::print_inlining(ciMethod* callee_method, int caller_bci, - const char* msg, bool success) const { - assert(msg != NULL, "just checking"); + bool success) const { + const char* inline_msg = msg(); + assert(inline_msg != NULL, "just checking"); if (C->log() != NULL) { if (success) { - C->log()->inline_success(msg); + C->log()->inline_success(inline_msg); } else { - C->log()->inline_fail(msg); + C->log()->inline_fail(inline_msg); } } if (PrintInlining) { - C->print_inlining(callee_method, inline_level(), caller_bci, msg); + C->print_inlining(callee_method, inline_level(), caller_bci, inline_msg); if (callee_method == NULL) tty->print(" callee not monotonic or profiled"); if (Verbose && callee_method) { const InlineTree *top = this; @@ -455,49 +500,51 @@ } assert(_method == jvms->method(), "redundant instance state"); #endif - const char *failure_msg = NULL; int caller_bci = jvms->bci(); - ciMethod *caller_method = jvms->method(); + ciMethod* caller_method = jvms->method(); // Do some initial checks. if (!pass_initial_checks(caller_method, caller_bci, callee_method)) { - print_inlining(callee_method, caller_bci, "failed initial checks", - false /* !success */); + set_msg("failed initial checks"); + print_inlining(callee_method, caller_bci, false /* !success */); return NULL; } // Do some parse checks. - failure_msg = check_can_parse(callee_method); - if (failure_msg != NULL) { - print_inlining(callee_method, caller_bci, failure_msg, - false /* !success */); + set_msg(check_can_parse(callee_method)); + if (msg() != NULL) { + print_inlining(callee_method, caller_bci, false /* !success */); return NULL; } // Check if inlining policy says no. WarmCallInfo wci = *(initial_wci); - failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, - &wci, should_delay); + bool success = try_to_inline(callee_method, caller_method, caller_bci, + profile, &wci, should_delay); #ifndef PRODUCT if (UseOldInlining && InlineWarmCalls && (PrintOpto || PrintOptoInlining || PrintInlining)) { bool cold = wci.is_cold(); bool hot = !cold && wci.is_hot(); - bool old_cold = (failure_msg != NULL); + bool old_cold = !success; if (old_cold != cold || (Verbose || WizardMode)) { + if (msg() == NULL) { + set_msg("OK"); + } tty->print(" OldInlining= %4s : %s\n WCI=", - old_cold ? "cold" : "hot", failure_msg ? failure_msg : "OK"); + old_cold ? "cold" : "hot", msg()); wci.print(); } } #endif if (UseOldInlining) { - if (failure_msg == NULL) + if (success) { wci = *(WarmCallInfo::always_hot()); - else + } else { wci = *(WarmCallInfo::always_cold()); } + } if (!InlineWarmCalls) { if (!wci.is_cold() && !wci.is_hot()) { // Do not inline the warm calls. @@ -507,9 +554,10 @@ if (!wci.is_cold()) { // Inline! - print_inlining(callee_method, caller_bci, - failure_msg ? failure_msg : "inline (hot)", - true /* success */); + if (msg() == NULL) { + set_msg("inline (hot)"); + } + print_inlining(callee_method, caller_bci, true /* success */); if (UseOldInlining) build_inline_tree_for_callee(callee_method, jvms, caller_bci); if (InlineWarmCalls && !wci.is_hot()) @@ -518,9 +566,10 @@ } // Do not inline - print_inlining(callee_method, caller_bci, - failure_msg ? failure_msg : "too cold to inline", - false /* !success */ ); + if (msg() == NULL) { + set_msg("too cold to inline"); + } + print_inlining(callee_method, caller_bci, false /* !success */ ); return NULL; } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/c2_globals.hpp --- a/src/share/vm/opto/c2_globals.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/c2_globals.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -54,6 +54,12 @@ #define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct) \ \ + develop(bool, StressLCM, false, \ + "Randomize instruction scheduling in LCM") \ + \ + develop(bool, StressGCM, false, \ + "Randomize instruction scheduling in GCM") \ + \ notproduct(intx, CompileZapFirst, 0, \ "If +ZapDeadCompiledLocals, " \ "skip this many before compiling in zap calls") \ diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/compile.cpp --- a/src/share/vm/opto/compile.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/compile.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -2899,6 +2899,13 @@ } } break; + case Op_MemBarStoreStore: + // Break the link with AllocateNode: it is no longer useful and + // confuses register allocation. + if (n->req() > MemBarNode::Precedent) { + n->set_req(MemBarNode::Precedent, top()); + } + break; default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" ); @@ -3669,3 +3676,38 @@ n->set_req(0, NULL); } } + +// Auxiliary method to support randomized stressing/fuzzing. +// +// This method can be called the arbitrary number of times, with current count +// as the argument. The logic allows selecting a single candidate from the +// running list of candidates as follows: +// int count = 0; +// Cand* selected = null; +// while(cand = cand->next()) { +// if (randomized_select(++count)) { +// selected = cand; +// } +// } +// +// Including count equalizes the chances any candidate is "selected". +// This is useful when we don't have the complete list of candidates to choose +// from uniformly. In this case, we need to adjust the randomicity of the +// selection, or else we will end up biasing the selection towards the latter +// candidates. +// +// Quick back-envelope calculation shows that for the list of n candidates +// the equal probability for the candidate to persist as "best" can be +// achieved by replacing it with "next" k-th candidate with the probability +// of 1/k. It can be easily shown that by the end of the run, the +// probability for any candidate is converged to 1/n, thus giving the +// uniform distribution among all the candidates. +// +// We don't care about the domain size as long as (RANDOMIZED_DOMAIN / count) is large. +#define RANDOMIZED_DOMAIN_POW 29 +#define RANDOMIZED_DOMAIN (1 << RANDOMIZED_DOMAIN_POW) +#define RANDOMIZED_DOMAIN_MASK ((1 << (RANDOMIZED_DOMAIN_POW + 1)) - 1) +bool Compile::randomized_select(int count) { + assert(count > 0, "only positive"); + return (os::random() & RANDOMIZED_DOMAIN_MASK) < (RANDOMIZED_DOMAIN / count); +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/compile.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -678,6 +678,7 @@ void record_dead_node(uint idx) { if (_dead_node_list.test_set(idx)) return; _dead_node_count++; } + bool is_dead_node(uint idx) { return _dead_node_list.test(idx) != 0; } uint dead_node_count() { return _dead_node_count; } void reset_dead_node_list() { _dead_node_list.Reset(); _dead_node_count = 0; @@ -1086,6 +1087,9 @@ // Definitions of pd methods static void pd_compiler2_init(); + + // Auxiliary method for randomized fuzzing/stressing + static bool randomized_select(int count); }; #endif // SHARE_VM_OPTO_COMPILE_HPP diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/gcm.cpp --- a/src/share/vm/opto/gcm.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/gcm.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1046,6 +1046,8 @@ } #endif + int cand_cnt = 0; // number of candidates tried + // Walk up the dominator tree from LCA (Lowest common ancestor) to // the earliest legal location. Capture the least execution frequency. while (LCA != early) { @@ -1071,8 +1073,11 @@ LCA->_pre_order, LCA->_nodes[0]->_idx, start_lat, end_idx, end_lat, LCA_freq); } #endif + cand_cnt++; if (LCA_freq < least_freq || // Better Frequency - ( !in_latency && // No block containing latency + (StressGCM && Compile::randomized_select(cand_cnt)) || // Should be randomly accepted in stress mode + (!StressGCM && // Otherwise, choose with latency + !in_latency && // No block containing latency LCA_freq < least_freq * delta && // No worse frequency target >= end_lat && // within latency range !self->is_iteratively_computed() ) // But don't hoist IV increments @@ -1210,7 +1215,8 @@ } // If there is no opportunity to hoist, then we're done. - bool try_to_hoist = (LCA != early); + // In stress mode, try to hoist even the single operations. + bool try_to_hoist = StressGCM || (LCA != early); // Must clone guys stay next to use; no hoisting allowed. // Also cannot hoist guys that alter memory or are otherwise not diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/lcm.cpp --- a/src/share/vm/opto/lcm.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/lcm.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -421,6 +421,7 @@ uint latency = 0; // Bigger is scheduled first uint score = 0; // Bigger is better int idx = -1; // Index in worklist + int cand_cnt = 0; // Candidate count for( uint i=0; ireq(); // Many inputs get high score to break ties // Keep best latency found - if( choice < n_choice || - ( choice == n_choice && - ( latency < n_latency || - ( latency == n_latency && - ( score < n_score ))))) { + cand_cnt++; + if (choice < n_choice || + (choice == n_choice && + ((StressLCM && Compile::randomized_select(cand_cnt)) || + (!StressLCM && + (latency < n_latency || + (latency == n_latency && + (score < n_score))))))) { choice = n_choice; latency = n_latency; score = n_score; diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/library_call.cpp --- a/src/share/vm/opto/library_call.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/library_call.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1481,10 +1481,10 @@ Node* arg = round_double_node(argument(0)); Node* n; switch (id) { - case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break; - case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(0, arg); break; - case vmIntrinsics::_dlog: n = new (C) LogDNode( arg); break; - case vmIntrinsics::_dlog10: n = new (C) Log10DNode( arg); break; + case vmIntrinsics::_dabs: n = new (C) AbsDNode( arg); break; + case vmIntrinsics::_dsqrt: n = new (C) SqrtDNode(C, control(), arg); break; + case vmIntrinsics::_dlog: n = new (C) LogDNode(C, control(), arg); break; + case vmIntrinsics::_dlog10: n = new (C) Log10DNode(C, control(), arg); break; default: fatal_unexpected_iid(id); break; } set_result(_gvn.transform(n)); @@ -1499,9 +1499,9 @@ Node* n = NULL; switch (id) { - case vmIntrinsics::_dsin: n = new (C) SinDNode(arg); break; - case vmIntrinsics::_dcos: n = new (C) CosDNode(arg); break; - case vmIntrinsics::_dtan: n = new (C) TanDNode(arg); break; + case vmIntrinsics::_dsin: n = new (C) SinDNode(C, control(), arg); break; + case vmIntrinsics::_dcos: n = new (C) CosDNode(C, control(), arg); break; + case vmIntrinsics::_dtan: n = new (C) TanDNode(C, control(), arg); break; default: fatal_unexpected_iid(id); break; } n = _gvn.transform(n); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/macro.cpp --- a/src/share/vm/opto/macro.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/macro.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1101,12 +1101,6 @@ Node* klass_node = alloc->in(AllocateNode::KlassNode); Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); - Node* storestore = alloc->storestore(); - if (storestore != NULL) { - // Break this link that is no longer useful and confuses register allocation - storestore->set_req(MemBarNode::Precedent, top()); - } - assert(ctrl != NULL, "must have control"); // We need a Region and corresponding Phi's to merge the slow-path and fast-path results. // they will not be used if "always_slow" is set @@ -1324,7 +1318,7 @@ // No InitializeNode or no stores captured by zeroing // elimination. Simply add the MemBarStoreStore after object // initialization. - MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot, fast_oop_rawmem); + MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); transform_later(mb); mb->init_req(TypeFunc::Memory, fast_oop_rawmem); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/memnode.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -238,7 +238,7 @@ return this; ctl = in(MemNode::Control); // Don't bother trying to transform a dead node - if( ctl && ctl->is_top() ) return NodeSentinel; + if (ctl && ctl->is_top()) return NodeSentinel; PhaseIterGVN *igvn = phase->is_IterGVN(); // Wait if control on the worklist. @@ -262,8 +262,8 @@ } // Ignore if memory is dead, or self-loop Node *mem = in(MemNode::Memory); - if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL - assert( mem != this, "dead loop in MemNode::Ideal" ); + if (phase->type( mem ) == Type::TOP) return NodeSentinel; // caller will return NULL + assert(mem != this, "dead loop in MemNode::Ideal"); if (can_reshape && igvn != NULL && igvn->_worklist.member(mem)) { // This memory slice may be dead. @@ -273,12 +273,12 @@ } Node *address = in(MemNode::Address); - const Type *t_adr = phase->type( address ); - if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL - - if( can_reshape && igvn != NULL && + const Type *t_adr = phase->type(address); + if (t_adr == Type::TOP) return NodeSentinel; // caller will return NULL + + if (can_reshape && igvn != NULL && (igvn->_worklist.member(address) || - igvn->_worklist.size() > 0 && (phase->type(address) != adr_type())) ) { + igvn->_worklist.size() > 0 && (t_adr != adr_type())) ) { // The address's base and type may change when the address is processed. // Delay this mem node transformation until the address is processed. phase->is_IterGVN()->_worklist.push(this); @@ -288,7 +288,7 @@ // Do NOT remove or optimize the next lines: ensure a new alias index // is allocated for an oop pointer type before Escape Analysis. // Note: C++ will not remove it since the call has side effect. - if ( t_adr->isa_oopptr() ) { + if (t_adr->isa_oopptr()) { int alias_idx = phase->C->get_alias_index(t_adr->is_ptr()); } @@ -296,6 +296,26 @@ Node* base = NULL; if (address->is_AddP()) base = address->in(AddPNode::Base); + if (base != NULL && phase->type(base)->higher_equal(TypePtr::NULL_PTR) && + !t_adr->isa_rawptr()) { + // Note: raw address has TOP base and top->higher_equal(TypePtr::NULL_PTR) is true. + Compile* C = phase->C; + tty->cr(); + tty->print_cr("===== NULL+offs not RAW address ====="); + if (C->is_dead_node(this->_idx)) tty->print_cr("'this' is dead"); + if ((ctl != NULL) && C->is_dead_node(ctl->_idx)) tty->print_cr("'ctl' is dead"); + if (C->is_dead_node(mem->_idx)) tty->print_cr("'mem' is dead"); + if (C->is_dead_node(address->_idx)) tty->print_cr("'address' is dead"); + if (C->is_dead_node(base->_idx)) tty->print_cr("'base' is dead"); + tty->cr(); + base->dump(1); + tty->cr(); + this->dump(2); + tty->print("this->adr_type(): "); adr_type()->dump(); tty->cr(); + tty->print("phase->type(address): "); t_adr->dump(); tty->cr(); + tty->print("phase->type(base): "); phase->type(address)->dump(); tty->cr(); + tty->cr(); + } assert(base == NULL || t_adr->isa_rawptr() || !phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?"); #endif @@ -320,6 +340,9 @@ if (mem != old_mem) { set_req(MemNode::Memory, mem); + if (can_reshape && old_mem->outcnt() == 0) { + igvn->_worklist.push(old_mem); + } if (phase->type( mem ) == Type::TOP) return NodeSentinel; return this; } @@ -2319,9 +2342,9 @@ if (ReduceFieldZeroing && /*can_reshape &&*/ mem->is_Proj() && mem->in(0)->is_Initialize()) { InitializeNode* init = mem->in(0)->as_Initialize(); - intptr_t offset = init->can_capture_store(this, phase); + intptr_t offset = init->can_capture_store(this, phase, can_reshape); if (offset > 0) { - Node* moved = init->capture_store(this, offset, phase); + Node* moved = init->capture_store(this, offset, phase, can_reshape); // If the InitializeNode captured me, it made a raw copy of me, // and I need to disappear. if (moved != NULL) { @@ -3134,7 +3157,7 @@ // an initialization. Returns zero if a check fails. // On success, returns the (constant) offset to which the store applies, // within the initialized memory. -intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) { +intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape) { const int FAIL = 0; if (st->req() != MemNode::ValueIn + 1) return FAIL; // an inscrutable StoreNode (card mark?) @@ -3156,6 +3179,91 @@ if (!detect_init_independence(val, true, complexity_count)) return FAIL; // stored value must be 'simple enough' + // The Store can be captured only if nothing after the allocation + // and before the Store is using the memory location that the store + // overwrites. + bool failed = false; + // If is_complete_with_arraycopy() is true the shape of the graph is + // well defined and is safe so no need for extra checks. + if (!is_complete_with_arraycopy()) { + // We are going to look at each use of the memory state following + // the allocation to make sure nothing reads the memory that the + // Store writes. + const TypePtr* t_adr = phase->type(adr)->isa_ptr(); + int alias_idx = phase->C->get_alias_index(t_adr); + ResourceMark rm; + Unique_Node_List mems; + mems.push(mem); + Node* unique_merge = NULL; + for (uint next = 0; next < mems.size(); ++next) { + Node *m = mems.at(next); + for (DUIterator_Fast jmax, j = m->fast_outs(jmax); j < jmax; j++) { + Node *n = m->fast_out(j); + if (n->outcnt() == 0) { + continue; + } + if (n == st) { + continue; + } else if (n->in(0) != NULL && n->in(0) != ctl) { + // If the control of this use is different from the control + // of the Store which is right after the InitializeNode then + // this node cannot be between the InitializeNode and the + // Store. + continue; + } else if (n->is_MergeMem()) { + if (n->as_MergeMem()->memory_at(alias_idx) == m) { + // We can hit a MergeMemNode (that will likely go away + // later) that is a direct use of the memory state + // following the InitializeNode on the same slice as the + // store node that we'd like to capture. We need to check + // the uses of the MergeMemNode. + mems.push(n); + } + } else if (n->is_Mem()) { + Node* other_adr = n->in(MemNode::Address); + if (other_adr == adr) { + failed = true; + break; + } else { + const TypePtr* other_t_adr = phase->type(other_adr)->isa_ptr(); + if (other_t_adr != NULL) { + int other_alias_idx = phase->C->get_alias_index(other_t_adr); + if (other_alias_idx == alias_idx) { + // A load from the same memory slice as the store right + // after the InitializeNode. We check the control of the + // object/array that is loaded from. If it's the same as + // the store control then we cannot capture the store. + assert(!n->is_Store(), "2 stores to same slice on same control?"); + Node* base = other_adr; + assert(base->is_AddP(), err_msg_res("should be addp but is %s", base->Name())); + base = base->in(AddPNode::Base); + if (base != NULL) { + base = base->uncast(); + if (base->is_Proj() && base->in(0) == alloc) { + failed = true; + break; + } + } + } + } + } + } else { + failed = true; + break; + } + } + } + } + if (failed) { + if (!can_reshape) { + // We decided we couldn't capture the store during parsing. We + // should try again during the next IGVN once the graph is + // cleaner. + phase->C->record_for_igvn(st); + } + return FAIL; + } + return offset; // success } @@ -3266,11 +3374,11 @@ // rawstore1 rawstore2) // Node* InitializeNode::capture_store(StoreNode* st, intptr_t start, - PhaseTransform* phase) { + PhaseTransform* phase, bool can_reshape) { assert(stores_are_sane(phase), ""); if (start < 0) return NULL; - assert(can_capture_store(st, phase) == start, "sanity"); + assert(can_capture_store(st, phase, can_reshape) == start, "sanity"); Compile* C = phase->C; int size_in_bytes = st->memory_size(); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/memnode.hpp --- a/src/share/vm/opto/memnode.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/memnode.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -1072,11 +1072,11 @@ // See if this store can be captured; return offset where it initializes. // Return 0 if the store cannot be moved (any sort of problem). - intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase); + intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase, bool can_reshape); // Capture another store; reformat it to write my internal raw memory. // Return the captured copy, else NULL if there is some sort of problem. - Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase); + Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase, bool can_reshape); // Find captured store which corresponds to the range [start..start+size). // Return my own memory projection (meaning the initial zero bits) diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/node.cpp --- a/src/share/vm/opto/node.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/node.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1261,6 +1261,7 @@ if (dead->is_expensive()) { igvn->C->remove_expensive_node(dead); } + igvn->C->record_dead_node(dead->_idx); // Kill all inputs to the dead guy for (uint i=0; i < dead->req(); i++) { Node *n = dead->in(i); // Get input to dead guy diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/parse.hpp --- a/src/share/vm/opto/parse.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/parse.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -58,7 +58,7 @@ GrowableArray _subtrees; void print_impl(outputStream* stj, int indent) const PRODUCT_RETURN; - + const char* _msg; protected: InlineTree(Compile* C, const InlineTree* caller_tree, @@ -70,17 +70,29 @@ InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, JVMState* caller_jvms, int caller_bci); - const char* try_to_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result, bool& should_delay); - const char* should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const; - const char* should_not_inline(ciMethod* callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const; + bool try_to_inline(ciMethod* callee_method, + ciMethod* caller_method, + int caller_bci, + ciCallProfile& profile, + WarmCallInfo* wci_result, + bool& should_delay); + bool should_inline(ciMethod* callee_method, + ciMethod* caller_method, + int caller_bci, + ciCallProfile& profile, + WarmCallInfo* wci_result); + bool should_not_inline(ciMethod* callee_method, + ciMethod* caller_method, + WarmCallInfo* wci_result); void print_inlining(ciMethod* callee_method, int caller_bci, - const char* msg, bool success) const; + bool success) const; - InlineTree *caller_tree() const { return _caller_tree; } + InlineTree* caller_tree() const { return _caller_tree; } InlineTree* callee_at(int bci, ciMethod* m) const; int inline_level() const { return stack_depth(); } int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } - + const char* msg() const { return _msg; } + void set_msg(const char* msg) { _msg = msg; } public: static const char* check_can_parse(ciMethod* callee); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/phaseX.cpp --- a/src/share/vm/opto/phaseX.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/phaseX.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1197,6 +1197,18 @@ assert(!(i < imax), "sanity"); } } + if (ReduceFieldZeroing && dead->is_Load() && i == MemNode::Memory && + in->is_Proj() && in->in(0) != NULL && in->in(0)->is_Initialize()) { + // A Load that directly follows an InitializeNode is + // going away. The Stores that follow are candidates + // again to be captured by the InitializeNode. + for (DUIterator_Fast jmax, j = in->fast_outs(jmax); j < jmax; j++) { + Node *n = in->fast_out(j); + if (n->is_Store()) { + _worklist.push(n); + } + } + } } } C->record_dead_node(dead->_idx); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/subnode.hpp --- a/src/share/vm/opto/subnode.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/subnode.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -399,7 +399,10 @@ // Cosinus of a double class CosDNode : public Node { public: - CosDNode( Node *in1 ) : Node(0, in1) {} + CosDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } virtual int Opcode() const; const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } @@ -410,7 +413,10 @@ // Sinus of a double class SinDNode : public Node { public: - SinDNode( Node *in1 ) : Node(0, in1) {} + SinDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } virtual int Opcode() const; const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } @@ -422,7 +428,10 @@ // tangens of a double class TanDNode : public Node { public: - TanDNode(Node *in1 ) : Node(0, in1) {} + TanDNode(Compile* C, Node *c,Node *in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } virtual int Opcode() const; const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } @@ -445,7 +454,10 @@ // square root a double class SqrtDNode : public Node { public: - SqrtDNode(Node *c, Node *in1 ) : Node(c, in1) {} + SqrtDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } virtual int Opcode() const; const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } @@ -470,7 +482,10 @@ // Log_e of a double class LogDNode : public Node { public: - LogDNode( Node *in1 ) : Node(0, in1) {} + LogDNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } virtual int Opcode() const; const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } @@ -481,7 +496,10 @@ // Log_10 of a double class Log10DNode : public Node { public: - Log10DNode( Node *in1 ) : Node(0, in1) {} + Log10DNode(Compile* C, Node *c, Node *in1) : Node(c, in1) { + init_flags(Flag_is_expensive); + C->add_expensive_node(this); + } virtual int Opcode() const; const Type *bottom_type() const { return Type::DOUBLE; } virtual uint ideal_reg() const { return Op_RegD; } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/superword.cpp --- a/src/share/vm/opto/superword.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/superword.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -143,7 +143,8 @@ // Ready the block - construct_bb(); + if (!construct_bb()) + return; // Exit if no interesting nodes or complex graph. dependence_graph(); @@ -615,6 +616,7 @@ if (n == stop) break; preds.push(n); prev = n; + assert(n->is_Mem(), err_msg_res("unexpected node %s", n->Name())); n = n->in(MemNode::Memory); } } @@ -1578,7 +1580,7 @@ //------------------------------construct_bb--------------------------- // Construct reverse postorder list of block members -void SuperWord::construct_bb() { +bool SuperWord::construct_bb() { Node* entry = bb(); assert(_stk.length() == 0, "stk is empty"); @@ -1596,6 +1598,12 @@ Node *n = lpt()->_body.at(i); set_bb_idx(n, i); // Create a temporary map if (in_bb(n)) { + if (n->is_LoadStore() || n->is_MergeMem() || + (n->is_Proj() && !n->as_Proj()->is_CFG())) { + // Bailout if the loop has LoadStore, MergeMem or data Proj + // nodes. Superword optimization does not work with them. + return false; + } bb_ct++; if (!n->is_CFG()) { bool found = false; @@ -1620,6 +1628,10 @@ if (in_bb(n) && (n->is_Phi() && n->bottom_type() == Type::MEMORY)) { Node* n_tail = n->in(LoopNode::LoopBackControl); if (n_tail != n->in(LoopNode::EntryControl)) { + if (!n_tail->is_Mem()) { + assert(n_tail->is_Mem(), err_msg_res("unexpected node for memory slice: %s", n_tail->Name())); + return false; // Bailout + } _mem_slice_head.push(n); _mem_slice_tail.push(n_tail); } @@ -1695,6 +1707,7 @@ } #endif assert(rpo_idx == -1 && bb_ct == _block.length(), "all block members found"); + return (_mem_slice_head.length() > 0) || (_data_entry.length() > 0); } //------------------------------initialize_bb--------------------------- diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/opto/superword.hpp --- a/src/share/vm/opto/superword.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/opto/superword.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -380,7 +380,7 @@ // Is use->in(u_idx) a vector use? bool is_vector_use(Node* use, int u_idx); // Construct reverse postorder list of block members - void construct_bb(); + bool construct_bb(); // Initialize per node info void initialize_bb(); // Insert n into block after pos diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/prims/jvmtiEnter.xsl --- a/src/share/vm/prims/jvmtiEnter.xsl Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/prims/jvmtiEnter.xsl Tue Mar 12 18:22:40 2013 -0700 @@ -773,7 +773,7 @@ JVMTI_ERROR_INVALID_THREAD - - jthread resolved to NULL - jthread = %0x%x + - jthread resolved to NULL - jthread = 0x%x , @@ -782,7 +782,7 @@ JVMTI_ERROR_INVALID_THREAD - - oop is not a thread - jthread = %0x%x + - oop is not a thread - jthread = 0x%x , @@ -794,7 +794,7 @@ JVMTI_ERROR_THREAD_NOT_ALIVE - - not a Java thread - jthread = %0x%x + - not a Java thread - jthread = 0x%x , @@ -838,7 +838,7 @@ JVMTI_ERROR_ILLEGAL_ARGUMENT - - negative depth - jthread = %0x%x + - negative depth - jthread = 0x%x , diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/prims/jvmtiEnvBase.cpp --- a/src/share/vm/prims/jvmtiEnvBase.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/prims/jvmtiEnvBase.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -997,13 +997,19 @@ // move our object at this point. However, our owner value is safe // since it is either the Lock word on a stack or a JavaThread *. owning_thread = Threads::owning_thread_from_monitor_owner(owner, !at_safepoint); - assert(owning_thread != NULL, "sanity check"); - if (owning_thread != NULL) { // robustness + // Cannot assume (owning_thread != NULL) here because this function + // may not have been called at a safepoint and the owning_thread + // might not be suspended. + if (owning_thread != NULL) { // The monitor's owner either has to be the current thread, at safepoint // or it has to be suspended. Any of these conditions will prevent both // contending and waiting threads from modifying the state of // the monitor. if (!at_safepoint && !JvmtiEnv::is_thread_fully_suspended(owning_thread, true, &debug_bits)) { + // Don't worry! This return of JVMTI_ERROR_THREAD_NOT_SUSPENDED + // will not make it back to the JVM/TI agent. The error code will + // get intercepted in JvmtiEnv::GetObjectMonitorUsage() which + // will retry the call via a VM_GetObjectMonitorUsage VM op. return JVMTI_ERROR_THREAD_NOT_SUSPENDED; } HandleMark hm; diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1558,6 +1558,18 @@ } break; } } // end for each bytecode + + // We also need to rewrite the parameter name indexes, if there is + // method parameter data present + if(method->has_method_parameters()) { + const int len = method->method_parameters_length(); + MethodParametersElement* elem = method->method_parameters_start(); + + for (int i = 0; i < len; i++) { + const u2 cp_index = elem[i].name_cp_index; + elem[i].name_cp_index = find_new_index(cp_index); + } + } } // end rewrite_cp_refs_in_method() diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/arguments.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1738,16 +1738,6 @@ return false; } -static void force_serial_gc() { - FLAG_SET_DEFAULT(UseSerialGC, true); - FLAG_SET_DEFAULT(UseParNewGC, false); - FLAG_SET_DEFAULT(UseConcMarkSweepGC, false); - FLAG_SET_DEFAULT(CMSIncrementalMode, false); // special CMS suboption - FLAG_SET_DEFAULT(UseParallelGC, false); - FLAG_SET_DEFAULT(UseParallelOldGC, false); - FLAG_SET_DEFAULT(UseG1GC, false); -} - static bool verify_serial_gc_flags() { return (UseSerialGC && !(UseParNewGC || (UseConcMarkSweepGC || CMSIncrementalMode) || UseG1GC || @@ -2191,19 +2181,6 @@ FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal); } - if (WhiteBoxAPI) { - // Append wb.jar to bootclasspath if enabled - const char* wb_jar = "wb.jar"; - size_t wb_path_len = strlen(get_meta_index_dir()) + 1 + - strlen(wb_jar); - char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len, mtInternal); - strcpy(wb_path, get_meta_index_dir()); - strcat(wb_path, wb_jar); - scp.add_suffix(wb_path); - scp_assembly_required = true; - FREE_C_HEAP_ARRAY(char, wb_path, mtInternal); - } - // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM) result = parse_java_options_environment_variable(&scp, &scp_assembly_required); if (result != JNI_OK) { @@ -2498,7 +2475,12 @@ } // Out of the box management support if (match_option(option, "-Dcom.sun.management", &tail)) { +#if INCLUDE_MANAGEMENT FLAG_SET_CMDLINE(bool, ManagementServer, true); +#else + vm_exit_during_initialization( + "-Dcom.sun.management is not supported in this VM.", NULL); +#endif } // -Xint } else if (match_option(option, "-Xint", &tail)) { @@ -2844,6 +2826,11 @@ // away and will cause VM initialization failures! warning("-XX:+UseVMInterruptibleIO is obsolete and will be removed in a future release."); FLAG_SET_CMDLINE(bool, UseVMInterruptibleIO, true); +#if !INCLUDE_MANAGEMENT + } else if (match_option(option, "-XX:+ManagementServer", &tail)) { + vm_exit_during_initialization( + "ManagementServer is not supported in this VM.", NULL); +#endif // INCLUDE_MANAGEMENT } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx // Skip -XX:Flags= since that case has already been handled if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) { @@ -3072,6 +3059,27 @@ } \ } while(0) + +#define UNSUPPORTED_GC_OPTION(gc) \ +do { \ + if (gc) { \ + if (FLAG_IS_CMDLINE(gc)) { \ + warning(#gc " is not supported in this VM. Using Serial GC."); \ + } \ + FLAG_SET_DEFAULT(gc, false); \ + } \ +} while(0) + +static void force_serial_gc() { + FLAG_SET_DEFAULT(UseSerialGC, true); + FLAG_SET_DEFAULT(CMSIncrementalMode, false); // special CMS suboption + UNSUPPORTED_GC_OPTION(UseG1GC); + UNSUPPORTED_GC_OPTION(UseParallelGC); + UNSUPPORTED_GC_OPTION(UseParallelOldGC); + UNSUPPORTED_GC_OPTION(UseConcMarkSweepGC); + UNSUPPORTED_GC_OPTION(UseParNewGC); +} + // Parse entry point called from JNI_CreateJavaVM jint Arguments::parse(const JavaVMInitArgs* args) { @@ -3187,28 +3195,15 @@ hotspotrc, hotspotrc); } -#if (defined JAVASE_EMBEDDED || defined ARM) - UNSUPPORTED_OPTION(UseG1GC, "G1 GC"); -#endif - #ifdef _ALLBSD_SOURCE // UseLargePages is not yet supported on BSD. UNSUPPORTED_OPTION(UseLargePages, "-XX:+UseLargePages"); #endif -#if !INCLUDE_ALL_GCS - if (UseParallelGC) { - warning("Parallel GC is not supported in this VM. Using Serial GC."); - } - if (UseParallelOldGC) { - warning("Parallel Old GC is not supported in this VM. Using Serial GC."); - } - if (UseConcMarkSweepGC) { - warning("Concurrent Mark Sweep GC is not supported in this VM. Using Serial GC."); - } - if (UseParNewGC) { - warning("Par New GC is not supported in this VM. Using Serial GC."); - } -#endif // INCLUDE_ALL_GCS +#if INCLUDE_ALL_GCS + #if (defined JAVASE_EMBEDDED || defined ARM) + UNSUPPORTED_OPTION(UseG1GC, "G1 GC"); + #endif +#endif #ifndef PRODUCT if (TraceBytecodesAt != 0) { diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/atomic.hpp --- a/src/share/vm/runtime/atomic.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/atomic.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -29,10 +29,17 @@ class Atomic : AllStatic { public: + // Atomic operations on jlong types are not available on all 32-bit + // platforms. If atomic ops on jlongs are defined here they must only + // be used from code that verifies they are available at runtime and + // can provide an alternative action if not - see supports_cx8() for + // a means to test availability. + // Atomically store to a location inline static void store (jbyte store_value, jbyte* dest); inline static void store (jshort store_value, jshort* dest); inline static void store (jint store_value, jint* dest); + // See comment above about using jlong atomics on 32-bit platforms inline static void store (jlong store_value, jlong* dest); inline static void store_ptr(intptr_t store_value, intptr_t* dest); inline static void store_ptr(void* store_value, void* dest); @@ -40,17 +47,19 @@ inline static void store (jbyte store_value, volatile jbyte* dest); inline static void store (jshort store_value, volatile jshort* dest); inline static void store (jint store_value, volatile jint* dest); + // See comment above about using jlong atomics on 32-bit platforms inline static void store (jlong store_value, volatile jlong* dest); inline static void store_ptr(intptr_t store_value, volatile intptr_t* dest); inline static void store_ptr(void* store_value, volatile void* dest); + // See comment above about using jlong atomics on 32-bit platforms inline static jlong load(volatile jlong* src); // Atomically add to a location, return updated value inline static jint add (jint add_value, volatile jint* dest); inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest); inline static void* add_ptr(intptr_t add_value, volatile void* dest); - + // See comment above about using jlong atomics on 32-bit platforms static jlong add (jlong add_value, volatile jlong* dest); // Atomically increment location @@ -75,6 +84,7 @@ // barrier across the cmpxchg. I.e., it's really a 'fence_cmpxchg_acquire'. static jbyte cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value); inline static jint cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value); + // See comment above about using jlong atomics on 32-bit platforms inline static jlong cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value); static unsigned int cmpxchg(unsigned int exchange_value, diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/frame.cpp --- a/src/share/vm/runtime/frame.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/frame.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -1070,7 +1070,12 @@ // First consult the ADLC on where it puts parameter 0 for this signature. VMReg reg = SharedRuntime::name_for_receiver(); - oop r = *caller.oopmapreg_to_location(reg, reg_map); + oop* oop_adr = caller.oopmapreg_to_location(reg, reg_map); + if (oop_adr == NULL) { + guarantee(oop_adr != NULL, "bad register save location"); + return NULL; + } + oop r = *oop_adr; assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (intptr_t) r, (intptr_t) r)); return r; } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/globals.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -1751,6 +1751,10 @@ manageable(intx, CMSWaitDuration, 2000, \ "Time in milliseconds that CMS thread waits for young GC") \ \ + develop(uintx, CMSCheckInterval, 1000, \ + "Interval in milliseconds that CMS thread checks if it " \ + "should start a collection cycle") \ + \ product(bool, CMSYield, true, \ "Yield between steps of concurrent mark & sweep") \ \ diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/synchronizer.cpp --- a/src/share/vm/runtime/synchronizer.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/synchronizer.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -813,6 +813,7 @@ } if (owner != NULL) { + // owning_thread_from_monitor_owner() may also return NULL here return Threads::owning_thread_from_monitor_owner(owner, doLock); } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/thread.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -4285,7 +4285,9 @@ if (owner == (address)p) return p; } } - assert(UseHeavyMonitors == false, "Did not find owning Java thread with UseHeavyMonitors enabled"); + // Cannot assert on lack of success here since this function may be + // used by code that is trying to report useful problem information + // like deadlock detection. if (UseHeavyMonitors) return NULL; // @@ -4303,7 +4305,7 @@ } } } - assert(the_owner != NULL, "Did not find owning Java thread for lock word address"); + // cannot assert on lack of success here; see above comment return the_owner; } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/runtime/vmStructs.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -2109,8 +2109,6 @@ /* Useful globals */ \ /******************/ \ \ - declare_constant(UseTLAB) \ - declare_constant(EnableInvokeDynamic) \ \ /**************/ \ /* Stack bias */ \ diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/services/memReporter.cpp --- a/src/share/vm/services/memReporter.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/services/memReporter.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -419,7 +419,7 @@ _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); _output->print("%28s", " "); } else { - _output->print("[" PTR_FORMAT "]%18s", " "); + _output->print("[" PTR_FORMAT "]%18s", pc, " "); } _output->print_cr("(mmap: reserved=%d%s, committed=%d%s)", @@ -596,7 +596,7 @@ _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); _output->print("%28s", " "); } else { - _output->print("[" PTR_FORMAT "]%18s", " "); + _output->print("[" PTR_FORMAT "]%18s", pc, " "); } } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/services/memSnapshot.cpp --- a/src/share/vm/services/memSnapshot.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/services/memSnapshot.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -528,7 +528,8 @@ // an arena record can be followed by a size record, we need to remove both if (matched_rec->is_arena_record()) { MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next(); - if (next->is_arena_memory_record() && next->is_memory_record_of_arena(matched_rec)) { + if (next != NULL && next->is_arena_memory_record() && + next->is_memory_record_of_arena(matched_rec)) { malloc_snapshot_itr.remove(); } } diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/services/threadService.cpp 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 @@ -327,8 +327,28 @@ while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) { cycle->add_thread(currentThread); if (waitingToLockMonitor != NULL) { - currentThread = Threads::owning_thread_from_monitor_owner((address)waitingToLockMonitor->owner(), - false /* no locking needed */); + currentThread = Threads::owning_thread_from_monitor_owner( + (address)waitingToLockMonitor->owner(), + false /* no locking needed */); + if (currentThread == NULL) { + // This function is called at a safepoint so the JavaThread + // that owns waitingToLockMonitor should be findable, but + // if it is not findable, then the previous currentThread is + // blocked permanently. We record this as a deadlock. + num_deadlocks++; + + cycle->set_deadlock(true); + + // add this cycle to the deadlocks list + if (deadlocks == NULL) { + deadlocks = cycle; + } else { + last->set_next(cycle); + } + last = cycle; + cycle = new DeadlockCycle(); + break; + } } else { if (concurrent_locks) { if (waitingToLockBlocker->is_a(SystemDictionary::abstract_ownable_synchronizer_klass())) { @@ -841,7 +861,17 @@ owner_desc = " (JVMTI raw monitor),\n which is held by"; } currentThread = Threads::owning_thread_from_monitor_owner( - (address)waitingToLockMonitor->owner(), false /* no locking needed */); + (address)waitingToLockMonitor->owner(), + false /* no locking needed */); + if (currentThread == NULL) { + // The deadlock was detected at a safepoint so the JavaThread + // that owns waitingToLockMonitor should be findable, but + // if it is not findable, then the previous currentThread is + // blocked permanently. + st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc, + (address)waitingToLockMonitor->owner()); + continue; + } } else { st->print(" waiting for ownable synchronizer " INTPTR_FORMAT ", (a %s)", (address)waitingToLockBlocker, diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/constantTag.cpp --- a/src/share/vm/utilities/constantTag.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/constantTag.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 @@ -52,7 +52,6 @@ case JVM_CONSTANT_StringIndex : case JVM_CONSTANT_MethodHandle : case JVM_CONSTANT_MethodType : - case JVM_CONSTANT_Object : return T_OBJECT; default: ShouldNotReachHere(); @@ -96,8 +95,6 @@ return "MethodType Error"; case JVM_CONSTANT_InvokeDynamic : return "InvokeDynamic"; - case JVM_CONSTANT_Object : - return "Object"; case JVM_CONSTANT_Utf8 : return "Utf8"; case JVM_CONSTANT_UnresolvedClass : diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/constantTag.hpp --- a/src/share/vm/utilities/constantTag.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/constantTag.hpp 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 @@ -43,8 +43,7 @@ JVM_CONSTANT_UnresolvedClassInError = 103, // Error tag due to resolution error JVM_CONSTANT_MethodHandleInError = 104, // Error tag due to resolution error JVM_CONSTANT_MethodTypeInError = 105, // Error tag due to resolution error - JVM_CONSTANT_Object = 106, // Required for BoundMethodHandle arguments. - JVM_CONSTANT_InternalMax = 106 // Last implementation tag + JVM_CONSTANT_InternalMax = 105 // Last implementation tag }; @@ -84,8 +83,6 @@ bool is_klass_index() const { return _tag == JVM_CONSTANT_ClassIndex; } bool is_string_index() const { return _tag == JVM_CONSTANT_StringIndex; } - bool is_object() const { return _tag == JVM_CONSTANT_Object; } - bool is_klass_reference() const { return is_klass_index() || is_unresolved_klass(); } bool is_klass_or_reference() const{ return is_klass() || is_klass_reference(); } bool is_field_or_method() const { return is_field() || is_method() || is_interface_method(); } @@ -98,7 +95,7 @@ bool is_loadable_constant() const { return ((_tag >= JVM_CONSTANT_Integer && _tag <= JVM_CONSTANT_String) || is_method_type() || is_method_handle() || - is_unresolved_klass() || is_object()); + is_unresolved_klass()); } constantTag() { diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/debug.cpp --- a/src/share/vm/utilities/debug.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/debug.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 @@ -228,28 +228,16 @@ report_vm_error(file, line, "fatal error", message); } -// Used by report_vm_out_of_memory to detect recursion. -static jint _exiting_out_of_mem = 0; - void report_vm_out_of_memory(const char* file, int line, size_t size, const char* message) { if (Debugging) return; - // We try to gather additional information for the first out of memory - // error only; gathering additional data might cause an allocation and a - // recursive out_of_memory condition. - - const jint exiting = 1; - // If we succeed in changing the value, we're the first one in. - bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting; + Thread* thread = ThreadLocalStorage::get_thread_slow(); + VMError(thread, file, line, size, message).report_and_die(); - if (first_time_here) { - Thread* thread = ThreadLocalStorage::get_thread_slow(); - VMError(thread, file, line, size, message).report_and_die(); - } - - // Dump core and abort - vm_abort(true); + // The UseOSErrorReporting option in report_and_die() may allow a return + // to here. If so then we'll have to figure out how to handle it. + guarantee(false, "report_and_die() should not return here"); } void report_should_not_call(const char* file, int line) { diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/numberSeq.cpp --- a/src/share/vm/utilities/numberSeq.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/numberSeq.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -245,7 +245,7 @@ void NumberSeq::dump_on(outputStream* s) { AbsSeq::dump_on(s); - s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f"); + s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f", _last, _maximum); } void TruncatedSeq::dump_on(outputStream* s) { diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/ostream.cpp --- a/src/share/vm/utilities/ostream.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/ostream.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -431,7 +431,7 @@ rotatingFileStream::rotatingFileStream(const char* file_name) { _cur_file_num = 0; - _bytes_writen = 0L; + _bytes_written = 0L; _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); _file = fopen(_file_name, "w"); @@ -440,7 +440,7 @@ rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) { _cur_file_num = 0; - _bytes_writen = 0L; + _bytes_written = 0L; _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal); jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num); _file = fopen(_file_name, opentype); @@ -448,10 +448,9 @@ } void rotatingFileStream::write(const char* s, size_t len) { - if (_file != NULL) { - // Make an unused local variable to avoid warning from gcc 4.x compiler. + if (_file != NULL) { size_t count = fwrite(s, 1, len, _file); - Atomic::add((jlong)count, &_bytes_writen); + _bytes_written += count; } update_position(s, len); } @@ -465,7 +464,10 @@ // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log // must be synchronized. void rotatingFileStream::rotate_log() { - if (_bytes_writen < (jlong)GCLogFileSize) return; + if (_bytes_written < (jlong)GCLogFileSize) { + return; + } + #ifdef ASSERT Thread *thread = Thread::current(); assert(thread == NULL || @@ -475,7 +477,7 @@ if (NumberOfGCLogFiles == 1) { // rotate in same file rewind(); - _bytes_writen = 0L; + _bytes_written = 0L; return; } @@ -491,7 +493,7 @@ } _file = fopen(_file_name, "w"); if (_file != NULL) { - _bytes_writen = 0L; + _bytes_written = 0L; _need_close = true; } else { tty->print_cr("failed to open rotation log file %s due to %s\n", diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/ostream.hpp --- a/src/share/vm/utilities/ostream.hpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/ostream.hpp Tue Mar 12 18:22:40 2013 -0700 @@ -231,7 +231,7 @@ class rotatingFileStream : public fileStream { protected: char* _file_name; - jlong _bytes_writen; + jlong _bytes_written; uintx _cur_file_num; // current logfile rotation number, from 0 to MaxGCLogFileNumbers-1 public: rotatingFileStream(const char* file_name); diff -r d4a32a6f8c82 -r 11d5942ef9c7 src/share/vm/utilities/yieldingWorkgroup.cpp --- a/src/share/vm/utilities/yieldingWorkgroup.cpp Mon Feb 25 07:22:06 2013 +0100 +++ b/src/share/vm/utilities/yieldingWorkgroup.cpp Tue Mar 12 18:22:40 2013 -0700 @@ -24,9 +24,7 @@ #include "precompiled.hpp" #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS #include "utilities/yieldingWorkgroup.hpp" -#endif // INCLUDE_ALL_GCS // Forward declaration of classes declared here. diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/TEST.ROOT --- a/test/TEST.ROOT Mon Feb 25 07:22:06 2013 +0100 +++ b/test/TEST.ROOT Tue Mar 12 18:22:40 2013 -0700 @@ -28,4 +28,4 @@ # DO NOT EDIT without first contacting hotspot-regtest@sun.com # The list of keywords supported in this test suite -keys=cte_test jcmd nmt regression +keys=cte_test jcmd nmt regression gc diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/5091921/Test6850611.java --- a/test/compiler/5091921/Test6850611.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/5091921/Test6850611.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @bug 6850611 * @summary int / long arithmetic seems to be broken in 1.6.0_14 HotSpot Server VM (Win XP) * - * @run main Test6850611 + * @run main/timeout=480 Test6850611 */ public class Test6850611 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/5091921/Test6890943.java --- a/test/compiler/5091921/Test6890943.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/5091921/Test6890943.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @bug 6890943 * @summary JVM mysteriously gives wrong result on 64-bit 1.6 VMs in hotspot mode. * - * @run shell Test6890943.sh + * @run shell/timeout=240 Test6890943.sh */ import java.util.*; import java.io.*; diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/5091921/Test6890943.sh --- a/test/compiler/5091921/Test6890943.sh Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/5091921/Test6890943.sh Tue Mar 12 18:22:40 2013 -0700 @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,10 @@ ${TESTJAVA}/bin/javac -d . Test6890943.java -${TESTJAVA}/bin/java -XX:-PrintVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > test.out 2>&1 +${TESTJAVA}/bin/java -XX:-PrintVMOptions -XX:+IgnoreUnrecognizedVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > pretest.out 2>&1 + +# This test sometimes tickles an unrelated performance warning that interferes with diff. +grep -v 'warning: Performance bug: SystemDictionary' pretest.out > test.out diff output6890943.txt test.out diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/5091921/Test6905845.java --- a/test/compiler/5091921/Test6905845.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/5091921/Test6905845.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @bug 6905845 * @summary Server VM improperly optimizing away loop. * - * @run main Test6905845 + * @run main/timeout=480 Test6905845 */ public class Test6905845 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/5091921/Test6992759.java --- a/test/compiler/5091921/Test6992759.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/5091921/Test6992759.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @bug 6992759 * @summary Bad code generated for integer <= comparison, fails for Integer.MAX_VALUE * - * @run main Test6992759 + * @run main/timeout=240 Test6992759 */ public class Test6992759 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6431242/Test.java --- a/test/compiler/6431242/Test.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6431242/Test.java Tue Mar 12 18:22:40 2013 -0700 @@ -25,7 +25,7 @@ /* * @test * @bug 6431242 - * @run main/othervm -server -XX:+PrintCompilation Test + * @run main Test */ public class Test{ diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6589834/Test_ia32.java --- a/test/compiler/6589834/Test_ia32.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6589834/Test_ia32.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,7 +26,7 @@ * @bug 6589834 * @summary deoptimization problem with -XX:+DeoptimizeALot * - * @run main/othervm -server Test_ia32 + * @run main Test_ia32 */ /*************************************************************************************** diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6636138/Test1.java --- a/test/compiler/6636138/Test1.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6636138/Test1.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,7 +26,7 @@ * @bug 6636138 * @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation. * - * @run main/othervm -server -Xbatch -XX:CompileOnly=Test1.init Test1 + * @run main/othervm -Xbatch -XX:CompileOnly=Test1.init Test1 */ public class Test1 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6636138/Test2.java --- a/test/compiler/6636138/Test2.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6636138/Test2.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,7 +26,7 @@ * @bug 6636138 * @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation. * - * @run main/othervm -server -Xbatch -XX:CompileOnly=Test2.shift Test2 + * @run main/othervm -Xbatch -XX:CompileOnly=Test2.shift Test2 */ public class Test2 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6795161/Test.java --- a/test/compiler/6795161/Test.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6795161/Test.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,7 +26,7 @@ * @test * @bug 6795161 * @summary Escape analysis leads to data corruption - * @run main/othervm -server -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test */ class Test_Class_1 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6852078/Test6852078.java --- a/test/compiler/6852078/Test6852078.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6852078/Test6852078.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 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 @@ -27,7 +27,7 @@ * @bug 6852078 * @summary Disable SuperWord optimization for unsafe read/write * - * @run main/othervm Test6852078 + * @run main Test6852078 */ import java.util.*; @@ -50,7 +50,11 @@ } public static void main(String [] args) { + long start = System.currentTimeMillis(); for (int i=0; i<2000; i++) { + // To protect slow systems from test-too-long timeouts + if ((i > 100) && ((System.currentTimeMillis() - start) > 100000)) + break; Test6852078 t = new Test6852078(args); } } diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/6946040/TestCharShortByteSwap.java --- a/test/compiler/6946040/TestCharShortByteSwap.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/6946040/TestCharShortByteSwap.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,7 +26,7 @@ * @test * @bug 6946040 * @summary Tests Character/Short.reverseBytes and their intrinsics implementation in the server compiler - * @run main/othervm -Xbatch -server -XX:CompileOnly=.testChar,.testShort TestCharShortByteSwap + * @run main/othervm -Xbatch -XX:CompileOnly=.testChar,.testShort TestCharShortByteSwap */ // This test must run without any command line arguments. diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/7068051/Test7068051.sh --- a/test/compiler/7068051/Test7068051.sh Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/7068051/Test7068051.sh Tue Mar 12 18:22:40 2013 -0700 @@ -45,5 +45,5 @@ ${TESTJAVA}/bin/javac -d . Test7068051.java -${TESTJAVA}/bin/java -showversion -Xbatch ${TESTVMOPTS} Test7068051 foo.jar +${TESTJAVA}/bin/java ${TESTVMOPTS} -showversion -Xbatch Test7068051 foo.jar diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8000805/Test8000805.java --- a/test/compiler/8000805/Test8000805.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/8000805/Test8000805.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,7 +26,7 @@ * @bug 8000805 * @summary JMM issue: short loads are non-atomic * - * @run main/othervm -server -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805 */ public class Test8000805 { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8004867/TestIntAtomicCAS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8004867/TestIntAtomicCAS.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,969 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8004867 + * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" + * + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntAtomicCAS + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntAtomicCAS + */ + +import java.util.concurrent.atomic.AtomicIntegerArray; + +public class TestIntAtomicCAS { + private static final int ARRLEN = 97; + private static final int ITERS = 11000; + private static final int OFFSET = 3; + private static final int SCALE = 2; + private static final int ALIGN_OFF = 8; + private static final int UNALIGN_OFF = 5; + + public static void main(String args[]) { + System.out.println("Testing Integer array atomic CAS operations"); + int errn = test(false); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test(boolean test_only) { + AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN); + AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN); + // Initialize + for (int i=0; i 0 || test_only) + return errn; + + // Initialize + for (int i=0; i= 0; i-=1) { + a.compareAndSet(i, old, -123); + } + } + static void test_vi_neg(AtomicIntegerArray a, int b, int old) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.compareAndSet(i, old, b); + } + } + static void test_cp_neg(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.compareAndSet(i, -123, b.get(i)); + } + } + static void test_2ci_neg(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.compareAndSet(i, 123, -123); + b.compareAndSet(i, 123, -103); + } + } + static void test_2vi_neg(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.compareAndSet(i, -123, c); + b.compareAndSet(i, -103, d); + } + } + static void test_ci_oppos(AtomicIntegerArray a, int old) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.compareAndSet((limit-i), old, -123); + } + } + static void test_vi_oppos(AtomicIntegerArray a, int b, int old) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + a.compareAndSet((limit-i), old, b); + } + } + static void test_cp_oppos(AtomicIntegerArray a, AtomicIntegerArray b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.compareAndSet(i, -123, b.get(limit-i)); + } + } + static void test_2ci_oppos(AtomicIntegerArray a, AtomicIntegerArray b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.compareAndSet((limit-i), 123, -123); + b.compareAndSet(i, 123, -103); + } + } + static void test_2vi_oppos(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + a.compareAndSet(i, -123, c); + b.compareAndSet((limit-i), -103, d); + } + } + static void test_ci_off(AtomicIntegerArray a, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.compareAndSet((i+OFFSET), old, -123); + } + } + static void test_vi_off(AtomicIntegerArray a, int b, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.compareAndSet((i+OFFSET), old, b); + } + } + static void test_cp_off(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.compareAndSet((i+OFFSET), -123, b.get(i+OFFSET)); + } + } + static void test_2ci_off(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.compareAndSet((i+OFFSET), 123, -123); + b.compareAndSet((i+OFFSET), 123, -103); + } + } + static void test_2vi_off(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.compareAndSet((i+OFFSET), -123, c); + b.compareAndSet((i+OFFSET), -103, d); + } + } + static void test_ci_inv(AtomicIntegerArray a, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.compareAndSet((i+k), old, -123); + } + } + static void test_vi_inv(AtomicIntegerArray a, int b, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.compareAndSet((i+k), old, b); + } + } + static void test_cp_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.compareAndSet((i+k), -123, b.get(i+k)); + } + } + static void test_2ci_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.compareAndSet((i+k), 123, -123); + b.compareAndSet((i+k), 123, -103); + } + } + static void test_2vi_inv(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.compareAndSet((i+k), -123, c); + b.compareAndSet((i+k), -103, d); + } + } + static void test_ci_scl(AtomicIntegerArray a, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.compareAndSet((i*SCALE), old, -123); + } + } + static void test_vi_scl(AtomicIntegerArray a, int b, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.compareAndSet((i*SCALE), old, b); + } + } + static void test_cp_scl(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.compareAndSet((i*SCALE), -123, b.get(i*SCALE)); + } + } + static void test_2ci_scl(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.compareAndSet((i*SCALE), 123, -123); + b.compareAndSet((i*SCALE), 123, -103); + } + } + static void test_2vi_scl(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.compareAndSet((i*SCALE), -123, c); + b.compareAndSet((i*SCALE), -103, d); + } + } + static void test_cp_alndst(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.compareAndSet((i+ALIGN_OFF), -1, b.get(i)); + } + } + static void test_cp_alnsrc(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.getAndSet(i, b.get(i+ALIGN_OFF)); + } + } + static void test_2ci_aln(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.compareAndSet((i+ALIGN_OFF), -1, -123); + b.getAndSet(i, -103); + } + } + static void test_2vi_aln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.getAndSet(i, c); + b.getAndSet((i+ALIGN_OFF), d); + } + } + static void test_cp_unalndst(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.compareAndSet((i+UNALIGN_OFF), -1, b.get(i)); + } + } + static void test_cp_unalnsrc(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.getAndSet(i, b.get(i+UNALIGN_OFF)); + } + } + static void test_2ci_unaln(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.compareAndSet((i+UNALIGN_OFF), -1, -123); + b.getAndSet(i, -103); + } + } + static void test_2vi_unaln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.getAndSet(i, c); + b.getAndSet((i+UNALIGN_OFF), d); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8004867/TestIntAtomicOrdered.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8004867/TestIntAtomicOrdered.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,969 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8004867 + * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" + * + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntAtomicOrdered + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntAtomicOrdered + */ + +import java.util.concurrent.atomic.AtomicIntegerArray; + +public class TestIntAtomicOrdered { + private static final int ARRLEN = 97; + private static final int ITERS = 11000; + private static final int OFFSET = 3; + private static final int SCALE = 2; + private static final int ALIGN_OFF = 8; + private static final int UNALIGN_OFF = 5; + + public static void main(String args[]) { + System.out.println("Testing Integer array atomic ordered operations"); + int errn = test(false); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test(boolean test_only) { + AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN); + AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN); + // Initialize + for (int i=0; i 0 || test_only) + return errn; + + // Initialize + for (int i=0; i= 0; i-=1) { + a.lazySet(i,-123); + } + } + static void test_vi_neg(AtomicIntegerArray a, int b, int old) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.lazySet(i, b); + } + } + static void test_cp_neg(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.lazySet(i, b.get(i)); + } + } + static void test_2ci_neg(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.lazySet(i, -123); + b.lazySet(i, -103); + } + } + static void test_2vi_neg(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.lazySet(i, c); + b.lazySet(i, d); + } + } + static void test_ci_oppos(AtomicIntegerArray a, int old) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.lazySet((limit-i), -123); + } + } + static void test_vi_oppos(AtomicIntegerArray a, int b, int old) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + a.lazySet((limit-i), b); + } + } + static void test_cp_oppos(AtomicIntegerArray a, AtomicIntegerArray b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.lazySet(i, b.get(limit-i)); + } + } + static void test_2ci_oppos(AtomicIntegerArray a, AtomicIntegerArray b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.lazySet((limit-i), -123); + b.lazySet(i, -103); + } + } + static void test_2vi_oppos(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + a.lazySet(i, c); + b.lazySet((limit-i), d); + } + } + static void test_ci_off(AtomicIntegerArray a, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.lazySet((i+OFFSET), -123); + } + } + static void test_vi_off(AtomicIntegerArray a, int b, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.lazySet((i+OFFSET), b); + } + } + static void test_cp_off(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.lazySet((i+OFFSET), b.get(i+OFFSET)); + } + } + static void test_2ci_off(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.lazySet((i+OFFSET), -123); + b.lazySet((i+OFFSET), -103); + } + } + static void test_2vi_off(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.lazySet((i+OFFSET), c); + b.lazySet((i+OFFSET), d); + } + } + static void test_ci_inv(AtomicIntegerArray a, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.lazySet((i+k),-123); + } + } + static void test_vi_inv(AtomicIntegerArray a, int b, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.lazySet((i+k), b); + } + } + static void test_cp_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.lazySet((i+k), b.get(i+k)); + } + } + static void test_2ci_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.lazySet((i+k), -123); + b.lazySet((i+k), -103); + } + } + static void test_2vi_inv(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.lazySet((i+k), c); + b.lazySet((i+k), d); + } + } + static void test_ci_scl(AtomicIntegerArray a, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.lazySet((i*SCALE), -123); + } + } + static void test_vi_scl(AtomicIntegerArray a, int b, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.lazySet((i*SCALE), b); + } + } + static void test_cp_scl(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.lazySet((i*SCALE), b.get(i*SCALE)); + } + } + static void test_2ci_scl(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.lazySet((i*SCALE), -123); + b.lazySet((i*SCALE), -103); + } + } + static void test_2vi_scl(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.lazySet((i*SCALE), c); + b.lazySet((i*SCALE), d); + } + } + static void test_cp_alndst(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.lazySet((i+ALIGN_OFF), b.get(i)); + } + } + static void test_cp_alnsrc(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.lazySet(i, b.get(i+ALIGN_OFF)); + } + } + static void test_2ci_aln(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.lazySet((i+ALIGN_OFF), -123); + b.lazySet(i, -103); + } + } + static void test_2vi_aln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.lazySet(i, c); + b.lazySet((i+ALIGN_OFF), d); + } + } + static void test_cp_unalndst(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.lazySet((i+UNALIGN_OFF), b.get(i)); + } + } + static void test_cp_unalnsrc(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.lazySet(i, b.get(i+UNALIGN_OFF)); + } + } + static void test_2ci_unaln(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.lazySet((i+UNALIGN_OFF), -123); + b.lazySet(i, -103); + } + } + static void test_2vi_unaln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.lazySet(i, c); + b.lazySet((i+UNALIGN_OFF), d); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8004867/TestIntAtomicVolatile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8004867/TestIntAtomicVolatile.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,969 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8004867 + * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" + * + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntAtomicVolatile + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntAtomicVolatile + */ + +import java.util.concurrent.atomic.AtomicIntegerArray; + +public class TestIntAtomicVolatile { + private static final int ARRLEN = 97; + private static final int ITERS = 11000; + private static final int OFFSET = 3; + private static final int SCALE = 2; + private static final int ALIGN_OFF = 8; + private static final int UNALIGN_OFF = 5; + + public static void main(String args[]) { + System.out.println("Testing Integer array atomic volatile operations"); + int errn = test(false); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test(boolean test_only) { + AtomicIntegerArray a1 = new AtomicIntegerArray(ARRLEN); + AtomicIntegerArray a2 = new AtomicIntegerArray(ARRLEN); + // Initialize + for (int i=0; i 0 || test_only) + return errn; + + // Initialize + for (int i=0; i= 0; i-=1) { + a.set(i,-123); + } + } + static void test_vi_neg(AtomicIntegerArray a, int b, int old) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.set(i, b); + } + } + static void test_cp_neg(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.set(i, b.get(i)); + } + } + static void test_2ci_neg(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.set(i, -123); + b.set(i, -103); + } + } + static void test_2vi_neg(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + a.set(i, c); + b.set(i, d); + } + } + static void test_ci_oppos(AtomicIntegerArray a, int old) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.set((limit-i), -123); + } + } + static void test_vi_oppos(AtomicIntegerArray a, int b, int old) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + a.set((limit-i), b); + } + } + static void test_cp_oppos(AtomicIntegerArray a, AtomicIntegerArray b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.set(i, b.get(limit-i)); + } + } + static void test_2ci_oppos(AtomicIntegerArray a, AtomicIntegerArray b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + a.set((limit-i), -123); + b.set(i, -103); + } + } + static void test_2vi_oppos(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + a.set(i, c); + b.set((limit-i), d); + } + } + static void test_ci_off(AtomicIntegerArray a, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.set((i+OFFSET), -123); + } + } + static void test_vi_off(AtomicIntegerArray a, int b, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.set((i+OFFSET), b); + } + } + static void test_cp_off(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.set((i+OFFSET), b.get(i+OFFSET)); + } + } + static void test_2ci_off(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.set((i+OFFSET), -123); + b.set((i+OFFSET), -103); + } + } + static void test_2vi_off(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + a.set((i+OFFSET), c); + b.set((i+OFFSET), d); + } + } + static void test_ci_inv(AtomicIntegerArray a, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.set((i+k),-123); + } + } + static void test_vi_inv(AtomicIntegerArray a, int b, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.set((i+k), b); + } + } + static void test_cp_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.set((i+k), b.get(i+k)); + } + } + static void test_2ci_inv(AtomicIntegerArray a, AtomicIntegerArray b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.set((i+k), -123); + b.set((i+k), -103); + } + } + static void test_2vi_inv(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + a.set((i+k), c); + b.set((i+k), d); + } + } + static void test_ci_scl(AtomicIntegerArray a, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.set((i*SCALE), -123); + } + } + static void test_vi_scl(AtomicIntegerArray a, int b, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.set((i*SCALE), b); + } + } + static void test_cp_scl(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.set((i*SCALE), b.get(i*SCALE)); + } + } + static void test_2ci_scl(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.set((i*SCALE), -123); + b.set((i*SCALE), -103); + } + } + static void test_2vi_scl(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + a.set((i*SCALE), c); + b.set((i*SCALE), d); + } + } + static void test_cp_alndst(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.set((i+ALIGN_OFF), b.get(i)); + } + } + static void test_cp_alnsrc(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.set(i, b.get(i+ALIGN_OFF)); + } + } + static void test_2ci_aln(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.set((i+ALIGN_OFF), -123); + b.set(i, -103); + } + } + static void test_2vi_aln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + a.set(i, c); + b.set((i+ALIGN_OFF), d); + } + } + static void test_cp_unalndst(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.set((i+UNALIGN_OFF), b.get(i)); + } + } + static void test_cp_unalnsrc(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.set(i, b.get(i+UNALIGN_OFF)); + } + } + static void test_2ci_unaln(AtomicIntegerArray a, AtomicIntegerArray b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.set((i+UNALIGN_OFF), -123); + b.set(i, -103); + } + } + static void test_2vi_unaln(AtomicIntegerArray a, AtomicIntegerArray b, int c, int d) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + a.set(i, c); + b.set((i+UNALIGN_OFF), d); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8004867/TestIntUnsafeCAS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8004867/TestIntUnsafeCAS.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,998 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8004867 + * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" + * + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeCAS + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeCAS + */ + +import sun.misc.Unsafe; +import java.lang.reflect.*; + +public class TestIntUnsafeCAS { + private static final int ARRLEN = 97; + private static final int ITERS = 11000; + private static final int OFFSET = 3; + private static final int SCALE = 2; + private static final int ALIGN_OFF = 8; + private static final int UNALIGN_OFF = 5; + + private static final Unsafe unsafe; + private static final int BASE; + static { + try { + Class c = TestIntUnsafeCAS.class.getClassLoader().loadClass("sun.misc.Unsafe"); + Field f = c.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe)f.get(c); + BASE = unsafe.arrayBaseOffset(int[].class); + } catch (Exception e) { + InternalError err = new InternalError(); + err.initCause(e); + throw err; + } + } + + public static void main(String args[]) { + System.out.println("Testing Integer array unsafe CAS operations"); + int errn = test(false); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test(boolean test_only) { + int[] a1 = new int[ARRLEN]; + int[] a2 = new int[ARRLEN]; + // Initialize + for (int i=0; i 0 || test_only) + return errn; + + // Initialize + for (int i=0; i= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), old, -123); + } + } + static void test_vi_neg(int[] a, int b, int old) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), old, b); + } + } + static void test_cp_neg(int[] a, int[] b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), -123, b[i]); + } + } + static void test_2ci_neg(int[] a, int[] b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), 123, -123); + unsafe.compareAndSwapInt(b, byte_offset(i), 123, -103); + } + } + static void test_2vi_neg(int[] a, int[] b, int c, int d) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), -123, c); + unsafe.compareAndSwapInt(b, byte_offset(i), -103, d); + } + } + static void test_ci_oppos(int[] a, int old) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(limit-i), old, -123); + } + } + static void test_vi_oppos(int[] a, int b, int old) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(limit-i), old, b); + } + } + static void test_cp_oppos(int[] a, int[] b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), -123, b[limit-i]); + } + } + static void test_2ci_oppos(int[] a, int[] b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(limit-i), 123, -123); + unsafe.compareAndSwapInt(b, byte_offset(i), 123, -103); + } + } + static void test_2vi_oppos(int[] a, int[] b, int c, int d) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + unsafe.compareAndSwapInt(a, byte_offset(i), -123, c); + unsafe.compareAndSwapInt(b, byte_offset(limit-i), -103, d); + } + } + static void test_ci_off(int[] a, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), old, -123); + } + } + static void test_vi_off(int[] a, int b, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), old, b); + } + } + static void test_cp_off(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), -123, b[i+OFFSET]); + } + } + static void test_2ci_off(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), 123, -123); + unsafe.compareAndSwapInt(b, byte_offset(i+OFFSET), 123, -103); + } + } + static void test_2vi_off(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+OFFSET), -123, c); + unsafe.compareAndSwapInt(b, byte_offset(i+OFFSET), -103, d); + } + } + static void test_ci_inv(int[] a, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+k), old, -123); + } + } + static void test_vi_inv(int[] a, int b, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+k), old, b); + } + } + static void test_cp_inv(int[] a, int[] b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+k), -123, b[i+k]); + } + } + static void test_2ci_inv(int[] a, int[] b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+k), 123, -123); + unsafe.compareAndSwapInt(b, byte_offset(i+k), 123, -103); + } + } + static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+k), -123, c); + unsafe.compareAndSwapInt(b, byte_offset(i+k), -103, d); + } + } + static void test_ci_scl(int[] a, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), old, -123); + } + } + static void test_vi_scl(int[] a, int b, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), old, b); + } + } + static void test_cp_scl(int[] a, int[] b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), -123, b[i*SCALE]); + } + } + static void test_2ci_scl(int[] a, int[] b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), 123, -123); + unsafe.compareAndSwapInt(b, byte_offset(i*SCALE), 123, -103); + } + } + static void test_2vi_scl(int[] a, int[] b, int c, int d) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i*SCALE), -123, c); + unsafe.compareAndSwapInt(b, byte_offset(i*SCALE), -103, d); + } + } + static void test_cp_alndst(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+ALIGN_OFF), -1, b[i]); + } + } + static void test_cp_alnsrc(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + int old = unsafe.getIntVolatile(a, byte_offset(i)); + unsafe.compareAndSwapInt(a, byte_offset(i), old, b[i+ALIGN_OFF]); + } + } + static void test_2ci_aln(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+ALIGN_OFF), -1, -123); + int old = unsafe.getIntVolatile(b, byte_offset(i)); + unsafe.compareAndSwapInt(b, byte_offset(i), old, -103); + } + } + static void test_2vi_aln(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + int old = unsafe.getIntVolatile(a, byte_offset(i)); + unsafe.compareAndSwapInt(a, byte_offset(i), old, c); + old = unsafe.getIntVolatile(b, byte_offset(i+ALIGN_OFF)); + unsafe.compareAndSwapInt(b, byte_offset(i+ALIGN_OFF), old, d); + } + } + static void test_cp_unalndst(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+UNALIGN_OFF), -1, b[i]); + } + } + static void test_cp_unalnsrc(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + int old = unsafe.getIntVolatile(a, byte_offset(i)); + unsafe.compareAndSwapInt(a, byte_offset(i), old, b[i+UNALIGN_OFF]); + } + } + static void test_2ci_unaln(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.compareAndSwapInt(a, byte_offset(i+UNALIGN_OFF), -1, -123); + int old = unsafe.getIntVolatile(b, byte_offset(i)); + unsafe.compareAndSwapInt(b, byte_offset(i), old, -103); + } + } + static void test_2vi_unaln(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + int old = unsafe.getIntVolatile(a, byte_offset(i)); + unsafe.compareAndSwapInt(a, byte_offset(i), old, c); + old = unsafe.getIntVolatile(b, byte_offset(i+UNALIGN_OFF)); + unsafe.compareAndSwapInt(b, byte_offset(i+UNALIGN_OFF), old, d); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8004867/TestIntUnsafeOrdered.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8004867/TestIntUnsafeOrdered.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,990 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8004867 + * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" + * + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeOrdered + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeOrdered + */ + +import sun.misc.Unsafe; +import java.lang.reflect.*; + +public class TestIntUnsafeOrdered { + private static final int ARRLEN = 97; + private static final int ITERS = 11000; + private static final int OFFSET = 3; + private static final int SCALE = 2; + private static final int ALIGN_OFF = 8; + private static final int UNALIGN_OFF = 5; + + private static final Unsafe unsafe; + private static final int BASE; + static { + try { + Class c = TestIntUnsafeOrdered.class.getClassLoader().loadClass("sun.misc.Unsafe"); + Field f = c.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe)f.get(c); + BASE = unsafe.arrayBaseOffset(int[].class); + } catch (Exception e) { + InternalError err = new InternalError(); + err.initCause(e); + throw err; + } + } + + public static void main(String args[]) { + System.out.println("Testing Integer array unsafe ordered operations"); + int errn = test(false); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test(boolean test_only) { + int[] a1 = new int[ARRLEN]; + int[] a2 = new int[ARRLEN]; + // Initialize + for (int i=0; i 0 || test_only) + return errn; + + // Initialize + for (int i=0; i= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(i), -123); + } + } + static void test_vi_neg(int[] a, int b, int old) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(i), b); + } + } + static void test_cp_neg(int[] a, int[] b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(i), b[i]); + } + } + static void test_2ci_neg(int[] a, int[] b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(i), -123); + unsafe.putOrderedInt(b, byte_offset(i), -103); + } + } + static void test_2vi_neg(int[] a, int[] b, int c, int d) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(i), c); + unsafe.putOrderedInt(b, byte_offset(i), d); + } + } + static void test_ci_oppos(int[] a, int old) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(limit-i), -123); + } + } + static void test_vi_oppos(int[] a, int b, int old) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(limit-i), b); + } + } + static void test_cp_oppos(int[] a, int[] b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i), b[limit-i]); + } + } + static void test_2ci_oppos(int[] a, int[] b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(limit-i), -123); + unsafe.putOrderedInt(b, byte_offset(i), -103); + } + } + static void test_2vi_oppos(int[] a, int[] b, int c, int d) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + unsafe.putOrderedInt(a, byte_offset(i), c); + unsafe.putOrderedInt(b, byte_offset(limit-i), d); + } + } + static void test_ci_off(int[] a, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+OFFSET), -123); + } + } + static void test_vi_off(int[] a, int b, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+OFFSET), b); + } + } + static void test_cp_off(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+OFFSET), b[i+OFFSET]); + } + } + static void test_2ci_off(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+OFFSET), -123); + unsafe.putOrderedInt(b, byte_offset(i+OFFSET), -103); + } + } + static void test_2vi_off(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+OFFSET), c); + unsafe.putOrderedInt(b, byte_offset(i+OFFSET), d); + } + } + static void test_ci_inv(int[] a, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+k), -123); + } + } + static void test_vi_inv(int[] a, int b, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+k), b); + } + } + static void test_cp_inv(int[] a, int[] b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+k), b[i+k]); + } + } + static void test_2ci_inv(int[] a, int[] b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+k), -123); + unsafe.putOrderedInt(b, byte_offset(i+k), -103); + } + } + static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+k), c); + unsafe.putOrderedInt(b, byte_offset(i+k), d); + } + } + static void test_ci_scl(int[] a, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i*SCALE), -123); + } + } + static void test_vi_scl(int[] a, int b, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i*SCALE), b); + } + } + static void test_cp_scl(int[] a, int[] b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i*SCALE), b[i*SCALE]); + } + } + static void test_2ci_scl(int[] a, int[] b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i*SCALE), -123); + unsafe.putOrderedInt(b, byte_offset(i*SCALE), -103); + } + } + static void test_2vi_scl(int[] a, int[] b, int c, int d) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i*SCALE), c); + unsafe.putOrderedInt(b, byte_offset(i*SCALE), d); + } + } + static void test_cp_alndst(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+ALIGN_OFF), b[i]); + } + } + static void test_cp_alnsrc(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i), b[i+ALIGN_OFF]); + } + } + static void test_2ci_aln(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+ALIGN_OFF), -123); + unsafe.putOrderedInt(b, byte_offset(i), -103); + } + } + static void test_2vi_aln(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i), c); + unsafe.putOrderedInt(b, byte_offset(i+ALIGN_OFF), d); + } + } + static void test_cp_unalndst(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+UNALIGN_OFF), b[i]); + } + } + static void test_cp_unalnsrc(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i), b[i+UNALIGN_OFF]); + } + } + static void test_2ci_unaln(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i+UNALIGN_OFF), -123); + unsafe.putOrderedInt(b, byte_offset(i), -103); + } + } + static void test_2vi_unaln(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putOrderedInt(a, byte_offset(i), c); + unsafe.putOrderedInt(b, byte_offset(i+UNALIGN_OFF), d); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8004867/TestIntUnsafeVolatile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8004867/TestIntUnsafeVolatile.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,990 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 8004867 + * @summary VM crashing with assert "share/vm/opto/node.hpp:357 - assert(i < _max) failed: oob" + * + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntUnsafeVolatile + * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+OptimizeFill TestIntUnsafeVolatile + */ + +import sun.misc.Unsafe; +import java.lang.reflect.*; + +public class TestIntUnsafeVolatile { + private static final int ARRLEN = 97; + private static final int ITERS = 11000; + private static final int OFFSET = 3; + private static final int SCALE = 2; + private static final int ALIGN_OFF = 8; + private static final int UNALIGN_OFF = 5; + + private static final Unsafe unsafe; + private static final int BASE; + static { + try { + Class c = TestIntUnsafeVolatile.class.getClassLoader().loadClass("sun.misc.Unsafe"); + Field f = c.getDeclaredField("theUnsafe"); + f.setAccessible(true); + unsafe = (Unsafe)f.get(c); + BASE = unsafe.arrayBaseOffset(int[].class); + } catch (Exception e) { + InternalError err = new InternalError(); + err.initCause(e); + throw err; + } + } + + public static void main(String args[]) { + System.out.println("Testing Integer array unsafe volatile operations"); + int errn = test(false); + if (errn > 0) { + System.err.println("FAILED: " + errn + " errors"); + System.exit(97); + } + System.out.println("PASSED"); + } + + static int test(boolean test_only) { + int[] a1 = new int[ARRLEN]; + int[] a2 = new int[ARRLEN]; + // Initialize + for (int i=0; i 0 || test_only) + return errn; + + // Initialize + for (int i=0; i= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(i), -123); + } + } + static void test_vi_neg(int[] a, int b, int old) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(i), b); + } + } + static void test_cp_neg(int[] a, int[] b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(i), b[i]); + } + } + static void test_2ci_neg(int[] a, int[] b) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(i), -123); + unsafe.putIntVolatile(b, byte_offset(i), -103); + } + } + static void test_2vi_neg(int[] a, int[] b, int c, int d) { + for (int i = ARRLEN-1; i >= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(i), c); + unsafe.putIntVolatile(b, byte_offset(i), d); + } + } + static void test_ci_oppos(int[] a, int old) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(limit-i), -123); + } + } + static void test_vi_oppos(int[] a, int b, int old) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(limit-i), b); + } + } + static void test_cp_oppos(int[] a, int[] b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i), b[limit-i]); + } + } + static void test_2ci_oppos(int[] a, int[] b) { + int limit = ARRLEN-1; + for (int i = 0; i < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(limit-i), -123); + unsafe.putIntVolatile(b, byte_offset(i), -103); + } + } + static void test_2vi_oppos(int[] a, int[] b, int c, int d) { + int limit = ARRLEN-1; + for (int i = limit; i >= 0; i-=1) { + unsafe.putIntVolatile(a, byte_offset(i), c); + unsafe.putIntVolatile(b, byte_offset(limit-i), d); + } + } + static void test_ci_off(int[] a, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+OFFSET), -123); + } + } + static void test_vi_off(int[] a, int b, int old) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+OFFSET), b); + } + } + static void test_cp_off(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+OFFSET), b[i+OFFSET]); + } + } + static void test_2ci_off(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+OFFSET), -123); + unsafe.putIntVolatile(b, byte_offset(i+OFFSET), -103); + } + } + static void test_2vi_off(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-OFFSET; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+OFFSET), c); + unsafe.putIntVolatile(b, byte_offset(i+OFFSET), d); + } + } + static void test_ci_inv(int[] a, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+k), -123); + } + } + static void test_vi_inv(int[] a, int b, int k, int old) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+k), b); + } + } + static void test_cp_inv(int[] a, int[] b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+k), b[i+k]); + } + } + static void test_2ci_inv(int[] a, int[] b, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+k), -123); + unsafe.putIntVolatile(b, byte_offset(i+k), -103); + } + } + static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) { + for (int i = 0; i < ARRLEN-k; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+k), c); + unsafe.putIntVolatile(b, byte_offset(i+k), d); + } + } + static void test_ci_scl(int[] a, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i*SCALE), -123); + } + } + static void test_vi_scl(int[] a, int b, int old) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i*SCALE), b); + } + } + static void test_cp_scl(int[] a, int[] b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i*SCALE), b[i*SCALE]); + } + } + static void test_2ci_scl(int[] a, int[] b) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i*SCALE), -123); + unsafe.putIntVolatile(b, byte_offset(i*SCALE), -103); + } + } + static void test_2vi_scl(int[] a, int[] b, int c, int d) { + for (int i = 0; i*SCALE < ARRLEN; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i*SCALE), c); + unsafe.putIntVolatile(b, byte_offset(i*SCALE), d); + } + } + static void test_cp_alndst(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+ALIGN_OFF), b[i]); + } + } + static void test_cp_alnsrc(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i), b[i+ALIGN_OFF]); + } + } + static void test_2ci_aln(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+ALIGN_OFF), -123); + unsafe.putIntVolatile(b, byte_offset(i), -103); + } + } + static void test_2vi_aln(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-ALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i), c); + unsafe.putIntVolatile(b, byte_offset(i+ALIGN_OFF), d); + } + } + static void test_cp_unalndst(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+UNALIGN_OFF), b[i]); + } + } + static void test_cp_unalnsrc(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i), b[i+UNALIGN_OFF]); + } + } + static void test_2ci_unaln(int[] a, int[] b) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i+UNALIGN_OFF), -123); + unsafe.putIntVolatile(b, byte_offset(i), -103); + } + } + static void test_2vi_unaln(int[] a, int[] b, int c, int d) { + for (int i = 0; i < ARRLEN-UNALIGN_OFF; i+=1) { + unsafe.putIntVolatile(a, byte_offset(i), c); + unsafe.putIntVolatile(b, byte_offset(i+UNALIGN_OFF), d); + } + } + + static int verify(String text, int i, int elem, int val) { + if (elem != val) { + System.err.println(text + "[" + i + "] = " + elem + " != " + val); + return 1; + } + return 0; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8007294/Test8007294.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8007294/Test8007294.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8007294 + * @summary ReduceFieldZeroing doesn't check for dependent load and can lead to incorrect execution + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+AlwaysIncrementalInline -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8007294 + * + */ + +public class Test8007294 { + + int i1; + int i2; + + Test8007294(int i1, int i2) { + this.i1 = i1; + this.i2 = i2; + } + + static int m(int v) { + return v; + } + + static Test8007294 test1() { + Test8007294 obj = new Test8007294(10, 100); + int v1 = obj.i1; + + int v3 = m(v1); + int v2 = obj.i2; + obj.i2 = v3; + obj.i1 = v2; + + return obj; + } + + static int test2(int i) { + int j = 0; + if (i > 0) { + j = 1; + } + + int[] arr = new int[10]; + arr[0] = 1; + arr[1] = 2; + int v1 = arr[j]; + arr[0] = 3; + arr[1] = 4; + + return v1; + } + + static public void main(String[] args) { + boolean failed = false; + for (int i = 0; i < 20000; i++) { + Test8007294 obj = test1(); + if (obj.i1 != 100 || obj.i2 != 10) { + System.out.println("FAILED test1 obj.i1 = " + obj.i1 +", obj.i2 = " + obj.i2); + failed = true; + break; + } + } + for (int i = 0; i < 20000; i++) { + int res = test2(1); + if (res != 2) { + System.out.println("FAILED test2 = " + res); + failed = true; + break; + } + } + if (failed) { + System.exit(97); + } else { + System.out.println("PASSED"); + } + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/8007722/Test8007722.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/8007722/Test8007722.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8007722 + * @summary GetAndSetP's MachNode should capture bottom type + * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8007722 + * + */ + +import java.util.concurrent.atomic.*; + +public class Test8007722 { + + int i; + static AtomicReference ref; + + static int test(Test8007722 new_obj) { + Test8007722 o = ref.getAndSet(new_obj); + int ret = o.i; + o.i = 5; + return ret; + } + + static public void main(String[] args) { + Test8007722 obj = new Test8007722(); + ref = new AtomicReference(obj); + + for (int i = 0; i < 20000; i++) { + test(obj); + } + + System.out.println("PASSED"); + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/whitebox/DeoptimizeAllTest.java --- a/test/compiler/whitebox/DeoptimizeAllTest.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/whitebox/DeoptimizeAllTest.java Tue Mar 12 18:22:40 2013 -0700 @@ -23,9 +23,10 @@ /* * @test DeoptimizeAllTest - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI DeoptimizeAllTest.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest + * @library /testlibrary /testlibrary/whitebox + * @build DeoptimizeAllTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest * @author igor.ignatyev@oracle.com */ public class DeoptimizeAllTest extends CompilerWhiteBoxTest { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/whitebox/DeoptimizeMethodTest.java --- a/test/compiler/whitebox/DeoptimizeMethodTest.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/whitebox/DeoptimizeMethodTest.java Tue Mar 12 18:22:40 2013 -0700 @@ -23,9 +23,10 @@ /* * @test DeoptimizeMethodTest - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI DeoptimizeMethodTest.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest + * @library /testlibrary /testlibrary/whitebox + * @build DeoptimizeMethodTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest * @author igor.ignatyev@oracle.com */ public class DeoptimizeMethodTest extends CompilerWhiteBoxTest { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/whitebox/IsMethodCompilableTest.java --- a/test/compiler/whitebox/IsMethodCompilableTest.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/whitebox/IsMethodCompilableTest.java Tue Mar 12 18:22:40 2013 -0700 @@ -24,9 +24,10 @@ /* * @test IsMethodCompilableTest * @bug 8007270 - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI IsMethodCompilableTest.java - * @run main/othervm/timeout=600 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest + * @library /testlibrary /testlibrary/whitebox + * @build IsMethodCompilableTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest * @author igor.ignatyev@oracle.com */ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/whitebox/MakeMethodNotCompilableTest.java --- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java Tue Mar 12 18:22:40 2013 -0700 @@ -23,9 +23,10 @@ /* * @test MakeMethodNotCompilableTest - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI MakeMethodNotCompilableTest.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest + * @library /testlibrary /testlibrary/whitebox + * @build MakeMethodNotCompilableTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest * @author igor.ignatyev@oracle.com */ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/compiler/whitebox/SetDontInlineMethodTest.java --- a/test/compiler/whitebox/SetDontInlineMethodTest.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/compiler/whitebox/SetDontInlineMethodTest.java Tue Mar 12 18:22:40 2013 -0700 @@ -23,9 +23,10 @@ /* * @test SetDontInlineMethodTest - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI CompilerWhiteBoxTest.java - * @compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI SetDontInlineMethodTest.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest + * @library /testlibrary /testlibrary/whitebox + * @build SetDontInlineMethodTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest * @author igor.ignatyev@oracle.com */ public class SetDontInlineMethodTest extends CompilerWhiteBoxTest { diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/8000311/Test8000311.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/8000311/Test8000311.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test Test8000311 + * @key gc + * @bug 8000311 + * @summary G1: ParallelGCThreads==0 broken + * @run main/othervm -XX:+UseG1GC -XX:ParallelGCThreads=0 -XX:+ResizePLAB -XX:+ExplicitGCInvokesConcurrent Test8000311 + * @author filipp.zhinkin@oracle.com + */ + +import java.util.*; + +public class Test8000311 { + public static void main(String args[]) { + for(int i = 0; i<100; i++) { + byte[] garbage = new byte[1000]; + System.gc(); + } + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/TestG1ZeroPGCTJcmdThreadPrint.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/TestG1ZeroPGCTJcmdThreadPrint.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test TestG1ZeroPGCTJcmdThreadPrint + * @key gc + * @bug 8005875 + * @summary Use jcmd to generate a thread dump of a Java program being run with PGCT=0 to verify 8005875 + * @library /testlibrary + * @run main/othervm -XX:+UseG1GC -XX:ParallelGCThreads=0 -XX:+IgnoreUnrecognizedVMOptions TestG1ZeroPGCTJcmdThreadPrint + */ + +import com.oracle.java.testlibrary.*; + +public class TestG1ZeroPGCTJcmdThreadPrint { + public static void main(String args[]) throws Exception { + + // Grab the pid from the current java process + String pid = Integer.toString(ProcessTools.getProcessId()); + + // Create a ProcessBuilder + ProcessBuilder pb = new ProcessBuilder(); + + // Run jcmd Thread.print + pb.command(JDKToolFinder.getJDKTool("jcmd"), pid, "Thread.print"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + // There shouldn't be a work gang for concurrent marking. + output.shouldNotContain("G1 Parallel Marking Threads"); + + // Make sure we didn't crash + output.shouldHaveExitValue(0); + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/metaspace/ClassMetaspaceSizeInJmapHeap.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test ClassMetaspaceSizeInJmapHeap + * @bug 8004924 + * @summary Checks that jmap -heap contains the flag ClassMetaspaceSize + * @library /testlibrary + * @run main/othervm -XX:ClassMetaspaceSize=50m ClassMetaspaceSizeInJmapHeap + */ + +import com.oracle.java.testlibrary.*; +import java.nio.file.*; +import java.io.File; +import java.nio.charset.Charset; +import java.util.List; + +public class ClassMetaspaceSizeInJmapHeap { + public static void main(String[] args) throws Exception { + String pid = Integer.toString(ProcessTools.getProcessId()); + + ProcessBuilder pb = new ProcessBuilder(); + pb.command(JDKToolFinder.getJDKTool("jmap"), "-heap", pid); + + File out = new File("ClassMetaspaceSizeInJmapHeap.stdout.txt"); + pb.redirectOutput(out); + + File err = new File("ClassMetaspaceSizeInJmapHeap.stderr.txt"); + pb.redirectError(err); + + run(pb); + + OutputAnalyzer output = new OutputAnalyzer(read(out)); + output.shouldContain("ClassMetaspaceSize = 52428800 (50.0MB)"); + out.delete(); + } + + private static void run(ProcessBuilder pb) throws Exception { + Process p = pb.start(); + p.waitFor(); + int exitValue = p.exitValue(); + if (exitValue != 0) { + throw new Exception("jmap -heap exited with error code: " + exitValue); + } + } + + private static String read(File f) throws Exception { + Path p = f.toPath(); + List lines = Files.readAllLines(p, Charset.defaultCharset()); + + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line).append('\n'); + } + return sb.toString(); + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestCMS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestCMS.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestCMS +* @key gc +* @bug 8006398 +* @summary Test that CMS does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestCMS { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestCMSIncrementalMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestCMSIncrementalMode.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ + +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestCMSIncrementalMode +* @key gc +* @bug 8006398 +* @summary Test that the deprecated CMSIncrementalMode print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestCMSIncrementalMode { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:+CMSIncrementalMode", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: Using incremental CMS is deprecated and will likely be removed in a future release"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestCMSNoIncrementalMode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestCMSNoIncrementalMode.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestCMSNoIncrementalMode +* @key gc +* @bug 8006398 +* @summary Test that CMS with incremental mode turned off does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestCMSNoIncrementalMode { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseConcMarkSweepGC", "-XX:-CMSIncrementalMode", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestDefNewCMS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestDefNewCMS.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestDefNewCMS +* @key gc +* @bug 8006398 +* @summary Test that the deprecated DefNew+CMS combination print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestDefNewCMS { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:-UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestG1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestG1.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestG1 +* @key gc +* @bug 8006398 +* @summary Test that the G1 collector does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestG1 { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseG1GC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestIncGC.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestIncGC.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestIncGC +* @key gc +* @bug 8006398 +* @summary Test that the deprecated -Xincgc print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestIncGC { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-Xincgc", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: Using incremental CMS is deprecated and will likely be removed in a future release"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestParNewCMS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestParNewCMS.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestParNewCMS +* @key gc +* @bug 8006398 +* @summary Test that the combination ParNew+CMS does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestParNewCMS { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-XX:+UseConcMarkSweepGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestParNewSerialOld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestParNewSerialOld.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestParNewSerialOld +* @key gc +* @bug 8006398 +* @summary Test that the deprecated ParNew+SerialOld combination print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestParNewSerialOld { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParNewGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestParallelGC.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestParallelGC.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestParallelGC +* @key gc +* @bug 8006398 +* @summary Test that ParallelGC does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestParallelGC { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParallelGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestParallelScavengeSerialOld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestParallelScavengeSerialOld.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestParallelScavengeSerialOld +* @key gc +* @bug 8006398 +* @summary Test that the ParallelScavenge+SerialOld combination does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestParallelScavengeSerialOld { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseParallelGC", "-XX:-UseParallelOldGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/gc/startup_warnings/TestSerialGC.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/startup_warnings/TestSerialGC.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +/* +* @test TestSerialGC +* @key gc +* @bug 8006398 +* @summary Test that SerialGC does not print a warning message +* @library /testlibrary +*/ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + + +public class TestSerialGC { + + public static void main(String args[]) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UseSerialGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("warning"); + output.shouldNotContain("error"); + output.shouldHaveExitValue(0); + } + +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/runtime/8007736/TestStaticIF.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/8007736/TestStaticIF.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8007736 + * @summary Test static interface method. + * @run main/othervm -Xverify:all TestStaticIF + */ + +public class TestStaticIF implements StaticMethodInInterface { + + public static void main(String[] args) { + System.out.printf("main: %s%n", StaticMethodInInterface.get()); + } +} + +interface StaticMethodInInterface { + + public static String get() { + return "Hello from StaticMethodInInterface.get()"; + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/runtime/NMT/AllocTestType.java --- a/test/runtime/NMT/AllocTestType.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/runtime/NMT/AllocTestType.java Tue Mar 12 18:22:40 2013 -0700 @@ -25,9 +25,10 @@ * @test * @summary Test consistency of NMT by leaking a few select allocations of the Test type and then verify visibility with jcmd * @key nmt jcmd - * @library /testlibrary - * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI AllocTestType.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail AllocTestType + * @library /testlibrary /testlibrary/whitebox + * @build AllocTestType + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail AllocTestType */ import com.oracle.java.testlibrary.*; diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/runtime/NMT/PrintNMTStatistics.java --- a/test/runtime/NMT/PrintNMTStatistics.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/runtime/NMT/PrintNMTStatistics.java Tue Mar 12 18:22:40 2013 -0700 @@ -26,8 +26,8 @@ * @key nmt regression * @bug 8005936 * @summary Make sure PrintNMTStatistics works on normal JVM exit - * @library /testlibrary - * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI PrintNMTStatistics.java + * @library /testlibrary /testlibrary/whitebox + * @run compile PrintNMTStatistics.java */ import com.oracle.java.testlibrary.*; diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/runtime/NMT/SummarySanityCheck.java --- a/test/runtime/NMT/SummarySanityCheck.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/runtime/NMT/SummarySanityCheck.java Tue Mar 12 18:22:40 2013 -0700 @@ -25,9 +25,10 @@ * @test * @key nmt jcmd * @summary Sanity check the output of NMT - * @library /testlibrary - * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI SummarySanityCheck.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+WhiteBoxAPI SummarySanityCheck + * @library /testlibrary /testlibrary/whitebox + * @build SummarySanityCheck + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:NativeMemoryTracking=summary -XX:+WhiteBoxAPI SummarySanityCheck */ import com.oracle.java.testlibrary.*; diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/sanity/WBApi.java --- a/test/sanity/WBApi.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/sanity/WBApi.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,8 +1,33 @@ +/* + * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + /* * @test WBApi * @summary verify that whitebox functions can be linked and executed - * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI WBApi.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI WBApi + * @library /testlibrary /testlibrary/whitebox + * @build WBApi + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI WBApi */ import sun.hotspot.WhiteBox; diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/serviceability/ParserTest.java --- a/test/serviceability/ParserTest.java Mon Feb 25 07:22:06 2013 +0100 +++ b/test/serviceability/ParserTest.java Tue Mar 12 18:22:40 2013 -0700 @@ -1,8 +1,33 @@ +/* + * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + /* * @test ParserTest - * @summary verify that whitebox functions can be linked and executed - * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI ParserTest.java - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest + * @summary Test that the diagnostic command arguemnt parser works + * @library /testlibrary /testlibrary/whitebox + * @build ParserTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest */ import java.math.BigInteger; diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/testlibrary/ClassFileInstaller.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/ClassFileInstaller.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +/** + * Dump a class file for a class on the class path in the current directory + */ +public class ClassFileInstaller { + /** + * @param args The names of the classes to dump + * @throws Exception + */ + public static void main(String... args) throws Exception { + for (String arg : args) { + ClassLoader cl = ClassFileInstaller.class.getClassLoader(); + + // Convert dotted class name to a path to a class file + String pathName = arg.replace('.', '/').concat(".class"); + InputStream is = cl.getResourceAsStream(pathName); + + // Create the class file's package directory + Path p = Paths.get(pathName); + Files.createDirectories(p.getParent()); + // Create the class file + Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); + } + } +} diff -r d4a32a6f8c82 -r 11d5942ef9c7 test/testlibrary/whitebox/sun/hotspot/WhiteBox.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java Tue Mar 12 18:22:40 2013 -0700 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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.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; + } +}