# HG changeset patch # User minqi # Date 1420922298 28800 # Node ID 247f60f5808f07d512eed77c205ab6e75c1250bf # Parent ad8137d441547830f410a7275957fed81d469bfa# Parent 0cef041bf4fcd91f80967064f2a6639dac89a6ff Merge diff -r ad8137d44154 -r 247f60f5808f .hgtags --- a/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -285,3 +285,5 @@ 82f4cb44b2d7af2352f48568a64b7b6a5ae960cd jdk9-b40 9fffb959eb4197ff806e4ac12244761815b4deee jdk9-b41 3107be2ba9c6e208a0b86bc7100a141abbc5b5fb jdk9-b42 +6494b13f88a867026ee316b444d9a4fa589dd6bd jdk9-b43 +abbfccd659b91a7bb815d5e36fed635dcdd40f31 jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f .hgtags-top-repo --- a/.hgtags-top-repo Thu Jan 08 10:44:54 2015 +0100 +++ b/.hgtags-top-repo Sat Jan 10 12:38:18 2015 -0800 @@ -285,3 +285,5 @@ cf136458ee747e151a27aa9ea0c1492ea55ef3e7 jdk9-b40 67395f7ca2db3b52e3a62a84888487de5cb9210a jdk9-b41 f7c11da0b0481d49cc7a65a453336c108191e821 jdk9-b42 +02ee8c65622e8bd97496d584e22fc7dcf0edc4ae jdk9-b43 +8994f5d87b3bb5e8d317d4e8ccb326da1a73684a jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f common/autoconf/generated-configure.sh --- a/common/autoconf/generated-configure.sh Thu Jan 08 10:44:54 2015 +0100 +++ b/common/autoconf/generated-configure.sh Sat Jan 10 12:38:18 2015 -0800 @@ -4329,7 +4329,7 @@ #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1418036274 +DATE_WHEN_GENERATED=1418395009 ############################################################################### # @@ -13965,7 +13965,8 @@ # ZERO_ARCHDEF is used to enable architecture-specific code case "${OPENJDK_TARGET_CPU}" in - ppc*) ZERO_ARCHDEF=PPC ;; + ppc) ZERO_ARCHDEF=PPC32 ;; + ppc64) ZERO_ARCHDEF=PPC64 ;; s390*) ZERO_ARCHDEF=S390 ;; sparc*) ZERO_ARCHDEF=SPARC ;; x86_64*) ZERO_ARCHDEF=AMD64 ;; diff -r ad8137d44154 -r 247f60f5808f common/autoconf/platform.m4 --- a/common/autoconf/platform.m4 Thu Jan 08 10:44:54 2015 +0100 +++ b/common/autoconf/platform.m4 Sat Jan 10 12:38:18 2015 -0800 @@ -367,7 +367,8 @@ # ZERO_ARCHDEF is used to enable architecture-specific code case "${OPENJDK_TARGET_CPU}" in - ppc*) ZERO_ARCHDEF=PPC ;; + ppc) ZERO_ARCHDEF=PPC32 ;; + ppc64) ZERO_ARCHDEF=PPC64 ;; s390*) ZERO_ARCHDEF=S390 ;; sparc*) ZERO_ARCHDEF=SPARC ;; x86_64*) ZERO_ARCHDEF=AMD64 ;; diff -r ad8137d44154 -r 247f60f5808f common/bin/hgforest.sh --- a/common/bin/hgforest.sh Thu Jan 08 10:44:54 2015 +0100 +++ b/common/bin/hgforest.sh Sat Jan 10 12:38:18 2015 -0800 @@ -106,12 +106,15 @@ echo "# Mercurial command: ${command}" > ${status_output} fi - -# capture command options and arguments (if any) -command_args="${@:-}" +# At this point all command options and args are in "$@". +# Always use "$@" (within double quotes) to avoid breaking +# args with spaces into separate args. if [ ${vflag} = "true" ] ; then - echo "# Mercurial command arguments: ${command_args}" > ${status_output} + echo "# Mercurial command argument count: $#" > ${status_output} + for cmdarg in "$@" ; do + echo "# Mercurial command argument: ${cmdarg}" > ${status_output} + done fi # Clean out the temporary directory that stores the pid files. @@ -205,13 +208,14 @@ pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'` - if [ -n "${command_args}" ] ; then + if [ $# -gt 0 ] ; then # if there is an "extra sources" path then reparent "extra" repos to that path if [ "x${pull_default}" = "x${pull_default_tail}" ] ; then echo "ERROR: Need initial clone from non-local source" > ${status_output} exit 1 fi - pull_extra="${command_args}/${pull_default_tail}" + # assume that "extra sources" path is the first arg + pull_extra="${1}/${pull_default_tail}" # determine which extra subrepos need to be cloned. for i in ${subrepos_extra} ; do @@ -356,8 +360,8 @@ (PYTHONUNBUFFERED=true hg${global_opts} clone ${clone_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 & else # run the command. - echo "cd ${i} && hg${global_opts} ${command} ${command_args}" > ${status_output} - cd ${i} && (PYTHONUNBUFFERED=true hg${global_opts} ${command} ${command_args}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 & + echo "cd ${i} && hg${global_opts} ${command} ${@}" > ${status_output} + cd ${i} && (PYTHONUNBUFFERED=true hg${global_opts} ${command} "${@}"; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 & fi echo $! > ${tmp}/${repopidfile}.pid diff -r ad8137d44154 -r 247f60f5808f corba/.hgtags --- a/corba/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/corba/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -285,3 +285,5 @@ e27c725d6c9d155667b35255f442d4ceb8c3c084 jdk9-b40 1908b886ba1eda46fa725cf1160fe5d30fd1a7e5 jdk9-b41 078bb11af876fe528d4b516f33ad4dd9bb60549e jdk9-b42 +9645e35616b60c5c07b4fdf11a132afc8081dfa8 jdk9-b43 +1f57bd728c9e6865ccb9d43ccd80a1c11230a32f jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f hotspot/.hgtags --- a/hotspot/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -445,3 +445,5 @@ 6b09b3193d731e3288e2a240c504a20d0a06c766 jdk9-b40 1d29b13e8a515a7ea3b882f140576d5d675bc11f jdk9-b41 38cb4fbd47e3472bd1b5ebac83bda96fe4869c4f jdk9-b42 +65a9747147b8090037541040ba67156ec914db6a jdk9-b43 +43a44b56dca61a4d766a20f0528fdd8b5ceff873 jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f hotspot/agent/src/os/win32/windbg/sawindbg.cpp --- a/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/agent/src/os/win32/windbg/sawindbg.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -22,6 +22,9 @@ * */ +// Disable CRT security warning against strcpy/strcat +#pragma warning(disable: 4996) + // this is source code windbg based SA debugger agent to debug // Dr. Watson dump files and process snapshots. diff -r ad8137d44154 -r 247f60f5808f hotspot/agent/src/share/native/sadis.c --- a/hotspot/agent/src/share/native/sadis.c Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/agent/src/share/native/sadis.c Sat Jan 10 12:38:18 2015 -0800 @@ -33,6 +33,8 @@ */ #ifdef _WINDOWS +// Disable CRT security warning against _snprintf +#pragma warning (disable : 4996) #define snprintf _snprintf #define vsnprintf _vsnprintf @@ -90,12 +92,8 @@ if (errno != 0) { /* C runtime error that has no corresponding DOS error code */ - const char *s = strerror(errno); - size_t n = strlen(s); - if (n >= len) n = len - 1; - strncpy(buf, s, n); - buf[n] = '\0'; - return (int)n; + strerror_s(buf, len, errno); + return strlen(buf); } return 0; } @@ -111,16 +109,30 @@ jstring jrepath_s, jstring libname_s) { uintptr_t func = 0; - const char* error_message = NULL; - jboolean isCopy; + const char *error_message = NULL; + const char *jrepath = NULL; + const char *libname = NULL; + char buffer[128]; + +#ifdef _WINDOWS + HINSTANCE hsdis_handle = (HINSTANCE) NULL; +#else + void* hsdis_handle = NULL; +#endif - const char * jrepath = (*env)->GetStringUTFChars(env, jrepath_s, &isCopy); // like $JAVA_HOME/jre/lib/sparc/ - const char * libname = (*env)->GetStringUTFChars(env, libname_s, &isCopy); - char buffer[128]; + jrepath = (*env)->GetStringUTFChars(env, jrepath_s, NULL); // like $JAVA_HOME/jre/lib/sparc/ + if (jrepath == NULL || (*env)->ExceptionOccurred(env)) { + return 0; + } + + libname = (*env)->GetStringUTFChars(env, libname_s, NULL); + if (libname == NULL || (*env)->ExceptionOccurred(env)) { + (*env)->ReleaseStringUTFChars(env, jrepath_s, jrepath); + return 0; + } /* Load the hsdis library */ #ifdef _WINDOWS - HINSTANCE hsdis_handle; hsdis_handle = LoadLibrary(libname); if (hsdis_handle == NULL) { snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname); @@ -134,7 +146,6 @@ error_message = buffer; } #else - void* hsdis_handle; hsdis_handle = dlopen(libname, RTLD_LAZY | RTLD_GLOBAL); if (hsdis_handle == NULL) { snprintf(buffer, sizeof(buffer), "%s%s", jrepath, libname); @@ -156,6 +167,11 @@ * platform dependent error message. */ jclass eclass = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"); + if ((*env)->ExceptionOccurred(env)) { + /* Can't throw exception, probably OOM, so silently return 0 */ + return (jlong) 0; + } + (*env)->ThrowNew(env, eclass, error_message); } return (jlong)func; @@ -184,16 +200,22 @@ /* event callback binding to Disassembler.handleEvent */ static void* event_to_env(void* env_pv, const char* event, void* arg) { + jlong result = 0; decode_env* denv = (decode_env*)env_pv; JNIEnv* env = denv->env; jstring event_string = (*env)->NewStringUTF(env, event); - jlong result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor, - event_string, (jlong) (uintptr_t)arg); - if ((*env)->ExceptionOccurred(env) != NULL) { + if ((*env)->ExceptionOccurred(env)) { + return NULL; + } + + result = (*env)->CallLongMethod(env, denv->dis, denv->handle_event, denv->visitor, + event_string, (jlong) (uintptr_t)arg); + if ((*env)->ExceptionOccurred(env)) { /* ignore exceptions for now */ (*env)->ExceptionClear(env); - result = 0; + return NULL; } + return (void*)(uintptr_t)result; } @@ -219,10 +241,13 @@ } if (raw != NULL) { jstring output = (*env)->NewStringUTF(env, raw); - (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); - if ((*env)->ExceptionOccurred(env) != NULL) { + if (!(*env)->ExceptionOccurred(env)) { + /* make sure that UTF allocation doesn't cause OOM */ + (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); + } + if ((*env)->ExceptionOccurred(env)) { /* ignore exceptions for now */ - (*env)->ExceptionClear(env); + (*env)->ExceptionClear(env); } return (int) flen; } @@ -231,11 +256,16 @@ va_end(ap); output = (*env)->NewStringUTF(env, denv->buffer); - (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); - if ((*env)->ExceptionOccurred(env) != NULL) { + if (!(*env)->ExceptionOccurred(env)) { + /* make sure that UTF allocation doesn't cause OOM */ + (*env)->CallVoidMethod(env, denv->dis, denv->raw_print, denv->visitor, output); + } + + if ((*env)->ExceptionOccurred(env)) { /* ignore exceptions for now */ (*env)->ExceptionClear(env); } + return cnt; } @@ -251,13 +281,24 @@ jbyteArray code, jstring options_s, jlong decode_instructions_virtual) { - jboolean isCopy; - jbyte* start = (*env)->GetByteArrayElements(env, code, &isCopy); - jbyte* end = start + (*env)->GetArrayLength(env, code); - const char * options = (*env)->GetStringUTFChars(env, options_s, &isCopy); - jclass disclass = (*env)->GetObjectClass(env, dis); + jbyte *start = NULL; + jbyte *end = NULL; + jclass disclass = NULL; + const char *options = NULL; + decode_env denv; - decode_env denv; + start = (*env)->GetByteArrayElements(env, code, NULL); + if ((*env)->ExceptionOccurred(env)) { + return; + } + end = start + (*env)->GetArrayLength(env, code); + options = (*env)->GetStringUTFChars(env, options_s, NULL); + if ((*env)->ExceptionOccurred(env)) { + (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT); + return; + } + disclass = (*env)->GetObjectClass(env, dis); + denv.env = env; denv.dis = dis; denv.visitor = visitor; @@ -266,6 +307,8 @@ denv.handle_event = (*env)->GetMethodID(env, disclass, "handleEvent", "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;J)J"); if ((*env)->ExceptionOccurred(env)) { + (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT); + (*env)->ReleaseStringUTFChars(env, options_s, options); return; } @@ -273,11 +316,13 @@ denv.raw_print = (*env)->GetMethodID(env, disclass, "rawPrint", "(Lsun/jvm/hotspot/asm/InstructionVisitor;Ljava/lang/String;)V"); if ((*env)->ExceptionOccurred(env)) { + (*env)->ReleaseByteArrayElements(env, code, start, JNI_ABORT); + (*env)->ReleaseStringUTFChars(env, options_s, options); return; } /* decode the buffer */ - (*(decode_func)(uintptr_t)decode_instructions_virtual)(startPc, + (*(decode_func)(uintptr_t)decode_instructions_virtual)((uintptr_t) startPc, startPc + end - start, (unsigned char*)start, end - start, diff -r ad8137d44154 -r 247f60f5808f hotspot/make/aix/makefiles/mapfile-vers-debug --- a/hotspot/make/aix/makefiles/mapfile-vers-debug Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/aix/makefiles/mapfile-vers-debug Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/make/aix/makefiles/mapfile-vers-product --- a/hotspot/make/aix/makefiles/mapfile-vers-product Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/aix/makefiles/mapfile-vers-product Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-debug Sat Jan 10 12:38:18 2015 -0800 @@ -70,7 +70,6 @@ _JVM_FillInStackTrace _JVM_FindClassFromCaller _JVM_FindClassFromClass - _JVM_FindClassFromClassLoader _JVM_FindClassFromBootLoader _JVM_FindLibraryEntry _JVM_FindLoadedClass diff -r ad8137d44154 -r 247f60f5808f hotspot/make/bsd/makefiles/mapfile-vers-darwin-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-darwin-product Sat Jan 10 12:38:18 2015 -0800 @@ -70,7 +70,6 @@ _JVM_FillInStackTrace _JVM_FindClassFromCaller _JVM_FindClassFromClass - _JVM_FindClassFromClassLoader _JVM_FindClassFromBootLoader _JVM_FindLibraryEntry _JVM_FindLoadedClass diff -r ad8137d44154 -r 247f60f5808f hotspot/make/bsd/makefiles/mapfile-vers-debug --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/make/bsd/makefiles/mapfile-vers-product --- a/hotspot/make/bsd/makefiles/mapfile-vers-product Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/make/linux/makefiles/mapfile-vers-debug --- a/hotspot/make/linux/makefiles/mapfile-vers-debug Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/make/linux/makefiles/mapfile-vers-product --- a/hotspot/make/linux/makefiles/mapfile-vers-product Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/linux/makefiles/mapfile-vers-product Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/make/solaris/makefiles/mapfile-vers --- a/hotspot/make/solaris/makefiles/mapfile-vers Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/make/solaris/makefiles/mapfile-vers Sat Jan 10 12:38:18 2015 -0800 @@ -72,7 +72,6 @@ JVM_FillInStackTrace; JVM_FindClassFromCaller; JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; JVM_FindClassFromBootLoader; JVM_FindLibraryEntry; JVM_FindLoadedClass; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -544,6 +544,9 @@ cmplw(CCR0, Rindex, Rlength); sldi(RsxtIndex, RsxtIndex, index_shift); blt(CCR0, LnotOOR); + // Index should be in R17_tos, array should be in R4_ARG2. + mr(R17_tos, Rindex); + mr(R4_ARG2, Rarray); load_dispatch_table(Rtmp, (address*)Interpreter::_throw_ArrayIndexOutOfBoundsException_entry); mtctr(Rtmp); bctr(); @@ -1678,6 +1681,228 @@ } } +// Argument and return type profilig. +// kills: tmp, tmp2, R0, CR0, CR1 +void InterpreterMacroAssembler::profile_obj_type(Register obj, Register mdo_addr_base, + RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2) { + Label do_nothing, do_update; + + // tmp2 = obj is allowed + assert_different_registers(obj, mdo_addr_base, tmp, R0); + assert_different_registers(tmp2, mdo_addr_base, tmp, R0); + const Register klass = tmp2; + + verify_oop(obj); + + ld(tmp, mdo_addr_offs, mdo_addr_base); + + // Set null_seen if obj is 0. + cmpdi(CCR0, obj, 0); + ori(R0, tmp, TypeEntries::null_seen); + beq(CCR0, do_update); + + load_klass(klass, obj); + + clrrdi(R0, tmp, exact_log2(-TypeEntries::type_klass_mask)); + // Basically same as andi(R0, tmp, TypeEntries::type_klass_mask); + cmpd(CCR1, R0, klass); + // Klass seen before, nothing to do (regardless of unknown bit). + //beq(CCR1, do_nothing); + + andi_(R0, klass, TypeEntries::type_unknown); + // Already unknown. Nothing to do anymore. + //bne(CCR0, do_nothing); + crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2); // cr0 eq = cr1 eq or cr0 ne + beq(CCR0, do_nothing); + + clrrdi_(R0, tmp, exact_log2(-TypeEntries::type_mask)); + orr(R0, klass, tmp); // Combine klass and null_seen bit (only used if (tmp & type_mask)==0). + beq(CCR0, do_update); // First time here. Set profile type. + + // Different than before. Cannot keep accurate profile. + ori(R0, tmp, TypeEntries::type_unknown); + + bind(do_update); + // update profile + std(R0, mdo_addr_offs, mdo_addr_base); + + align(32, 12); + bind(do_nothing); +} + +void InterpreterMacroAssembler::profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual) { + if (!ProfileInterpreter) { + return; + } + + assert_different_registers(callee, tmp1, tmp2, R28_mdx); + + if (MethodData::profile_arguments() || MethodData::profile_return()) { + Label profile_continue; + + test_method_data_pointer(profile_continue); + + int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size()); + + lbz(tmp1, in_bytes(DataLayout::tag_offset()) - off_to_start, R28_mdx); + cmpwi(CCR0, tmp1, is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag); + bne(CCR0, profile_continue); + + if (MethodData::profile_arguments()) { + Label done; + int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset()); + add(R28_mdx, off_to_args, R28_mdx); + + for (int i = 0; i < TypeProfileArgsLimit; i++) { + if (i > 0 || MethodData::profile_return()) { + // If return value type is profiled we may have no argument to profile. + ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx); + cmpdi(CCR0, tmp1, (i+1)*TypeStackSlotEntries::per_arg_count()); + addi(tmp1, tmp1, -i*TypeStackSlotEntries::per_arg_count()); + blt(CCR0, done); + } + ld(tmp1, in_bytes(Method::const_offset()), callee); + lhz(tmp1, in_bytes(ConstMethod::size_of_parameters_offset()), tmp1); + // Stack offset o (zero based) from the start of the argument + // list, for n arguments translates into offset n - o - 1 from + // the end of the argument list. But there's an extra slot at + // the top of the stack. So the offset is n - o from Lesp. + ld(tmp2, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args, R28_mdx); + subf(tmp1, tmp2, tmp1); + + sldi(tmp1, tmp1, Interpreter::logStackElementSize); + ldx(tmp1, tmp1, R15_esp); + + profile_obj_type(tmp1, R28_mdx, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args, tmp2, tmp1); + + int to_add = in_bytes(TypeStackSlotEntries::per_arg_size()); + addi(R28_mdx, R28_mdx, to_add); + off_to_args += to_add; + } + + if (MethodData::profile_return()) { + ld(tmp1, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args, R28_mdx); + addi(tmp1, tmp1, -TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count()); + } + + bind(done); + + if (MethodData::profile_return()) { + // We're right after the type profile for the last + // argument. tmp1 is the number of cells left in the + // CallTypeData/VirtualCallTypeData to reach its end. Non null + // if there's a return to profile. + assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type"); + sldi(tmp1, tmp1, exact_log2(DataLayout::cell_size)); + add(R28_mdx, tmp1, R28_mdx); + } + } else { + assert(MethodData::profile_return(), "either profile call args or call ret"); + update_mdp_by_constant(in_bytes(TypeEntriesAtCall::return_only_size())); + } + + // Mdp points right after the end of the + // CallTypeData/VirtualCallTypeData, right after the cells for the + // return value type if there's one. + align(32, 12); + bind(profile_continue); + } +} + +void InterpreterMacroAssembler::profile_return_type(Register ret, Register tmp1, Register tmp2) { + assert_different_registers(ret, tmp1, tmp2); + if (ProfileInterpreter && MethodData::profile_return()) { + Label profile_continue; + + test_method_data_pointer(profile_continue); + + if (MethodData::profile_return_jsr292_only()) { + // If we don't profile all invoke bytecodes we must make sure + // it's a bytecode we indeed profile. We can't go back to the + // begining of the ProfileData we intend to update to check its + // type because we're right after it and we don't known its + // length. + lbz(tmp1, 0, R14_bcp); + lbz(tmp2, Method::intrinsic_id_offset_in_bytes(), R19_method); + cmpwi(CCR0, tmp1, Bytecodes::_invokedynamic); + cmpwi(CCR1, tmp1, Bytecodes::_invokehandle); + cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + cmpwi(CCR1, tmp2, vmIntrinsics::_compiledLambdaForm); + cror(/*CR0 eq*/2, /*CR1 eq*/4+2, /*CR0 eq*/2); + bne(CCR0, profile_continue); + } + + profile_obj_type(ret, R28_mdx, -in_bytes(ReturnTypeEntry::size()), tmp1, tmp2); + + align(32, 12); + bind(profile_continue); + } +} + +void InterpreterMacroAssembler::profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4) { + if (ProfileInterpreter && MethodData::profile_parameters()) { + Label profile_continue, done; + + test_method_data_pointer(profile_continue); + + // Load the offset of the area within the MDO used for + // parameters. If it's negative we're not profiling any parameters. + lwz(tmp1, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset()), R28_mdx); + cmpwi(CCR0, tmp1, 0); + blt(CCR0, profile_continue); + + // Compute a pointer to the area for parameters from the offset + // and move the pointer to the slot for the last + // parameters. Collect profiling from last parameter down. + // mdo start + parameters offset + array length - 1 + + // Pointer to the parameter area in the MDO. + const Register mdp = tmp1; + add(mdp, tmp1, R28_mdx); + + // Pffset of the current profile entry to update. + const Register entry_offset = tmp2; + // entry_offset = array len in number of cells + ld(entry_offset, in_bytes(ArrayData::array_len_offset()), mdp); + + int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0)); + assert(off_base % DataLayout::cell_size == 0, "should be a number of cells"); + + // entry_offset (number of cells) = array len - size of 1 entry + offset of the stack slot field + addi(entry_offset, entry_offset, -TypeStackSlotEntries::per_arg_count() + (off_base / DataLayout::cell_size)); + // entry_offset in bytes + sldi(entry_offset, entry_offset, exact_log2(DataLayout::cell_size)); + + Label loop; + align(32, 12); + bind(loop); + + // Load offset on the stack from the slot for this parameter. + ld(tmp3, entry_offset, mdp); + sldi(tmp3, tmp3, Interpreter::logStackElementSize); + neg(tmp3, tmp3); + // Read the parameter from the local area. + ldx(tmp3, tmp3, R18_locals); + + // Make entry_offset now point to the type field for this parameter. + int type_base = in_bytes(ParametersTypeData::type_offset(0)); + assert(type_base > off_base, "unexpected"); + addi(entry_offset, entry_offset, type_base - off_base); + + // Profile the parameter. + profile_obj_type(tmp3, mdp, entry_offset, tmp4, tmp3); + + // Go to next parameter. + int delta = TypeStackSlotEntries::per_arg_count() * DataLayout::cell_size + (type_base - off_base); + cmpdi(CCR0, entry_offset, off_base + delta); + addi(entry_offset, entry_offset, -delta); + bge(CCR0, loop); + + align(32, 12); + bind(profile_continue); + } +} + // Add a InterpMonitorElem to stack (see frame_sparc.hpp). void InterpreterMacroAssembler::add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2) { @@ -2039,20 +2264,19 @@ bne(CCR0, test); address fd = CAST_FROM_FN_PTR(address, verify_return_address); - unsigned int nbytes_save = 10*8; // 10 volatile gprs - - save_LR_CR(Rtmp); + const int nbytes_save = 11*8; // volatile gprs except R0 + save_volatile_gprs(R1_SP, -nbytes_save); // except R0 + save_LR_CR(Rtmp); // Save in old frame. push_frame_reg_args(nbytes_save, Rtmp); - save_volatile_gprs(R1_SP, 112); // except R0 load_const_optimized(Rtmp, fd, R0); mr_if_needed(R4_ARG2, reg); mr(R3_ARG1, R19_method); call_c(Rtmp); // call C - restore_volatile_gprs(R1_SP, 112); // except R0 pop_frame(); restore_LR_CR(Rtmp); + restore_volatile_gprs(R1_SP, -nbytes_save); // except R0 b(skip); // Perform a more elaborate out-of-line call. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp --- a/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/interp_masm_ppc_64.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -255,6 +255,12 @@ void record_klass_in_profile(Register receiver, Register scratch1, Register scratch2, bool is_virtual_call); void record_klass_in_profile_helper(Register receiver, Register scratch1, Register scratch2, int start_row, Label& done, bool is_virtual_call); + // Argument and return type profiling. + void profile_obj_type(Register obj, Register mdo_addr_base, RegisterOrConstant mdo_addr_offs, Register tmp, Register tmp2); + void profile_arguments_type(Register callee, Register tmp1, Register tmp2, bool is_virtual); + void profile_return_type(Register ret, Register tmp1, Register tmp2); + void profile_parameters_type(Register tmp1, Register tmp2, Register tmp3, Register tmp4); + #endif // !CC_INTERP // Debugging diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -807,6 +807,7 @@ // For verify_oops. void MacroAssembler::save_volatile_gprs(Register dst, int offset) { + std(R2, offset, dst); offset += 8; std(R3, offset, dst); offset += 8; std(R4, offset, dst); offset += 8; std(R5, offset, dst); offset += 8; @@ -821,6 +822,7 @@ // For verify_oops. void MacroAssembler::restore_volatile_gprs(Register src, int offset) { + ld(R2, offset, src); offset += 8; ld(R3, offset, src); offset += 8; ld(R4, offset, src); offset += 8; ld(R5, offset, src); offset += 8; @@ -1187,6 +1189,16 @@ call_VM(oop_result, entry_point, check_exceptions); } +void MacroAssembler::call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg_3, + bool check_exceptions) { + // R3_ARG1 is reserved for the thread + mr_if_needed(R4_ARG2, arg_1); + assert(arg_2 != R4_ARG2, "smashed argument"); + mr_if_needed(R5_ARG3, arg_2); + mr_if_needed(R6_ARG4, arg_3); + call_VM(oop_result, entry_point, check_exceptions); +} + void MacroAssembler::call_VM_leaf(address entry_point) { call_VM_leaf_base(entry_point); } @@ -3059,35 +3071,27 @@ if (!VerifyOops) { return; } - // Will be preserved. - Register tmp = R11; - assert(oop != tmp, "precondition"); - unsigned int nbytes_save = 10*8; // 10 volatile gprs + address/* FunctionDescriptor** */fd = StubRoutines::verify_oop_subroutine_entry_address(); - // save tmp - mr(R0, tmp); - // kill tmp - save_LR_CR(tmp); + const Register tmp = R11; // Will be preserved. + const int nbytes_save = 11*8; // Volatile gprs except R0. + save_volatile_gprs(R1_SP, -nbytes_save); // except R0 + + if (oop == tmp) mr(R4_ARG2, oop); + save_LR_CR(tmp); // save in old frame push_frame_reg_args(nbytes_save, tmp); - // restore tmp - mr(tmp, R0); - save_volatile_gprs(R1_SP, 112); // except R0 // load FunctionDescriptor** / entry_address * - load_const(tmp, fd); + load_const_optimized(tmp, fd, R0); // load FunctionDescriptor* / entry_address ld(tmp, 0, tmp); - mr(R4_ARG2, oop); - load_const(R3_ARG1, (address)msg); - // call destination for its side effect + if (oop != tmp) mr_if_needed(R4_ARG2, oop); + load_const_optimized(R3_ARG1, (address)msg, R0); + // Call destination for its side effect. call_c(tmp); - restore_volatile_gprs(R1_SP, 112); // except R0 + pop_frame(); - // save tmp - mr(R0, tmp); - // kill tmp restore_LR_CR(tmp); - // restore tmp - mr(tmp, R0); + restore_volatile_gprs(R1_SP, -nbytes_save); // except R0 } const char* stop_types[] = { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp --- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -369,6 +369,7 @@ void call_VM(Register oop_result, address entry_point, bool check_exceptions = true); void call_VM(Register oop_result, address entry_point, Register arg_1, bool check_exceptions = true); void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, bool check_exceptions = true); + void call_VM(Register oop_result, address entry_point, Register arg_1, Register arg_2, Register arg3, bool check_exceptions = true); void call_VM_leaf(address entry_point); void call_VM_leaf(address entry_point, Register arg_1); void call_VM_leaf(address entry_point, Register arg_1, Register arg_2); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/nativeInst_ppc.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -100,10 +100,7 @@ MacroAssembler* a = new MacroAssembler(&cb); // Patch the call. - if (ReoptimizeCallSequences && - a->is_within_range_of_b(dest, addr_call)) { - a->bl(dest); - } else { + if (!ReoptimizeCallSequences || !a->is_within_range_of_b(dest, addr_call)) { address trampoline_stub_addr = get_trampoline(); // We did not find a trampoline stub because the current codeblob @@ -115,9 +112,12 @@ // Patch the constant in the call's trampoline stub. NativeCallTrampolineStub_at(trampoline_stub_addr)->set_destination(dest); + dest = trampoline_stub_addr; + } - a->bl(trampoline_stub_addr); - } + OrderAccess::release(); + a->bl(dest); + ICache::ppc64_flush_icache_bytes(addr_call, code_size); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/ppc.ad --- a/hotspot/src/cpu/ppc/vm/ppc.ad Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/ppc.ad Sat Jan 10 12:38:18 2015 -0800 @@ -1936,8 +1936,9 @@ // -------------------------------------------------------------------- // Check for hi bits still needing moving. Only happens for misaligned // arguments to native calls. - if (src_hi == dst_hi) + if (src_hi == dst_hi) { return ppc64Opcode_none; // Self copy; no move. + } ShouldNotReachHere(); return ppc64Opcode_undefined; @@ -1959,14 +1960,15 @@ } uint MachNopNode::size(PhaseRegAlloc *ra_) const { - return _count * 4; + return _count * 4; } #ifndef PRODUCT void BoxLockNode::format(PhaseRegAlloc *ra_, outputStream *st) const { int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); - int reg = ra_->get_reg_first(this); - st->print("ADDI %s, SP, %d \t// box node", Matcher::regName[reg], offset); + char reg_str[128]; + ra_->dump_register(this, reg_str); + st->print("ADDI %s, SP, %d \t// box node", reg_str, offset); } #endif diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/templateInterpreter_ppc.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -91,7 +91,7 @@ // Thread will be loaded to R3_ARG1. // Target class oop is in register R5_ARG3 by convention! - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose, R17_tos, R5_ARG3)); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_ClassCastException_verbose), R17_tos, R5_ARG3); // Above call must not return here since exception pending. DEBUG_ONLY(__ should_not_reach_here();) return entry; @@ -172,6 +172,10 @@ // Compiled code destroys templateTableBase, reload. __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R12_scratch2); + if (state == atos) { + __ profile_return_type(R3_RET, R11_scratch1, R12_scratch2); + } + const Register cache = R11_scratch1; const Register size = R12_scratch2; __ get_cache_and_index_at_bcp(cache, 1, index_size); @@ -1189,6 +1193,10 @@ __ li(R0, 1); __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread); } + + // Argument and return type profiling. + __ profile_parameters_type(R3_ARG1, R4_ARG2, R5_ARG3, R6_ARG4); + // Increment invocation counter and check for overflow. if (inc_counter) { generate_counter_incr(&invocation_counter_overflow, &profile_method, &profile_method_continue); @@ -1469,6 +1477,8 @@ __ resize_frame_absolute(R12_scratch2, R11_scratch1, R0); if (ProfileInterpreter) { __ set_method_data_pointer_for_bcp(); + __ ld(R11_scratch1, 0, R1_SP); + __ std(R28_mdx, _ijava_state_neg(mdx), R11_scratch1); } #if INCLUDE_JVMTI Label L_done; @@ -1480,13 +1490,11 @@ // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. __ ld(R4_ARG2, 0, R18_locals); - __ call_VM(R11_scratch1, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), - R4_ARG2, R19_method, R14_bcp); - - __ cmpdi(CCR0, R11_scratch1, 0); + __ MacroAssembler::call_VM(R4_ARG2, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), R4_ARG2, R19_method, R14_bcp, false); + __ restore_interpreter_state(R11_scratch1, /*bcp_and_mdx_only*/ true); + __ cmpdi(CCR0, R4_ARG2, 0); __ beq(CCR0, L_done); - - __ std(R11_scratch1, wordSize, R15_esp); + __ std(R4_ARG2, wordSize, R15_esp); __ bind(L_done); #endif // INCLUDE_JVMTI __ dispatch_next(vtos); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp --- a/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/templateTable_ppc_64.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -3235,6 +3235,8 @@ // Load target. __ addi(Rrecv_klass, Rrecv_klass, base + vtableEntry::method_offset_in_bytes()); __ ldx(Rtarget_method, Rindex, Rrecv_klass); + // Argument and return type profiling. + __ profile_arguments_type(Rtarget_method, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */, true); __ call_from_interpreter(Rtarget_method, Rret, Rrecv_klass /* scratch1 */, Rtemp /* scratch2 */); } @@ -3318,6 +3320,8 @@ __ null_check_throw(Rrecv, -1, Rscratch1); __ profile_final_call(Rrecv, Rscratch1); + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, true); // Do the call. __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1, Rscratch2); @@ -3339,6 +3343,8 @@ __ null_check_throw(Rreceiver, -1, R11_scratch1); __ profile_call(R11_scratch1, R12_scratch2); + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, R11_scratch1, R12_scratch2, false); __ call_from_interpreter(Rmethod, Rret_addr, R11_scratch1, R12_scratch2); } @@ -3353,6 +3359,8 @@ prepare_invoke(byte_no, R19_method, Rret_addr, noreg, noreg, Rflags, R11_scratch1); __ profile_call(R11_scratch1, R12_scratch2); + // Argument and return type profiling. + __ profile_arguments_type(R19_method, R11_scratch1, R12_scratch2, false); __ call_from_interpreter(R19_method, Rret_addr, R11_scratch1, R12_scratch2); } @@ -3374,6 +3382,8 @@ // Final call case. __ profile_final_call(Rtemp1, Rscratch); + // Argument and return type profiling. + __ profile_arguments_type(Rindex, Rscratch, Rrecv_klass /* scratch */, true); // Do the final call - the index (f2) contains the method. __ call_from_interpreter(Rindex, Rret, Rscratch, Rrecv_klass /* scratch */); @@ -3425,6 +3435,8 @@ __ cmpdi(CCR0, Rindex, 0); __ beq(CCR0, Lthrow_ame); // Found entry. Jump off! + // Argument and return type profiling. + __ profile_arguments_type(Rindex, Rscratch1, Rscratch2, true); __ call_from_interpreter(Rindex, Rret_addr, Rscratch1, Rscratch2); // Vtable entry was NULL => Throw abstract method error. @@ -3468,6 +3480,8 @@ // to be the callsite object the bootstrap method returned. This is passed to a // "link" method which does the dispatch (Most likely just grabs the MH stored // inside the callsite and does an invokehandle). + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, false); __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */); } @@ -3488,6 +3502,8 @@ __ profile_final_call(Rrecv, Rscratch1); // Still no call from handle => We call the method handle interpreter here. + // Argument and return type profiling. + __ profile_arguments_type(Rmethod, Rscratch1, Rscratch2, true); __ call_from_interpreter(Rmethod, Rret_addr, Rscratch1 /* scratch1 */, Rscratch2 /* scratch2 */); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp --- a/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/ppc/vm/vm_version_ppc.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -134,13 +134,44 @@ } assert(AllocatePrefetchLines > 0, "invalid value"); - if (AllocatePrefetchLines < 1) // Set valid value in product VM. + if (AllocatePrefetchLines < 1) { // Set valid value in product VM. AllocatePrefetchLines = 1; // Conservative value. + } - if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) + if (AllocatePrefetchStyle == 3 && AllocatePrefetchDistance < cache_line_size) { AllocatePrefetchStyle = 1; // Fall back if inappropriate. + } assert(AllocatePrefetchStyle >= 0, "AllocatePrefetchStyle should be positive"); + + if (UseCRC32Intrinsics) { + if (!FLAG_IS_DEFAULT(UseCRC32Intrinsics)) + warning("CRC32 intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseCRC32Intrinsics, false); + } + + // The AES intrinsic stubs require AES instruction support. + if (UseAES) { + warning("AES instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseAES, false); + } + if (UseAESIntrinsics) { + if (!FLAG_IS_DEFAULT(UseAESIntrinsics)) + warning("AES intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseAESIntrinsics, false); + } + + if (UseSHA) { + warning("SHA instructions are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA, false); + } + if (UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics) { + warning("SHA intrinsics are not available on this CPU"); + FLAG_SET_DEFAULT(UseSHA1Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA256Intrinsics, false); + FLAG_SET_DEFAULT(UseSHA512Intrinsics, false); + } + } void VM_Version::print_features() { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp --- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -675,7 +675,7 @@ case handle_exception_nofpu_id: case handle_exception_id: // At this point all registers MAY be live. - oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id); + oop_map = save_live_registers(sasm, 1 /*thread*/, id != handle_exception_nofpu_id); break; case handle_exception_from_callee_id: { // At this point all registers except exception oop (RAX) and @@ -748,7 +748,7 @@ case handle_exception_nofpu_id: case handle_exception_id: // Restore the registers that were saved at the beginning. - restore_live_registers(sasm, id == handle_exception_nofpu_id); + restore_live_registers(sasm, id != handle_exception_nofpu_id); break; case handle_exception_from_callee_id: // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/aix/vm/osThread_aix.cpp --- a/hotspot/src/os/aix/vm/osThread_aix.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/aix/vm/osThread_aix.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * Copyright 2012, 2013 SAP AG. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -45,7 +45,8 @@ sigemptyset(&_caller_sigmask); - _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true); + _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true, + Monitor::_safepoint_check_never); assert(_startThread_lock !=NULL, "check"); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/aix/vm/os_aix.cpp --- a/hotspot/src/os/aix/vm/os_aix.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/aix/vm/os_aix.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -124,12 +124,6 @@ } #endif -// Excerpts from systemcfg.h definitions newer than AIX 5.3 -#ifndef PV_7 -# define PV_7 0x200000 // Power PC 7 -# define PV_7_Compat 0x208000 // Power PC 7 -#endif - #define MAX_PATH (2 * K) // for timer info max values which include all bits @@ -140,17 +134,40 @@ #define ERROR_MP_VMGETINFO_FAILED 102 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103 -// the semantics in this file are thus that codeptr_t is a *real code ptr* +// The semantics in this file are thus that codeptr_t is a *real code ptr*. // This means that any function taking codeptr_t as arguments will assume // a real codeptr and won't handle function descriptors (eg getFuncName), // whereas functions taking address as args will deal with function -// descriptors (eg os::dll_address_to_library_name) +// descriptors (eg os::dll_address_to_library_name). typedef unsigned int* codeptr_t; -// typedefs for stackslots, stack pointers, pointers to op codes +// Typedefs for stackslots, stack pointers, pointers to op codes. typedef unsigned long stackslot_t; typedef stackslot_t* stackptr_t; +// Excerpts from systemcfg.h definitions newer than AIX 5.3. +#ifndef PV_7 +#define PV_7 0x200000 /* Power PC 7 */ +#define PV_7_Compat 0x208000 /* Power PC 7 */ +#endif +#ifndef PV_8 +#define PV_8 0x300000 /* Power PC 8 */ +#define PV_8_Compat 0x308000 /* Power PC 8 */ +#endif + +#define trcVerbose(fmt, ...) { /* PPC port */ \ + if (Verbose) { \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ + fputc('\n', stderr); fflush(stderr); \ + } \ +} +#define trc(fmt, ...) /* PPC port */ + +#define ERRBYE(s) { \ + trcVerbose(s); \ + return -1; \ +} + // query dimensions of the stack of the calling thread static void query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); @@ -182,12 +199,12 @@ return true; } -// macro to check a given stack pointer against given stack limits and to die if test fails +// Macro to check a given stack pointer against given stack limits and to die if test fails. #define CHECK_STACK_PTR(sp, stack_base, stack_size) { \ guarantee(is_valid_stackpointer((stackptr_t)(sp), (stackptr_t)(stack_base), stack_size), "Stack Pointer Invalid"); \ } -// macro to check the current stack pointer against given stacklimits +// Macro to check the current stack pointer against given stacklimits. #define CHECK_CURRENT_STACK_PTR(stack_base, stack_size) { \ address sp; \ sp = os::current_stack_pointer(); \ @@ -221,7 +238,7 @@ static pid_t _initial_pid = 0; static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) static sigset_t SR_sigset; -static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls */ +static pthread_mutex_t dl_mutex; // Used to protect dlsym() calls. julong os::available_memory() { return Aix::available_memory(); @@ -253,7 +270,6 @@ return false; } - // Return true if user is running as root. bool os::have_special_privileges() { @@ -284,8 +300,7 @@ for (int i = 0; i < numFullDisclaimsNeeded; i ++) { if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { - //if (Verbose) - fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); + trc("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); return false; } p += maxDisclaimSize; @@ -293,8 +308,7 @@ if (lastDisclaimSize > 0) { if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { - //if (Verbose) - fprintf(stderr, "Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); + trc("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); return false; } } @@ -334,11 +348,11 @@ void os::Aix::initialize_system_info() { - // get the number of online(logical) cpus instead of configured + // Get the number of online(logical) cpus instead of configured. os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN); assert(_processor_count > 0, "_processor_count must be > 0"); - // retrieve total physical storage + // Retrieve total physical storage. os::Aix::meminfo_t mi; if (!os::Aix::get_meminfo(&mi)) { fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr); @@ -513,7 +527,6 @@ } // end os::Aix::query_multipage_support() -// The code for this method was initially derived from the version in os_linux.cpp. void os::init_system_properties_values() { #define DEFAULT_LIBPATH "/usr/lib:/lib" @@ -603,10 +616,11 @@ sigaction(sig, (struct sigaction*)NULL, &oact); void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) : CAST_FROM_FN_PTR(void*, oact.sa_handler); - if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) + if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) { return true; - else + } else { return false; + } } void os::Aix::signal_sets_init() { @@ -780,6 +794,9 @@ // get the processor version from _system_configuration switch (_system_configuration.version) { + case PV_8: + strcpy(pci->version, "Power PC 8"); + break; case PV_7: strcpy(pci->version, "Power PC 7"); break; @@ -807,6 +824,9 @@ case PV_7_Compat: strcpy(pci->version, "PV_7_Compat"); break; + case PV_8_Compat: + strcpy(pci->version, "PV_8_Compat"); + break; default: strcpy(pci->version, "unknown"); } @@ -942,7 +962,9 @@ pthread_attr_destroy(&attr); - if (ret != 0) { + if (ret == 0) { + // PPC port traceOsMisc(("Created New Thread : pthread-id %u", tid)); + } else { if (PrintMiscellaneous && (Verbose || WizardMode)) { perror("pthread_create()"); } @@ -1103,8 +1125,7 @@ if (os::Aix::on_pase()) { Unimplemented(); return 0; - } - else { + } else { // On AIX use the precision of processors real time clock // or time base registers. timebasestruct_t time; @@ -1152,7 +1173,6 @@ } } - char * os::local_time_string(char *buf, size_t buflen) { struct tm t; time_t long_time; @@ -1190,7 +1210,6 @@ if (abort_hook != NULL) { abort_hook(); } - } // Note: os::abort() might be called very early during initialization, or @@ -1222,8 +1241,7 @@ // from src/solaris/hpi/src/system_md.c size_t os::lasterror(char *buf, size_t len) { - - if (errno == 0) return 0; + if (errno == 0) return 0; const char *s = ::strerror(errno); size_t n = ::strlen(s); @@ -1236,6 +1254,7 @@ } intx os::current_thread_id() { return (intx)pthread_self(); } + int os::current_process_id() { // This implementation returns a unique pid, the pid of the @@ -1372,9 +1391,9 @@ if (offset) { *offset = -1; } - if (buf) { - buf[0] = '\0'; - } + // Buf is not optional, but offset is optional. + assert(buf != NULL, "sanity check"); + buf[0] = '\0'; // Resolve function ptr literals first. addr = resolve_function_descriptor_to_code_pointer(addr); @@ -1407,12 +1426,9 @@ return 0; } - if (Verbose) { - fprintf(stderr, "pc outside any module"); - } + trcVerbose("pc outside any module"); return -1; - } bool os::dll_address_to_library_name(address addr, char* buf, @@ -1420,9 +1436,9 @@ if (offset) { *offset = -1; } - if (buf) { - buf[0] = '\0'; - } + // Buf is not optional, but offset is optional. + assert(buf != NULL, "sanity check"); + buf[0] = '\0'; // Resolve function ptr literals first. addr = resolve_function_descriptor_to_code_pointer(addr); @@ -1437,7 +1453,7 @@ } // Loads .dll/.so and in case of error it checks if .dll/.so was built -// for the same architecture as Hotspot is running on +// for the same architecture as Hotspot is running on. void *os::dll_load(const char *filename, char *ebuf, int ebuflen) { if (ebuf && ebuflen > 0) { @@ -1600,7 +1616,6 @@ st->cr(); } - static void print_signal_handler(outputStream* st, int sig, char* buf, size_t buflen); @@ -1624,7 +1639,7 @@ static char saved_jvm_path[MAXPATHLEN] = {0}; -// Find the full path to the current module, libjvm.so or libjvm_g.so +// Find the full path to the current module, libjvm.so. void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -1695,7 +1710,7 @@ // Do not block out synchronous signals in the signal handler. // Blocking synchronous signals only makes sense if you can really // be sure that those signals won't happen during signal handling, - // when the blocking applies. Normal signal handlers are lean and + // when the blocking applies. Normal signal handlers are lean and // do not cause signals. But our signal handlers tend to be "risky" // - secondary SIGSEGV, SIGILL, SIGBUS' may and do happen. // On AIX, PASE there was a case where a SIGSEGV happened, followed @@ -2861,13 +2876,9 @@ param.sched_priority = newpri; int ret = pthread_setschedparam(thr, policy, ¶m); - if (Verbose) { - if (ret == 0) { - fprintf(stderr, "changed priority of thread %d to %d\n", (int)thr, newpri); - } else { - fprintf(stderr, "Could not changed priority for thread %d to %d (error %d, %s)\n", - (int)thr, newpri, ret, strerror(ret)); - } + if (ret != 0) { + trcVerbose("Could not change priority for thread %d to %d (error %d, %s)", + (int)thr, newpri, ret, strerror(ret)); } return (ret == 0) ? OS_OK : OS_ERR; } @@ -2988,7 +2999,6 @@ errno = old_errno; } - static int SR_initialize() { struct sigaction act; char *s; @@ -3187,7 +3197,6 @@ JVM_handle_aix_signal(sig, info, uc, true); } - // This boolean allows users to forward their own non-matching signals // to JVM_handle_aix_signal, harmlessly. bool os::Aix::signal_handlers_are_installed = false; @@ -3381,7 +3390,7 @@ set_signal_handler(SIGDANGER, true); if (libjsig_is_loaded) { - // Tell libjsig jvm finishes setting signal handlers + // Tell libjsig jvm finishes setting signal handlers. (*end_signal_setting)(); } @@ -3397,7 +3406,7 @@ tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); check_signals = false; } - // need to initialize check_signal_done + // Need to initialize check_signal_done. ::sigemptyset(&check_signal_done); } } @@ -3471,7 +3480,6 @@ st->cr(); } - #define DO_SIGNAL_CHECK(sig) \ if (!sigismember(&check_signal_done, sig)) \ os::Aix::check_signal_handler(sig) @@ -3532,7 +3540,6 @@ ? CAST_FROM_FN_PTR(address, act.sa_sigaction) : CAST_FROM_FN_PTR(address, act.sa_handler); - switch(sig) { case SIGSEGV: case SIGBUS: @@ -3685,15 +3692,13 @@ pthread_mutex_init(&dl_mutex, NULL); } -// this is called _after_ the global arguments have been parsed +// This is called _after_ the global arguments have been parsed. jint os::init_2(void) { - if (Verbose) { - fprintf(stderr, "processor count: %d\n", os::_processor_count); - fprintf(stderr, "physical memory: %lu\n", Aix::_physical_memory); - } - - // initially build up the loaded dll map + trcVerbose("processor count: %d", os::_processor_count); + trcVerbose("physical memory: %lu", Aix::_physical_memory); + + // Initially build up the loaded dll map. LoadedLibraries::reload(); const int page_size = Aix::page_size(); @@ -3743,7 +3748,7 @@ } if (map_address != (address) MAP_FAILED) { - // map succeeded, but polling_page is not at wished address, unmap and continue. + // Map succeeded, but polling_page is not at wished address, unmap and continue. ::munmap(map_address, map_size); map_address = (address) MAP_FAILED; } @@ -3797,7 +3802,7 @@ // Make the stack size a multiple of the page size so that // the yellow/red zones can be guarded. - // note that this can be 0, if no default stacksize was set + // Note that this can be 0, if no default stacksize was set. JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); Aix::libpthread_init(); @@ -4088,7 +4093,6 @@ return fd; } - // create binary file, rewriting existing file if required int os::create_binary_file(const char* path, bool rewrite_existing) { int oflags = O_WRONLY | O_CREAT; @@ -4169,7 +4173,6 @@ return mapped_address; } - // Remap a block of memory. char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, @@ -4217,14 +4220,14 @@ jlong sys_time = 0; jlong user_time = 0; - // reimplemented using getthrds64(). + // Reimplemented using getthrds64(). // - // goes like this: + // Works like this: // For the thread in question, get the kernel thread id. Then get the // kernel thread statistics using that id. // // This only works of course when no pthread scheduling is used, - // ie there is a 1:1 relationship to kernel threads. + // i.e. there is a 1:1 relationship to kernel threads. // On AIX, see AIXTHREAD_SCOPE variable. pthread_t pthtid = thread->osthread()->pthread_id(); @@ -4371,14 +4374,12 @@ memset(&uts, 0, sizeof(uts)); strcpy(uts.sysname, "?"); if (::uname(&uts) == -1) { - fprintf(stderr, "uname failed (%d)\n", errno); + trc("uname failed (%d)", errno); guarantee(0, "Could not determine whether we run on AIX or PASE"); } else { - if (Verbose) { - fprintf(stderr,"uname says: sysname \"%s\" version \"%s\" release \"%s\" " - "node \"%s\" machine \"%s\"\n", - uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); - } + trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" " + "node \"%s\" machine \"%s\"\n", + uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); const int major = atoi(uts.version); assert(major > 0, "invalid OS version"); const int minor = atoi(uts.release); @@ -4390,12 +4391,10 @@ // We run on AIX. We do not support versions older than AIX 5.3. _on_pase = 0; if (_os_version < 0x0503) { - fprintf(stderr, "AIX release older than AIX 5.3 not supported.\n"); + trc("AIX release older than AIX 5.3 not supported."); assert(false, "AIX release too old."); } else { - if (Verbose) { - fprintf(stderr, "We run on AIX %d.%d\n", major, minor); - } + trcVerbose("We run on AIX %d.%d\n", major, minor); } } else { assert(false, "unknown OS"); @@ -4403,7 +4402,6 @@ } guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release"); - } // end: os::Aix::initialize_os_info() // Scan environment for important settings which might effect the VM. @@ -4441,12 +4439,10 @@ // Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before // exec() ? before loading the libjvm ? ....) p = ::getenv("XPG_SUS_ENV"); - if (Verbose) { - fprintf(stderr, "XPG_SUS_ENV=%s.\n", p ? p : ""); - } + trcVerbose("XPG_SUS_ENV=%s.", p ? p : ""); if (p && strcmp(p, "ON") == 0) { _xpg_sus_mode = 1; - fprintf(stderr, "Unsupported setting: XPG_SUS_ENV=ON\n"); + trc("Unsupported setting: XPG_SUS_ENV=ON"); // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to // clobber address ranges. If we ever want to support that, we have to do some // testing first. @@ -4458,10 +4454,7 @@ // Switch off AIX internal (pthread) guard pages. This has // immediate effect for any pthread_create calls which follow. p = ::getenv("AIXTHREAD_GUARDPAGES"); - if (Verbose) { - fprintf(stderr, "AIXTHREAD_GUARDPAGES=%s.\n", p ? p : ""); - fprintf(stderr, "setting AIXTHREAD_GUARDPAGES=0.\n"); - } + trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : ""); rc = ::putenv("AIXTHREAD_GUARDPAGES=0"); guarantee(rc == 0, ""); @@ -4479,7 +4472,7 @@ assert(os::Aix::on_aix(), "AIX only"); if (!libperfstat::init()) { - fprintf(stderr, "libperfstat initialization failed.\n"); + trc("libperfstat initialization failed."); assert(false, "libperfstat initialization failed"); } else { if (Verbose) { @@ -4651,7 +4644,6 @@ return abstime; } - // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. // Conceptually TryPark() should be equivalent to park(0). @@ -4732,7 +4724,7 @@ while (_Event < 0) { status = pthread_cond_timedwait(_cond, _mutex, &abst); assert_status(status == 0 || status == ETIMEDOUT, - status, "cond_timedwait"); + status, "cond_timedwait"); if (!FilterSpuriousWakeups) break; // previous semantics if (status == ETIMEDOUT) break; // We consume and ignore EINTR and spurious wakeups. @@ -4866,9 +4858,9 @@ // Optional fast-path check: // Return immediately if a permit is available. if (_counter > 0) { - _counter = 0; - OrderAccess::fence(); - return; + _counter = 0; + OrderAccess::fence(); + return; } Thread* thread = Thread::current(); @@ -4890,7 +4882,6 @@ unpackTime(&absTime, isAbsolute, time); } - // Enter safepoint region // Beware of deadlocks such as 6317397. // The per-thread Parker:: mutex is a classic leaf-lock. @@ -4978,7 +4969,6 @@ } } - extern char** environ; // Run the specified command in a separate process. Return its exit value, @@ -4997,44 +4987,43 @@ } else if (pid == 0) { // child process - // try to be consistent with system(), which uses "/usr/bin/sh" on AIX + // Try to be consistent with system(), which uses "/usr/bin/sh" on AIX. execve("/usr/bin/sh", argv, environ); // execve failed _exit(-1); - } else { + } else { // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't // care about the actual exit code, for now. int status; - // Wait for the child process to exit. This returns immediately if + // Wait for the child process to exit. This returns immediately if // the child has already exited. */ while (waitpid(pid, &status, 0) < 0) { - switch (errno) { + switch (errno) { case ECHILD: return 0; case EINTR: break; default: return -1; - } + } } if (WIFEXITED(status)) { - // The child exited normally; get its exit code. - return WEXITSTATUS(status); + // The child exited normally; get its exit code. + return WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { - // The child exited because of a signal - // The best value to return is 0x80 + signal number, - // because that is what all Unix shells do, and because - // it allows callers to distinguish between process exit and - // process death by signal. - return 0x80 + WTERMSIG(status); + // The child exited because of a signal. + // The best value to return is 0x80 + signal number, + // because that is what all Unix shells do, and because + // it allows callers to distinguish between process exit and + // process death by signal. + return 0x80 + WTERMSIG(status); } else { - // Unknown exit code; pass it through - return status; + // Unknown exit code; pass it through. + return status; } } - // Remove warning. return -1; } @@ -5049,7 +5038,7 @@ struct stat statbuf; char buf[MAXPATHLEN]; char libmawtpath[MAXPATHLEN]; - const char *xawtstr = "/xawt/libmawt.so"; + const char *xawtstr = "/xawt/libmawt.so"; const char *new_xawtstr = "/libawt_xawt.so"; char *p; @@ -5090,6 +5079,9 @@ return 0; } + jio_snprintf(buffer, bufferSize, "%s/core or core.%d", + p, current_process_id()); + return strlen(buffer); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/aix/vm/os_aix.hpp --- a/hotspot/src/os/aix/vm/os_aix.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/aix/vm/os_aix.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -209,7 +209,7 @@ return _can_use_16M_pages == 1 ? true : false; } - static address ucontext_get_pc(ucontext_t* uc); + static address ucontext_get_pc(const ucontext_t* uc); static intptr_t* ucontext_get_sp(ucontext_t* uc); static intptr_t* ucontext_get_fp(ucontext_t* uc); // Set PC into context. Needed for continuation after signal. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/bsd/vm/osThread_bsd.cpp --- a/hotspot/src/os/bsd/vm/osThread_bsd.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/bsd/vm/osThread_bsd.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,8 @@ sigemptyset(&_caller_sigmask); - _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true); + _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true, + Monitor::_safepoint_check_never); assert(_startThread_lock !=NULL, "check"); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/bsd/vm/os_bsd.cpp --- a/hotspot/src/os/bsd/vm/os_bsd.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -4673,7 +4673,7 @@ // Get the default path to the core file // Returns the length of the string int os::get_core_path(char* buffer, size_t bufferSize) { - int n = jio_snprintf(buffer, bufferSize, "/cores"); + int n = jio_snprintf(buffer, bufferSize, "/cores/core.%d", current_process_id()); // Truncate if theoretical string was longer than bufferSize n = MIN2(n, (int)bufferSize); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/linux/vm/osThread_linux.cpp --- a/hotspot/src/os/linux/vm/osThread_linux.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/linux/vm/osThread_linux.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,8 @@ sigemptyset(&_caller_sigmask); - _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true); + _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true, + Monitor::_safepoint_check_never); assert(_startThread_lock !=NULL, "check"); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/linux/vm/os_linux.cpp --- a/hotspot/src/os/linux/vm/os_linux.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/linux/vm/os_linux.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -5988,13 +5988,70 @@ // Get the default path to the core file // Returns the length of the string int os::get_core_path(char* buffer, size_t bufferSize) { - const char* p = get_current_directory(buffer, bufferSize); - - if (p == NULL) { - assert(p != NULL, "failed to get current directory"); + /* + * Max length of /proc/sys/kernel/core_pattern is 128 characters. + * See https://www.kernel.org/doc/Documentation/sysctl/kernel.txt + */ + const int core_pattern_len = 129; + char core_pattern[core_pattern_len] = {0}; + + int core_pattern_file = ::open("/proc/sys/kernel/core_pattern", O_RDONLY); + if (core_pattern_file != -1) { + ssize_t ret = ::read(core_pattern_file, core_pattern, core_pattern_len); + ::close(core_pattern_file); + + if (ret > 0) { + char *last_char = core_pattern + strlen(core_pattern) - 1; + + if (*last_char == '\n') { + *last_char = '\0'; + } + } + } + + if (strlen(core_pattern) == 0) { return 0; } + char *pid_pos = strstr(core_pattern, "%p"); + size_t written; + + if (core_pattern[0] == '/') { + written = jio_snprintf(buffer, bufferSize, core_pattern); + } else { + char cwd[PATH_MAX]; + + const char* p = get_current_directory(cwd, PATH_MAX); + if (p == NULL) { + assert(p != NULL, "failed to get current directory"); + return 0; + } + + if (core_pattern[0] == '|') { + written = jio_snprintf(buffer, bufferSize, + "\"%s\" (or dumping to %s/core.%d)", + &core_pattern[1], p, current_process_id()); + } else { + written = jio_snprintf(buffer, bufferSize, "%s/%s", p, core_pattern); + } + } + + if ((written >= 0) && (written < bufferSize) + && (pid_pos == NULL) && (core_pattern[0] != '|')) { + int core_uses_pid_file = ::open("/proc/sys/kernel/core_uses_pid", O_RDONLY); + + if (core_uses_pid_file != -1) { + char core_uses_pid = 0; + ssize_t ret = ::read(core_uses_pid_file, &core_uses_pid, 1); + ::close(core_uses_pid_file); + + if (core_uses_pid == '1'){ + jio_snprintf(buffer + written, bufferSize - written, + ".%d", current_process_id()); + } + } + } + return strlen(buffer); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/posix/vm/os_posix.cpp --- a/hotspot/src/os/posix/vm/os_posix.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/posix/vm/os_posix.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -51,15 +51,24 @@ struct rlimit rlim; bool success; - n = get_core_path(buffer, bufferSize); + char core_path[PATH_MAX]; + n = get_core_path(core_path, PATH_MAX); - if (getrlimit(RLIMIT_CORE, &rlim) != 0) { - jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (may not exist)", current_process_id()); + if (n <= 0) { + jio_snprintf(buffer, bufferSize, "core.%d (may not exist)", current_process_id()); + success = true; +#ifdef LINUX + } else if (core_path[0] == '"') { // redirect to user process + jio_snprintf(buffer, bufferSize, "Core dumps may be processed with %s", core_path); + success = true; +#endif + } else if (getrlimit(RLIMIT_CORE, &rlim) != 0) { + jio_snprintf(buffer, bufferSize, "%s (may not exist)", core_path); success = true; } else { switch(rlim.rlim_cur) { case RLIM_INFINITY: - jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id()); + jio_snprintf(buffer, bufferSize, "%s", core_path); success = true; break; case 0: @@ -67,11 +76,12 @@ success = false; break; default: - jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", current_process_id(), (unsigned long)(rlim.rlim_cur >> 10)); + jio_snprintf(buffer, bufferSize, "%s (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", core_path, (unsigned long)(rlim.rlim_cur >> 10)); success = true; break; } } + VMError::report_coredump_status(buffer, success); } @@ -89,8 +99,8 @@ } else { stack[frame_idx ++] = fr.pc(); } - if (fr.fp() == NULL || os::is_first_C_frame(&fr) - ||fr.sender_pc() == NULL || fr.cb() != NULL) break; + if (fr.fp() == NULL || fr.cb() != NULL || + fr.sender_pc() == NULL || os::is_first_C_frame(&fr)) break; if (fr.sender_pc() && !os::is_first_C_frame(&fr)) { fr = os::get_sender_for_C_frame(&fr); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/solaris/vm/os_solaris.cpp --- a/hotspot/src/os/solaris/vm/os_solaris.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -5979,6 +5979,9 @@ return 0; } + jio_snprintf(buffer, bufferSize, "%s/core or core.%d", + p, current_process_id()); + return strlen(buffer); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os/windows/vm/os_windows.cpp --- a/hotspot/src/os/windows/vm/os_windows.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os/windows/vm/os_windows.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -3074,7 +3074,7 @@ char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) { assert((size_t)addr % os::vm_allocation_granularity() == 0, "reserve alignment"); - assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size"); + assert(bytes % os::vm_page_size() == 0, "reserve page size"); char* res; // note that if UseLargePages is on, all the areas that require interleaving // will go thru reserve_memory_special rather than thru here. @@ -3768,7 +3768,6 @@ return NULL; } -#define MAX_EXIT_HANDLES PRODUCT_ONLY(32) NOT_PRODUCT(128) #define EXIT_TIMEOUT PRODUCT_ONLY(1000) NOT_PRODUCT(4000) /* 1 sec in product, 4 sec in debug */ static BOOL CALLBACK init_crit_sect_call(PINIT_ONCE, PVOID pcrit_sect, PVOID*) { @@ -3787,7 +3786,7 @@ // _endthreadex(). // Should be large enough to avoid blocking the exiting thread due to lack of // a free slot. - static HANDLE handles[MAX_EXIT_HANDLES]; + static HANDLE handles[MAXIMUM_WAIT_OBJECTS]; static int handle_count = 0; static INIT_ONCE init_once_crit_sect = INIT_ONCE_STATIC_INIT; @@ -3809,32 +3808,34 @@ if (res == WAIT_TIMEOUT) { handles[j++] = handles[i]; } else { - if (res != WAIT_OBJECT_0) { - warning("WaitForSingleObject failed in %s: %d\n", __FILE__, __LINE__); - // Don't keep the handle, if we failed waiting for it. + if (res == WAIT_FAILED) { + warning("WaitForSingleObject failed (%u) in %s: %d\n", + GetLastError(), __FILE__, __LINE__); } + // Don't keep the handle, if we failed waiting for it. CloseHandle(handles[i]); } } // If there's no free slot in the array of the kept handles, we'll have to // wait until at least one thread completes exiting. - if ((handle_count = j) == MAX_EXIT_HANDLES) { + if ((handle_count = j) == MAXIMUM_WAIT_OBJECTS) { // Raise the priority of the oldest exiting thread to increase its chances // to complete sooner. SetThreadPriority(handles[0], THREAD_PRIORITY_ABOVE_NORMAL); - res = WaitForMultipleObjects(MAX_EXIT_HANDLES, handles, FALSE, EXIT_TIMEOUT); - if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) { + res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, handles, FALSE, EXIT_TIMEOUT); + if (res >= WAIT_OBJECT_0 && res < (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)) { i = (res - WAIT_OBJECT_0); - handle_count = MAX_EXIT_HANDLES - 1; + handle_count = MAXIMUM_WAIT_OBJECTS - 1; for (; i < handle_count; ++i) { handles[i] = handles[i + 1]; } } else { - warning("WaitForMultipleObjects %s in %s: %d\n", - (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__); + warning("WaitForMultipleObjects %s (%u) in %s: %d\n", + (res == WAIT_FAILED ? "failed" : "timed out"), + GetLastError(), __FILE__, __LINE__); // Don't keep handles, if we failed waiting for them. - for (i = 0; i < MAX_EXIT_HANDLES; ++i) { + for (i = 0; i < MAXIMUM_WAIT_OBJECTS; ++i) { CloseHandle(handles[i]); } handle_count = 0; @@ -3846,7 +3847,8 @@ hthr = GetCurrentThread(); if (!DuplicateHandle(hproc, hthr, hproc, &handles[handle_count], 0, FALSE, DUPLICATE_SAME_ACCESS)) { - warning("DuplicateHandle failed in %s: %d\n", __FILE__, __LINE__); + warning("DuplicateHandle failed (%u) in %s: %d\n", + GetLastError(), __FILE__, __LINE__); } else { ++handle_count; } @@ -3869,9 +3871,10 @@ SetThreadPriority(handles[i], THREAD_PRIORITY_ABOVE_NORMAL); } res = WaitForMultipleObjects(handle_count, handles, TRUE, EXIT_TIMEOUT); - if (res < WAIT_OBJECT_0 || res >= (WAIT_OBJECT_0 + MAX_EXIT_HANDLES)) { - warning("WaitForMultipleObjects %s in %s: %d\n", - (res == WAIT_FAILED ? "failed" : "timed out"), __FILE__, __LINE__); + if (res == WAIT_FAILED || res == WAIT_TIMEOUT) { + warning("WaitForMultipleObjects %s (%u) in %s: %d\n", + (res == WAIT_FAILED ? "failed" : "timed out"), + GetLastError(), __FILE__, __LINE__); } for (i = 0; i < handle_count; ++i) { CloseHandle(handles[i]); @@ -3909,7 +3912,6 @@ return exit_code; } -#undef MAX_EXIT_HANDLES #undef EXIT_TIMEOUT void os::win32::setmode_streams() { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp --- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -91,8 +91,9 @@ // Frame information (pc, sp, fp) retrieved via ucontext // always looks like a C-frame according to the frame -// conventions in frame_ppc64.hpp. -address os::Aix::ucontext_get_pc(ucontext_t * uc) { +// conventions in frame_ppc.hpp. + +address os::Aix::ucontext_get_pc(const ucontext_t * uc) { return (address)uc->uc_mcontext.jmp_context.iar; } @@ -486,7 +487,7 @@ //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Aix::min_stack_allowed = 768*K; +size_t os::Aix::min_stack_allowed = 128*K; // Aix is always in floating stack mode. The stack size for a new // thread can be set via pthread_attr_setstacksize(). @@ -499,7 +500,7 @@ // because of the strange 'fallback logic' in os::create_thread(). // Better set CompilerThreadStackSize in globals_.hpp if you want to // specify a different stack size for compiler threads! - size_t s = (thr_type == os::compiler_thread ? 4 * M : 1024 * K); + size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); return s; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp --- a/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os_cpu/aix_ppc/vm/os_aix_ppc.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP -#define OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP +#define OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP static void setup_fpu() {} @@ -32,4 +32,4 @@ // Note: Currently only used in 64 bit Windows implementations static bool register_code_area(char *low, char *high) { return true; } -#endif // OS_CPU_AIX_OJDKPPC_VM_OS_AIX_PPC_HPP +#endif // OS_CPU_AIX_PPC_VM_OS_AIX_PPC_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp --- a/hotspot/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os_cpu/aix_ppc/vm/prefetch_aix_ppc.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP -#define OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP +#ifndef OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP +#define OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP #include "runtime/prefetch.hpp" @@ -55,4 +55,4 @@ #endif } -#endif // OS_CPU_AIX_PPC_64_VM_PREFETCH_AIX_PPC_64_INLINE_HPP +#endif // OS_CPU_AIX_PPC_VM_PREFETCH_AIX_PPC_INLINE_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp --- a/hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os_cpu/aix_ppc/vm/threadLS_aix_ppc.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP -#define OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP +#define OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP // Processor dependent parts of ThreadLocalStorage @@ -33,4 +33,4 @@ return (Thread *) os::thread_local_storage_at(thread_index()); } -#endif // OS_CPU_AIX_OJDKPPC_VM_THREADLS_AIX_PPC_HPP +#endif // OS_CPU_AIX_PPC_VM_THREADLS_AIX_PPC_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp --- a/hotspot/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os_cpu/aix_ppc/vm/thread_aix_ppc.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -23,8 +23,8 @@ * */ -#ifndef OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP -#define OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP +#ifndef OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP +#define OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP private: void pd_initialize() { @@ -76,4 +76,4 @@ intptr_t* last_interpreter_fp() { return _last_interpreter_fp; } -#endif // OS_CPU_AIX_OJDKPPC_VM_THREAD_AIX_PPC_HPP +#endif // OS_CPU_AIX_PPC_VM_THREAD_AIX_PPC_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp --- a/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -453,7 +453,7 @@ //////////////////////////////////////////////////////////////////////////////// // thread stack -size_t os::Linux::min_stack_allowed = 768*K; +size_t os::Linux::min_stack_allowed = 128*K; bool os::Linux::supports_variable_stack_size() { return true; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/classfile/classFileParser.cpp --- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -3108,21 +3108,39 @@ } } -// Transfer ownership of metadata allocated to the InstanceKlass. -void ClassFileParser::apply_parsed_class_metadata( - instanceKlassHandle this_klass, - int java_fields_count, TRAPS) { - // Assign annotations if needed - if (_annotations != NULL || _type_annotations != NULL || - _fields_annotations != NULL || _fields_type_annotations != NULL) { +// Create the Annotations object that will +// hold the annotations array for the Klass. +void ClassFileParser::create_combined_annotations(TRAPS) { + if (_annotations == NULL && + _type_annotations == NULL && + _fields_annotations == NULL && + _fields_type_annotations == NULL) { + // Don't create the Annotations object unnecessarily. + return; + } + Annotations* annotations = Annotations::allocate(_loader_data, CHECK); annotations->set_class_annotations(_annotations); annotations->set_class_type_annotations(_type_annotations); annotations->set_fields_annotations(_fields_annotations); annotations->set_fields_type_annotations(_fields_type_annotations); - this_klass->set_annotations(annotations); - } - + + // This is the Annotations object that will be + // assigned to InstanceKlass being constructed. + _combined_annotations = annotations; + + // The annotations arrays below has been transfered the + // _combined_annotations so these fields can now be cleared. + _annotations = NULL; + _type_annotations = NULL; + _fields_annotations = NULL; + _fields_type_annotations = NULL; +} + +// Transfer ownership of metadata allocated to the InstanceKlass. +void ClassFileParser::apply_parsed_class_metadata( + instanceKlassHandle this_klass, + int java_fields_count, TRAPS) { _cp->set_pool_holder(this_klass()); this_klass->set_constants(_cp); this_klass->set_fields(_fields, java_fields_count); @@ -3130,6 +3148,7 @@ this_klass->set_inner_classes(_inner_classes); this_klass->set_local_interfaces(_local_interfaces); this_klass->set_transitive_interfaces(_transitive_interfaces); + this_klass->set_annotations(_combined_annotations); // Clear out these fields so they don't get deallocated by the destructor clear_class_metadata(); @@ -4002,6 +4021,10 @@ ClassAnnotationCollector parsed_annotations; parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle)); + // Finalize the Annotations metadata object, + // now that all annotation arrays have been created. + create_combined_annotations(CHECK_(nullHandle)); + // Make sure this is the end of class file stream guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle)); @@ -4302,10 +4325,27 @@ InstanceKlass::deallocate_interfaces(_loader_data, _super_klass(), _local_interfaces, _transitive_interfaces); - MetadataFactory::free_array(_loader_data, _annotations); - MetadataFactory::free_array(_loader_data, _type_annotations); - Annotations::free_contents(_loader_data, _fields_annotations); - Annotations::free_contents(_loader_data, _fields_type_annotations); + if (_combined_annotations != NULL) { + // After all annotations arrays have been created, they are installed into the + // Annotations object that will be assigned to the InstanceKlass being created. + + // Deallocate the Annotations object and the installed annotations arrays. + _combined_annotations->deallocate_contents(_loader_data); + + // If the _combined_annotations pointer is non-NULL, + // then the other annotations fields should have been cleared. + assert(_annotations == NULL, "Should have been cleared"); + assert(_type_annotations == NULL, "Should have been cleared"); + assert(_fields_annotations == NULL, "Should have been cleared"); + assert(_fields_type_annotations == NULL, "Should have been cleared"); + } else { + // If the annotations arrays were not installed into the Annotations object, + // then they have to be deallocated explicitly. + MetadataFactory::free_array(_loader_data, _annotations); + MetadataFactory::free_array(_loader_data, _type_annotations); + Annotations::free_contents(_loader_data, _fields_annotations); + Annotations::free_contents(_loader_data, _fields_type_annotations); + } clear_class_metadata(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/classfile/classFileParser.hpp --- a/hotspot/src/share/vm/classfile/classFileParser.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -75,6 +75,7 @@ Array* _inner_classes; Array* _local_interfaces; Array* _transitive_interfaces; + Annotations* _combined_annotations; AnnotationArray* _annotations; AnnotationArray* _type_annotations; Array* _fields_annotations; @@ -86,6 +87,8 @@ void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; } void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; } + void create_combined_annotations(TRAPS); + void init_parsed_class_attributes(ClassLoaderData* loader_data) { _loader_data = loader_data; _synthetic_flag = false; @@ -110,6 +113,7 @@ _inner_classes = NULL; _local_interfaces = NULL; _transitive_interfaces = NULL; + _combined_annotations = NULL; _annotations = _type_annotations = NULL; _fields_annotations = _fields_type_annotations = NULL; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/classfile/classLoaderData.cpp --- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -81,7 +81,8 @@ _metaspace(NULL), _unloading(false), _klasses(NULL), _claimed(0), _jmethod_ids(NULL), _handles(NULL), _deallocate_list(NULL), _next(NULL), _dependencies(dependencies), - _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true)) { + _metaspace_lock(new Mutex(Monitor::leaf+1, "Metaspace allocation lock", true, + Monitor::_safepoint_check_never)) { // empty } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -83,9 +83,11 @@ // Note: this requires that CFLspace c'tors // are called serially in the order in which the locks are // are acquired in the program text. This is true today. - _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true), + _freelistLock(_lockRank--, "CompactibleFreeListSpace._lock", true, + Monitor::_safepoint_check_sometimes), _parDictionaryAllocLock(Mutex::leaf - 1, // == rank(ExpandHeap_lock) - 1 - "CompactibleFreeListSpace._dict_par_lock", true), + "CompactibleFreeListSpace._dict_par_lock", true, + Monitor::_safepoint_check_never), _rescan_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord * CMSRescanMultiple), _marking_task_size(CardTableModRefBS::card_size_in_words * BitsPerWord * @@ -152,8 +154,7 @@ // Initialize locks for parallel case. for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) { _indexedFreeListParLocks[i] = new Mutex(Mutex::leaf - 1, // == ExpandHeap_lock - 1 - "a freelist par lock", - true); + "a freelist par lock", true, Mutex::_safepoint_check_sometimes); DEBUG_ONLY( _indexedFreeList[i].set_protecting_lock(_indexedFreeListParLocks[i]); ) @@ -2559,12 +2560,12 @@ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, \ x } -// Initialize with default setting of CMSParPromoteBlocksToClaim, _not_ -// OldPLABSize, whose static default is different; if overridden at the +// Initialize with default setting for CMS, _not_ +// generic OldPLABSize, whose static default is different; if overridden at the // command-line, this will get reinitialized via a call to // modify_initialization() below. AdaptiveWeightedAverage CFLS_LAB::_blocks_to_claim[] = - VECTOR_257(AdaptiveWeightedAverage(OldPLABWeight, (float)CMSParPromoteBlocksToClaim)); + VECTOR_257(AdaptiveWeightedAverage(OldPLABWeight, (float)CFLS_LAB::_default_dynamic_old_plab_size)); size_t CFLS_LAB::_global_num_blocks[] = VECTOR_257(0); uint CFLS_LAB::_global_num_workers[] = VECTOR_257(0); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -690,6 +690,9 @@ void get_from_global_pool(size_t word_sz, AdaptiveFreeList* fl); public: + static const int _default_dynamic_old_plab_size = 16; + static const int _default_static_old_plab_size = 50; + CFLS_LAB(CompactibleFreeListSpace* cfls); // Allocate and return a block of the given size, or else return NULL. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -42,6 +42,7 @@ #include "gc_implementation/shared/isGCActiveMark.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "memory/allocation.hpp" +#include "memory/cardGeneration.inline.hpp" #include "memory/cardTableRS.hpp" #include "memory/collectorPolicy.hpp" #include "memory/gcLocker.inline.hpp" @@ -479,7 +480,9 @@ _restart_addr(NULL), _overflow_list(NULL), _stats(cmsGen), - _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)), + _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true, + //verify that this lock should be acquired with safepoint check. + Monitor::_safepoint_check_sometimes)), _eden_chunk_array(NULL), // may be set in ctor body _eden_chunk_capacity(0), // -- ditto -- _eden_chunk_index(0), // -- ditto -- @@ -793,11 +796,6 @@ } } -CompactibleSpace* -ConcurrentMarkSweepGeneration::first_compaction_space() const { - return _cmsSpace; -} - void ConcurrentMarkSweepGeneration::reset_after_compaction() { // Clear the promotion information. These pointers can be adjusted // along with all the other pointers into the heap but @@ -808,10 +806,6 @@ } } -void ConcurrentMarkSweepGeneration::space_iterate(SpaceClosure* blk, bool usedOnly) { - blk->do_space(_cmsSpace); -} - void ConcurrentMarkSweepGeneration::compute_new_size() { assert_locked_or_safepoint(Heap_lock); @@ -882,7 +876,7 @@ expand_bytes); } // safe if expansion fails - expand(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio); + expand_for_gc_cause(expand_bytes, 0, CMSExpansionCause::_satisfy_free_ratio); if (PrintGCDetails && Verbose) { gclog_or_tty->print_cr(" Expanded free fraction %f", ((double) free()) / capacity()); @@ -1048,8 +1042,7 @@ if (res == NULL) { // expand and retry size_t s = _cmsSpace->expansionSpaceRequired(obj_size); // HeapWords - expand(s*HeapWordSize, MinHeapDeltaBytes, - CMSExpansionCause::_satisfy_promotion); + expand_for_gc_cause(s*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_promotion); // Since there's currently no next generation, we don't try to promote // into a more senior generation. assert(next_gen() == NULL, "assumption, based upon which no attempt " @@ -1618,14 +1611,15 @@ // If the collection is being acquired from the background // collector, there may be references on the discovered - // references lists that have NULL referents (being those - // that were concurrently cleared by a mutator) or - // that are no longer active (having been enqueued concurrently - // by the mutator). - // Scrub the list of those references because Mark-Sweep-Compact - // code assumes referents are not NULL and that all discovered - // Reference objects are active. - ref_processor()->clean_up_discovered_references(); + // references lists. Abandon those references, since some + // of them may have become unreachable after concurrent + // discovery; the STW compacting collector will redo discovery + // more precisely, without being subject to floating garbage. + // Leaving otherwise unreachable references in the discovered + // lists would require special handling. + ref_processor()->disable_discovery(); + ref_processor()->abandon_partial_discovery(); + ref_processor()->verify_no_references_recorded(); if (first_state > Idling) { save_heap_summary(); @@ -1691,7 +1685,7 @@ ReferenceProcessorMTDiscoveryMutator rp_mut_discovery(ref_processor(), false); ref_processor()->set_enqueuing_is_done(false); - ref_processor()->enable_discovery(false /*verify_disabled*/, false /*check_no_refs*/); + ref_processor()->enable_discovery(); ref_processor()->setup_policy(clear_all_soft_refs); // If an asynchronous collection finishes, the _modUnionTable is // all clear. If we are assuming the collection from an asynchronous @@ -2625,13 +2619,6 @@ ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN) void -ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) { - cl->set_generation(this); - younger_refs_in_space_iterate(_cmsSpace, cl); - cl->reset_generation(); -} - -void ConcurrentMarkSweepGeneration::oop_iterate(ExtendedOopClosure* cl) { if (freelistLock()->owned_by_self()) { Generation::oop_iterate(cl); @@ -2803,23 +2790,17 @@ CMSSynchronousYieldRequest yr; assert(!tlab, "Can't deal with TLAB allocation"); MutexLockerEx x(freelistLock(), Mutex::_no_safepoint_check_flag); - expand(word_size*HeapWordSize, MinHeapDeltaBytes, - CMSExpansionCause::_satisfy_allocation); + expand_for_gc_cause(word_size*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_satisfy_allocation); if (GCExpandToAllocateDelayMillis > 0) { os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false); } return have_lock_and_allocate(word_size, tlab); } -// YSR: All of this generation expansion/shrinking stuff is an exact copy of -// TenuredGeneration, which makes me wonder if we should move this -// to CardGeneration and share it... -bool ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes) { - return CardGeneration::expand(bytes, expand_bytes); -} - -void ConcurrentMarkSweepGeneration::expand(size_t bytes, size_t expand_bytes, - CMSExpansionCause::Cause cause) +void ConcurrentMarkSweepGeneration::expand_for_gc_cause( + size_t bytes, + size_t expand_bytes, + CMSExpansionCause::Cause cause) { bool success = expand(bytes, expand_bytes); @@ -2848,8 +2829,7 @@ return NULL; } // Otherwise, we try expansion. - expand(word_sz*HeapWordSize, MinHeapDeltaBytes, - CMSExpansionCause::_allocate_par_lab); + expand_for_gc_cause(word_sz*HeapWordSize, MinHeapDeltaBytes, CMSExpansionCause::_allocate_par_lab); // Now go around the loop and try alloc again; // A competing par_promote might beat us to the expansion space, // so we may go around the loop again if promotion fails again. @@ -2876,8 +2856,7 @@ return false; } // Otherwise, we try expansion. - expand(refill_size_bytes, MinHeapDeltaBytes, - CMSExpansionCause::_allocate_par_spooling_space); + expand_for_gc_cause(refill_size_bytes, MinHeapDeltaBytes, CMSExpansionCause::_allocate_par_spooling_space); // Now go around the loop and try alloc again; // A competing allocation might beat us to the expansion space, // so we may go around the loop again if allocation fails again. @@ -2887,77 +2866,16 @@ } } - -void ConcurrentMarkSweepGeneration::shrink_by(size_t bytes) { - assert_locked_or_safepoint(ExpandHeap_lock); - // Shrink committed space - _virtual_space.shrink_by(bytes); - // Shrink space; this also shrinks the space's BOT - _cmsSpace->set_end((HeapWord*) _virtual_space.high()); - size_t new_word_size = heap_word_size(_cmsSpace->capacity()); - // Shrink the shared block offset array - _bts->resize(new_word_size); - MemRegion mr(_cmsSpace->bottom(), new_word_size); - // Shrink the card table - Universe::heap()->barrier_set()->resize_covered_region(mr); - - if (Verbose && PrintGC) { - size_t new_mem_size = _virtual_space.committed_size(); - size_t old_mem_size = new_mem_size + bytes; - gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", - name(), old_mem_size/K, new_mem_size/K); - } -} - void ConcurrentMarkSweepGeneration::shrink(size_t bytes) { - assert_locked_or_safepoint(Heap_lock); - size_t size = ReservedSpace::page_align_size_down(bytes); // Only shrink if a compaction was done so that all the free space // in the generation is in a contiguous block at the end. - if (size > 0 && did_compact()) { - shrink_by(size); - } -} - -bool ConcurrentMarkSweepGeneration::grow_by(size_t bytes) { + if (did_compact()) { + CardGeneration::shrink(bytes); + } +} + +void ConcurrentMarkSweepGeneration::assert_correct_size_change_locking() { assert_locked_or_safepoint(Heap_lock); - bool result = _virtual_space.expand_by(bytes); - if (result) { - size_t new_word_size = - heap_word_size(_virtual_space.committed_size()); - MemRegion mr(_cmsSpace->bottom(), new_word_size); - _bts->resize(new_word_size); // resize the block offset shared array - Universe::heap()->barrier_set()->resize_covered_region(mr); - // Hmmmm... why doesn't CFLS::set_end verify locking? - // This is quite ugly; FIX ME XXX - _cmsSpace->assert_locked(freelistLock()); - _cmsSpace->set_end((HeapWord*)_virtual_space.high()); - - // update the space and generation capacity counters - if (UsePerfData) { - _space_counters->update_capacity(); - _gen_counters->update_all(); - } - - if (Verbose && PrintGC) { - size_t new_mem_size = _virtual_space.committed_size(); - size_t old_mem_size = new_mem_size - bytes; - gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K", - name(), old_mem_size/K, bytes/K, new_mem_size/K); - } - } - return result; -} - -bool ConcurrentMarkSweepGeneration::grow_to_reserved() { - assert_locked_or_safepoint(Heap_lock); - bool success = true; - const size_t remaining_bytes = _virtual_space.uncommitted_size(); - if (remaining_bytes > 0) { - success = grow_by(remaining_bytes); - DEBUG_ONLY(if (!success) warning("grow to reserved failed");) - } - return success; } void ConcurrentMarkSweepGeneration::shrink_free_list_by(size_t bytes) { @@ -3084,7 +3002,7 @@ Mutex::_no_safepoint_check_flag); checkpointRootsInitialWork(); // enable ("weak") refs discovery - rp->enable_discovery(true /*verify_disabled*/, true /*check_no_refs*/); + rp->enable_discovery(); _collectorState = Marking; } SpecializationStats::print(); @@ -6031,7 +5949,8 @@ CMSBitMap::CMSBitMap(int shifter, int mutex_rank, const char* mutex_name): _bm(), _shifter(shifter), - _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true) : NULL) + _lock(mutex_rank >= 0 ? new Mutex(mutex_rank, mutex_name, true, + Monitor::_safepoint_check_sometimes) : NULL) { _bmStartWord = 0; _bmWordSize = 0; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,10 @@ #include "gc_implementation/shared/gcStats.hpp" #include "gc_implementation/shared/gcWhen.hpp" #include "gc_implementation/shared/generationCounters.hpp" +#include "memory/cardGeneration.hpp" #include "memory/freeBlockDictionary.hpp" -#include "memory/generation.hpp" #include "memory/iterator.hpp" +#include "memory/space.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/virtualspace.hpp" #include "services/memoryService.hpp" @@ -171,9 +172,7 @@ // Represents a marking stack used by the CMS collector. // Ideally this should be GrowableArray<> just like MSC's marking stack(s). class CMSMarkStack: public CHeapObj { - // friend class CMSCollector; // To get at expansion stats further below. - // VirtualSpace _virtual_space; // Space for the stack oop* _base; // Bottom of stack @@ -188,7 +187,8 @@ public: CMSMarkStack(): - _par_lock(Mutex::event, "CMSMarkStack._par_lock", true), + _par_lock(Mutex::event, "CMSMarkStack._par_lock", true, + Monitor::_safepoint_check_never), _hit_limit(0), _failed_double(0) {} @@ -1031,6 +1031,9 @@ void set_expansion_cause(CMSExpansionCause::Cause v) { _expansion_cause = v;} CMSExpansionCause::Cause expansion_cause() const { return _expansion_cause; } + // Accessing spaces + CompactibleSpace* space() const { return (CompactibleSpace*)_cmsSpace; } + private: // For parallel young-gen GC support. CMSParGCThreadState** _par_gc_thread_states; @@ -1064,6 +1067,10 @@ double initiating_occupancy() const { return _initiating_occupancy; } void init_initiating_occupancy(intx io, uintx tr); + void expand_for_gc_cause(size_t bytes, size_t expand_bytes, CMSExpansionCause::Cause cause); + + void assert_correct_size_change_locking(); + public: ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size, int level, CardTableRS* ct, @@ -1100,23 +1107,14 @@ // Override virtual void ref_processor_init(); - // Grow generation by specified size (returns false if unable to grow) - bool grow_by(size_t bytes); - // Grow generation to reserved size. - bool grow_to_reserved(); - void clear_expansion_cause() { _expansion_cause = CMSExpansionCause::_no_expansion; } // Space enquiries - size_t capacity() const; - size_t used() const; - size_t free() const; double occupancy() const { return ((double)used())/((double)capacity()); } size_t contiguous_available() const; size_t unsafe_max_alloc_nogc() const; // over-rides - MemRegion used_region() const; MemRegion used_region_at_save_marks() const; // Does a "full" (forced) collection invoked on this generation collect @@ -1127,10 +1125,6 @@ return !ScavengeBeforeFullGC; } - void space_iterate(SpaceClosure* blk, bool usedOnly = false); - - // Support for compaction - CompactibleSpace* first_compaction_space() const; // Adjust quantities in the generation affected by // the compaction. void reset_after_compaction(); @@ -1190,18 +1184,13 @@ } // Allocation failure - void expand(size_t bytes, size_t expand_bytes, - CMSExpansionCause::Cause cause); - virtual bool expand(size_t bytes, size_t expand_bytes); void shrink(size_t bytes); - void shrink_by(size_t bytes); HeapWord* expand_and_par_lab_allocate(CMSParGCThreadState* ps, size_t word_sz); bool expand_and_ensure_spooling_space(PromotionInfo* promo); // Iteration support and related enquiries void save_marks(); bool no_allocs_since_save_marks(); - void younger_refs_iterate(OopsInGenClosure* cl); // Iteration support specific to CMS generations void save_sweep_limit(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -369,22 +369,6 @@ cmsSpace()->save_sweep_limit(); } -inline size_t ConcurrentMarkSweepGeneration::capacity() const { - return _cmsSpace->capacity(); -} - -inline size_t ConcurrentMarkSweepGeneration::used() const { - return _cmsSpace->used(); -} - -inline size_t ConcurrentMarkSweepGeneration::free() const { - return _cmsSpace->free(); -} - -inline MemRegion ConcurrentMarkSweepGeneration::used_region() const { - return _cmsSpace->used_region(); -} - inline MemRegion ConcurrentMarkSweepGeneration::used_region_at_save_marks() const { return _cmsSpace->used_region_at_save_marks(); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,8 @@ // The 0th worker in notified by mutator threads and has a special monitor. // The last worker is used for young gen rset size sampling. if (worker_id > 0) { - _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true); + _monitor = new Monitor(Mutex::nonleaf, "Refinement monitor", true, + Monitor::_safepoint_check_never); } else { _monitor = DirtyCardQ_CBL_mon; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -971,7 +971,7 @@ // Start Concurrent Marking weak-reference discovery. ReferenceProcessor* rp = g1h->ref_processor_cm(); // enable ("weak") refs discovery - rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + rp->enable_discovery(); rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -254,25 +254,23 @@ HeapRegion* SurvivorGCAllocRegion::allocate_new_region(size_t word_size, bool force) { assert(!force, "not supported for GC alloc regions"); - return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForSurvived); + return _g1h->new_gc_alloc_region(word_size, count(), InCSetState::Young); } void SurvivorGCAllocRegion::retire_region(HeapRegion* alloc_region, size_t allocated_bytes) { - _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, - GCAllocForSurvived); + _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, InCSetState::Young); } HeapRegion* OldGCAllocRegion::allocate_new_region(size_t word_size, bool force) { assert(!force, "not supported for GC alloc regions"); - return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForTenured); + return _g1h->new_gc_alloc_region(word_size, count(), InCSetState::Old); } void OldGCAllocRegion::retire_region(HeapRegion* alloc_region, size_t allocated_bytes) { - _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, - GCAllocForTenured); + _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, InCSetState::Old); } HeapRegion* OldGCAllocRegion::release() { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -113,15 +113,16 @@ G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : ParGCAllocBuffer(gclab_word_size), _retired(true) { } -HeapWord* G1ParGCAllocator::allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) { - HeapWord* obj = NULL; - size_t gclab_word_size = _g1h->desired_plab_sz(purpose); +HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest, + size_t word_sz, + AllocationContext_t context) { + size_t gclab_word_size = _g1h->desired_plab_sz(dest); if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) { - G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose, context); + G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context); add_to_alloc_buffer_waste(alloc_buf->words_remaining()); alloc_buf->retire(false /* end_of_gc */, false /* retain */); - HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size, context); + HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context); if (buf == NULL) { return NULL; // Let caller handle allocation failure. } @@ -129,30 +130,33 @@ alloc_buf->set_word_size(gclab_word_size); alloc_buf->set_buf(buf); - obj = alloc_buf->allocate(word_sz); + HeapWord* const obj = alloc_buf->allocate(word_sz); assert(obj != NULL, "buffer was definitely big enough..."); + return obj; } else { - obj = _g1h->par_allocate_during_gc(purpose, word_sz, context); + return _g1h->par_allocate_during_gc(dest, word_sz, context); } - return obj; } G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) : - G1ParGCAllocator(g1h), - _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), - _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)) { - - _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer; - _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer; - + G1ParGCAllocator(g1h), + _surviving_alloc_buffer(g1h->desired_plab_sz(InCSetState::Young)), + _tenured_alloc_buffer(g1h->desired_plab_sz(InCSetState::Old)) { + for (uint state = 0; state < InCSetState::Num; state++) { + _alloc_buffers[state] = NULL; + } + _alloc_buffers[InCSetState::Young] = &_surviving_alloc_buffer; + _alloc_buffers[InCSetState::Old] = &_tenured_alloc_buffer; } void G1DefaultParGCAllocator::retire_alloc_buffers() { - for (int ap = 0; ap < GCAllocPurposeCount; ++ap) { - size_t waste = _alloc_buffers[ap]->words_remaining(); - add_to_alloc_buffer_waste(waste); - _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap), - true /* end_of_gc */, - false /* retain */); + for (uint state = 0; state < InCSetState::Num; state++) { + G1ParGCAllocBuffer* const buf = _alloc_buffers[state]; + if (buf != NULL) { + add_to_alloc_buffer_waste(buf->words_remaining()); + buf->flush_stats_and_retire(_g1h->alloc_buffer_stats(state), + true /* end_of_gc */, + false /* retain */); + } } } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1Allocator.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -27,14 +27,9 @@ #include "gc_implementation/g1/g1AllocationContext.hpp" #include "gc_implementation/g1/g1AllocRegion.hpp" +#include "gc_implementation/g1/g1InCSetState.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp" -enum GCAllocPurpose { - GCAllocForTenured, - GCAllocForSurvived, - GCAllocPurposeCount -}; - // Base class for G1 allocators. class G1Allocator : public CHeapObj { friend class VMStructs; @@ -178,20 +173,40 @@ protected: G1CollectedHeap* _g1h; + // The survivor alignment in effect in bytes. + // == 0 : don't align survivors + // != 0 : align survivors to that alignment + // These values were chosen to favor the non-alignment case since some + // architectures have a special compare against zero instructions. + const uint _survivor_alignment_bytes; + size_t _alloc_buffer_waste; size_t _undo_waste; void add_to_alloc_buffer_waste(size_t waste) { _alloc_buffer_waste += waste; } void add_to_undo_waste(size_t waste) { _undo_waste += waste; } - HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context); + virtual void retire_alloc_buffers() = 0; + virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) = 0; - virtual void retire_alloc_buffers() = 0; - virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) = 0; + // Calculate the survivor space object alignment in bytes. Returns that or 0 if + // there are no restrictions on survivor alignment. + static uint calc_survivor_alignment_bytes() { + assert(SurvivorAlignmentInBytes >= ObjectAlignmentInBytes, "sanity"); + if (SurvivorAlignmentInBytes == ObjectAlignmentInBytes) { + // No need to align objects in the survivors differently, return 0 + // which means "survivor alignment is not used". + return 0; + } else { + assert(SurvivorAlignmentInBytes > 0, "sanity"); + return SurvivorAlignmentInBytes; + } + } public: G1ParGCAllocator(G1CollectedHeap* g1h) : - _g1h(g1h), _alloc_buffer_waste(0), _undo_waste(0) { + _g1h(g1h), _survivor_alignment_bytes(calc_survivor_alignment_bytes()), + _alloc_buffer_waste(0), _undo_waste(0) { } static G1ParGCAllocator* create_allocator(G1CollectedHeap* g1h); @@ -199,24 +214,40 @@ size_t alloc_buffer_waste() { return _alloc_buffer_waste; } size_t undo_waste() {return _undo_waste; } - HeapWord* allocate(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) { - HeapWord* obj = NULL; - if (purpose == GCAllocForSurvived) { - obj = alloc_buffer(purpose, context)->allocate_aligned(word_sz, SurvivorAlignmentInBytes); + // Allocate word_sz words in dest, either directly into the regions or by + // allocating a new PLAB. Returns the address of the allocated memory, NULL if + // not successful. + HeapWord* allocate_direct_or_new_plab(InCSetState dest, + size_t word_sz, + AllocationContext_t context); + + // Allocate word_sz words in the PLAB of dest. Returns the address of the + // allocated memory, NULL if not successful. + HeapWord* plab_allocate(InCSetState dest, + size_t word_sz, + AllocationContext_t context) { + G1ParGCAllocBuffer* buffer = alloc_buffer(dest, context); + if (_survivor_alignment_bytes == 0) { + return buffer->allocate(word_sz); } else { - obj = alloc_buffer(purpose, context)->allocate(word_sz); + return buffer->allocate_aligned(word_sz, _survivor_alignment_bytes); } + } + + HeapWord* allocate(InCSetState dest, size_t word_sz, + AllocationContext_t context) { + HeapWord* const obj = plab_allocate(dest, word_sz, context); if (obj != NULL) { return obj; } - return allocate_slow(purpose, word_sz, context); + return allocate_direct_or_new_plab(dest, word_sz, context); } - void undo_allocation(GCAllocPurpose purpose, HeapWord* obj, size_t word_sz, AllocationContext_t context) { - if (alloc_buffer(purpose, context)->contains(obj)) { - assert(alloc_buffer(purpose, context)->contains(obj + word_sz - 1), + void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) { + if (alloc_buffer(dest, context)->contains(obj)) { + assert(alloc_buffer(dest, context)->contains(obj + word_sz - 1), "should contain whole object"); - alloc_buffer(purpose, context)->undo_allocation(obj, word_sz); + alloc_buffer(dest, context)->undo_allocation(obj, word_sz); } else { CollectedHeap::fill_with_object(obj, word_sz); add_to_undo_waste(word_sz); @@ -227,13 +258,17 @@ class G1DefaultParGCAllocator : public G1ParGCAllocator { G1ParGCAllocBuffer _surviving_alloc_buffer; G1ParGCAllocBuffer _tenured_alloc_buffer; - G1ParGCAllocBuffer* _alloc_buffers[GCAllocPurposeCount]; + G1ParGCAllocBuffer* _alloc_buffers[InCSetState::Num]; public: G1DefaultParGCAllocator(G1CollectedHeap* g1h); - virtual G1ParGCAllocBuffer* alloc_buffer(GCAllocPurpose purpose, AllocationContext_t context) { - return _alloc_buffers[purpose]; + virtual G1ParGCAllocBuffer* alloc_buffer(InCSetState dest, AllocationContext_t context) { + assert(dest.is_valid(), + err_msg("Allocation buffer index out-of-bounds: " CSETSTATE_FORMAT, dest.value())); + assert(_alloc_buffers[dest.value()] != NULL, + err_msg("Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value())); + return _alloc_buffers[dest.value()]; } virtual void retire_alloc_buffers() ; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -352,7 +352,7 @@ } void G1RegionMappingChangedListener::reset_from_card_cache(uint start_idx, size_t num_regions) { - OtherRegionsTable::invalidate(start_idx, num_regions); + HeapRegionRemSet::invalidate_from_card_cache(start_idx, num_regions); } void G1RegionMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) { @@ -1301,7 +1301,7 @@ // Temporarily clear the STW ref processor's _is_alive_non_header field. ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL); - ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + ref_processor_stw()->enable_discovery(); ref_processor_stw()->setup_policy(do_clear_all_soft_refs); // Do collection work @@ -1886,13 +1886,12 @@ initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); - // Create the gen rem set (and barrier set) for the entire reserved region. - _rem_set = collector_policy()->create_rem_set(reserved_region()); - set_barrier_set(rem_set()->bs()); - if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) { - vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS"); - return JNI_ENOMEM; - } + // Create the barrier set for the entire reserved region. + G1SATBCardTableLoggingModRefBS* bs + = new G1SATBCardTableLoggingModRefBS(reserved_region()); + bs->initialize(); + assert(bs->is_a(BarrierSet::G1SATBCTLogging), "sanity"); + set_barrier_set(bs); // Also create a G1 rem set. _g1_rem_set = new G1RemSet(this, g1_barrier_set()); @@ -3153,8 +3152,6 @@ failures = true; } } - if (!silent) gclog_or_tty->print("RemSet "); - rem_set()->verify(); if (G1StringDedup::is_enabled()) { if (!silent) gclog_or_tty->print("StrDedup "); @@ -3750,8 +3747,7 @@ // reference processing currently works in G1. // Enable discovery in the STW reference processor - ref_processor_stw()->enable_discovery(true /*verify_disabled*/, - true /*verify_no_refs*/); + ref_processor_stw()->enable_discovery(); { // We want to temporarily turn off discovery by the @@ -3819,6 +3815,8 @@ register_humongous_regions_with_in_cset_fast_test(); + assert(check_cset_fast_test(), "Inconsistency in the InCSetState table."); + _cm->note_start_of_gc(); // We should not verify the per-thread SATB buffers given that // we have not filtered them yet (we'll do so during the @@ -4048,29 +4046,6 @@ return true; } -size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) -{ - size_t gclab_word_size; - switch (purpose) { - case GCAllocForSurvived: - gclab_word_size = _survivor_plab_stats.desired_plab_sz(); - break; - case GCAllocForTenured: - gclab_word_size = _old_plab_stats.desired_plab_sz(); - break; - default: - assert(false, "unknown GCAllocPurpose"); - gclab_word_size = _old_plab_stats.desired_plab_sz(); - break; - } - - // Prevent humongous PLAB sizes for two reasons: - // * PLABs are allocated using a similar paths as oops, but should - // never be in a humongous region - // * Allowing humongous PLABs needlessly churns the region free lists - return MIN2(_humongous_object_threshold_in_words, gclab_word_size); -} - void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) { _drain_in_progress = false; set_evac_failure_closure(cl); @@ -4196,35 +4171,6 @@ } } -HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, - size_t word_size, - AllocationContext_t context) { - if (purpose == GCAllocForSurvived) { - HeapWord* result = survivor_attempt_allocation(word_size, context); - if (result != NULL) { - return result; - } else { - // Let's try to allocate in the old gen in case we can fit the - // object there. - return old_attempt_allocation(word_size, context); - } - } else { - assert(purpose == GCAllocForTenured, "sanity"); - HeapWord* result = old_attempt_allocation(word_size, context); - if (result != NULL) { - return result; - } else { - // Let's try to allocate in the survivors in case we can fit the - // object there. - return survivor_attempt_allocation(word_size, context); - } - } - - ShouldNotReachHere(); - // Trying to keep some compilers happy. - return NULL; -} - void G1ParCopyHelper::mark_object(oop obj) { assert(!_g1->heap_region_containing(obj)->in_collection_set(), "should not mark objects in the CSet"); @@ -4267,15 +4213,14 @@ assert(_worker_id == _par_scan_state->queue_num(), "sanity"); - G1CollectedHeap::in_cset_state_t state = _g1->in_cset_state(obj); - - if (state == G1CollectedHeap::InCSet) { + const InCSetState state = _g1->in_cset_state(obj); + if (state.is_in_cset()) { oop forwardee; markOop m = obj->mark(); if (m->is_marked()) { forwardee = (oop) m->decode_pointer(); } else { - forwardee = _par_scan_state->copy_to_survivor_space(obj, m); + forwardee = _par_scan_state->copy_to_survivor_space(state, obj, m); } assert(forwardee != NULL, "forwardee should not be NULL"); oopDesc::encode_store_heap_oop(p, forwardee); @@ -4289,7 +4234,7 @@ do_klass_barrier(p, forwardee); } } else { - if (state == G1CollectedHeap::IsHumongous) { + if (state.is_humongous()) { _g1->set_humongous_is_live(obj); } // The object is not in collection set. If we're a root scanning @@ -4609,7 +4554,7 @@ G1CollectedHeap:: g1_process_roots(OopClosure* scan_non_heap_roots, OopClosure* scan_non_heap_weak_roots, - OopsInHeapRegionClosure* scan_rs, + G1ParPushHeapRSClosure* scan_rs, CLDClosure* scan_strong_clds, CLDClosure* scan_weak_clds, CodeBlobClosure* scan_strong_code, @@ -4933,7 +4878,7 @@ } }; -Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock"); +Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never); class G1KlassCleaningTask : public StackObj { BoolObjectClosure* _is_alive; @@ -5145,17 +5090,17 @@ oop obj = *p; assert(obj != NULL, "the caller should have filtered out NULL values"); - G1CollectedHeap::in_cset_state_t cset_state = _g1->in_cset_state(obj); - if (cset_state == G1CollectedHeap::InNeither) { + const InCSetState cset_state = _g1->in_cset_state(obj); + if (!cset_state.is_in_cset_or_humongous()) { return; } - if (cset_state == G1CollectedHeap::InCSet) { + if (cset_state.is_in_cset()) { assert( obj->is_forwarded(), "invariant" ); *p = obj->forwardee(); } else { assert(!obj->is_forwarded(), "invariant" ); - assert(cset_state == G1CollectedHeap::IsHumongous, - err_msg("Only allowed InCSet state is IsHumongous, but is %d", cset_state)); + assert(cset_state.is_humongous(), + err_msg("Only allowed InCSet state is IsHumongous, but is %d", cset_state.value())); _g1->set_humongous_is_live(obj); } } @@ -5640,8 +5585,6 @@ init_for_evac_failure(NULL); - rem_set()->prepare_for_younger_refs_iterate(true); - assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty"); double start_par_time_sec = os::elapsedTime(); double end_par_time_sec; @@ -5951,6 +5894,70 @@ heap_region_iterate(&cl); guarantee(!cl.failures(), "bitmap verification"); } + +class G1CheckCSetFastTableClosure : public HeapRegionClosure { + private: + bool _failures; + public: + G1CheckCSetFastTableClosure() : HeapRegionClosure(), _failures(false) { } + + virtual bool doHeapRegion(HeapRegion* hr) { + uint i = hr->hrm_index(); + InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i); + if (hr->is_humongous()) { + if (hr->in_collection_set()) { + gclog_or_tty->print_cr("\n## humongous region %u in CSet", i); + _failures = true; + return true; + } + if (cset_state.is_in_cset()) { + gclog_or_tty->print_cr("\n## inconsistent cset state %d for humongous region %u", cset_state.value(), i); + _failures = true; + return true; + } + if (hr->is_continues_humongous() && cset_state.is_humongous()) { + gclog_or_tty->print_cr("\n## inconsistent cset state %d for continues humongous region %u", cset_state.value(), i); + _failures = true; + return true; + } + } else { + if (cset_state.is_humongous()) { + gclog_or_tty->print_cr("\n## inconsistent cset state %d for non-humongous region %u", cset_state.value(), i); + _failures = true; + return true; + } + if (hr->in_collection_set() != cset_state.is_in_cset()) { + gclog_or_tty->print_cr("\n## in CSet %d / cset state %d inconsistency for region %u", + hr->in_collection_set(), cset_state.value(), i); + _failures = true; + return true; + } + if (cset_state.is_in_cset()) { + if (hr->is_young() != (cset_state.is_young())) { + gclog_or_tty->print_cr("\n## is_young %d / cset state %d inconsistency for region %u", + hr->is_young(), cset_state.value(), i); + _failures = true; + return true; + } + if (hr->is_old() != (cset_state.is_old())) { + gclog_or_tty->print_cr("\n## is_old %d / cset state %d inconsistency for region %u", + hr->is_old(), cset_state.value(), i); + _failures = true; + return true; + } + } + } + return false; + } + + bool failures() const { return _failures; } +}; + +bool G1CollectedHeap::check_cset_fast_test() { + G1CheckCSetFastTableClosure cl; + _hrm.iterate(&cl); + return !cl.failures(); +} #endif // PRODUCT void G1CollectedHeap::cleanUpCardTable() { @@ -6519,20 +6526,20 @@ HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, uint count, - GCAllocPurpose ap) { + InCSetState dest) { assert(FreeList_lock->owned_by_self(), "pre-condition"); - if (count < g1_policy()->max_regions(ap)) { - bool survivor = (ap == GCAllocForSurvived); + if (count < g1_policy()->max_regions(dest)) { + const bool is_survivor = (dest.is_young()); HeapRegion* new_alloc_region = new_region(word_size, - !survivor, + !is_survivor, true /* do_expand */); if (new_alloc_region != NULL) { // We really only need to do this for old regions given that we // should never scan survivors. But it doesn't hurt to do it // for survivors too. new_alloc_region->record_timestamp(); - if (survivor) { + if (is_survivor) { new_alloc_region->set_survivor(); _hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor); check_bitmaps("Survivor Region Allocation", new_alloc_region); @@ -6544,8 +6551,6 @@ bool during_im = g1_policy()->during_initial_mark_pause(); new_alloc_region->note_start_of_copying(during_im); return new_alloc_region; - } else { - g1_policy()->note_alloc_region_limit_reached(ap); } } return NULL; @@ -6553,11 +6558,11 @@ void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region, size_t allocated_bytes, - GCAllocPurpose ap) { + InCSetState dest) { bool during_im = g1_policy()->during_initial_mark_pause(); alloc_region->note_end_of_copying(during_im); g1_policy()->record_bytes_copied_during_gc(allocated_bytes); - if (ap == GCAllocForSurvived) { + if (dest.is_young()) { young_list()->add_survivor_region(alloc_region); } else { _old_set.add(alloc_region); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -32,6 +32,7 @@ #include "gc_implementation/g1/g1AllocRegion.hpp" #include "gc_implementation/g1/g1BiasedArray.hpp" #include "gc_implementation/g1/g1HRPrinter.hpp" +#include "gc_implementation/g1/g1InCSetState.hpp" #include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1YCTypes.hpp" @@ -213,6 +214,9 @@ friend class G1MarkSweep; friend class HeapRegionClaimer; + // Testing classes. + friend class G1CheckCSetFastTableClosure; + private: // The one and only G1CollectedHeap, so static functions can find it. static G1CollectedHeap* _g1h; @@ -547,15 +551,9 @@ // allocation region, either by picking one or expanding the // heap, and then allocate a block of the given size. The block // may not be a humongous - it must fit into a single heap region. - HeapWord* par_allocate_during_gc(GCAllocPurpose purpose, - size_t word_size, - AllocationContext_t context); - - HeapWord* allocate_during_gc_slow(GCAllocPurpose purpose, - HeapRegion* alloc_region, - bool par, - size_t word_size); - + inline HeapWord* par_allocate_during_gc(InCSetState dest, + size_t word_size, + AllocationContext_t context); // Ensure that no further allocations can happen in "r", bearing in mind // that parallel threads might be attempting allocations. void par_allocate_remaining_space(HeapRegion* r); @@ -577,9 +575,9 @@ // For GC alloc regions. HeapRegion* new_gc_alloc_region(size_t word_size, uint count, - GCAllocPurpose ap); + InCSetState dest); void retire_gc_alloc_region(HeapRegion* alloc_region, - size_t allocated_bytes, GCAllocPurpose ap); + size_t allocated_bytes, InCSetState dest); // - if explicit_gc is true, the GC is for a System.gc() or a heap // inspection request and should collect the entire heap @@ -640,26 +638,11 @@ // (Rounds up to a HeapRegion boundary.) bool expand(size_t expand_bytes); - // Returns the PLAB statistics given a purpose. - PLABStats* stats_for_purpose(GCAllocPurpose purpose) { - PLABStats* stats = NULL; + // Returns the PLAB statistics for a given destination. + inline PLABStats* alloc_buffer_stats(InCSetState dest); - switch (purpose) { - case GCAllocForSurvived: - stats = &_survivor_plab_stats; - break; - case GCAllocForTenured: - stats = &_old_plab_stats; - break; - default: - assert(false, "unrecognized GCAllocPurpose"); - } - - return stats; - } - - // Determines PLAB size for a particular allocation purpose. - size_t desired_plab_sz(GCAllocPurpose purpose); + // Determines PLAB size for a given destination. + inline size_t desired_plab_sz(InCSetState dest); inline AllocationContextStats& allocation_context_stats(); @@ -683,8 +666,11 @@ void register_humongous_regions_with_in_cset_fast_test(); // We register a region with the fast "in collection set" test. We // simply set to true the array slot corresponding to this region. - void register_region_with_in_cset_fast_test(HeapRegion* r) { - _in_cset_fast_test.set_in_cset(r->hrm_index()); + void register_young_region_with_in_cset_fast_test(HeapRegion* r) { + _in_cset_fast_test.set_in_young(r->hrm_index()); + } + void register_old_region_with_in_cset_fast_test(HeapRegion* r) { + _in_cset_fast_test.set_in_old(r->hrm_index()); } // This is a fast test on whether a reference points into the @@ -821,7 +807,7 @@ // In the sequential case this param will be ignored. void g1_process_roots(OopClosure* scan_non_heap_roots, OopClosure* scan_non_heap_weak_roots, - OopsInHeapRegionClosure* scan_rs, + G1ParPushHeapRSClosure* scan_rs, CLDClosure* scan_strong_clds, CLDClosure* scan_weak_clds, CodeBlobClosure* scan_strong_code, @@ -1181,6 +1167,9 @@ // appropriate error messages and crash. void check_bitmaps(const char* caller) PRODUCT_RETURN; + // Do sanity check on the contents of the in-cset fast test table. + bool check_cset_fast_test() PRODUCT_RETURN_( return true; ); + // verify_region_sets() performs verification over the region // lists. It will be compiled in the product code to be used when // necessary (i.e., during heap verification). @@ -1276,53 +1265,15 @@ inline bool is_in_cset_or_humongous(const oop obj); - enum in_cset_state_t { - InNeither, // neither in collection set nor humongous - InCSet, // region is in collection set only - IsHumongous // region is a humongous start region - }; private: - // Instances of this class are used for quick tests on whether a reference points - // into the collection set or is a humongous object (points into a humongous - // object). - // Each of the array's elements denotes whether the corresponding region is in - // the collection set or a humongous region. - // We use this to quickly reclaim humongous objects: by making a humongous region - // succeed this test, we sort-of add it to the collection set. During the reference - // iteration closures, when we see a humongous region, we simply mark it as - // referenced, i.e. live. - class G1FastCSetBiasedMappedArray : public G1BiasedMappedArray { - protected: - char default_value() const { return G1CollectedHeap::InNeither; } - public: - void set_humongous(uintptr_t index) { - assert(get_by_index(index) != InCSet, "Should not overwrite InCSet values"); - set_by_index(index, G1CollectedHeap::IsHumongous); - } - - void clear_humongous(uintptr_t index) { - set_by_index(index, G1CollectedHeap::InNeither); - } - - void set_in_cset(uintptr_t index) { - assert(get_by_index(index) != G1CollectedHeap::IsHumongous, "Should not overwrite IsHumongous value"); - set_by_index(index, G1CollectedHeap::InCSet); - } - - bool is_in_cset_or_humongous(HeapWord* addr) const { return get_by_address(addr) != G1CollectedHeap::InNeither; } - bool is_in_cset(HeapWord* addr) const { return get_by_address(addr) == G1CollectedHeap::InCSet; } - G1CollectedHeap::in_cset_state_t at(HeapWord* addr) const { return (G1CollectedHeap::in_cset_state_t)get_by_address(addr); } - void clear() { G1BiasedMappedArray::clear(); } - }; - // This array is used for a quick test on whether a reference points into // the collection set or not. Each of the array's elements denotes whether the // corresponding region is in the collection set or not. - G1FastCSetBiasedMappedArray _in_cset_fast_test; + G1InCSetStateFastTestBiasedMappedArray _in_cset_fast_test; public: - inline in_cset_state_t in_cset_state(const oop obj); + inline InCSetState in_cset_state(const oop obj); // Return "TRUE" iff the given object address is in the reserved // region of g1. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -35,6 +35,41 @@ #include "runtime/orderAccess.inline.hpp" #include "utilities/taskqueue.hpp" +PLABStats* G1CollectedHeap::alloc_buffer_stats(InCSetState dest) { + switch (dest.value()) { + case InCSetState::Young: + return &_survivor_plab_stats; + case InCSetState::Old: + return &_old_plab_stats; + default: + ShouldNotReachHere(); + return NULL; // Keep some compilers happy + } +} + +size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) { + size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(); + // Prevent humongous PLAB sizes for two reasons: + // * PLABs are allocated using a similar paths as oops, but should + // never be in a humongous region + // * Allowing humongous PLABs needlessly churns the region free lists + return MIN2(_humongous_object_threshold_in_words, gclab_word_size); +} + +HeapWord* G1CollectedHeap::par_allocate_during_gc(InCSetState dest, + size_t word_size, + AllocationContext_t context) { + switch (dest.value()) { + case InCSetState::Young: + return survivor_attempt_allocation(word_size, context); + case InCSetState::Old: + return old_attempt_allocation(word_size, context); + default: + ShouldNotReachHere(); + return NULL; // Keep some compilers happy + } +} + // Inline functions for G1CollectedHeap inline AllocationContextStats& G1CollectedHeap::allocation_context_stats() { @@ -203,7 +238,7 @@ return _in_cset_fast_test.is_in_cset_or_humongous((HeapWord*)obj); } -G1CollectedHeap::in_cset_state_t G1CollectedHeap::in_cset_state(const oop obj) { +InCSetState G1CollectedHeap::in_cset_state(const oop obj) { return _in_cset_fast_test.at((HeapWord*)obj); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1437,18 +1437,6 @@ return young_list_length < young_list_max_length; } -uint G1CollectorPolicy::max_regions(int purpose) { - switch (purpose) { - case GCAllocForSurvived: - return _max_survivor_regions; - case GCAllocForTenured: - return REGIONS_UNLIMITED; - default: - ShouldNotReachHere(); - return REGIONS_UNLIMITED; - }; -} - void G1CollectorPolicy::update_max_gc_locker_expansion() { uint expansion_region_num = 0; if (GCLockerEdenExpansionPercent > 0) { @@ -1634,7 +1622,7 @@ hr->set_next_in_collection_set(_collection_set); _collection_set = hr; _collection_set_bytes_used_before += hr->used(); - _g1->register_region_with_in_cset_fast_test(hr); + _g1->register_old_region_with_in_cset_fast_test(hr); size_t rs_length = hr->rem_set()->occupied(); _recorded_rs_lengths += rs_length; _old_cset_region_length += 1; @@ -1767,7 +1755,7 @@ hr->set_in_collection_set(true); assert( hr->next_in_collection_set() == NULL, "invariant"); - _g1->register_region_with_in_cset_fast_test(hr); + _g1->register_young_region_with_in_cset_fast_test(hr); } // Add the region at the RHS of the incremental cset diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -881,28 +881,20 @@ public: uint tenuring_threshold() const { return _tenuring_threshold; } - inline GCAllocPurpose - evacuation_destination(HeapRegion* src_region, uint age, size_t word_sz) { - if (age < _tenuring_threshold && src_region->is_young()) { - return GCAllocForSurvived; - } else { - return GCAllocForTenured; - } - } - - inline bool track_object_age(GCAllocPurpose purpose) { - return purpose == GCAllocForSurvived; - } - static const uint REGIONS_UNLIMITED = (uint) -1; - uint max_regions(int purpose); - - // The limit on regions for a particular purpose is reached. - void note_alloc_region_limit_reached(int purpose) { - if (purpose == GCAllocForSurvived) { - _tenuring_threshold = 0; + uint max_regions(InCSetState dest) { + switch (dest.value()) { + case InCSetState::Young: + return _max_survivor_regions; + case InCSetState::Old: + return REGIONS_UNLIMITED; + default: + assert(false, err_msg("Unknown dest state: " CSETSTATE_FORMAT, dest.value())); + break; } + // keep some compilers happy + return 0; } void note_start_adding_survivor_regions() { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1InCSetState.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1InCSetState.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP + +#include "gc_implementation/g1/g1BiasedArray.hpp" +#include "memory/allocation.hpp" + +// Per-region state during garbage collection. +struct InCSetState { + public: + // We use different types to represent the state value. Particularly SPARC puts + // values in structs from "left to right", i.e. MSB to LSB. This results in many + // unnecessary shift operations when loading and storing values of this type. + // This degrades performance significantly (>10%) on that platform. + // Other tested ABIs do not seem to have this problem, and actually tend to + // favor smaller types, so we use the smallest usable type there. +#ifdef SPARC + #define CSETSTATE_FORMAT INTPTR_FORMAT + typedef intptr_t in_cset_state_t; +#else + #define CSETSTATE_FORMAT "%d" + typedef int8_t in_cset_state_t; +#endif + private: + in_cset_state_t _value; + public: + enum { + // Selection of the values were driven to micro-optimize the encoding and + // frequency of the checks. + // The most common check is whether the region is in the collection set or not. + // This encoding allows us to use an != 0 check which in some architectures + // (x86*) can be encoded slightly more efficently than a normal comparison + // against zero. + // The same situation occurs when checking whether the region is humongous + // or not, which is encoded by values < 0. + // The other values are simply encoded in increasing generation order, which + // makes getting the next generation fast by a simple increment. + Humongous = -1, // The region is humongous - note that actually any value < 0 would be possible here. + NotInCSet = 0, // The region is not in the collection set. + Young = 1, // The region is in the collection set and a young region. + Old = 2, // The region is in the collection set and an old region. + Num + }; + + InCSetState(in_cset_state_t value = NotInCSet) : _value(value) { + assert(is_valid(), err_msg("Invalid state %d", _value)); + } + + in_cset_state_t value() const { return _value; } + + void set_old() { _value = Old; } + + bool is_in_cset_or_humongous() const { return _value != NotInCSet; } + bool is_in_cset() const { return _value > NotInCSet; } + bool is_humongous() const { return _value < NotInCSet; } + bool is_young() const { return _value == Young; } + bool is_old() const { return _value == Old; } + +#ifdef ASSERT + bool is_default() const { return !is_in_cset_or_humongous(); } + bool is_valid() const { return (_value >= Humongous) && (_value < Num); } + bool is_valid_gen() const { return (_value >= Young && _value <= Old); } +#endif +}; + +// Instances of this class are used for quick tests on whether a reference points +// into the collection set and into which generation or is a humongous object +// +// Each of the array's elements indicates whether the corresponding region is in +// the collection set and if so in which generation, or a humongous region. +// +// We use this to speed up reference processing during young collection and +// quickly reclaim humongous objects. For the latter, by making a humongous region +// succeed this test, we sort-of add it to the collection set. During the reference +// iteration closures, when we see a humongous region, we then simply mark it as +// referenced, i.e. live. +class G1InCSetStateFastTestBiasedMappedArray : public G1BiasedMappedArray { + protected: + InCSetState default_value() const { return InCSetState::NotInCSet; } + public: + void set_humongous(uintptr_t index) { + assert(get_by_index(index).is_default(), + err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value())); + set_by_index(index, InCSetState::Humongous); + } + + void clear_humongous(uintptr_t index) { + set_by_index(index, InCSetState::NotInCSet); + } + + void set_in_young(uintptr_t index) { + assert(get_by_index(index).is_default(), + err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value())); + set_by_index(index, InCSetState::Young); + } + + void set_in_old(uintptr_t index) { + assert(get_by_index(index).is_default(), + err_msg("State at index " INTPTR_FORMAT" should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value())); + set_by_index(index, InCSetState::Old); + } + + bool is_in_cset_or_humongous(HeapWord* addr) const { return at(addr).is_in_cset_or_humongous(); } + bool is_in_cset(HeapWord* addr) const { return at(addr).is_in_cset(); } + InCSetState at(HeapWord* addr) const { return get_by_address(addr); } + void clear() { G1BiasedMappedArray::clear(); } +}; + +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1INCSETSTATE_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_G1_G1OOPCLOSURES_HPP #include "memory/iterator.hpp" +#include "oops/markOop.hpp" class HeapRegion; class G1CollectedHeap; @@ -239,14 +240,14 @@ G1CollectedHeap* _g1; G1RemSet* _g1_rem_set; HeapRegion* _from; - OopsInHeapRegionClosure* _push_ref_cl; + G1ParPushHeapRSClosure* _push_ref_cl; bool _record_refs_into_cset; uint _worker_i; public: G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, G1RemSet* rs, - OopsInHeapRegionClosure* push_ref_cl, + G1ParPushHeapRSClosure* push_ref_cl, bool record_refs_into_cset, uint worker_i = 0); @@ -256,7 +257,8 @@ } bool self_forwarded(oop obj) { - bool result = (obj->is_forwarded() && (obj->forwardee()== obj)); + markOop m = obj->mark(); + bool result = (m->is_marked() && ((oop)m->decode_pointer() == obj)); return result; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -67,8 +67,8 @@ if (!oopDesc::is_null(heap_oop)) { oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); - G1CollectedHeap::in_cset_state_t state = _g1->in_cset_state(obj); - if (state == G1CollectedHeap::InCSet) { + const InCSetState state = _g1->in_cset_state(obj); + if (state.is_in_cset()) { // We're not going to even bother checking whether the object is // already forwarded or not, as this usually causes an immediate // stall. We'll try to prefetch the object (for write, given that @@ -87,7 +87,7 @@ _par_scan_state->push_on_queue(p); } else { - if (state == G1CollectedHeap::IsHumongous) { + if (state.is_humongous()) { _g1->set_humongous_is_live(obj); } _par_scan_state->update_rs(_from, p, _worker_id); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -131,6 +131,9 @@ _committed.set_range(start, start + size_in_pages); MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize); + if (AlwaysPreTouch) { + os::pretouch_memory((char*)result.start(), (char*)result.end()); + } return result; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -38,6 +38,7 @@ _g1_rem(g1h->g1_rem_set()), _hash_seed(17), _queue_num(queue_num), _term_attempts(0), + _tenuring_threshold(g1h->g1_policy()->tenuring_threshold()), _age_table(false), _scanner(g1h, rp), _strong_roots_time(0), _term_time(0) { _scanner.set_par_scan_thread_state(this); @@ -59,6 +60,12 @@ _g1_par_allocator = G1ParGCAllocator::create_allocator(_g1h); + _dest[InCSetState::NotInCSet] = InCSetState::NotInCSet; + // The dest for Young is used when the objects are aged enough to + // need to be moved to the next space. + _dest[InCSetState::Young] = InCSetState::Old; + _dest[InCSetState::Old] = InCSetState::Old; + _start = os::elapsedTime(); } @@ -150,52 +157,94 @@ } while (!_refs->is_empty()); } -oop G1ParScanThreadState::copy_to_survivor_space(oop const old, +HeapWord* G1ParScanThreadState::allocate_in_next_plab(InCSetState const state, + InCSetState* dest, + size_t word_sz, + AllocationContext_t const context) { + assert(state.is_in_cset_or_humongous(), err_msg("Unexpected state: " CSETSTATE_FORMAT, state.value())); + assert(dest->is_in_cset_or_humongous(), err_msg("Unexpected dest: " CSETSTATE_FORMAT, dest->value())); + + // Right now we only have two types of regions (young / old) so + // let's keep the logic here simple. We can generalize it when necessary. + if (dest->is_young()) { + HeapWord* const obj_ptr = _g1_par_allocator->allocate(InCSetState::Old, + word_sz, context); + if (obj_ptr == NULL) { + return NULL; + } + // Make sure that we won't attempt to copy any other objects out + // of a survivor region (given that apparently we cannot allocate + // any new ones) to avoid coming into this slow path. + _tenuring_threshold = 0; + dest->set_old(); + return obj_ptr; + } else { + assert(dest->is_old(), err_msg("Unexpected dest: " CSETSTATE_FORMAT, dest->value())); + // no other space to try. + return NULL; + } +} + +InCSetState G1ParScanThreadState::next_state(InCSetState const state, markOop const m, uint& age) { + if (state.is_young()) { + age = !m->has_displaced_mark_helper() ? m->age() + : m->displaced_mark_helper()->age(); + if (age < _tenuring_threshold) { + return state; + } + } + return dest(state); +} + +oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state, + oop const old, markOop const old_mark) { - size_t word_sz = old->size(); - HeapRegion* from_region = _g1h->heap_region_containing_raw(old); + const size_t word_sz = old->size(); + HeapRegion* const from_region = _g1h->heap_region_containing_raw(old); // +1 to make the -1 indexes valid... - int young_index = from_region->young_index_in_cset()+1; + const int young_index = from_region->young_index_in_cset()+1; assert( (from_region->is_young() && young_index > 0) || (!from_region->is_young() && young_index == 0), "invariant" ); - G1CollectorPolicy* g1p = _g1h->g1_policy(); - uint age = old_mark->has_displaced_mark_helper() ? old_mark->displaced_mark_helper()->age() - : old_mark->age(); - GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, - word_sz); - AllocationContext_t context = from_region->allocation_context(); - HeapWord* obj_ptr = _g1_par_allocator->allocate(alloc_purpose, word_sz, context); + const AllocationContext_t context = from_region->allocation_context(); + + uint age = 0; + InCSetState dest_state = next_state(state, old_mark, age); + HeapWord* obj_ptr = _g1_par_allocator->plab_allocate(dest_state, word_sz, context); + + // PLAB allocations should succeed most of the time, so we'll + // normally check against NULL once and that's it. + if (obj_ptr == NULL) { + obj_ptr = _g1_par_allocator->allocate_direct_or_new_plab(dest_state, word_sz, context); + if (obj_ptr == NULL) { + obj_ptr = allocate_in_next_plab(state, &dest_state, word_sz, context); + if (obj_ptr == NULL) { + // This will either forward-to-self, or detect that someone else has + // installed a forwarding pointer. + return _g1h->handle_evacuation_failure_par(this, old); + } + } + } + + assert(obj_ptr != NULL, "when we get here, allocation should have succeeded"); #ifndef PRODUCT // Should this evacuation fail? if (_g1h->evacuation_should_fail()) { - if (obj_ptr != NULL) { - _g1_par_allocator->undo_allocation(alloc_purpose, obj_ptr, word_sz, context); - obj_ptr = NULL; - } + // Doing this after all the allocation attempts also tests the + // undo_allocation() method too. + _g1_par_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); + return _g1h->handle_evacuation_failure_par(this, old); } #endif // !PRODUCT - if (obj_ptr == NULL) { - // This will either forward-to-self, or detect that someone else has - // installed a forwarding pointer. - return _g1h->handle_evacuation_failure_par(this, old); - } - - oop obj = oop(obj_ptr); - // We're going to allocate linearly, so might as well prefetch ahead. Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); - oop forward_ptr = old->forward_to_atomic(obj); + const oop obj = oop(obj_ptr); + const oop forward_ptr = old->forward_to_atomic(obj); if (forward_ptr == NULL) { Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); - // alloc_purpose is just a hint to allocate() above, recheck the type of region - // we actually allocated from and update alloc_purpose accordingly - HeapRegion* to_region = _g1h->heap_region_containing_raw(obj_ptr); - alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured; - - if (g1p->track_object_age(alloc_purpose)) { + if (dest_state.is_young()) { if (age < markOopDesc::max_age) { age++; } @@ -215,13 +264,19 @@ } if (G1StringDedup::is_enabled()) { - G1StringDedup::enqueue_from_evacuation(from_region->is_young(), - to_region->is_young(), + const bool is_from_young = state.is_young(); + const bool is_to_young = dest_state.is_young(); + assert(is_from_young == _g1h->heap_region_containing_raw(old)->is_young(), + "sanity"); + assert(is_to_young == _g1h->heap_region_containing_raw(obj)->is_young(), + "sanity"); + G1StringDedup::enqueue_from_evacuation(is_from_young, + is_to_young, queue_num(), obj); } - size_t* surv_young_words = surviving_young_words(); + size_t* const surv_young_words = surviving_young_words(); surv_young_words[young_index] += word_sz; if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { @@ -232,14 +287,13 @@ oop* old_p = set_partial_array_mask(old); push_on_queue(old_p); } else { - // No point in using the slower heap_region_containing() method, - // given that we know obj is in the heap. - _scanner.set_region(_g1h->heap_region_containing_raw(obj)); + HeapRegion* const to_region = _g1h->heap_region_containing_raw(obj_ptr); + _scanner.set_region(to_region); obj->oop_iterate_backwards(&_scanner); } + return obj; } else { - _g1_par_allocator->undo_allocation(alloc_purpose, obj_ptr, word_sz, context); - obj = forward_ptr; + _g1_par_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context); + return forward_ptr; } - return obj; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -46,14 +46,16 @@ G1SATBCardTableModRefBS* _ct_bs; G1RemSet* _g1_rem; - G1ParGCAllocator* _g1_par_allocator; - - ageTable _age_table; + G1ParGCAllocator* _g1_par_allocator; - G1ParScanClosure _scanner; + ageTable _age_table; + InCSetState _dest[InCSetState::Num]; + // Local tenuring threshold. + uint _tenuring_threshold; + G1ParScanClosure _scanner; - size_t _alloc_buffer_waste; - size_t _undo_waste; + size_t _alloc_buffer_waste; + size_t _undo_waste; OopsInHeapRegionClosure* _evac_failure_cl; @@ -82,6 +84,14 @@ DirtyCardQueue& dirty_card_queue() { return _dcq; } G1SATBCardTableModRefBS* ctbs() { return _ct_bs; } + InCSetState dest(InCSetState original) const { + assert(original.is_valid(), + err_msg("Original state invalid: " CSETSTATE_FORMAT, original.value())); + assert(_dest[original.value()].is_valid_gen(), + err_msg("Dest state is invalid: " CSETSTATE_FORMAT, _dest[original.value()].value())); + return _dest[original.value()]; + } + public: G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp); ~G1ParScanThreadState(); @@ -112,7 +122,6 @@ } } } - public: void set_evac_failure_closure(OopsInHeapRegionClosure* evac_failure_cl) { _evac_failure_cl = evac_failure_cl; @@ -193,9 +202,20 @@ template inline void deal_with_reference(T* ref_to_scan); inline void dispatch_reference(StarTask ref); + + // Tries to allocate word_sz in the PLAB of the next "generation" after trying to + // allocate into dest. State is the original (source) cset state for the object + // that is allocated for. + // Returns a non-NULL pointer if successful, and updates dest if required. + HeapWord* allocate_in_next_plab(InCSetState const state, + InCSetState* dest, + size_t word_sz, + AllocationContext_t const context); + + inline InCSetState next_state(InCSetState const state, markOop const m, uint& age); public: - oop copy_to_survivor_space(oop const obj, markOop const old_mark); + oop copy_to_survivor_space(InCSetState const state, oop const obj, markOop const old_mark); void trim_queue(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -38,21 +38,21 @@ // set, due to (benign) races in the claim mechanism during RSet scanning more // than one thread might claim the same card. So the same card may be // processed multiple times. So redo this check. - G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj); - if (in_cset_state == G1CollectedHeap::InCSet) { + const InCSetState in_cset_state = _g1h->in_cset_state(obj); + if (in_cset_state.is_in_cset()) { oop forwardee; markOop m = obj->mark(); if (m->is_marked()) { forwardee = (oop) m->decode_pointer(); } else { - forwardee = copy_to_survivor_space(obj, m); + forwardee = copy_to_survivor_space(in_cset_state, obj, m); } oopDesc::encode_store_heap_oop(p, forwardee); - } else if (in_cset_state == G1CollectedHeap::IsHumongous) { + } else if (in_cset_state.is_humongous()) { _g1h->set_humongous_is_live(obj); } else { - assert(in_cset_state == G1CollectedHeap::InNeither, - err_msg("In_cset_state must be InNeither here, but is %d", in_cset_state)); + assert(!in_cset_state.is_in_cset_or_humongous(), + err_msg("In_cset_state must be NotInCSet here, but is " CSETSTATE_FORMAT, in_cset_state.value())); } assert(obj != NULL, "Must be"); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -80,7 +80,7 @@ _prev_period_summary() { _seq_task = new SubTasksDone(NumSeqTasks); - _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC); + _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC); for (uint i = 0; i < n_workers(); i++) { _cset_rs_update_cl[i] = NULL; } @@ -94,14 +94,14 @@ for (uint i = 0; i < n_workers(); i++) { assert(_cset_rs_update_cl[i] == NULL, "it should be"); } - FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl); + FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl); } class ScanRSClosure : public HeapRegionClosure { size_t _cards_done, _cards; G1CollectedHeap* _g1h; - OopsInHeapRegionClosure* _oc; + G1ParPushHeapRSClosure* _oc; CodeBlobClosure* _code_root_cl; G1BlockOffsetSharedArray* _bot_shared; @@ -113,7 +113,7 @@ bool _try_claimed; public: - ScanRSClosure(OopsInHeapRegionClosure* oc, + ScanRSClosure(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) : _oc(oc), @@ -135,8 +135,7 @@ void scanCard(size_t index, HeapRegion *r) { // Stack allocate the DirtyCardToOopClosure instance HeapRegionDCTOC cl(_g1h, r, _oc, - CardTableModRefBS::Precise, - HeapRegionDCTOC::IntoCSFilterKind); + CardTableModRefBS::Precise); // Set the "from" region in the closure. _oc->set_region(r); @@ -231,7 +230,7 @@ size_t cards_looked_up() { return _cards;} }; -void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, +void G1RemSet::scanRS(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) { double rs_time_start = os::elapsedTime(); @@ -301,7 +300,7 @@ HeapRegionRemSet::cleanup(); } -void G1RemSet::oops_into_collection_set_do(OopsInHeapRegionClosure* oc, +void G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) { #if CARD_REPEAT_HISTO @@ -417,7 +416,7 @@ G1UpdateRSOrPushRefOopClosure:: G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, G1RemSet* rs, - OopsInHeapRegionClosure* push_ref_cl, + G1ParPushHeapRSClosure* push_ref_cl, bool record_refs_into_cset, uint worker_i) : _g1(g1h), _g1_rem_set(rs), _from(NULL), @@ -518,7 +517,7 @@ ct_freq_note_card(_ct_bs->index_for(start)); #endif - OopsInHeapRegionClosure* oops_in_heap_closure = NULL; + G1ParPushHeapRSClosure* oops_in_heap_closure = NULL; if (check_for_refs_into_cset) { // ConcurrentG1RefineThreads have worker numbers larger than what // _cset_rs_update_cl[] is set up to handle. But those threads should diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -33,6 +33,7 @@ class G1CollectedHeap; class CardTableModRefBarrierSet; class ConcurrentG1Refine; +class G1ParPushHeapRSClosure; // A G1RemSet in which each heap region has a rem set that records the // external heap references into it. Uses a mod ref bs to track updates, @@ -68,7 +69,7 @@ // Used for caching the closure that is responsible for scanning // references into the collection set. - OopsInHeapRegionClosure** _cset_rs_update_cl; + G1ParPushHeapRSClosure** _cset_rs_update_cl; // Print the given summary info virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL); @@ -95,7 +96,7 @@ // partitioning the work to be done. It should be the same as // the "i" passed to the calling thread's work(i) function. // In the sequential case this param will be ignored. - void oops_into_collection_set_do(OopsInHeapRegionClosure* blk, + void oops_into_collection_set_do(G1ParPushHeapRSClosure* blk, CodeBlobClosure* code_root_cl, uint worker_i); @@ -107,7 +108,7 @@ void prepare_for_oops_into_collection_set_do(); void cleanup_after_oops_into_collection_set_do(); - void scanRS(OopsInHeapRegionClosure* oc, + void scanRS(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ #include "runtime/thread.inline.hpp" G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap) : - CardTableModRefBSForCTRS(whole_heap) + CardTableModRefBS(whole_heap) { _kind = G1SATBCT; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,7 @@ // This barrier is specialized to use a logging barrier to support // snapshot-at-the-beginning marking. -class G1SATBCardTableModRefBS: public CardTableModRefBSForCTRS { +class G1SATBCardTableModRefBS: public CardTableModRefBS { protected: enum G1CardValues { g1_young_gen = CT_MR_BS_last_reserved << 1 diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -48,93 +48,55 @@ size_t HeapRegion::CardsPerRegion = 0; HeapRegionDCTOC::HeapRegionDCTOC(G1CollectedHeap* g1, - HeapRegion* hr, ExtendedOopClosure* cl, - CardTableModRefBS::PrecisionStyle precision, - FilterKind fk) : + HeapRegion* hr, + G1ParPushHeapRSClosure* cl, + CardTableModRefBS::PrecisionStyle precision) : DirtyCardToOopClosure(hr, cl, precision, NULL), - _hr(hr), _fk(fk), _g1(g1) { } + _hr(hr), _rs_scan(cl), _g1(g1) { } FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc) : _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { } -template -HeapWord* walk_mem_region_loop(ClosureType* cl, G1CollectedHeap* g1h, - HeapRegion* hr, - HeapWord* cur, HeapWord* top) { - oop cur_oop = oop(cur); - size_t oop_size = hr->block_size(cur); - HeapWord* next_obj = cur + oop_size; - while (next_obj < top) { - // Keep filtering the remembered set. - if (!g1h->is_obj_dead(cur_oop, hr)) { - // Bottom lies entirely below top, so we can call the - // non-memRegion version of oop_iterate below. - cur_oop->oop_iterate(cl); - } - cur = next_obj; - cur_oop = oop(cur); - oop_size = hr->block_size(cur); - next_obj = cur + oop_size; - } - return cur; -} - void HeapRegionDCTOC::walk_mem_region(MemRegion mr, HeapWord* bottom, HeapWord* top) { G1CollectedHeap* g1h = _g1; size_t oop_size; - ExtendedOopClosure* cl2 = NULL; - - FilterIntoCSClosure intoCSFilt(this, g1h, _cl); - FilterOutOfRegionClosure outOfRegionFilt(_hr, _cl); - - switch (_fk) { - case NoFilterKind: cl2 = _cl; break; - case IntoCSFilterKind: cl2 = &intoCSFilt; break; - case OutOfRegionFilterKind: cl2 = &outOfRegionFilt; break; - default: ShouldNotReachHere(); - } + HeapWord* cur = bottom; // Start filtering what we add to the remembered set. If the object is // not considered dead, either because it is marked (in the mark bitmap) // or it was allocated after marking finished, then we add it. Otherwise // we can safely ignore the object. - if (!g1h->is_obj_dead(oop(bottom), _hr)) { - oop_size = oop(bottom)->oop_iterate(cl2, mr); + if (!g1h->is_obj_dead(oop(cur), _hr)) { + oop_size = oop(cur)->oop_iterate(_rs_scan, mr); } else { - oop_size = _hr->block_size(bottom); + oop_size = _hr->block_size(cur); } - bottom += oop_size; - - if (bottom < top) { - // We replicate the loop below for several kinds of possible filters. - switch (_fk) { - case NoFilterKind: - bottom = walk_mem_region_loop(_cl, g1h, _hr, bottom, top); - break; + cur += oop_size; - case IntoCSFilterKind: { - FilterIntoCSClosure filt(this, g1h, _cl); - bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); - break; - } - - case OutOfRegionFilterKind: { - FilterOutOfRegionClosure filt(_hr, _cl); - bottom = walk_mem_region_loop(&filt, g1h, _hr, bottom, top); - break; - } - - default: - ShouldNotReachHere(); + if (cur < top) { + oop cur_oop = oop(cur); + oop_size = _hr->block_size(cur); + HeapWord* next_obj = cur + oop_size; + while (next_obj < top) { + // Keep filtering the remembered set. + if (!g1h->is_obj_dead(cur_oop, _hr)) { + // Bottom lies entirely below top, so we can call the + // non-memRegion version of oop_iterate below. + cur_oop->oop_iterate(_rs_scan); + } + cur = next_obj; + cur_oop = oop(cur); + oop_size = _hr->block_size(cur); + next_obj = cur + oop_size; } // Last object. Need to do dead-obj filtering here too. - if (!g1h->is_obj_dead(oop(bottom), _hr)) { - oop(bottom)->oop_iterate(cl2, mr); + if (!g1h->is_obj_dead(oop(cur), _hr)) { + oop(cur)->oop_iterate(_rs_scan, mr); } } } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -67,17 +67,9 @@ // sets. class HeapRegionDCTOC : public DirtyCardToOopClosure { -public: - // Specification of possible DirtyCardToOopClosure filtering. - enum FilterKind { - NoFilterKind, - IntoCSFilterKind, - OutOfRegionFilterKind - }; - -protected: +private: HeapRegion* _hr; - FilterKind _fk; + G1ParPushHeapRSClosure* _rs_scan; G1CollectedHeap* _g1; // Walk the given memory region from bottom to (actual) top @@ -90,9 +82,9 @@ public: HeapRegionDCTOC(G1CollectedHeap* g1, - HeapRegion* hr, ExtendedOopClosure* cl, - CardTableModRefBS::PrecisionStyle precision, - FilterKind fk); + HeapRegion* hr, + G1ParPushHeapRSClosure* cl, + CardTableModRefBS::PrecisionStyle precision); }; // The complicating factor is that BlockOffsetTable diverged diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -407,20 +407,8 @@ } } -void OtherRegionsTable::initialize(uint max_regions) { - FromCardCache::initialize(HeapRegionRemSet::num_par_rem_sets(), max_regions); -} - -void OtherRegionsTable::invalidate(uint start_idx, size_t num_regions) { - FromCardCache::invalidate(start_idx, num_regions); -} - -void OtherRegionsTable::print_from_card_cache() { - FromCardCache::print(); -} - void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) { - uint cur_hrm_ind = hr()->hrm_index(); + uint cur_hrm_ind = _hr->hrm_index(); if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").", @@ -434,7 +422,7 @@ if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)", - hr()->bottom(), from_card, + _hr->bottom(), from_card, FromCardCache::at(tid, cur_hrm_ind)); } @@ -477,13 +465,13 @@ if (G1HRRSUseSparseTable && _sparse_table.add_card(from_hrm_ind, card_index)) { if (G1RecordHRRSOops) { - HeapRegionRemSet::record(hr(), from); + HeapRegionRemSet::record(_hr, from); if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print(" Added card " PTR_FORMAT " to region " "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n", align_size_down(uintptr_t(from), CardTableModRefBS::card_size), - hr()->bottom(), from); + _hr->bottom(), from); } } if (G1TraceHeapRegionRememberedSet) { @@ -539,13 +527,13 @@ prt->add_reference(from); if (G1RecordHRRSOops) { - HeapRegionRemSet::record(hr(), from); + HeapRegionRemSet::record(_hr, from); if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print("Added card " PTR_FORMAT " to region " "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n", align_size_down(uintptr_t(from), CardTableModRefBS::card_size), - hr()->bottom(), from); + _hr->bottom(), from); } } assert(contains_reference(from), "We just added it!"); @@ -614,7 +602,7 @@ if (G1TraceHeapRegionRememberedSet) { gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] " "for region [" PTR_FORMAT "...] (" SIZE_FORMAT " coarse entries).\n", - hr()->bottom(), + _hr->bottom(), max->hr()->bottom(), _n_coarse_entries); } @@ -627,13 +615,11 @@ return max; } - -// At present, this must be called stop-world single-threaded. void OtherRegionsTable::scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm) { // First eliminated garbage regions from the coarse map. if (G1RSScrubVerbose) { - gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrm_index()); + gclog_or_tty->print_cr("Scrubbing region %u:", _hr->hrm_index()); } assert(_coarse_map.size() == region_bm->size(), "Precondition"); @@ -752,7 +738,7 @@ } void OtherRegionsTable::clear_fcc() { - FromCardCache::clear(hr()->hrm_index()); + FromCardCache::clear(_hr->hrm_index()); } void OtherRegionsTable::clear() { @@ -774,27 +760,6 @@ clear_fcc(); } -bool OtherRegionsTable::del_single_region_table(size_t ind, - HeapRegion* hr) { - assert(0 <= ind && ind < _max_fine_entries, "Preconditions."); - PerRegionTable** prev_addr = &_fine_grain_regions[ind]; - PerRegionTable* prt = *prev_addr; - while (prt != NULL && prt->hr() != hr) { - prev_addr = prt->collision_list_next_addr(); - prt = prt->collision_list_next(); - } - if (prt != NULL) { - assert(prt->hr() == hr, "Loop postcondition."); - *prev_addr = prt->collision_list_next(); - unlink_from_all(prt); - PerRegionTable::free(prt); - _n_fine_entries--; - return true; - } else { - return false; - } -} - bool OtherRegionsTable::contains_reference(OopOrNarrowOopStar from) const { // Cast away const in this case. MutexLockerEx x((Mutex*)_m, Mutex::_no_safepoint_check_flag); @@ -840,7 +805,7 @@ HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr) : _bosa(bosa), - _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true), + _m(Mutex::leaf, FormatBuffer<128>("HeapRegionRemSet lock #%u", hr->hrm_index()), true, Monitor::_safepoint_check_never), _code_roots(), _other_regions(hr, &_m), _iter_state(Unclaimed), _iter_claimed(0) { reset_for_par_iteration(); } @@ -975,7 +940,7 @@ _hrrs(hrrs), _g1h(G1CollectedHeap::heap()), _coarse_map(&hrrs->_other_regions._coarse_map), - _bosa(hrrs->bosa()), + _bosa(hrrs->_bosa), _is(Sparse), // Set these values so that we increment to the first region. _coarse_cur_region_index(-1), diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp --- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -162,32 +162,36 @@ // to hold _m, and the fine-grain table to be full. PerRegionTable* delete_region_table(); - // If a PRT for "hr" is in the bucket list indicated by "ind" (which must - // be the correct index for "hr"), delete it and return true; else return - // false. - bool del_single_region_table(size_t ind, HeapRegion* hr); - // link/add the given fine grain remembered set into the "all" list void link_to_all(PerRegionTable * prt); // unlink/remove the given fine grain remembered set into the "all" list void unlink_from_all(PerRegionTable * prt); + bool contains_reference_locked(OopOrNarrowOopStar from) const; + + // Clear the from_card_cache entries for this region. + void clear_fcc(); public: + // Create a new remembered set for the given heap region. The given mutex should + // be used to ensure consistency. OtherRegionsTable(HeapRegion* hr, Mutex* m); - HeapRegion* hr() const { return _hr; } - // For now. Could "expand" some tables in the future, so that this made // sense. void add_reference(OopOrNarrowOopStar from, uint tid); + // Returns whether the remembered set contains the given reference. + bool contains_reference(OopOrNarrowOopStar from) const; + // Removes any entries shown by the given bitmaps to contain only dead - // objects. + // objects. Not thread safe. + // Set bits in the bitmaps indicate that the given region or card is live. void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); - // Returns whether this remembered set (and all sub-sets) contain no entries. + // Returns whether this remembered set (and all sub-sets) does not contain any entry. bool is_empty() const; + // Returns the number of cards contained in this remembered set. size_t occupied() const; size_t occ_fine() const; size_t occ_coarse() const; @@ -195,31 +199,17 @@ static jint n_coarsenings() { return _n_coarsenings; } - // Returns size in bytes. - // Not const because it takes a lock. + // Returns size of the actual remembered set containers in bytes. size_t mem_size() const; + // Returns the size of static data in bytes. static size_t static_mem_size(); + // Returns the size of the free list content in bytes. static size_t fl_mem_size(); - bool contains_reference(OopOrNarrowOopStar from) const; - bool contains_reference_locked(OopOrNarrowOopStar from) const; - + // Clear the entire contents of this remembered set. void clear(); - // Specifically clear the from_card_cache. - void clear_fcc(); - void do_cleanup_work(HRRSCleanupTask* hrrs_cleanup_task); - - // Declare the heap size (in # of regions) to the OtherRegionsTable. - // (Uses it to initialize from_card_cache). - static void initialize(uint max_regions); - - // Declares that regions between start_idx <= i < start_idx + num_regions are - // not in use. Make sure that any entries for these regions are invalid. - static void invalidate(uint start_idx, size_t num_regions); - - static void print_from_card_cache(); }; class HeapRegionRemSet : public CHeapObj { @@ -233,7 +223,6 @@ private: G1BlockOffsetSharedArray* _bosa; - G1BlockOffsetSharedArray* bosa() const { return _bosa; } // A set of code blobs (nmethods) whose code contains pointers into // the region that owns this RSet. @@ -268,10 +257,6 @@ static uint num_par_rem_sets(); static void setup_remset_size(); - HeapRegion* hr() const { - return _other_regions.hr(); - } - bool is_empty() const { return (strong_code_roots_list_length() == 0) && _other_regions.is_empty(); } @@ -305,8 +290,9 @@ _other_regions.add_reference(from, tid); } - // Removes any entries shown by the given bitmaps to contain only dead - // objects. + // Removes any entries in the remembered set shown by the given bitmaps to + // contain only dead objects. Not thread safe. + // One bits in the bitmaps indicate that the given region or card is live. void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm); // The region is being reclaimed; clear its remset, and any mention of @@ -397,16 +383,16 @@ // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). // (Uses it to initialize from_card_cache). static void init_heap(uint max_regions) { - OtherRegionsTable::initialize(max_regions); + FromCardCache::initialize(num_par_rem_sets(), max_regions); } - static void invalidate(uint start_idx, uint num_regions) { - OtherRegionsTable::invalidate(start_idx, num_regions); + static void invalidate_from_card_cache(uint start_idx, size_t num_regions) { + FromCardCache::invalidate(start_idx, num_regions); } #ifndef PRODUCT static void print_from_card_cache() { - OtherRegionsTable::print_from_card_cache(); + FromCardCache::print(); } #endif diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -400,7 +400,8 @@ assert(workers() != 0, "no workers"); _monitor = new Monitor(Mutex::barrier, // rank "GCTaskManager monitor", // name - Mutex::_allow_vm_block_flag); // allow_vm_block + Mutex::_allow_vm_block_flag, // allow_vm_block + Monitor::_safepoint_check_never); // The queue for the GCTaskManager must be a CHeapObj. GCTaskQueue* unsynchronized_queue = GCTaskQueue::create_on_c_heap(); _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock()); @@ -1125,7 +1126,8 @@ } else { result = new Monitor(Mutex::barrier, // rank "MonitorSupply monitor", // name - Mutex::_allow_vm_block_flag); // allow_vm_block + Mutex::_allow_vm_block_flag, // allow_vm_block + Monitor::_safepoint_check_never); } guarantee(result != NULL, "shouldn't return NULL"); assert(!result->is_locked(), "shouldn't be locked"); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -195,7 +195,7 @@ COMPILER2_PRESENT(DerivedPointerTable::clear()); - ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + ref_processor()->enable_discovery(); ref_processor()->setup_policy(clear_all_softrefs); mark_sweep_phase1(clear_all_softrefs); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -41,31 +41,24 @@ // Closure accessors static OopClosure* mark_and_push_closure() { return &MarkSweep::mark_and_push_closure; } - static VoidClosure* follow_stack_closure() { return (VoidClosure*)&MarkSweep::follow_stack_closure; } + static VoidClosure* follow_stack_closure() { return &MarkSweep::follow_stack_closure; } static CLDClosure* follow_cld_closure() { return &MarkSweep::follow_cld_closure; } - static OopClosure* adjust_pointer_closure() { return (OopClosure*)&MarkSweep::adjust_pointer_closure; } + static OopClosure* adjust_pointer_closure() { return &MarkSweep::adjust_pointer_closure; } static CLDClosure* adjust_cld_closure() { return &MarkSweep::adjust_cld_closure; } - static BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&MarkSweep::is_alive; } + static BoolObjectClosure* is_alive_closure() { return &MarkSweep::is_alive; } - debug_only(public:) // Used for PSParallelCompact debugging // Mark live objects static void mark_sweep_phase1(bool clear_all_softrefs); // Calculate new addresses static void mark_sweep_phase2(); - debug_only(private:) // End used for PSParallelCompact debugging // Update pointers static void mark_sweep_phase3(); // Move objects to new positions static void mark_sweep_phase4(); - debug_only(public:) // Used for PSParallelCompact debugging // Temporary data structures for traversal and storing/restoring marks static void allocate_stacks(); static void deallocate_stacks(); - static void set_ref_processor(ReferenceProcessor* rp) { // delete this method - _ref_processor = rp; - } - debug_only(private:) // End used for PSParallelCompact debugging // If objects are left in eden after a collection, try to move the boundary // and absorb them into the old gen. Returns true if eden was emptied. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -2069,7 +2069,7 @@ COMPILER2_PRESENT(DerivedPointerTable::clear()); - ref_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + ref_processor()->enable_discovery(); ref_processor()->setup_policy(maximum_heap_compaction); bool marked_for_unloading = false; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -147,6 +147,10 @@ claimed_stack_depth()->push(p); } + inline void promotion_trace_event(oop new_obj, oop old_obj, size_t obj_size, + uint age, bool tenured, + const PSPromotionLAB* lab); + protected: static OopStarTaskQueueSet* stack_array_depth() { return _stack_array_depth; } public: diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -64,6 +64,33 @@ claim_or_forward_internal_depth(p); } +inline void PSPromotionManager::promotion_trace_event(oop new_obj, oop old_obj, + size_t obj_size, + uint age, bool tenured, + const PSPromotionLAB* lab) { + // Skip if memory allocation failed + if (new_obj != NULL) { + const ParallelScavengeTracer* gc_tracer = PSScavenge::gc_tracer(); + + if (lab != NULL) { + // Promotion of object through newly allocated PLAB + if (gc_tracer->should_report_promotion_in_new_plab_event()) { + size_t obj_bytes = obj_size * HeapWordSize; + size_t lab_size = lab->capacity(); + gc_tracer->report_promotion_in_new_plab_event(old_obj->klass(), obj_bytes, + age, tenured, lab_size); + } + } else { + // Promotion of object directly to heap + if (gc_tracer->should_report_promotion_outside_plab_event()) { + size_t obj_bytes = obj_size * HeapWordSize; + gc_tracer->report_promotion_outside_plab_event(old_obj->klass(), obj_bytes, + age, tenured); + } + } + } +} + // // This method is pretty bulky. It would be nice to split it up // into smaller submethods, but we need to be careful not to hurt @@ -85,11 +112,11 @@ bool new_obj_is_tenured = false; size_t new_obj_size = o->size(); + // Find the objects age, MT safe. + uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ? + test_mark->displaced_mark_helper()->age() : test_mark->age(); + if (!promote_immediately) { - // Find the objects age, MT safe. - uint age = (test_mark->has_displaced_mark_helper() /* o->has_displaced_mark() */) ? - test_mark->displaced_mark_helper()->age() : test_mark->age(); - // Try allocating obj in to-space (unless too old) if (age < PSScavenge::tenuring_threshold()) { new_obj = (oop) _young_lab.allocate(new_obj_size); @@ -98,6 +125,7 @@ if (new_obj_size > (YoungPLABSize / 2)) { // Allocate this object directly new_obj = (oop)young_space()->cas_allocate(new_obj_size); + promotion_trace_event(new_obj, o, new_obj_size, age, false, NULL); } else { // Flush and fill _young_lab.flush(); @@ -107,6 +135,7 @@ _young_lab.initialize(MemRegion(lab_base, YoungPLABSize)); // Try the young lab allocation again. new_obj = (oop) _young_lab.allocate(new_obj_size); + promotion_trace_event(new_obj, o, new_obj_size, age, false, &_young_lab); } else { _young_gen_is_full = true; } @@ -132,6 +161,7 @@ if (new_obj_size > (OldPLABSize / 2)) { // Allocate this object directly new_obj = (oop)old_gen()->cas_allocate(new_obj_size); + promotion_trace_event(new_obj, o, new_obj_size, age, true, NULL); } else { // Flush and fill _old_lab.flush(); @@ -148,6 +178,7 @@ _old_lab.initialize(MemRegion(lab_base, OldPLABSize)); // Try the old lab allocation again. new_obj = (oop) _old_lab.allocate(new_obj_size); + promotion_trace_event(new_obj, o, new_obj_size, age, true, &_old_lab); } } } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -362,7 +362,7 @@ COMPILER2_PRESENT(DerivedPointerTable::clear()); - reference_processor()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + reference_processor()->enable_discovery(); reference_processor()->setup_policy(false); // We track how much was promoted to the next generation for diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -92,6 +92,7 @@ // Private accessors static CardTableExtension* const card_table() { assert(_card_table != NULL, "Sanity"); return _card_table; } + static const ParallelScavengeTracer* gc_tracer() { return &_gc_tracer; } public: // Accessors diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/shared/concurrentGCThread.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -88,7 +88,8 @@ SurrogateLockerThread::SurrogateLockerThread() : JavaThread(&_sltLoop), - _monitor(Mutex::nonleaf, "SLTMonitor"), + _monitor(Mutex::nonleaf, "SLTMonitor", false, + Monitor::_safepoint_check_sometimes), _buffer(empty) {} diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -172,6 +172,27 @@ _tenuring_threshold = tenuring_threshold; } +bool YoungGCTracer::should_report_promotion_in_new_plab_event() const { + return should_send_promotion_in_new_plab_event(); +} + +bool YoungGCTracer::should_report_promotion_outside_plab_event() const { + return should_send_promotion_outside_plab_event(); +} + +void YoungGCTracer::report_promotion_in_new_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured, + size_t plab_size) const { + assert_set_gc_id(); + send_promotion_in_new_plab_event(klass, obj_size, age, tenured, plab_size); +} + +void YoungGCTracer::report_promotion_outside_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured) const { + assert_set_gc_id(); + send_promotion_outside_plab_event(klass, obj_size, age, tenured); +} + void OldGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -156,9 +156,38 @@ void report_promotion_failed(const PromotionFailedInfo& pf_info); void report_tenuring_threshold(const uint tenuring_threshold); + /* + * Methods for reporting Promotion in new or outside PLAB Events. + * + * The object age is always required as it is not certain that the mark word + * of the oop can be trusted at this stage. + * + * obj_size is the size of the promoted object in bytes. + * + * tenured should be true if the object has been promoted to the old + * space during this GC, if the object is copied to survivor space + * from young space or survivor space (aging) tenured should be false. + * + * plab_size is the size of the newly allocated PLAB in bytes. + */ + bool should_report_promotion_in_new_plab_event() const; + bool should_report_promotion_outside_plab_event() const; + void report_promotion_in_new_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured, + size_t plab_size) const; + void report_promotion_outside_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured) const; + private: void send_young_gc_event() const; void send_promotion_failed_event(const PromotionFailedInfo& pf_info) const; + bool should_send_promotion_in_new_plab_event() const; + bool should_send_promotion_outside_plab_event() const; + void send_promotion_in_new_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured, + size_t plab_size) const; + void send_promotion_outside_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured) const; }; class OldGCTracer : public GCTracer { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -111,6 +111,44 @@ } } +bool YoungGCTracer::should_send_promotion_in_new_plab_event() const { + return EventPromoteObjectInNewPLAB::is_enabled(); +} + +bool YoungGCTracer::should_send_promotion_outside_plab_event() const { + return EventPromoteObjectOutsidePLAB::is_enabled(); +} + +void YoungGCTracer::send_promotion_in_new_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured, + size_t plab_size) const { + + EventPromoteObjectInNewPLAB event; + if (event.should_commit()) { + event.set_gcId(_shared_gc_info.gc_id().id()); + event.set_class(klass); + event.set_objectSize(obj_size); + event.set_tenured(tenured); + event.set_tenuringAge(age); + event.set_plabSize(plab_size); + event.commit(); + } +} + +void YoungGCTracer::send_promotion_outside_plab_event(Klass* klass, size_t obj_size, + uint age, bool tenured) const { + + EventPromoteObjectOutsidePLAB event; + if (event.should_commit()) { + event.set_gcId(_shared_gc_info.gc_id().id()); + event.set_class(klass); + event.set_objectSize(obj_size); + event.set_tenured(tenured); + event.set_tenuringAge(age); + event.commit(); + } +} + void OldGCTracer::send_old_gc_event() const { EventGCOldGarbageCollection e(UNTIMED); if (e.should_commit()) { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp --- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -63,9 +63,7 @@ } void MutableSpace::pretouch_pages(MemRegion mr) { - for (volatile char *p = (char*)mr.start(); p < (char*)mr.end(); p += os::vm_page_size()) { - char t = *p; *p = t; - } + os::pretouch_memory((char*)mr.start(), (char*)mr.end()); } void MutableSpace::initialize(MemRegion mr, diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/interpreter/interpreterRuntime.cpp --- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -385,6 +385,22 @@ int handler_bci; int current_bci = bci(thread); + if (thread->frames_to_pop_failed_realloc() > 0) { + // Allocation of scalar replaced object used in this frame + // failed. Unconditionally pop the frame. + thread->dec_frames_to_pop_failed_realloc(); + thread->set_vm_result(h_exception()); + // If the method is synchronized we already unlocked the monitor + // during deoptimization so the interpreter needs to skip it when + // the frame is popped. + thread->set_do_not_unlock_if_synchronized(true); +#ifdef CC_INTERP + return (address) -1; +#else + return Interpreter::remove_activation_entry(); +#endif + } + // Need to do this check first since when _do_not_unlock_if_synchronized // is set, we don't want to trigger any classloading which may make calls // into java, or surprisingly find a matching exception handler for bci 0 diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/cardGeneration.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/memory/cardGeneration.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,360 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 "precompiled.hpp" + +#include "memory/blockOffsetTable.inline.hpp" +#include "memory/cardGeneration.inline.hpp" +#include "memory/gcLocker.hpp" +#include "memory/generationSpec.hpp" +#include "memory/genOopClosures.inline.hpp" +#include "memory/genRemSet.hpp" +#include "memory/iterator.hpp" +#include "memory/memRegion.hpp" +#include "memory/space.inline.hpp" +#include "runtime/java.hpp" + +CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, + int level, + GenRemSet* remset) : + Generation(rs, initial_byte_size, level), _rs(remset), + _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(), + _used_at_prologue() +{ + HeapWord* start = (HeapWord*)rs.base(); + size_t reserved_byte_size = rs.size(); + assert((uintptr_t(start) & 3) == 0, "bad alignment"); + assert((reserved_byte_size & 3) == 0, "bad alignment"); + MemRegion reserved_mr(start, heap_word_size(reserved_byte_size)); + _bts = new BlockOffsetSharedArray(reserved_mr, + heap_word_size(initial_byte_size)); + MemRegion committed_mr(start, heap_word_size(initial_byte_size)); + _rs->resize_covered_region(committed_mr); + if (_bts == NULL) { + vm_exit_during_initialization("Could not allocate a BlockOffsetArray"); + } + + // Verify that the start and end of this generation is the start of a card. + // If this wasn't true, a single card could span more than on generation, + // which would cause problems when we commit/uncommit memory, and when we + // clear and dirty cards. + guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned"); + if (reserved_mr.end() != Universe::heap()->reserved_region().end()) { + // Don't check at the very end of the heap as we'll assert that we're probing off + // the end if we try. + guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned"); + } + _min_heap_delta_bytes = MinHeapDeltaBytes; + _capacity_at_prologue = initial_byte_size; + _used_at_prologue = 0; +} + +bool CardGeneration::grow_by(size_t bytes) { + assert_correct_size_change_locking(); + bool result = _virtual_space.expand_by(bytes); + if (result) { + size_t new_word_size = + heap_word_size(_virtual_space.committed_size()); + MemRegion mr(space()->bottom(), new_word_size); + // Expand card table + Universe::heap()->barrier_set()->resize_covered_region(mr); + // Expand shared block offset array + _bts->resize(new_word_size); + + // Fix for bug #4668531 + if (ZapUnusedHeapArea) { + MemRegion mangle_region(space()->end(), + (HeapWord*)_virtual_space.high()); + SpaceMangler::mangle_region(mangle_region); + } + + // Expand space -- also expands space's BOT + // (which uses (part of) shared array above) + space()->set_end((HeapWord*)_virtual_space.high()); + + // update the space and generation capacity counters + update_counters(); + + if (Verbose && PrintGC) { + size_t new_mem_size = _virtual_space.committed_size(); + size_t old_mem_size = new_mem_size - bytes; + gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " + SIZE_FORMAT "K to " SIZE_FORMAT "K", + name(), old_mem_size/K, bytes/K, new_mem_size/K); + } + } + return result; +} + +bool CardGeneration::expand(size_t bytes, size_t expand_bytes) { + assert_locked_or_safepoint(Heap_lock); + if (bytes == 0) { + return true; // That's what grow_by(0) would return + } + size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); + if (aligned_bytes == 0){ + // The alignment caused the number of bytes to wrap. An expand_by(0) will + // return true with the implication that an expansion was done when it + // was not. A call to expand implies a best effort to expand by "bytes" + // but not a guarantee. Align down to give a best effort. This is likely + // the most that the generation can expand since it has some capacity to + // start with. + aligned_bytes = ReservedSpace::page_align_size_down(bytes); + } + size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); + bool success = false; + if (aligned_expand_bytes > aligned_bytes) { + success = grow_by(aligned_expand_bytes); + } + if (!success) { + success = grow_by(aligned_bytes); + } + if (!success) { + success = grow_to_reserved(); + } + if (PrintGC && Verbose) { + if (success && GC_locker::is_active_and_needs_gc()) { + gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); + } + } + + return success; +} + +bool CardGeneration::grow_to_reserved() { + assert_correct_size_change_locking(); + bool success = true; + const size_t remaining_bytes = _virtual_space.uncommitted_size(); + if (remaining_bytes > 0) { + success = grow_by(remaining_bytes); + DEBUG_ONLY(if (!success) warning("grow to reserved failed");) + } + return success; +} + +void CardGeneration::shrink(size_t bytes) { + assert_correct_size_change_locking(); + + size_t size = ReservedSpace::page_align_size_down(bytes); + if (size == 0) { + return; + } + + // Shrink committed space + _virtual_space.shrink_by(size); + // Shrink space; this also shrinks the space's BOT + space()->set_end((HeapWord*) _virtual_space.high()); + size_t new_word_size = heap_word_size(space()->capacity()); + // Shrink the shared block offset array + _bts->resize(new_word_size); + MemRegion mr(space()->bottom(), new_word_size); + // Shrink the card table + Universe::heap()->barrier_set()->resize_covered_region(mr); + + if (Verbose && PrintGC) { + size_t new_mem_size = _virtual_space.committed_size(); + size_t old_mem_size = new_mem_size + size; + gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", + name(), old_mem_size/K, new_mem_size/K); + } +} + +// No young generation references, clear this generation's cards. +void CardGeneration::clear_remembered_set() { + _rs->clear(reserved()); +} + +// Objects in this generation may have moved, invalidate this +// generation's cards. +void CardGeneration::invalidate_remembered_set() { + _rs->invalidate(used_region()); +} + +void CardGeneration::compute_new_size() { + assert(_shrink_factor <= 100, "invalid shrink factor"); + size_t current_shrink_factor = _shrink_factor; + _shrink_factor = 0; + + // We don't have floating point command-line arguments + // Note: argument processing ensures that MinHeapFreeRatio < 100. + const double minimum_free_percentage = MinHeapFreeRatio / 100.0; + const double maximum_used_percentage = 1.0 - minimum_free_percentage; + + // Compute some numbers about the state of the heap. + const size_t used_after_gc = used(); + const size_t capacity_after_gc = capacity(); + + const double min_tmp = used_after_gc / maximum_used_percentage; + size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx)); + // Don't shrink less than the initial generation size + minimum_desired_capacity = MAX2(minimum_desired_capacity, + spec()->init_size()); + assert(used_after_gc <= minimum_desired_capacity, "sanity check"); + + if (PrintGC && Verbose) { + const size_t free_after_gc = free(); + const double free_percentage = ((double)free_after_gc) / capacity_after_gc; + gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: "); + gclog_or_tty->print_cr(" " + " minimum_free_percentage: %6.2f" + " maximum_used_percentage: %6.2f", + minimum_free_percentage, + maximum_used_percentage); + gclog_or_tty->print_cr(" " + " free_after_gc : %6.1fK" + " used_after_gc : %6.1fK" + " capacity_after_gc : %6.1fK", + free_after_gc / (double) K, + used_after_gc / (double) K, + capacity_after_gc / (double) K); + gclog_or_tty->print_cr(" " + " free_percentage: %6.2f", + free_percentage); + } + + if (capacity_after_gc < minimum_desired_capacity) { + // If we have less free space than we want then expand + size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; + // Don't expand unless it's significant + if (expand_bytes >= _min_heap_delta_bytes) { + expand(expand_bytes, 0); // safe if expansion fails + } + if (PrintGC && Verbose) { + gclog_or_tty->print_cr(" expanding:" + " minimum_desired_capacity: %6.1fK" + " expand_bytes: %6.1fK" + " _min_heap_delta_bytes: %6.1fK", + minimum_desired_capacity / (double) K, + expand_bytes / (double) K, + _min_heap_delta_bytes / (double) K); + } + return; + } + + // No expansion, now see if we want to shrink + size_t shrink_bytes = 0; + // We would never want to shrink more than this + size_t max_shrink_bytes = capacity_after_gc - minimum_desired_capacity; + + if (MaxHeapFreeRatio < 100) { + const double maximum_free_percentage = MaxHeapFreeRatio / 100.0; + const double minimum_used_percentage = 1.0 - maximum_free_percentage; + const double max_tmp = used_after_gc / minimum_used_percentage; + size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx)); + maximum_desired_capacity = MAX2(maximum_desired_capacity, + spec()->init_size()); + if (PrintGC && Verbose) { + gclog_or_tty->print_cr(" " + " maximum_free_percentage: %6.2f" + " minimum_used_percentage: %6.2f", + maximum_free_percentage, + minimum_used_percentage); + gclog_or_tty->print_cr(" " + " _capacity_at_prologue: %6.1fK" + " minimum_desired_capacity: %6.1fK" + " maximum_desired_capacity: %6.1fK", + _capacity_at_prologue / (double) K, + minimum_desired_capacity / (double) K, + maximum_desired_capacity / (double) K); + } + assert(minimum_desired_capacity <= maximum_desired_capacity, + "sanity check"); + + if (capacity_after_gc > maximum_desired_capacity) { + // Capacity too large, compute shrinking size + shrink_bytes = capacity_after_gc - maximum_desired_capacity; + // We don't want shrink all the way back to initSize if people call + // System.gc(), because some programs do that between "phases" and then + // we'd just have to grow the heap up again for the next phase. So we + // damp the shrinking: 0% on the first call, 10% on the second call, 40% + // on the third call, and 100% by the fourth call. But if we recompute + // size without shrinking, it goes back to 0%. + shrink_bytes = shrink_bytes / 100 * current_shrink_factor; + assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size"); + if (current_shrink_factor == 0) { + _shrink_factor = 10; + } else { + _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100); + } + if (PrintGC && Verbose) { + gclog_or_tty->print_cr(" " + " shrinking:" + " initSize: %.1fK" + " maximum_desired_capacity: %.1fK", + spec()->init_size() / (double) K, + maximum_desired_capacity / (double) K); + gclog_or_tty->print_cr(" " + " shrink_bytes: %.1fK" + " current_shrink_factor: " SIZE_FORMAT + " new shrink factor: " SIZE_FORMAT + " _min_heap_delta_bytes: %.1fK", + shrink_bytes / (double) K, + current_shrink_factor, + _shrink_factor, + _min_heap_delta_bytes / (double) K); + } + } + } + + if (capacity_after_gc > _capacity_at_prologue) { + // We might have expanded for promotions, in which case we might want to + // take back that expansion if there's room after GC. That keeps us from + // stretching the heap with promotions when there's plenty of room. + size_t expansion_for_promotion = capacity_after_gc - _capacity_at_prologue; + expansion_for_promotion = MIN2(expansion_for_promotion, max_shrink_bytes); + // We have two shrinking computations, take the largest + shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion); + assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size"); + if (PrintGC && Verbose) { + gclog_or_tty->print_cr(" " + " aggressive shrinking:" + " _capacity_at_prologue: %.1fK" + " capacity_after_gc: %.1fK" + " expansion_for_promotion: %.1fK" + " shrink_bytes: %.1fK", + capacity_after_gc / (double) K, + _capacity_at_prologue / (double) K, + expansion_for_promotion / (double) K, + shrink_bytes / (double) K); + } + } + // Don't shrink unless it's significant + if (shrink_bytes >= _min_heap_delta_bytes) { + shrink(shrink_bytes); + } +} + +// Currently nothing to do. +void CardGeneration::prepare_for_verify() {} + +void CardGeneration::space_iterate(SpaceClosure* blk, + bool usedOnly) { + blk->do_space(space()); +} + +void CardGeneration::younger_refs_iterate(OopsInGenClosure* blk) { + blk->set_generation(this); + younger_refs_in_space_iterate(space(), blk); + blk->reset_generation(); +} diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/cardGeneration.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/memory/cardGeneration.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#ifndef SHARE_VM_MEMORY_CARDGENERATION_HPP +#define SHARE_VM_MEMORY_CARDGENERATION_HPP + +// Class CardGeneration is a generation that is covered by a card table, +// and uses a card-size block-offset array to implement block_start. + +#include "memory/generation.hpp" + +class BlockOffsetSharedArray; +class CompactibleSpace; + +class CardGeneration: public Generation { + friend class VMStructs; + protected: + // This is shared with other generations. + GenRemSet* _rs; + // This is local to this generation. + BlockOffsetSharedArray* _bts; + + // Current shrinking effect: this damps shrinking when the heap gets empty. + size_t _shrink_factor; + + size_t _min_heap_delta_bytes; // Minimum amount to expand. + + // Some statistics from before gc started. + // These are gathered in the gc_prologue (and should_collect) + // to control growing/shrinking policy in spite of promotions. + size_t _capacity_at_prologue; + size_t _used_at_prologue; + + CardGeneration(ReservedSpace rs, size_t initial_byte_size, int level, + GenRemSet* remset); + + virtual void assert_correct_size_change_locking() = 0; + + virtual CompactibleSpace* space() const = 0; + + public: + + // Attempt to expand the generation by "bytes". Expand by at a + // minimum "expand_bytes". Return true if some amount (not + // necessarily the full "bytes") was done. + virtual bool expand(size_t bytes, size_t expand_bytes); + + // Shrink generation with specified size + virtual void shrink(size_t bytes); + + virtual void compute_new_size(); + + virtual void clear_remembered_set(); + + virtual void invalidate_remembered_set(); + + virtual void prepare_for_verify(); + + // Grow generation with specified size (returns false if unable to grow) + bool grow_by(size_t bytes); + // Grow generation to reserved size. + bool grow_to_reserved(); + + size_t capacity() const; + size_t used() const; + size_t free() const; + MemRegion used_region() const; + + void space_iterate(SpaceClosure* blk, bool usedOnly = false); + + void younger_refs_iterate(OopsInGenClosure* blk); + + bool is_in(const void* p) const; + + CompactibleSpace* first_compaction_space() const; +}; + +#endif // SHARE_VM_MEMORY_CARDGENERATION_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/cardGeneration.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/src/share/vm/memory/cardGeneration.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + * + */ + +#ifndef SHARE_VM_MEMORY_CARDGENERATION_INLINE_HPP +#define SHARE_VM_MEMORY_CARDGENERATION_INLINE_HPP + +#include "memory/cardGeneration.hpp" +#include "memory/space.hpp" + +inline size_t CardGeneration::capacity() const { + return space()->capacity(); +} + +inline size_t CardGeneration::used() const { + return space()->used(); +} + +inline size_t CardGeneration::free() const { + return space()->free(); +} + +inline MemRegion CardGeneration::used_region() const { + return space()->used_region(); +} + +inline bool CardGeneration::is_in(const void* p) const { + return space()->is_in(p); +} + +inline CompactibleSpace* CardGeneration::first_compaction_space() const { + return space(); +} + +#endif // SHARE_VM_MEMORY_CARDGENERATION_INLINE_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/cardTableModRefBS.cpp --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -275,29 +275,26 @@ // the new_end_aligned does not intrude onto the committed // space of another region. int ri = 0; - for (ri = 0; ri < _cur_covered_regions; ri++) { - if (ri != ind) { - if (_committed[ri].contains(new_end_aligned)) { - // The prior check included in the assert - // (new_end_aligned >= _committed[ri].start()) - // is redundant with the "contains" test. - // Any region containing the new end - // should start at or beyond the region found (ind) - // for the new end (committed regions are not expected to - // be proper subsets of other committed regions). - assert(_committed[ri].start() >= _committed[ind].start(), - "New end of committed region is inconsistent"); - new_end_aligned = _committed[ri].start(); - // new_end_aligned can be equal to the start of its - // committed region (i.e., of "ind") if a second - // region following "ind" also start at the same location - // as "ind". - assert(new_end_aligned >= _committed[ind].start(), - "New end of committed region is before start"); - debug_only(collided = true;) - // Should only collide with 1 region - break; - } + for (ri = ind + 1; ri < _cur_covered_regions; ri++) { + if (new_end_aligned > _committed[ri].start()) { + assert(new_end_aligned <= _committed[ri].end(), + "An earlier committed region can't cover a later committed region"); + // Any region containing the new end + // should start at or beyond the region found (ind) + // for the new end (committed regions are not expected to + // be proper subsets of other committed regions). + assert(_committed[ri].start() >= _committed[ind].start(), + "New end of committed region is inconsistent"); + new_end_aligned = _committed[ri].start(); + // new_end_aligned can be equal to the start of its + // committed region (i.e., of "ind") if a second + // region following "ind" also start at the same location + // as "ind". + assert(new_end_aligned >= _committed[ind].start(), + "New end of committed region is before start"); + debug_only(collided = true;) + // Should only collide with 1 region + break; } } #ifdef ASSERT diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/cardTableRS.cpp --- a/hotspot/src/share/vm/memory/cardTableRS.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -33,24 +33,13 @@ #include "runtime/java.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" -#if INCLUDE_ALL_GCS -#include "gc_implementation/g1/concurrentMark.hpp" -#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" -#endif // INCLUDE_ALL_GCS CardTableRS::CardTableRS(MemRegion whole_heap) : GenRemSet(), _cur_youngergen_card_val(youngergenP1_card) { -#if INCLUDE_ALL_GCS - if (UseG1GC) { - _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap); - } else { - _ct_bs = new CardTableModRefBSForCTRS(whole_heap); - } -#else + guarantee(Universe::heap()->kind() == CollectedHeap::GenCollectedHeap, "sanity"); _ct_bs = new CardTableModRefBSForCTRS(whole_heap); -#endif _ct_bs->initialize(); set_bs(_ct_bs); _last_cur_val_in_gen = NEW_C_HEAP_ARRAY3(jbyte, GenCollectedHeap::max_gens + 1, diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/filemap.cpp --- a/hotspot/src/share/vm/memory/filemap.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/filemap.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -98,11 +98,11 @@ tty->print_cr("UseSharedSpaces: %s", msg); } } + UseSharedSpaces = false; + assert(current_info() != NULL, "singleton must be registered"); + current_info()->close(); } va_end(ap); - UseSharedSpaces = false; - assert(current_info() != NULL, "singleton must be registered"); - current_info()->close(); } // Fill in the fileMapInfo structure with data about this VM instance. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/genCollectedHeap.cpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -70,6 +70,7 @@ GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) : SharedHeap(policy), + _rem_set(NULL), _gen_policy(policy), _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)), _full_collections_completed(0) @@ -465,7 +466,7 @@ // atomic wrt other collectors in this configuration, we // are guaranteed to have empty discovered ref lists. if (rp->discovery_is_atomic()) { - rp->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + rp->enable_discovery(); rp->setup_policy(do_clear_all_soft_refs); } else { // collect() below will enable discovery as appropriate diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/genCollectedHeap.hpp --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,6 +66,9 @@ Generation* _gens[max_gens]; GenerationSpec** _gen_specs; + // The singleton Gen Remembered Set. + GenRemSet* _rem_set; + // The generational collector policy. GenCollectorPolicy* _gen_policy; @@ -383,6 +386,10 @@ return _n_gens; } + // This function returns the "GenRemSet" object that allows us to scan + // generations in a fully generational heap. + GenRemSet* rem_set() { return _rem_set; } + // Convenience function to be used in situations where the heap type can be // asserted to be this type. static GenCollectedHeap* heap(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/genOopClosures.inline.hpp --- a/hotspot/src/share/vm/memory/genOopClosures.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/genOopClosures.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,7 @@ _gen_boundary = _gen->reserved().start(); // Barrier set for the heap, must be set after heap is initialized if (_rs == NULL) { - GenRemSet* rs = SharedHeap::heap()->rem_set(); + GenRemSet* rs = GenCollectedHeap::heap()->rem_set(); _rs = (CardTableRS*)rs; } } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/generation.cpp --- a/hotspot/src/share/vm/memory/generation.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/generation.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -297,7 +297,7 @@ void Generation::younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl) { - GenRemSet* rs = SharedHeap::heap()->rem_set(); + GenRemSet* rs = GenCollectedHeap::heap()->rem_set(); rs->younger_refs_in_space_iterate(sp, cl); } @@ -361,244 +361,3 @@ sp = sp->next_compaction_space(); } } - -CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, - int level, - GenRemSet* remset) : - Generation(rs, initial_byte_size, level), _rs(remset), - _shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(), - _used_at_prologue() -{ - HeapWord* start = (HeapWord*)rs.base(); - size_t reserved_byte_size = rs.size(); - assert((uintptr_t(start) & 3) == 0, "bad alignment"); - assert((reserved_byte_size & 3) == 0, "bad alignment"); - MemRegion reserved_mr(start, heap_word_size(reserved_byte_size)); - _bts = new BlockOffsetSharedArray(reserved_mr, - heap_word_size(initial_byte_size)); - MemRegion committed_mr(start, heap_word_size(initial_byte_size)); - _rs->resize_covered_region(committed_mr); - if (_bts == NULL) - vm_exit_during_initialization("Could not allocate a BlockOffsetArray"); - - // Verify that the start and end of this generation is the start of a card. - // If this wasn't true, a single card could span more than on generation, - // which would cause problems when we commit/uncommit memory, and when we - // clear and dirty cards. - guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned"); - if (reserved_mr.end() != Universe::heap()->reserved_region().end()) { - // Don't check at the very end of the heap as we'll assert that we're probing off - // the end if we try. - guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned"); - } - _min_heap_delta_bytes = MinHeapDeltaBytes; - _capacity_at_prologue = initial_byte_size; - _used_at_prologue = 0; -} - -bool CardGeneration::expand(size_t bytes, size_t expand_bytes) { - assert_locked_or_safepoint(Heap_lock); - if (bytes == 0) { - return true; // That's what grow_by(0) would return - } - size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); - if (aligned_bytes == 0){ - // The alignment caused the number of bytes to wrap. An expand_by(0) will - // return true with the implication that an expansion was done when it - // was not. A call to expand implies a best effort to expand by "bytes" - // but not a guarantee. Align down to give a best effort. This is likely - // the most that the generation can expand since it has some capacity to - // start with. - aligned_bytes = ReservedSpace::page_align_size_down(bytes); - } - size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); - bool success = false; - if (aligned_expand_bytes > aligned_bytes) { - success = grow_by(aligned_expand_bytes); - } - if (!success) { - success = grow_by(aligned_bytes); - } - if (!success) { - success = grow_to_reserved(); - } - if (PrintGC && Verbose) { - if (success && GC_locker::is_active_and_needs_gc()) { - gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); - } - } - - return success; -} - - -// No young generation references, clear this generation's cards. -void CardGeneration::clear_remembered_set() { - _rs->clear(reserved()); -} - - -// Objects in this generation may have moved, invalidate this -// generation's cards. -void CardGeneration::invalidate_remembered_set() { - _rs->invalidate(used_region()); -} - - -void CardGeneration::compute_new_size() { - assert(_shrink_factor <= 100, "invalid shrink factor"); - size_t current_shrink_factor = _shrink_factor; - _shrink_factor = 0; - - // We don't have floating point command-line arguments - // Note: argument processing ensures that MinHeapFreeRatio < 100. - const double minimum_free_percentage = MinHeapFreeRatio / 100.0; - const double maximum_used_percentage = 1.0 - minimum_free_percentage; - - // Compute some numbers about the state of the heap. - const size_t used_after_gc = used(); - const size_t capacity_after_gc = capacity(); - - const double min_tmp = used_after_gc / maximum_used_percentage; - size_t minimum_desired_capacity = (size_t)MIN2(min_tmp, double(max_uintx)); - // Don't shrink less than the initial generation size - minimum_desired_capacity = MAX2(minimum_desired_capacity, - spec()->init_size()); - assert(used_after_gc <= minimum_desired_capacity, "sanity check"); - - if (PrintGC && Verbose) { - const size_t free_after_gc = free(); - const double free_percentage = ((double)free_after_gc) / capacity_after_gc; - gclog_or_tty->print_cr("TenuredGeneration::compute_new_size: "); - gclog_or_tty->print_cr(" " - " minimum_free_percentage: %6.2f" - " maximum_used_percentage: %6.2f", - minimum_free_percentage, - maximum_used_percentage); - gclog_or_tty->print_cr(" " - " free_after_gc : %6.1fK" - " used_after_gc : %6.1fK" - " capacity_after_gc : %6.1fK", - free_after_gc / (double) K, - used_after_gc / (double) K, - capacity_after_gc / (double) K); - gclog_or_tty->print_cr(" " - " free_percentage: %6.2f", - free_percentage); - } - - if (capacity_after_gc < minimum_desired_capacity) { - // If we have less free space than we want then expand - size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; - // Don't expand unless it's significant - if (expand_bytes >= _min_heap_delta_bytes) { - expand(expand_bytes, 0); // safe if expansion fails - } - if (PrintGC && Verbose) { - gclog_or_tty->print_cr(" expanding:" - " minimum_desired_capacity: %6.1fK" - " expand_bytes: %6.1fK" - " _min_heap_delta_bytes: %6.1fK", - minimum_desired_capacity / (double) K, - expand_bytes / (double) K, - _min_heap_delta_bytes / (double) K); - } - return; - } - - // No expansion, now see if we want to shrink - size_t shrink_bytes = 0; - // We would never want to shrink more than this - size_t max_shrink_bytes = capacity_after_gc - minimum_desired_capacity; - - if (MaxHeapFreeRatio < 100) { - const double maximum_free_percentage = MaxHeapFreeRatio / 100.0; - const double minimum_used_percentage = 1.0 - maximum_free_percentage; - const double max_tmp = used_after_gc / minimum_used_percentage; - size_t maximum_desired_capacity = (size_t)MIN2(max_tmp, double(max_uintx)); - maximum_desired_capacity = MAX2(maximum_desired_capacity, - spec()->init_size()); - if (PrintGC && Verbose) { - gclog_or_tty->print_cr(" " - " maximum_free_percentage: %6.2f" - " minimum_used_percentage: %6.2f", - maximum_free_percentage, - minimum_used_percentage); - gclog_or_tty->print_cr(" " - " _capacity_at_prologue: %6.1fK" - " minimum_desired_capacity: %6.1fK" - " maximum_desired_capacity: %6.1fK", - _capacity_at_prologue / (double) K, - minimum_desired_capacity / (double) K, - maximum_desired_capacity / (double) K); - } - assert(minimum_desired_capacity <= maximum_desired_capacity, - "sanity check"); - - if (capacity_after_gc > maximum_desired_capacity) { - // Capacity too large, compute shrinking size - shrink_bytes = capacity_after_gc - maximum_desired_capacity; - // We don't want shrink all the way back to initSize if people call - // System.gc(), because some programs do that between "phases" and then - // we'd just have to grow the heap up again for the next phase. So we - // damp the shrinking: 0% on the first call, 10% on the second call, 40% - // on the third call, and 100% by the fourth call. But if we recompute - // size without shrinking, it goes back to 0%. - shrink_bytes = shrink_bytes / 100 * current_shrink_factor; - assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size"); - if (current_shrink_factor == 0) { - _shrink_factor = 10; - } else { - _shrink_factor = MIN2(current_shrink_factor * 4, (size_t) 100); - } - if (PrintGC && Verbose) { - gclog_or_tty->print_cr(" " - " shrinking:" - " initSize: %.1fK" - " maximum_desired_capacity: %.1fK", - spec()->init_size() / (double) K, - maximum_desired_capacity / (double) K); - gclog_or_tty->print_cr(" " - " shrink_bytes: %.1fK" - " current_shrink_factor: " SIZE_FORMAT - " new shrink factor: " SIZE_FORMAT - " _min_heap_delta_bytes: %.1fK", - shrink_bytes / (double) K, - current_shrink_factor, - _shrink_factor, - _min_heap_delta_bytes / (double) K); - } - } - } - - if (capacity_after_gc > _capacity_at_prologue) { - // We might have expanded for promotions, in which case we might want to - // take back that expansion if there's room after GC. That keeps us from - // stretching the heap with promotions when there's plenty of room. - size_t expansion_for_promotion = capacity_after_gc - _capacity_at_prologue; - expansion_for_promotion = MIN2(expansion_for_promotion, max_shrink_bytes); - // We have two shrinking computations, take the largest - shrink_bytes = MAX2(shrink_bytes, expansion_for_promotion); - assert(shrink_bytes <= max_shrink_bytes, "invalid shrink size"); - if (PrintGC && Verbose) { - gclog_or_tty->print_cr(" " - " aggressive shrinking:" - " _capacity_at_prologue: %.1fK" - " capacity_after_gc: %.1fK" - " expansion_for_promotion: %.1fK" - " shrink_bytes: %.1fK", - capacity_after_gc / (double) K, - _capacity_at_prologue / (double) K, - expansion_for_promotion / (double) K, - shrink_bytes / (double) K); - } - } - // Don't shrink unless it's significant - if (shrink_bytes >= _min_heap_delta_bytes) { - shrink(shrink_bytes); - } -} - -// Currently nothing to do. -void CardGeneration::prepare_for_verify() {} - diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/generation.hpp --- a/hotspot/src/share/vm/memory/generation.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/generation.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -584,57 +584,4 @@ virtual CollectorCounters* counters() { return _gc_counters; } }; -// Class CardGeneration is a generation that is covered by a card table, -// and uses a card-size block-offset array to implement block_start. - -// class BlockOffsetArray; -// class BlockOffsetArrayContigSpace; -class BlockOffsetSharedArray; - -class CardGeneration: public Generation { - friend class VMStructs; - protected: - // This is shared with other generations. - GenRemSet* _rs; - // This is local to this generation. - BlockOffsetSharedArray* _bts; - - // current shrinking effect: this damps shrinking when the heap gets empty. - size_t _shrink_factor; - - size_t _min_heap_delta_bytes; // Minimum amount to expand. - - // Some statistics from before gc started. - // These are gathered in the gc_prologue (and should_collect) - // to control growing/shrinking policy in spite of promotions. - size_t _capacity_at_prologue; - size_t _used_at_prologue; - - CardGeneration(ReservedSpace rs, size_t initial_byte_size, int level, - GenRemSet* remset); - - public: - - // Attempt to expand the generation by "bytes". Expand by at a - // minimum "expand_bytes". Return true if some amount (not - // necessarily the full "bytes") was done. - virtual bool expand(size_t bytes, size_t expand_bytes); - - // Shrink generation with specified size (returns false if unable to shrink) - virtual void shrink(size_t bytes) = 0; - - virtual void compute_new_size(); - - virtual void clear_remembered_set(); - - virtual void invalidate_remembered_set(); - - virtual void prepare_for_verify(); - - // Grow generation with specified size (returns false if unable to grow) - virtual bool grow_by(size_t bytes) = 0; - // Grow generation to reserved size. - virtual bool grow_to_reserved() = 0; -}; - #endif // SHARE_VM_MEMORY_GENERATION_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/metaspace.cpp --- a/hotspot/src/share/vm/memory/metaspace.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/metaspace.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -792,7 +792,8 @@ Mutex* const SpaceManager::_expand_lock = new Mutex(SpaceManager::_expand_lock_rank, SpaceManager::_expand_lock_name, - Mutex::_allow_vm_block_flag); + Mutex::_allow_vm_block_flag, + Monitor::_safepoint_check_never); void VirtualSpaceNode::inc_container_count() { assert_lock_strong(SpaceManager::expand_lock()); @@ -3158,7 +3159,25 @@ SharedMiscDataSize = align_size_up(SharedMiscDataSize, max_alignment); SharedMiscCodeSize = align_size_up(SharedMiscCodeSize, max_alignment); - // the min_misc_code_size estimate is based on MetaspaceShared::generate_vtable_methods() + // make sure SharedReadOnlySize and SharedReadWriteSize are not less than + // the minimum values. + if (SharedReadOnlySize < MetaspaceShared::min_ro_size){ + report_out_of_shared_space(SharedReadOnly); + } + + if (SharedReadWriteSize < MetaspaceShared::min_rw_size){ + report_out_of_shared_space(SharedReadWrite); + } + + // the min_misc_data_size and min_misc_code_size estimates are based on + // MetaspaceShared::generate_vtable_methods() + uint min_misc_data_size = align_size_up( + MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size * sizeof(void*), max_alignment); + + if (SharedMiscDataSize < min_misc_data_size) { + report_out_of_shared_space(SharedMiscData); + } + uintx min_misc_code_size = align_size_up( (MetaspaceShared::num_virtuals * MetaspaceShared::vtbl_list_size) * (sizeof(void*) + MetaspaceShared::vtbl_method_size) + MetaspaceShared::vtbl_common_code_size, diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/metaspaceShared.cpp --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -969,7 +969,7 @@ #endif // If -Xshare:on is specified, print out the error message and exit VM, // otherwise, set UseSharedSpaces to false and continue. - if (RequireSharedSpaces) { + if (RequireSharedSpaces || PrintSharedArchiveAndExit) { vm_exit_during_initialization("Unable to use shared archive.", "Failed map_region for using -Xshare:on."); } else { FLAG_SET_DEFAULT(UseSharedSpaces, false); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/metaspaceShared.hpp --- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -70,6 +70,11 @@ }; enum { + min_ro_size = NOT_LP64(8*M) LP64_ONLY(9*M), // minimum ro and rw regions sizes based on dumping + min_rw_size = NOT_LP64(7*M) LP64_ONLY(12*M) // of a shared archive using the default classlist + }; + + enum { ro = 0, // read-only shared space in the heap rw = 1, // read-write shared space in the heap md = 2, // miscellaneous data for initializing tables, etc. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/referenceProcessor.cpp --- a/hotspot/src/share/vm/memory/referenceProcessor.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -68,10 +68,10 @@ _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field(); } -void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) { +void ReferenceProcessor::enable_discovery(bool check_no_refs) { #ifdef ASSERT // Verify that we're not currently discovering refs - assert(!verify_disabled || !_discovering_refs, "nested call?"); + assert(!_discovering_refs, "nested call?"); if (check_no_refs) { // Verify that the discovered lists are empty @@ -963,52 +963,6 @@ return total_list_count; } -void ReferenceProcessor::clean_up_discovered_references() { - // loop over the lists - for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { - if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) { - gclog_or_tty->print_cr( - "\nScrubbing %s discovered list of Null referents", - list_name(i)); - } - clean_up_discovered_reflist(_discovered_refs[i]); - } -} - -void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) { - assert(!discovery_is_atomic(), "Else why call this method?"); - DiscoveredListIterator iter(refs_list, NULL, NULL); - while (iter.has_next()) { - iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); - oop next = java_lang_ref_Reference::next(iter.obj()); - assert(next->is_oop_or_null(), err_msg("Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next))); - // If referent has been cleared or Reference is not active, - // drop it. - if (iter.referent() == NULL || next != NULL) { - debug_only( - if (PrintGCDetails && TraceReferenceGC) { - gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: " - INTPTR_FORMAT " with next field: " INTPTR_FORMAT - " and referent: " INTPTR_FORMAT, - (void *)iter.obj(), (void *)next, (void *)iter.referent()); - } - ) - // Remove Reference object from list - iter.remove(); - iter.move_to_next(); - } else { - iter.next(); - } - } - NOT_PRODUCT( - if (PrintGCDetails && TraceReferenceGC) { - gclog_or_tty->print( - " Removed %d Refs with NULL referents out of %d discovered Refs", - iter.removed(), iter.processed()); - } - ) -} - inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) { uint id = 0; // Determine the queue index to use for this object. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/referenceProcessor.hpp --- a/hotspot/src/share/vm/memory/referenceProcessor.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -353,19 +353,6 @@ GCTimer* gc_timer, GCId gc_id); - // Delete entries in the discovered lists that have - // either a null referent or are not active. Such - // Reference objects can result from the clearing - // or enqueueing of Reference objects concurrent - // with their discovery by a (concurrent) collector. - // For a definition of "active" see java.lang.ref.Reference; - // Refs are born active, become inactive when enqueued, - // and never become active again. The state of being - // active is encoded as follows: A Ref is active - // if and only if its "next" field is NULL. - void clean_up_discovered_references(); - void clean_up_discovered_reflist(DiscoveredList& refs_list); - // Returns the name of the discovered reference list // occupying the i / _num_q slot. const char* list_name(uint i); @@ -439,7 +426,7 @@ void set_span(MemRegion span) { _span = span; } // start and stop weak ref discovery - void enable_discovery(bool verify_disabled, bool check_no_refs); + void enable_discovery(bool check_no_refs = true); void disable_discovery() { _discovering_refs = false; } bool discovery_enabled() { return _discovering_refs; } @@ -517,7 +504,7 @@ ~NoRefDiscovery() { if (_was_discovering_refs) { - _rp->enable_discovery(true /*verify_disabled*/, false /*check_no_refs*/); + _rp->enable_discovery(false /*check_no_refs*/); } } }; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/sharedHeap.cpp --- a/hotspot/src/share/vm/memory/sharedHeap.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -58,7 +58,6 @@ SharedHeap::SharedHeap(CollectorPolicy* policy_) : CollectedHeap(), _collector_policy(policy_), - _rem_set(NULL), _strong_roots_scope(NULL), _strong_roots_parity(0), _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)), @@ -152,7 +151,7 @@ } } -Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false); +Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false, Monitor::_safepoint_check_never); void SharedHeap::StrongRootsScope::mark_worker_done_with_threads(uint n_workers) { // The Thread work barrier is only needed by G1 Class Unloading. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/sharedHeap.hpp --- a/hotspot/src/share/vm/memory/sharedHeap.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/sharedHeap.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,10 +114,6 @@ // set the static pointer "_sh" to that instance. static SharedHeap* _sh; - // and the Gen Remembered Set, at least one good enough to scan the perm - // gen. - GenRemSet* _rem_set; - // A gc policy, controls global gc resource issues CollectorPolicy *_collector_policy; @@ -152,10 +148,6 @@ // Initialization of ("weak") reference processing support virtual void ref_processing_init(); - // This function returns the "GenRemSet" object that allows us to scan - // generations in a fully generational heap. - GenRemSet* rem_set() { return _rem_set; } - // Iteration functions. void oop_iterate(ExtendedOopClosure* cl) = 0; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/tenuredGeneration.cpp --- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ #include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "memory/allocation.inline.hpp" #include "memory/blockOffsetTable.inline.hpp" +#include "memory/cardGeneration.inline.hpp" #include "memory/generationSpec.hpp" #include "memory/genMarkSweep.hpp" #include "memory/genOopClosures.inline.hpp" @@ -235,34 +236,6 @@ return CardGeneration::expand(bytes, expand_bytes); } - -void TenuredGeneration::shrink(size_t bytes) { - assert_locked_or_safepoint(ExpandHeap_lock); - size_t size = ReservedSpace::page_align_size_down(bytes); - if (size > 0) { - shrink_by(size); - } -} - - -size_t TenuredGeneration::capacity() const { - return _the_space->capacity(); -} - - -size_t TenuredGeneration::used() const { - return _the_space->used(); -} - - -size_t TenuredGeneration::free() const { - return _the_space->free(); -} - -MemRegion TenuredGeneration::used_region() const { - return the_space()->used_region(); -} - size_t TenuredGeneration::unsafe_max_alloc_nogc() const { return _the_space->free(); } @@ -271,74 +244,8 @@ return _the_space->free() + _virtual_space.uncommitted_size(); } -bool TenuredGeneration::grow_by(size_t bytes) { +void TenuredGeneration::assert_correct_size_change_locking() { assert_locked_or_safepoint(ExpandHeap_lock); - bool result = _virtual_space.expand_by(bytes); - if (result) { - size_t new_word_size = - heap_word_size(_virtual_space.committed_size()); - MemRegion mr(_the_space->bottom(), new_word_size); - // Expand card table - Universe::heap()->barrier_set()->resize_covered_region(mr); - // Expand shared block offset array - _bts->resize(new_word_size); - - // Fix for bug #4668531 - if (ZapUnusedHeapArea) { - MemRegion mangle_region(_the_space->end(), - (HeapWord*)_virtual_space.high()); - SpaceMangler::mangle_region(mangle_region); - } - - // Expand space -- also expands space's BOT - // (which uses (part of) shared array above) - _the_space->set_end((HeapWord*)_virtual_space.high()); - - // update the space and generation capacity counters - update_counters(); - - if (Verbose && PrintGC) { - size_t new_mem_size = _virtual_space.committed_size(); - size_t old_mem_size = new_mem_size - bytes; - gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " - SIZE_FORMAT "K to " SIZE_FORMAT "K", - name(), old_mem_size/K, bytes/K, new_mem_size/K); - } - } - return result; -} - - -bool TenuredGeneration::grow_to_reserved() { - assert_locked_or_safepoint(ExpandHeap_lock); - bool success = true; - const size_t remaining_bytes = _virtual_space.uncommitted_size(); - if (remaining_bytes > 0) { - success = grow_by(remaining_bytes); - DEBUG_ONLY(if (!success) warning("grow to reserved failed");) - } - return success; -} - -void TenuredGeneration::shrink_by(size_t bytes) { - assert_locked_or_safepoint(ExpandHeap_lock); - // Shrink committed space - _virtual_space.shrink_by(bytes); - // Shrink space; this also shrinks the space's BOT - _the_space->set_end((HeapWord*) _virtual_space.high()); - size_t new_word_size = heap_word_size(_the_space->capacity()); - // Shrink the shared block offset array - _bts->resize(new_word_size); - MemRegion mr(_the_space->bottom(), new_word_size); - // Shrink the card table - Universe::heap()->barrier_set()->resize_covered_region(mr); - - if (Verbose && PrintGC) { - size_t new_mem_size = _virtual_space.committed_size(); - size_t old_mem_size = new_mem_size + bytes; - gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", - name(), old_mem_size/K, new_mem_size/K); - } } // Currently nothing to do. @@ -348,27 +255,14 @@ _the_space->object_iterate(blk); } -void TenuredGeneration::space_iterate(SpaceClosure* blk, - bool usedOnly) { - blk->do_space(_the_space); -} - -void TenuredGeneration::younger_refs_iterate(OopsInGenClosure* blk) { - blk->set_generation(this); - younger_refs_in_space_iterate(_the_space, blk); - blk->reset_generation(); -} - void TenuredGeneration::save_marks() { _the_space->set_saved_mark(); } - void TenuredGeneration::reset_saved_marks() { _the_space->reset_saved_mark(); } - bool TenuredGeneration::no_allocs_since_save_marks() { return _the_space->saved_mark_at_top(); } @@ -387,28 +281,25 @@ #undef TenuredGen_SINCE_SAVE_MARKS_ITERATE_DEFN - void TenuredGeneration::gc_epilogue(bool full) { - _last_gc = WaterMark(the_space(), the_space()->top()); - // update the generation and space performance counters update_counters(); if (ZapUnusedHeapArea) { - the_space()->check_mangled_unused_area_complete(); + _the_space->check_mangled_unused_area_complete(); } } void TenuredGeneration::record_spaces_top() { assert(ZapUnusedHeapArea, "Not mangling unused space"); - the_space()->set_top_for_allocations(); + _the_space->set_top_for_allocations(); } void TenuredGeneration::verify() { - the_space()->verify(); + _the_space->verify(); } void TenuredGeneration::print_on(outputStream* st) const { Generation::print_on(st); st->print(" the"); - the_space()->print_on(st); + _the_space->print_on(st); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/tenuredGeneration.hpp --- a/hotspot/src/share/vm/memory/tenuredGeneration.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/tenuredGeneration.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ #include "gc_implementation/shared/cSpaceCounters.hpp" #include "gc_implementation/shared/gcStats.hpp" #include "gc_implementation/shared/generationCounters.hpp" -#include "memory/generation.hpp" +#include "memory/cardGeneration.hpp" #include "utilities/macros.hpp" // TenuredGeneration models the heap containing old (promoted/tenured) objects @@ -42,27 +42,18 @@ friend class VM_PopulateDumpSharedSpace; protected: - ContiguousSpace* _the_space; // actual space holding objects - WaterMark _last_gc; // watermark between objects allocated before - // and after last GC. + ContiguousSpace* _the_space; // Actual space holding objects GenerationCounters* _gen_counters; CSpaceCounters* _space_counters; - // Grow generation with specified size (returns false if unable to grow) - virtual bool grow_by(size_t bytes); - // Grow generation to reserved size. - virtual bool grow_to_reserved(); - // Shrink generation with specified size (returns false if unable to shrink) - void shrink_by(size_t bytes); - // Allocation failure virtual bool expand(size_t bytes, size_t expand_bytes); - void shrink(size_t bytes); // Accessing spaces - ContiguousSpace* the_space() const { return _the_space; } + ContiguousSpace* space() const { return _the_space; } + void assert_correct_size_change_locking(); public: TenuredGeneration(ReservedSpace rs, size_t initial_byte_size, int level, GenRemSet* remset); @@ -81,33 +72,15 @@ return !ScavengeBeforeFullGC; } - inline bool is_in(const void* p) const; - - // Space enquiries - size_t capacity() const; - size_t used() const; - size_t free() const; - - MemRegion used_region() const; - size_t unsafe_max_alloc_nogc() const; size_t contiguous_available() const; // Iteration void object_iterate(ObjectClosure* blk); - void space_iterate(SpaceClosure* blk, bool usedOnly = false); - - void younger_refs_iterate(OopsInGenClosure* blk); - - inline CompactibleSpace* first_compaction_space() const; virtual inline HeapWord* allocate(size_t word_size, bool is_tlab); virtual inline HeapWord* par_allocate(size_t word_size, bool is_tlab); - // Accessing marks - inline WaterMark top_mark(); - inline WaterMark bottom_mark(); - #define TenuredGen_SINCE_SAVE_MARKS_DECL(OopClosureType, nv_suffix) \ void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl); TenuredGen_SINCE_SAVE_MARKS_DECL(OopsInGenClosure,_v) diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/tenuredGeneration.inline.hpp --- a/hotspot/src/share/vm/memory/tenuredGeneration.inline.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/tenuredGeneration.inline.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,53 +22,35 @@ * */ -#ifndef SHARE_VM_MEMORY_GENERATION_INLINE_HPP -#define SHARE_VM_MEMORY_GENERATION_INLINE_HPP +#ifndef SHARE_VM_MEMORY_TENUREDGENERATION_INLINE_HPP +#define SHARE_VM_MEMORY_TENUREDGENERATION_INLINE_HPP -#include "memory/genCollectedHeap.hpp" #include "memory/space.hpp" #include "memory/tenuredGeneration.hpp" -bool TenuredGeneration::is_in(const void* p) const { - return the_space()->is_in(p); -} - - -WaterMark TenuredGeneration::top_mark() { - return the_space()->top_mark(); -} - -CompactibleSpace* -TenuredGeneration::first_compaction_space() const { - return the_space(); -} - HeapWord* TenuredGeneration::allocate(size_t word_size, bool is_tlab) { assert(!is_tlab, "TenuredGeneration does not support TLAB allocation"); - return the_space()->allocate(word_size); + return _the_space->allocate(word_size); } HeapWord* TenuredGeneration::par_allocate(size_t word_size, bool is_tlab) { assert(!is_tlab, "TenuredGeneration does not support TLAB allocation"); - return the_space()->par_allocate(word_size); -} - -WaterMark TenuredGeneration::bottom_mark() { - return the_space()->bottom_mark(); + return _the_space->par_allocate(word_size); } size_t TenuredGeneration::block_size(const HeapWord* addr) const { - if (addr < the_space()->top()) return oop(addr)->size(); - else { - assert(addr == the_space()->top(), "non-block head arg to block_size"); - return the_space()->end() - the_space()->top(); + if (addr < _the_space->top()) { + return oop(addr)->size(); + } else { + assert(addr == _the_space->top(), "non-block head arg to block_size"); + return _the_space->end() - _the_space->top(); } } bool TenuredGeneration::block_is_obj(const HeapWord* addr) const { - return addr < the_space()->top(); + return addr < _the_space ->top(); } -#endif // SHARE_VM_MEMORY_GENERATION_INLINE_HPP +#endif // SHARE_VM_MEMORY_TENUREDGENERATION_INLINE_HPP diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/universe.cpp --- a/hotspot/src/share/vm/memory/universe.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/universe.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -120,6 +120,7 @@ oop Universe::_out_of_memory_error_class_metaspace = NULL; oop Universe::_out_of_memory_error_array_size = NULL; oop Universe::_out_of_memory_error_gc_overhead_limit = NULL; +oop Universe::_out_of_memory_error_realloc_objects = NULL; objArrayOop Universe::_preallocated_out_of_memory_error_array = NULL; volatile jint Universe::_preallocated_out_of_memory_error_avail_count = 0; bool Universe::_verify_in_progress = false; @@ -191,6 +192,7 @@ f->do_oop((oop*)&_out_of_memory_error_class_metaspace); f->do_oop((oop*)&_out_of_memory_error_array_size); f->do_oop((oop*)&_out_of_memory_error_gc_overhead_limit); + f->do_oop((oop*)&_out_of_memory_error_realloc_objects); f->do_oop((oop*)&_preallocated_out_of_memory_error_array); f->do_oop((oop*)&_null_ptr_exception_instance); f->do_oop((oop*)&_arithmetic_exception_instance); @@ -575,7 +577,8 @@ (throwable() != Universe::_out_of_memory_error_metaspace) && (throwable() != Universe::_out_of_memory_error_class_metaspace) && (throwable() != Universe::_out_of_memory_error_array_size) && - (throwable() != Universe::_out_of_memory_error_gc_overhead_limit)); + (throwable() != Universe::_out_of_memory_error_gc_overhead_limit) && + (throwable() != Universe::_out_of_memory_error_realloc_objects)); } @@ -1039,6 +1042,7 @@ Universe::_out_of_memory_error_array_size = k_h->allocate_instance(CHECK_false); Universe::_out_of_memory_error_gc_overhead_limit = k_h->allocate_instance(CHECK_false); + Universe::_out_of_memory_error_realloc_objects = k_h->allocate_instance(CHECK_false); // Setup preallocated NullPointerException // (this is currently used for a cheap & dirty solution in compiler exception handling) @@ -1078,6 +1082,9 @@ msg = java_lang_String::create_from_str("GC overhead limit exceeded", CHECK_false); java_lang_Throwable::set_message(Universe::_out_of_memory_error_gc_overhead_limit, msg()); + msg = java_lang_String::create_from_str("Java heap space: failed reallocation of scalar replaced objects", CHECK_false); + java_lang_Throwable::set_message(Universe::_out_of_memory_error_realloc_objects, msg()); + msg = java_lang_String::create_from_str("/ by zero", CHECK_false); java_lang_Throwable::set_message(Universe::_arithmetic_exception_instance, msg()); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/memory/universe.hpp --- a/hotspot/src/share/vm/memory/universe.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/memory/universe.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -157,6 +157,7 @@ static oop _out_of_memory_error_class_metaspace; static oop _out_of_memory_error_array_size; static oop _out_of_memory_error_gc_overhead_limit; + static oop _out_of_memory_error_realloc_objects; static Array* _the_empty_int_array; // Canonicalized int array static Array* _the_empty_short_array; // Canonicalized short array @@ -328,6 +329,7 @@ static oop out_of_memory_error_class_metaspace() { return gen_out_of_memory_error(_out_of_memory_error_class_metaspace); } static oop out_of_memory_error_array_size() { return gen_out_of_memory_error(_out_of_memory_error_array_size); } static oop out_of_memory_error_gc_overhead_limit() { return gen_out_of_memory_error(_out_of_memory_error_gc_overhead_limit); } + static oop out_of_memory_error_realloc_objects() { return gen_out_of_memory_error(_out_of_memory_error_realloc_objects); } // Accessors needed for fast allocation static Klass** boolArrayKlassObj_addr() { return &_boolArrayKlassObj; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/oops/cpCache.cpp --- a/hotspot/src/share/vm/oops/cpCache.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/oops/cpCache.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -287,9 +287,13 @@ // the lock, so that when the losing writer returns, he can use the linked // cache entry. - // Use the lock from the metaspace for this, which cannot stop for safepoint. - Mutex* metaspace_lock = cpool->pool_holder()->class_loader_data()->metaspace_lock(); - MutexLockerEx ml(metaspace_lock, Mutex::_no_safepoint_check_flag); + objArrayHandle resolved_references = cpool->resolved_references(); + // Use the resolved_references() lock for this cpCache entry. + // resolved_references are created for all classes with Invokedynamic, MethodHandle + // or MethodType constant pool cache entries. + assert(resolved_references() != NULL, + "a resolved_references array should have been created for this class"); + ObjectLocker ol(resolved_references, Thread::current()); if (!is_f1_null()) { return; } @@ -336,7 +340,6 @@ // This allows us to create fewer Methods, while keeping type safety. // - objArrayHandle resolved_references = cpool->resolved_references(); // Store appendix, if any. if (has_appendix) { const int appendix_index = f2_as_index() + _indy_resolved_references_appendix_offset; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/callnode.cpp --- a/hotspot/src/share/vm/opto/callnode.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/callnode.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -658,7 +658,7 @@ void CallNode::dump_spec(outputStream *st) const { st->print(" "); - tf()->dump_on(st); + if (tf() != NULL) tf()->dump_on(st); if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); if (jvms() != NULL) jvms()->dump_spec(st); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/castnode.cpp --- a/hotspot/src/share/vm/opto/castnode.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/castnode.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -104,7 +104,8 @@ // Try to improve the type of the CastII if we recognize a CmpI/If // pattern. if (_carry_dependency) { - if (in(0) != NULL && (in(0)->is_IfFalse() || in(0)->is_IfTrue())) { + if (in(0) != NULL && in(0)->in(0) != NULL && in(0)->in(0)->is_If()) { + assert(in(0)->is_IfFalse() || in(0)->is_IfTrue(), "should be If proj"); Node* proj = in(0); if (proj->in(0)->in(1)->is_Bool()) { Node* b = proj->in(0)->in(1); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/ifnode.cpp --- a/hotspot/src/share/vm/opto/ifnode.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/ifnode.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -820,6 +820,11 @@ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff); +struct RangeCheck { + Node* ctl; + jint off; +}; + //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. Strip out // control copies @@ -861,83 +866,141 @@ jint offset1; int flip1 = is_range_check(range1, index1, offset1); if( flip1 ) { - Node *first_prev_dom = NULL; - // Try to remove extra range checks. All 'up_one_dom' gives up at merges // so all checks we inspect post-dominate the top-most check we find. // If we are going to fail the current check and we reach the top check // then we are guaranteed to fail, so just start interpreting there. - // We 'expand' the top 2 range checks to include all post-dominating + // We 'expand' the top 3 range checks to include all post-dominating // checks. - // The top 2 range checks seen - Node *prev_chk1 = NULL; - Node *prev_chk2 = NULL; + // The top 3 range checks seen + const int NRC =3; + RangeCheck prev_checks[NRC]; + int nb_checks = 0; + // Low and high offsets seen so far jint off_lo = offset1; jint off_hi = offset1; - // Scan for the top 2 checks and collect range of offsets - for( int dist = 0; dist < 999; dist++ ) { // Range-Check scan limit - if( dom->Opcode() == Op_If && // Not same opcode? - prev_dom->in(0) == dom ) { // One path of test does dominate? - if( dom == this ) return NULL; // dead loop + bool found_immediate_dominator = false; + + // Scan for the top checks and collect range of offsets + for (int dist = 0; dist < 999; dist++) { // Range-Check scan limit + if (dom->Opcode() == Op_If && // Not same opcode? + prev_dom->in(0) == dom) { // One path of test does dominate? + if (dom == this) return NULL; // dead loop // See if this is a range check Node *index2, *range2; jint offset2; int flip2 = dom->as_If()->is_range_check(range2, index2, offset2); // See if this is a _matching_ range check, checking against // the same array bounds. - if( flip2 == flip1 && range2 == range1 && index2 == index1 && - dom->outcnt() == 2 ) { + if (flip2 == flip1 && range2 == range1 && index2 == index1 && + dom->outcnt() == 2) { + if (nb_checks == 0 && dom->in(1) == in(1)) { + // Found an immediately dominating test at the same offset. + // This kind of back-to-back test can be eliminated locally, + // and there is no need to search further for dominating tests. + assert(offset2 == offset1, "Same test but different offsets"); + found_immediate_dominator = true; + break; + } // Gather expanded bounds off_lo = MIN2(off_lo,offset2); off_hi = MAX2(off_hi,offset2); - // Record top 2 range checks - prev_chk2 = prev_chk1; - prev_chk1 = prev_dom; - // If we match the test exactly, then the top test covers - // both our lower and upper bounds. - if( dom->in(1) == in(1) ) - prev_chk2 = prev_chk1; + // Record top NRC range checks + prev_checks[nb_checks%NRC].ctl = prev_dom; + prev_checks[nb_checks%NRC].off = offset2; + nb_checks++; } } prev_dom = dom; - dom = up_one_dom( dom ); - if( !dom ) break; + dom = up_one_dom(dom); + if (!dom) break; } - - // Attempt to widen the dominating range check to cover some later - // ones. Since range checks "fail" by uncommon-trapping to the - // interpreter, widening a check can make us speculative enter the - // interpreter. If we see range-check deopt's, do not widen! - if (!phase->C->allow_range_check_smearing()) return NULL; + if (!found_immediate_dominator) { + // Attempt to widen the dominating range check to cover some later + // ones. Since range checks "fail" by uncommon-trapping to the + // interpreter, widening a check can make us speculatively enter + // the interpreter. If we see range-check deopt's, do not widen! + if (!phase->C->allow_range_check_smearing()) return NULL; - // Constant indices only need to check the upper bound. - // Non-constance indices must check both low and high. - if( index1 ) { - // Didn't find 2 prior covering checks, so cannot remove anything. - if( !prev_chk2 ) return NULL; - // 'Widen' the offsets of the 1st and 2nd covering check - adjust_check( prev_chk1, range1, index1, flip1, off_lo, igvn ); - // Do not call adjust_check twice on the same projection - // as the first call may have transformed the BoolNode to a ConI - if( prev_chk1 != prev_chk2 ) { - adjust_check( prev_chk2, range1, index1, flip1, off_hi, igvn ); + // Didn't find prior covering check, so cannot remove anything. + if (nb_checks == 0) { + return NULL; } - // Test is now covered by prior checks, dominate it out - prev_dom = prev_chk2; - } else { - // Didn't find prior covering check, so cannot remove anything. - if( !prev_chk1 ) return NULL; - // 'Widen' the offset of the 1st and only covering check - adjust_check( prev_chk1, range1, index1, flip1, off_hi, igvn ); - // Test is now covered by prior checks, dominate it out - prev_dom = prev_chk1; + // Constant indices only need to check the upper bound. + // Non-constant indices must check both low and high. + int chk0 = (nb_checks - 1) % NRC; + if (index1) { + if (nb_checks == 1) { + return NULL; + } else { + // If the top range check's constant is the min or max of + // all constants we widen the next one to cover the whole + // range of constants. + RangeCheck rc0 = prev_checks[chk0]; + int chk1 = (nb_checks - 2) % NRC; + RangeCheck rc1 = prev_checks[chk1]; + if (rc0.off == off_lo) { + adjust_check(rc1.ctl, range1, index1, flip1, off_hi, igvn); + prev_dom = rc1.ctl; + } else if (rc0.off == off_hi) { + adjust_check(rc1.ctl, range1, index1, flip1, off_lo, igvn); + prev_dom = rc1.ctl; + } else { + // If the top test's constant is not the min or max of all + // constants, we need 3 range checks. We must leave the + // top test unchanged because widening it would allow the + // accesses it protects to successfully read/write out of + // bounds. + if (nb_checks == 2) { + return NULL; + } + int chk2 = (nb_checks - 3) % NRC; + RangeCheck rc2 = prev_checks[chk2]; + // The top range check a+i covers interval: -a <= i < length-a + // The second range check b+i covers interval: -b <= i < length-b + if (rc1.off <= rc0.off) { + // if b <= a, we change the second range check to: + // -min_of_all_constants <= i < length-min_of_all_constants + // Together top and second range checks now cover: + // -min_of_all_constants <= i < length-a + // which is more restrictive than -b <= i < length-b: + // -b <= -min_of_all_constants <= i < length-a <= length-b + // The third check is then changed to: + // -max_of_all_constants <= i < length-max_of_all_constants + // so 2nd and 3rd checks restrict allowed values of i to: + // -min_of_all_constants <= i < length-max_of_all_constants + adjust_check(rc1.ctl, range1, index1, flip1, off_lo, igvn); + adjust_check(rc2.ctl, range1, index1, flip1, off_hi, igvn); + } else { + // if b > a, we change the second range check to: + // -max_of_all_constants <= i < length-max_of_all_constants + // Together top and second range checks now cover: + // -a <= i < length-max_of_all_constants + // which is more restrictive than -b <= i < length-b: + // -b < -a <= i < length-max_of_all_constants <= length-b + // The third check is then changed to: + // -max_of_all_constants <= i < length-max_of_all_constants + // so 2nd and 3rd checks restrict allowed values of i to: + // -min_of_all_constants <= i < length-max_of_all_constants + adjust_check(rc1.ctl, range1, index1, flip1, off_hi, igvn); + adjust_check(rc2.ctl, range1, index1, flip1, off_lo, igvn); + } + prev_dom = rc2.ctl; + } + } + } else { + RangeCheck rc0 = prev_checks[chk0]; + // 'Widen' the offset of the 1st and only covering check + adjust_check(rc0.ctl, range1, index1, flip1, off_hi, igvn); + // Test is now covered by prior checks, dominate it out + prev_dom = rc0.ctl; + } } - } else { // Scan for an equivalent test Node *cmp; @@ -1019,7 +1082,7 @@ // for lower and upper bounds. ProjNode* unc_proj = proj_out(1 - prev_dom->as_Proj()->_con)->as_Proj(); if (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate)) - prev_dom = idom; + prev_dom = idom; // Now walk the current IfNode's projections. // Loop ends when 'this' has no more uses. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/lcm.cpp --- a/hotspot/src/share/vm/opto/lcm.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/lcm.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -417,8 +417,15 @@ for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2) old_tst->last_out(i2)->set_req(0, nul_chk); // Clean-up any dead code - for (uint i3 = 0; i3 < old_tst->req(); i3++) + for (uint i3 = 0; i3 < old_tst->req(); i3++) { + Node* in = old_tst->in(i3); old_tst->set_req(i3, NULL); + if (in->outcnt() == 0) { + // Remove dead input node + in->disconnect_inputs(NULL, C); + block->find_remove(in); + } + } latency_from_uses(nul_chk); latency_from_uses(best); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1147,7 +1147,7 @@ // Dump special per-node info #ifndef PRODUCT void CountedLoopEndNode::dump_spec(outputStream *st) const { - if( in(TestValue)->is_Bool() ) { + if( in(TestValue) != NULL && in(TestValue)->is_Bool() ) { BoolTest bt( test_trip()); // Added this for g++. st->print("["); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/loopopts.cpp --- a/hotspot/src/share/vm/opto/loopopts.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/loopopts.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -241,8 +241,13 @@ ProjNode* dp_proj = dp->as_Proj(); ProjNode* unc_proj = iff->as_If()->proj_out(1 - dp_proj->_con)->as_Proj(); if (exclude_loop_predicate && - unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate)) + (unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_predicate) || + unc_proj->is_uncommon_trap_proj(Deoptimization::Reason_range_check))) { + // If this is a range check (IfNode::is_range_check), do not + // reorder because Compile::allow_range_check_smearing might have + // changed the check. return; // Let IGVN transformation change control dependence. + } IdealLoopTree *old_loop = get_loop(dp); @@ -898,23 +903,23 @@ int n_op = n->Opcode(); // Check for an IF being dominated by another IF same test - if( n_op == Op_If ) { + if (n_op == Op_If) { Node *bol = n->in(1); uint max = bol->outcnt(); // Check for same test used more than once? - if( n_op == Op_If && max > 1 && bol->is_Bool() ) { + if (max > 1 && bol->is_Bool()) { // Search up IDOMs to see if this IF is dominated. Node *cutoff = get_ctrl(bol); // Now search up IDOMs till cutoff, looking for a dominating test Node *prevdom = n; Node *dom = idom(prevdom); - while( dom != cutoff ) { - if( dom->req() > 1 && dom->in(1) == bol && prevdom->in(0) == dom ) { + while (dom != cutoff) { + if (dom->req() > 1 && dom->in(1) == bol && prevdom->in(0) == dom) { // Replace the dominated test with an obvious true or false. // Place it on the IGVN worklist for later cleanup. C->set_major_progress(); - dominated_by( prevdom, n, false, true ); + dominated_by(prevdom, n, false, true); #ifndef PRODUCT if( VerifyLoopOptimizations ) verify(); #endif diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/machnode.cpp --- a/hotspot/src/share/vm/opto/machnode.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/machnode.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -473,8 +473,13 @@ // Print any per-operand special info void MachNode::dump_spec(outputStream *st) const { uint cnt = num_opnds(); - for( uint i=0; idump_spec(st); + for( uint i=0; idump_spec(st); + } else { + st->print(" _"); + } + } const TypePtr *t = adr_type(); if( t ) { Compile* C = Compile::current(); @@ -493,7 +498,11 @@ //============================================================================= #ifndef PRODUCT void MachTypeNode::dump_spec(outputStream *st) const { - _bottom_type->dump_on(st); + if (_bottom_type != NULL) { + _bottom_type->dump_on(st); + } else { + st->print(" NULL"); + } } #endif @@ -635,7 +644,7 @@ #ifndef PRODUCT void MachCallNode::dump_spec(outputStream *st) const { st->print("# "); - tf()->dump_on(st); + if (tf() != NULL) tf()->dump_on(st); if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); if (jvms() != NULL) jvms()->dump_spec(st); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/macro.cpp --- a/hotspot/src/share/vm/opto/macro.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/macro.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -971,7 +971,11 @@ } bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { - if (!EliminateAllocations || !alloc->_is_non_escaping) { + // Don't do scalar replacement if the frame can be popped by JVMTI: + // if reallocation fails during deoptimization we'll pop all + // interpreter frames for this compiled frame and that won't play + // nice with JVMTI popframe. + if (!EliminateAllocations || JvmtiExport::can_pop_frame() || !alloc->_is_non_escaping) { return false; } Node* klass = alloc->in(AllocateNode::KlassNode); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/opto/memnode.cpp --- a/hotspot/src/share/vm/opto/memnode.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/opto/memnode.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -4370,7 +4370,7 @@ st->print(" {"); Node* base_mem = base_memory(); for( uint i = Compile::AliasIdxRaw; i < req(); i++ ) { - Node* mem = memory_at(i); + Node* mem = (in(i) != NULL) ? memory_at(i) : base_mem; if (mem == base_mem) { st->print(" -"); continue; } st->print( " N%d:", mem->_idx ); Compile::current()->get_adr_type(i)->dump_on(st); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/prims/jvm.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -700,23 +700,7 @@ // Returns a class loaded by the bootstrap class loader; or null // if not found. ClassNotFoundException is not thrown. -// -// Rationale behind JVM_FindClassFromBootLoader -// a> JVM_FindClassFromClassLoader was never exported in the export tables. -// b> because of (a) java.dll has a direct dependecy on the unexported -// private symbol "_JVM_FindClassFromClassLoader@20". -// c> the launcher cannot use the private symbol as it dynamically opens -// the entry point, so if something changes, the launcher will fail -// unexpectedly at runtime, it is safest for the launcher to dlopen a -// stable exported interface. -// d> re-exporting JVM_FindClassFromClassLoader as public, will cause its -// signature to change from _JVM_FindClassFromClassLoader@20 to -// JVM_FindClassFromClassLoader and will not be backward compatible -// with older JDKs. -// Thus a public/stable exported entry point is the right solution, -// public here means public in linker semantics, and is exported only -// to the JDK, and is not intended to be a public API. - +// FindClassFromBootLoader is exported to the launcher for windows. JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env, const char* name)) JVMWrapper2("JVM_FindClassFromBootLoader %s", name); @@ -740,33 +724,6 @@ return (jclass) JNIHandles::make_local(env, k->java_mirror()); JVM_END -// Not used; JVM_FindClassFromCaller replaces this. -JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, - jboolean init, jobject loader, - jboolean throwError)) - JVMWrapper3("JVM_FindClassFromClassLoader %s throw %s", name, - throwError ? "error" : "exception"); - // Java libraries should ensure that name is never null... - if (name == NULL || (int)strlen(name) > Symbol::max_length()) { - // It's impossible to create this class; the name cannot fit - // into the constant pool. - if (throwError) { - THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name); - } else { - THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name); - } - } - TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL); - Handle h_loader(THREAD, JNIHandles::resolve(loader)); - jclass result = find_class_from_class_loader(env, h_name, init, h_loader, - Handle(), throwError, THREAD); - - if (TraceClassResolution && result != NULL) { - trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); - } - return result; -JVM_END - // Find a class with this name in this loader, using the caller's protection domain. JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name, jboolean init, jobject loader, diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/prims/jvm.h --- a/hotspot/src/share/vm/prims/jvm.h Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/prims/jvm.h Sat Jan 10 12:38:18 2015 -0800 @@ -335,15 +335,6 @@ JVM_FindPrimitiveClass(JNIEnv *env, const char *utf); /* - * Find a class from a given class loader. Throw ClassNotFoundException - * or NoClassDefFoundError depending on the value of the last - * argument. - */ -JNIEXPORT jclass JNICALL -JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init, - jobject loader, jboolean throwError); - -/* * Find a class from a boot class loader. Returns NULL if class not found. */ JNIEXPORT jclass JNICALL diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/prims/whitebox.cpp --- a/hotspot/src/share/vm/prims/whitebox.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/prims/whitebox.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -69,6 +69,14 @@ bool WhiteBox::_used = false; volatile bool WhiteBox::compilation_locked = false; +class VM_WhiteBoxOperation : public VM_Operation { + public: + VM_WhiteBoxOperation() { } + VMOp_Type type() const { return VMOp_WhiteBoxOperation; } + bool allow_nested_vm_operations() const { return true; } +}; + + WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj)) return (jlong)(void*)JNIHandles::resolve(obj); WB_END @@ -404,6 +412,43 @@ return env->FromReflectedMethod(method); } +// Deoptimizes all compiled frames and makes nmethods not entrant if it's requested +class VM_WhiteBoxDeoptimizeFrames : public VM_WhiteBoxOperation { + private: + int _result; + const bool _make_not_entrant; + public: + VM_WhiteBoxDeoptimizeFrames(bool make_not_entrant) : + _result(0), _make_not_entrant(make_not_entrant) { } + int result() const { return _result; } + + void doit() { + for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) { + if (t->has_last_Java_frame()) { + for (StackFrameStream fst(t, UseBiasedLocking); !fst.is_done(); fst.next()) { + frame* f = fst.current(); + if (f->can_be_deoptimized() && !f->is_deoptimized_frame()) { + RegisterMap* reg_map = fst.register_map(); + Deoptimization::deoptimize(t, *f, reg_map); + if (_make_not_entrant) { + nmethod* nm = CodeCache::find_nmethod(f->pc()); + assert(nm != NULL, "sanity check"); + nm->make_not_entrant(); + } + ++_result; + } + } + } + } + } +}; + +WB_ENTRY(jint, WB_DeoptimizeFrames(JNIEnv* env, jobject o, jboolean make_not_entrant)) + VM_WhiteBoxDeoptimizeFrames op(make_not_entrant == JNI_TRUE); + VMThread::execute(&op); + return op.result(); +WB_END + WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o)) MutexLockerEx mu(Compile_lock); CodeCache::mark_all_nmethods_for_deoptimization(); @@ -526,13 +571,6 @@ return (mh->queued_for_compilation() || nm != NULL); WB_END -class VM_WhiteBoxOperation : public VM_Operation { - public: - VM_WhiteBoxOperation() { } - VMOp_Type type() const { return VMOp_WhiteBoxOperation; } - bool allow_nested_vm_operations() const { return true; } -}; - class AlwaysFalseClosure : public BoolObjectClosure { public: bool do_object_b(oop p) { return false; } @@ -761,7 +799,6 @@ } WB_END - WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout)) WhiteBox::compilation_locked = true; WB_END @@ -1078,6 +1115,14 @@ return (jlong) MetaspaceGC::capacity_until_GC(); WB_END +WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue)) + Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ? + Monitor::_safepoint_check_always : + Monitor::_safepoint_check_never; + MutexLockerEx ml(new Mutex(Mutex::leaf, "SFPT_Test_lock", true, sfpt_check_required), + attemptedNoSafepointValue == JNI_TRUE); +WB_END + //Some convenience methods to deal with objects from java int WhiteBox::offset_for_field(const char* field_name, oop object, Symbol* signature_symbol) { @@ -1201,6 +1246,7 @@ {CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel}, {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize }, #endif // INCLUDE_NMT + {CC"deoptimizeFrames", CC"(Z)I", (void*)&WB_DeoptimizeFrames }, {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll }, {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_DeoptimizeMethod }, @@ -1274,6 +1320,7 @@ {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob }, {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, + {CC"assertMatchingSafepointCalls", CC"(ZZ)V", (void*)&WB_AssertMatchingSafepointCalls }, }; #undef CC diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/prims/whitebox.hpp --- a/hotspot/src/share/vm/prims/whitebox.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/prims/whitebox.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -74,7 +74,7 @@ static JavaThread* create_sweeper_thread(TRAPS); static int get_blob_type(const CodeBlob* code); static CodeHeap* get_code_heap(int blob_type); - static CodeBlob* allocate_code_blob(int blob_type, int size); + static CodeBlob* allocate_code_blob(int size, int blob_type); static int array_bytes_to_length(size_t bytes); static void register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -125,8 +125,8 @@ char* Arguments::_meta_index_dir = NULL; char* Arguments::_ext_dirs = NULL; -// Check if head of 'option' matches 'name', and sets 'tail' remaining part of option string - +// Check if head of 'option' matches 'name', and sets 'tail' to the remaining +// part of the option string. static bool match_option(const JavaVMOption *option, const char* name, const char** tail) { int len = (int)strlen(name); @@ -138,6 +138,32 @@ } } +// Check if 'option' matches 'name'. No "tail" is allowed. +static bool match_option(const JavaVMOption *option, const char* name) { + const char* tail = NULL; + bool result = match_option(option, name, &tail); + if (tail != NULL && *tail == '\0') { + return result; + } else { + return false; + } +} + +// Return true if any of the strings in null-terminated array 'names' matches. +// If tail_allowed is true, then the tail must begin with a colon; otherwise, +// the option must match exactly. +static bool match_option(const JavaVMOption* option, const char** names, const char** tail, + bool tail_allowed) { + for (/* empty */; *names != NULL; ++names) { + if (match_option(option, *names, tail)) { + if (**tail == '\0' || tail_allowed && **tail == ':') { + return true; + } + } + } + return false; +} + static void logOption(const char* opt) { if (PrintVMOptions) { jio_fprintf(defaultStream::output_stream(), "VM option '%s'\n", opt); @@ -899,9 +925,9 @@ "Warning: support for %s was removed in %s\n", fuzzy_matched->_name, version); - } } } + } // allow for commandline "commenting out" options like -XX:#+Verbose return arg[0] == '#'; @@ -1356,41 +1382,24 @@ if (FLAG_IS_DEFAULT(SurvivorRatio) && MaxTenuringThreshold == 0) { FLAG_SET_ERGO(uintx, SurvivorRatio, MAX2((uintx)1024, SurvivorRatio)); } - // If OldPLABSize is set and CMSParPromoteBlocksToClaim is not, - // set CMSParPromoteBlocksToClaim equal to OldPLABSize. - // This is done in order to make ParNew+CMS configuration to work - // with YoungPLABSize and OldPLABSize options. - // See CR 6362902. - if (!FLAG_IS_DEFAULT(OldPLABSize)) { - if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) { - // OldPLABSize is not the default value but CMSParPromoteBlocksToClaim - // is. In this situation let CMSParPromoteBlocksToClaim follow - // the value (either from the command line or ergonomics) of - // OldPLABSize. Following OldPLABSize is an ergonomics decision. - FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, OldPLABSize); + + // OldPLABSize is interpreted in CMS as not the size of the PLAB in words, + // but rather the number of free blocks of a given size that are used when + // replenishing the local per-worker free list caches. + if (FLAG_IS_DEFAULT(OldPLABSize)) { + if (!FLAG_IS_DEFAULT(ResizeOldPLAB) && !ResizeOldPLAB) { + // OldPLAB sizing manually turned off: Use a larger default setting, + // unless it was manually specified. This is because a too-low value + // will slow down scavenges. + FLAG_SET_ERGO(uintx, OldPLABSize, CFLS_LAB::_default_static_old_plab_size); // default value before 6631166 } else { - // OldPLABSize and CMSParPromoteBlocksToClaim are both set. - // CMSParPromoteBlocksToClaim is a collector-specific flag, so - // we'll let it to take precedence. - jio_fprintf(defaultStream::error_stream(), - "Both OldPLABSize and CMSParPromoteBlocksToClaim" - " options are specified for the CMS collector." - " CMSParPromoteBlocksToClaim will take precedence.\n"); + FLAG_SET_DEFAULT(OldPLABSize, CFLS_LAB::_default_dynamic_old_plab_size); // old CMSParPromoteBlocksToClaim default } } - if (!FLAG_IS_DEFAULT(ResizeOldPLAB) && !ResizeOldPLAB) { - // OldPLAB sizing manually turned off: Use a larger default setting, - // unless it was manually specified. This is because a too-low value - // will slow down scavenges. - if (FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim)) { - FLAG_SET_ERGO(uintx, CMSParPromoteBlocksToClaim, 50); // default value before 6631166 - } - } - // Overwrite OldPLABSize which is the variable we will internally use everywhere. - FLAG_SET_ERGO(uintx, OldPLABSize, CMSParPromoteBlocksToClaim); + // If either of the static initialization defaults have changed, note this // modification. - if (!FLAG_IS_DEFAULT(CMSParPromoteBlocksToClaim) || !FLAG_IS_DEFAULT(OldPLABWeight)) { + if (!FLAG_IS_DEFAULT(OldPLABSize) || !FLAG_IS_DEFAULT(OldPLABWeight)) { CFLS_LAB::modify_initialization(OldPLABSize, OldPLABWeight); } if (PrintGCDetails && Verbose) { @@ -2526,21 +2535,6 @@ "-dsa", "-esa", "-disablesystemassertions", "-enablesystemassertions", 0 }; -// Return true if any of the strings in null-terminated array 'names' matches. -// If tail_allowed is true, then the tail must begin with a colon; otherwise, -// the option must match exactly. -static bool match_option(const JavaVMOption* option, const char** names, const char** tail, - bool tail_allowed) { - for (/* empty */; *names != NULL; ++names) { - if (match_option(option, *names, tail)) { - if (**tail == '\0' || tail_allowed && **tail == ':') { - return true; - } - } - } - return false; -} - bool Arguments::parse_uintx(const char* value, uintx* uintx_arg, uintx min_size) { @@ -2782,16 +2776,16 @@ } #endif // !INCLUDE_JVMTI // -Xnoclassgc - } else if (match_option(option, "-Xnoclassgc", &tail)) { + } else if (match_option(option, "-Xnoclassgc")) { FLAG_SET_CMDLINE(bool, ClassUnloading, false); // -Xconcgc - } else if (match_option(option, "-Xconcgc", &tail)) { + } else if (match_option(option, "-Xconcgc")) { FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, true); // -Xnoconcgc - } else if (match_option(option, "-Xnoconcgc", &tail)) { + } else if (match_option(option, "-Xnoconcgc")) { FLAG_SET_CMDLINE(bool, UseConcMarkSweepGC, false); // -Xbatch - } else if (match_option(option, "-Xbatch", &tail)) { + } else if (match_option(option, "-Xbatch")) { FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); // -Xmn for compatibility with other JVM vendors } else if (match_option(option, "-Xmn", &tail)) { @@ -2936,28 +2930,28 @@ } FLAG_SET_CMDLINE(uintx, IncreaseFirstTierCompileThresholdAt, (uintx)uint_IncreaseFirstTierCompileThresholdAt); // -green - } else if (match_option(option, "-green", &tail)) { + } else if (match_option(option, "-green")) { jio_fprintf(defaultStream::error_stream(), "Green threads support not available\n"); return JNI_EINVAL; // -native - } else if (match_option(option, "-native", &tail)) { + } else if (match_option(option, "-native")) { // HotSpot always uses native threads, ignore silently for compatibility // -Xsqnopause - } else if (match_option(option, "-Xsqnopause", &tail)) { + } else if (match_option(option, "-Xsqnopause")) { // EVM option, ignore silently for compatibility // -Xrs - } else if (match_option(option, "-Xrs", &tail)) { + } else if (match_option(option, "-Xrs")) { // Classic/EVM option, new functionality FLAG_SET_CMDLINE(bool, ReduceSignalUsage, true); - } else if (match_option(option, "-Xusealtsigs", &tail)) { + } else if (match_option(option, "-Xusealtsigs")) { // change default internal VM signals used - lower case for back compat FLAG_SET_CMDLINE(bool, UseAltSigs, true); // -Xoptimize - } else if (match_option(option, "-Xoptimize", &tail)) { + } else if (match_option(option, "-Xoptimize")) { // EVM option, ignore silently for compatibility // -Xprof - } else if (match_option(option, "-Xprof", &tail)) { + } else if (match_option(option, "-Xprof")) { #if INCLUDE_FPROF _has_profile = true; #else // INCLUDE_FPROF @@ -2966,7 +2960,7 @@ return JNI_ERR; #endif // INCLUDE_FPROF // -Xconcurrentio - } else if (match_option(option, "-Xconcurrentio", &tail)) { + } else if (match_option(option, "-Xconcurrentio")) { FLAG_SET_CMDLINE(bool, UseLWPSynchronization, true); FLAG_SET_CMDLINE(bool, BackgroundCompilation, false); FLAG_SET_CMDLINE(intx, DeferThrSuspendLoopCount, 1); @@ -2974,29 +2968,32 @@ FLAG_SET_CMDLINE(uintx, NewSizeThreadIncrease, 16 * K); // 20Kb per thread added to new generation // -Xinternalversion - } else if (match_option(option, "-Xinternalversion", &tail)) { + } else if (match_option(option, "-Xinternalversion")) { jio_fprintf(defaultStream::output_stream(), "%s\n", VM_Version::internal_vm_info_string()); vm_exit(0); #ifndef PRODUCT // -Xprintflags - } else if (match_option(option, "-Xprintflags", &tail)) { + } else if (match_option(option, "-Xprintflags")) { CommandLineFlags::printFlags(tty, false); vm_exit(0); #endif // -D } else if (match_option(option, "-D", &tail)) { - if (match_option(option, "-Djava.endorsed.dirs=", &tail)) { + const char* value; + if (match_option(option, "-Djava.endorsed.dirs=", &value) && + *value!= '\0' && strcmp(value, "\"\"") != 0) { // abort if -Djava.endorsed.dirs is set jio_fprintf(defaultStream::output_stream(), - "-Djava.endorsed.dirs is not supported. Endorsed standards and standalone APIs\n" - "in modular form will be supported via the concept of upgradeable modules.\n"); + "-Djava.endorsed.dirs=%s is not supported. Endorsed standards and standalone APIs\n" + "in modular form will be supported via the concept of upgradeable modules.\n", value); return JNI_EINVAL; } - if (match_option(option, "-Djava.ext.dirs=", &tail)) { + if (match_option(option, "-Djava.ext.dirs=", &value) && + *value != '\0' && strcmp(value, "\"\"") != 0) { // abort if -Djava.ext.dirs is set jio_fprintf(defaultStream::output_stream(), - "-Djava.ext.dirs is not supported. Use -classpath instead.\n"); + "-Djava.ext.dirs=%s is not supported. Use -classpath instead.\n", value); return JNI_EINVAL; } @@ -3014,29 +3011,29 @@ #endif } // -Xint - } else if (match_option(option, "-Xint", &tail)) { + } else if (match_option(option, "-Xint")) { set_mode_flags(_int); // -Xmixed - } else if (match_option(option, "-Xmixed", &tail)) { + } else if (match_option(option, "-Xmixed")) { set_mode_flags(_mixed); // -Xcomp - } else if (match_option(option, "-Xcomp", &tail)) { + } else if (match_option(option, "-Xcomp")) { // for testing the compiler; turn off all flags that inhibit compilation set_mode_flags(_comp); // -Xshare:dump - } else if (match_option(option, "-Xshare:dump", &tail)) { + } else if (match_option(option, "-Xshare:dump")) { FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true); set_mode_flags(_int); // Prevent compilation, which creates objects // -Xshare:on - } else if (match_option(option, "-Xshare:on", &tail)) { + } else if (match_option(option, "-Xshare:on")) { FLAG_SET_CMDLINE(bool, UseSharedSpaces, true); FLAG_SET_CMDLINE(bool, RequireSharedSpaces, true); // -Xshare:auto - } else if (match_option(option, "-Xshare:auto", &tail)) { + } else if (match_option(option, "-Xshare:auto")) { FLAG_SET_CMDLINE(bool, UseSharedSpaces, true); FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false); // -Xshare:off - } else if (match_option(option, "-Xshare:off", &tail)) { + } else if (match_option(option, "-Xshare:off")) { FLAG_SET_CMDLINE(bool, UseSharedSpaces, false); FLAG_SET_CMDLINE(bool, RequireSharedSpaces, false); // -Xverify @@ -3054,13 +3051,13 @@ return JNI_EINVAL; } // -Xdebug - } else if (match_option(option, "-Xdebug", &tail)) { + } else if (match_option(option, "-Xdebug")) { // note this flag has been used, then ignore set_xdebug_mode(true); // -Xnoagent - } else if (match_option(option, "-Xnoagent", &tail)) { + } else if (match_option(option, "-Xnoagent")) { // For compatibility with classic. HotSpot refuses to load the old style agent.dll. - } else if (match_option(option, "-Xboundthreads", &tail)) { + } else if (match_option(option, "-Xboundthreads")) { // Bind user level threads to kernel threads (Solaris only) FLAG_SET_CMDLINE(bool, UseBoundThreads, true); } else if (match_option(option, "-Xloggc:", &tail)) { @@ -3090,14 +3087,14 @@ "check")) { return JNI_EINVAL; } - } else if (match_option(option, "vfprintf", &tail)) { + } else if (match_option(option, "vfprintf")) { _vfprintf_hook = CAST_TO_FN_PTR(vfprintf_hook_t, option->extraInfo); - } else if (match_option(option, "exit", &tail)) { + } else if (match_option(option, "exit")) { _exit_hook = CAST_TO_FN_PTR(exit_hook_t, option->extraInfo); - } else if (match_option(option, "abort", &tail)) { + } else if (match_option(option, "abort")) { _abort_hook = CAST_TO_FN_PTR(abort_hook_t, option->extraInfo); // -XX:+AggressiveHeap - } else if (match_option(option, "-XX:+AggressiveHeap", &tail)) { + } else if (match_option(option, "-XX:+AggressiveHeap")) { // This option inspects the machine and attempts to set various // parameters to be optimal for long-running, memory allocation @@ -3188,11 +3185,11 @@ // Need to keep consistency of MaxTenuringThreshold and AlwaysTenure/NeverTenure; // and the last option wins. - } else if (match_option(option, "-XX:+NeverTenure", &tail)) { + } else if (match_option(option, "-XX:+NeverTenure")) { FLAG_SET_CMDLINE(bool, NeverTenure, true); FLAG_SET_CMDLINE(bool, AlwaysTenure, false); FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, markOopDesc::max_age + 1); - } else if (match_option(option, "-XX:+AlwaysTenure", &tail)) { + } else if (match_option(option, "-XX:+AlwaysTenure")) { FLAG_SET_CMDLINE(bool, NeverTenure, false); FLAG_SET_CMDLINE(bool, AlwaysTenure, true); FLAG_SET_CMDLINE(uintx, MaxTenuringThreshold, 0); @@ -3211,59 +3208,13 @@ FLAG_SET_CMDLINE(bool, NeverTenure, false); FLAG_SET_CMDLINE(bool, AlwaysTenure, false); } - } else if (match_option(option, "-XX:+CMSPermGenSweepingEnabled", &tail) || - match_option(option, "-XX:-CMSPermGenSweepingEnabled", &tail)) { - jio_fprintf(defaultStream::error_stream(), - "Please use CMSClassUnloadingEnabled in place of " - "CMSPermGenSweepingEnabled in the future\n"); - } else if (match_option(option, "-XX:+UseGCTimeLimit", &tail)) { - FLAG_SET_CMDLINE(bool, UseGCOverheadLimit, true); - jio_fprintf(defaultStream::error_stream(), - "Please use -XX:+UseGCOverheadLimit in place of " - "-XX:+UseGCTimeLimit in the future\n"); - } else if (match_option(option, "-XX:-UseGCTimeLimit", &tail)) { - FLAG_SET_CMDLINE(bool, UseGCOverheadLimit, false); - jio_fprintf(defaultStream::error_stream(), - "Please use -XX:-UseGCOverheadLimit in place of " - "-XX:-UseGCTimeLimit in the future\n"); - // The TLE options are for compatibility with 1.3 and will be - // removed without notice in a future release. These options - // are not to be documented. - } else if (match_option(option, "-XX:MaxTLERatio=", &tail)) { - // No longer used. - } else if (match_option(option, "-XX:+ResizeTLE", &tail)) { - FLAG_SET_CMDLINE(bool, ResizeTLAB, true); - } else if (match_option(option, "-XX:-ResizeTLE", &tail)) { - FLAG_SET_CMDLINE(bool, ResizeTLAB, false); - } else if (match_option(option, "-XX:+PrintTLE", &tail)) { - FLAG_SET_CMDLINE(bool, PrintTLAB, true); - } else if (match_option(option, "-XX:-PrintTLE", &tail)) { - FLAG_SET_CMDLINE(bool, PrintTLAB, false); - } else if (match_option(option, "-XX:TLEFragmentationRatio=", &tail)) { - // No longer used. - } else if (match_option(option, "-XX:TLESize=", &tail)) { - julong long_tlab_size = 0; - ArgsRange errcode = parse_memory_size(tail, &long_tlab_size, 1); - if (errcode != arg_in_range) { - jio_fprintf(defaultStream::error_stream(), - "Invalid TLAB size: %s\n", option->optionString); - describe_range_error(errcode); - return JNI_EINVAL; - } - FLAG_SET_CMDLINE(uintx, TLABSize, long_tlab_size); - } else if (match_option(option, "-XX:TLEThreadRatio=", &tail)) { - // No longer used. - } else if (match_option(option, "-XX:+UseTLE", &tail)) { - FLAG_SET_CMDLINE(bool, UseTLAB, true); - } else if (match_option(option, "-XX:-UseTLE", &tail)) { - FLAG_SET_CMDLINE(bool, UseTLAB, false); - } else if (match_option(option, "-XX:+DisplayVMOutputToStderr", &tail)) { + } else if (match_option(option, "-XX:+DisplayVMOutputToStderr")) { FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false); FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true); - } else if (match_option(option, "-XX:+DisplayVMOutputToStdout", &tail)) { + } else if (match_option(option, "-XX:+DisplayVMOutputToStdout")) { FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, false); FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, true); - } else if (match_option(option, "-XX:+ExtendedDTraceProbes", &tail)) { + } else if (match_option(option, "-XX:+ExtendedDTraceProbes")) { #if defined(DTRACE_ENABLED) FLAG_SET_CMDLINE(bool, ExtendedDTraceProbes, true); FLAG_SET_CMDLINE(bool, DTraceMethodProbes, true); @@ -3275,49 +3226,11 @@ return JNI_EINVAL; #endif // defined(DTRACE_ENABLED) #ifdef ASSERT - } else if (match_option(option, "-XX:+FullGCALot", &tail)) { + } else if (match_option(option, "-XX:+FullGCALot")) { FLAG_SET_CMDLINE(bool, FullGCALot, true); // disable scavenge before parallel mark-compact FLAG_SET_CMDLINE(bool, ScavengeBeforeFullGC, false); #endif - } else if (match_option(option, "-XX:CMSParPromoteBlocksToClaim=", &tail)) { - julong cms_blocks_to_claim = (julong)atol(tail); - FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, cms_blocks_to_claim); - jio_fprintf(defaultStream::error_stream(), - "Please use -XX:OldPLABSize in place of " - "-XX:CMSParPromoteBlocksToClaim in the future\n"); - } else if (match_option(option, "-XX:ParCMSPromoteBlocksToClaim=", &tail)) { - julong cms_blocks_to_claim = (julong)atol(tail); - FLAG_SET_CMDLINE(uintx, CMSParPromoteBlocksToClaim, cms_blocks_to_claim); - jio_fprintf(defaultStream::error_stream(), - "Please use -XX:OldPLABSize in place of " - "-XX:ParCMSPromoteBlocksToClaim in the future\n"); - } else if (match_option(option, "-XX:ParallelGCOldGenAllocBufferSize=", &tail)) { - julong old_plab_size = 0; - ArgsRange errcode = parse_memory_size(tail, &old_plab_size, 1); - if (errcode != arg_in_range) { - jio_fprintf(defaultStream::error_stream(), - "Invalid old PLAB size: %s\n", option->optionString); - describe_range_error(errcode); - return JNI_EINVAL; - } - FLAG_SET_CMDLINE(uintx, OldPLABSize, old_plab_size); - jio_fprintf(defaultStream::error_stream(), - "Please use -XX:OldPLABSize in place of " - "-XX:ParallelGCOldGenAllocBufferSize in the future\n"); - } else if (match_option(option, "-XX:ParallelGCToSpaceAllocBufferSize=", &tail)) { - julong young_plab_size = 0; - ArgsRange errcode = parse_memory_size(tail, &young_plab_size, 1); - if (errcode != arg_in_range) { - jio_fprintf(defaultStream::error_stream(), - "Invalid young PLAB size: %s\n", option->optionString); - describe_range_error(errcode); - return JNI_EINVAL; - } - FLAG_SET_CMDLINE(uintx, YoungPLABSize, young_plab_size); - jio_fprintf(defaultStream::error_stream(), - "Please use -XX:YoungPLABSize in place of " - "-XX:ParallelGCToSpaceAllocBufferSize in the future\n"); } else if (match_option(option, "-XX:CMSMarkStackSize=", &tail) || match_option(option, "-XX:G1MarkStackSize=", &tail)) { julong stack_size = 0; @@ -3328,6 +3241,9 @@ describe_range_error(errcode); return JNI_EINVAL; } + jio_fprintf(defaultStream::error_stream(), + "Please use -XX:MarkStackSize in place of " + "-XX:CMSMarkStackSize or -XX:G1MarkStackSize in the future\n"); FLAG_SET_CMDLINE(uintx, MarkStackSize, stack_size); } else if (match_option(option, "-XX:CMSMarkStackSizeMax=", &tail)) { julong max_stack_size = 0; @@ -3339,6 +3255,9 @@ describe_range_error(errcode); return JNI_EINVAL; } + jio_fprintf(defaultStream::error_stream(), + "Please use -XX:MarkStackSizeMax in place of " + "-XX:CMSMarkStackSizeMax in the future\n"); FLAG_SET_CMDLINE(uintx, MarkStackSizeMax, max_stack_size); } else if (match_option(option, "-XX:ParallelMarkingThreads=", &tail) || match_option(option, "-XX:ParallelCMSThreads=", &tail)) { @@ -3348,6 +3267,9 @@ "Invalid concurrent threads: %s\n", option->optionString); return JNI_EINVAL; } + jio_fprintf(defaultStream::error_stream(), + "Please use -XX:ConcGCThreads in place of " + "-XX:ParallelMarkingThreads or -XX:ParallelCMSThreads in the future\n"); FLAG_SET_CMDLINE(uintx, ConcGCThreads, conc_threads); } else if (match_option(option, "-XX:MaxDirectMemorySize=", &tail)) { julong max_direct_memory_size = 0; @@ -3361,7 +3283,7 @@ } FLAG_SET_CMDLINE(uintx, MaxDirectMemorySize, max_direct_memory_size); #if !INCLUDE_MANAGEMENT - } else if (match_option(option, "-XX:+ManagementServer", &tail)) { + } else if (match_option(option, "-XX:+ManagementServer")) { jio_fprintf(defaultStream::error_stream(), "ManagementServer is not supported in this VM.\n"); return JNI_ERR; @@ -3796,23 +3718,23 @@ settings_file_specified = true; continue; } - if (match_option(option, "-XX:+PrintVMOptions", &tail)) { + if (match_option(option, "-XX:+PrintVMOptions")) { PrintVMOptions = true; continue; } - if (match_option(option, "-XX:-PrintVMOptions", &tail)) { + if (match_option(option, "-XX:-PrintVMOptions")) { PrintVMOptions = false; continue; } - if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions", &tail)) { + if (match_option(option, "-XX:+IgnoreUnrecognizedVMOptions")) { IgnoreUnrecognizedVMOptions = true; continue; } - if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) { + if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions")) { IgnoreUnrecognizedVMOptions = false; continue; } - if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) { + if (match_option(option, "-XX:+PrintFlagsInitial")) { CommandLineFlags::printFlags(tty, false); vm_exit(0); } @@ -3838,7 +3760,7 @@ #ifndef PRODUCT - if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) { + if (match_option(option, "-XX:+PrintFlagsWithComments")) { CommandLineFlags::printFlags(tty, true); vm_exit(0); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/deoptimization.cpp --- a/hotspot/src/share/vm/runtime/deoptimization.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -176,6 +176,8 @@ assert(vf->is_compiled_frame(), "Wrong frame type"); chunk->push(compiledVFrame::cast(vf)); + bool realloc_failures = false; + #ifdef COMPILER2 // Reallocate the non-escaping objects and restore their fields. Then // relock objects if synchronization on them was eliminated. @@ -206,19 +208,16 @@ tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, (void *)result, thread); } } - bool reallocated = false; if (objects != NULL) { JRT_BLOCK - reallocated = realloc_objects(thread, &deoptee, objects, THREAD); + realloc_failures = realloc_objects(thread, &deoptee, objects, THREAD); JRT_END - } - if (reallocated) { - reassign_fields(&deoptee, &map, objects); + reassign_fields(&deoptee, &map, objects, realloc_failures); #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); - print_objects(objects); + print_objects(objects, realloc_failures); } #endif } @@ -236,7 +235,7 @@ assert (cvf->scope() != NULL,"expect only compiled java frames"); GrowableArray* monitors = cvf->monitors(); if (monitors->is_nonempty()) { - relock_objects(monitors, thread); + relock_objects(monitors, thread, realloc_failures); #ifndef PRODUCT if (TraceDeoptimization) { ttyLocker ttyl; @@ -247,7 +246,12 @@ first = false; tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); } - tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner()); + if (mi->owner_is_scalar_replaced()) { + Klass* k = java_lang_Class::as_Klass(mi->owner_klass()); + tty->print_cr(" failed reallocation for klass %s", k->external_name()); + } else { + tty->print_cr(" object <" INTPTR_FORMAT "> locked", (void *)mi->owner()); + } } } } @@ -262,9 +266,14 @@ // out the java state residing in the vframeArray will be missed. No_Safepoint_Verifier no_safepoint; - vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk); + vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk, realloc_failures); +#ifdef COMPILER2 + if (realloc_failures) { + pop_frames_failed_reallocs(thread, array); + } +#endif - assert(thread->vframe_array_head() == NULL, "Pending deopt!");; + assert(thread->vframe_array_head() == NULL, "Pending deopt!"); thread->set_vframe_array_head(array); // Now that the vframeArray has been created if we have any deferred local writes @@ -718,6 +727,8 @@ int exception_line = thread->exception_line(); thread->clear_pending_exception(); + bool failures = false; + for (int i = 0; i < objects->length(); i++) { assert(objects->at(i)->is_object(), "invalid debug information"); ObjectValue* sv = (ObjectValue*) objects->at(i); @@ -727,27 +738,34 @@ if (k->oop_is_instance()) { InstanceKlass* ik = InstanceKlass::cast(k()); - obj = ik->allocate_instance(CHECK_(false)); + obj = ik->allocate_instance(THREAD); } else if (k->oop_is_typeArray()) { TypeArrayKlass* ak = TypeArrayKlass::cast(k()); assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); int len = sv->field_size() / type2size[ak->element_type()]; - obj = ak->allocate(len, CHECK_(false)); + obj = ak->allocate(len, THREAD); } else if (k->oop_is_objArray()) { ObjArrayKlass* ak = ObjArrayKlass::cast(k()); - obj = ak->allocate(sv->field_size(), CHECK_(false)); + obj = ak->allocate(sv->field_size(), THREAD); } - assert(obj != NULL, "allocation failed"); + if (obj == NULL) { + failures = true; + } + assert(sv->value().is_null(), "redundant reallocation"); + assert(obj != NULL || HAS_PENDING_EXCEPTION, "allocation should succeed or we should get an exception"); + CLEAR_PENDING_EXCEPTION; sv->set_value(obj); } - if (pending_exception.not_null()) { + if (failures) { + THROW_OOP_(Universe::out_of_memory_error_realloc_objects(), failures); + } else if (pending_exception.not_null()) { thread->set_pending_exception(pending_exception(), exception_file, exception_line); } - return true; + return failures; } // This assumes that the fields are stored in ObjectValue in the same order @@ -885,12 +903,15 @@ // restore fields of all eliminated objects and arrays -void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects) { +void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects, bool realloc_failures) { for (int i = 0; i < objects->length(); i++) { ObjectValue* sv = (ObjectValue*) objects->at(i); KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); Handle obj = sv->value(); - assert(obj.not_null(), "reallocation was missed"); + assert(obj.not_null() || realloc_failures, "reallocation was missed"); + if (obj.is_null()) { + continue; + } if (k->oop_is_instance()) { InstanceKlass* ik = InstanceKlass::cast(k()); @@ -907,34 +928,36 @@ // relock objects for which synchronization was eliminated -void Deoptimization::relock_objects(GrowableArray* monitors, JavaThread* thread) { +void Deoptimization::relock_objects(GrowableArray* monitors, JavaThread* thread, bool realloc_failures) { for (int i = 0; i < monitors->length(); i++) { MonitorInfo* mon_info = monitors->at(i); if (mon_info->eliminated()) { - assert(mon_info->owner() != NULL, "reallocation was missed"); - Handle obj = Handle(mon_info->owner()); - markOop mark = obj->mark(); - if (UseBiasedLocking && mark->has_bias_pattern()) { - // New allocated objects may have the mark set to anonymously biased. - // Also the deoptimized method may called methods with synchronization - // where the thread-local object is bias locked to the current thread. - assert(mark->is_biased_anonymously() || - mark->biased_locker() == thread, "should be locked to current thread"); - // Reset mark word to unbiased prototype. - markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); - obj->set_mark(unbiased_prototype); + assert(!mon_info->owner_is_scalar_replaced() || realloc_failures, "reallocation was missed"); + if (!mon_info->owner_is_scalar_replaced()) { + Handle obj = Handle(mon_info->owner()); + markOop mark = obj->mark(); + if (UseBiasedLocking && mark->has_bias_pattern()) { + // New allocated objects may have the mark set to anonymously biased. + // Also the deoptimized method may called methods with synchronization + // where the thread-local object is bias locked to the current thread. + assert(mark->is_biased_anonymously() || + mark->biased_locker() == thread, "should be locked to current thread"); + // Reset mark word to unbiased prototype. + markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); + obj->set_mark(unbiased_prototype); + } + BasicLock* lock = mon_info->lock(); + ObjectSynchronizer::slow_enter(obj, lock, thread); + assert(mon_info->owner()->is_locked(), "object must be locked now"); } - BasicLock* lock = mon_info->lock(); - ObjectSynchronizer::slow_enter(obj, lock, thread); } - assert(mon_info->owner()->is_locked(), "object must be locked now"); } } #ifndef PRODUCT // print information about reallocated objects -void Deoptimization::print_objects(GrowableArray* objects) { +void Deoptimization::print_objects(GrowableArray* objects, bool realloc_failures) { fieldDescriptor fd; for (int i = 0; i < objects->length(); i++) { @@ -944,10 +967,15 @@ tty->print(" object <" INTPTR_FORMAT "> of type ", (void *)sv->value()()); k->print_value(); - tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); + assert(obj.not_null() || realloc_failures, "reallocation was missed"); + if (obj.is_null()) { + tty->print(" allocation failed"); + } else { + tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); + } tty->cr(); - if (Verbose) { + if (Verbose && !obj.is_null()) { k->oop_print_on(obj(), tty); } } @@ -955,7 +983,7 @@ #endif #endif // COMPILER2 -vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk) { +vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk, bool realloc_failures) { Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp()); #ifndef PRODUCT @@ -998,7 +1026,7 @@ // Since the Java thread being deoptimized will eventually adjust it's own stack, // the vframeArray containing the unpacking information is allocated in the C heap. // For Compiler1, the caller of the deoptimized frame is saved for use by unpack_frames(). - vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr); + vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr, realloc_failures); // Compare the vframeArray to the collected vframes assert(array->structural_compare(thread, chunk), "just checking"); @@ -1013,6 +1041,33 @@ return array; } +#ifdef COMPILER2 +void Deoptimization::pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array) { + // Reallocation of some scalar replaced objects failed. Record + // that we need to pop all the interpreter frames for the + // deoptimized compiled frame. + assert(thread->frames_to_pop_failed_realloc() == 0, "missed frames to pop?"); + thread->set_frames_to_pop_failed_realloc(array->frames()); + // Unlock all monitors here otherwise the interpreter will see a + // mix of locked and unlocked monitors (because of failed + // reallocations of synchronized objects) and be confused. + for (int i = 0; i < array->frames(); i++) { + MonitorChunk* monitors = array->element(i)->monitors(); + if (monitors != NULL) { + for (int j = 0; j < monitors->number_of_monitors(); j++) { + BasicObjectLock* src = monitors->at(j); + if (src->obj() != NULL) { + ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread); + } + } + array->element(i)->free_monitors(thread); +#ifdef ASSERT + array->element(i)->set_removed_monitors(); +#endif + } + } +} +#endif static void collect_monitors(compiledVFrame* cvf, GrowableArray* objects_to_revoke) { GrowableArray* monitors = cvf->monitors(); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/deoptimization.hpp --- a/hotspot/src/share/vm/runtime/deoptimization.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -125,13 +125,14 @@ static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS); static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); - static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects); - static void relock_objects(GrowableArray* monitors, JavaThread* thread); - NOT_PRODUCT(static void print_objects(GrowableArray* objects);) + static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects, bool realloc_failures); + static void relock_objects(GrowableArray* monitors, JavaThread* thread, bool realloc_failures); + static void pop_frames_failed_reallocs(JavaThread* thread, vframeArray* array); + NOT_PRODUCT(static void print_objects(GrowableArray* objects, bool realloc_failures);) #endif // COMPILER2 public: - static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk); + static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk, bool realloc_failures); // Interface used for unpacking deoptimized frames diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/globals.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1341,7 +1341,7 @@ develop(bool, TraceClassInitialization, false, \ "Trace class initialization") \ \ - develop(bool, TraceExceptions, false, \ + product(bool, TraceExceptions, false, \ "Trace exceptions") \ \ develop(bool, TraceICs, false, \ @@ -1472,7 +1472,8 @@ "Size of young gen promotion LAB's (in HeapWords)") \ \ product(uintx, OldPLABSize, 1024, \ - "Size of old gen promotion LAB's (in HeapWords)") \ + "Size of old gen promotion LAB's (in HeapWords), or Number \ + of blocks to attempt to claim when refilling CMS LAB's") \ \ product(uintx, GCTaskTimeStampEntries, 200, \ "Number of time stamp entries per gc worker thread") \ @@ -1583,14 +1584,10 @@ "The number of cards in each chunk of the parallel chunks used " \ "during card table scanning") \ \ - product(uintx, CMSParPromoteBlocksToClaim, 16, \ - "Number of blocks to attempt to claim when refilling CMS LAB's " \ - "for parallel GC") \ - \ product(uintx, OldPLABWeight, 50, \ "Percentage (0-100) used to weight the current sample when " \ "computing exponentially decaying average for resizing " \ - "CMSParPromoteBlocksToClaim") \ + "OldPLABSize") \ \ product(bool, ResizeOldPLAB, true, \ "Dynamically resize (old gen) promotion LAB's") \ diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/mutex.cpp --- a/hotspot/src/share/vm/runtime/mutex.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/mutex.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -895,6 +895,11 @@ // of Mutex-Monitor and instead directly address the underlying design flaw. void Monitor::lock(Thread * Self) { + // Ensure that the Monitor requires/allows safepoint checks. + assert(_safepoint_check_required != Monitor::_safepoint_check_never, + err_msg("This lock should never have a safepoint check: %s", + name())); + #ifdef CHECK_UNHANDLED_OOPS // Clear unhandled oops so we get a crash right away. Only clear for non-vm // or GC threads. @@ -953,6 +958,10 @@ // thread state set to be in VM, the safepoint synchronization code will deadlock! void Monitor::lock_without_safepoint_check(Thread * Self) { + // Ensure that the Monitor does not require or allow safepoint checks. + assert(_safepoint_check_required != Monitor::_safepoint_check_always, + err_msg("This lock should always have a safepoint check: %s", + name())); assert(_owner != Self, "invariant"); ILock(Self); assert(_owner == NULL, "invariant"); @@ -1082,6 +1091,12 @@ bool Monitor::wait(bool no_safepoint_check, long timeout, bool as_suspend_equivalent) { + // Make sure safepoint checking is used properly. + assert(!(_safepoint_check_required == Monitor::_safepoint_check_never && no_safepoint_check == false), + err_msg("This lock should never have a safepoint check: %s", name())); + assert(!(_safepoint_check_required == Monitor::_safepoint_check_always && no_safepoint_check == true), + err_msg("This lock should always have a safepoint check: %s", name())); + Thread * const Self = Thread::current(); assert(_owner == Self, "invariant"); assert(ILocked(), "invariant"); @@ -1168,11 +1183,13 @@ Monitor::Monitor() { ClearMonitor(this); } -Monitor::Monitor(int Rank, const char * name, bool allow_vm_block) { +Monitor::Monitor(int Rank, const char * name, bool allow_vm_block, + SafepointCheckRequired safepoint_check_required) { ClearMonitor(this, name); #ifdef ASSERT _allow_vm_block = allow_vm_block; _rank = Rank; + NOT_PRODUCT(_safepoint_check_required = safepoint_check_required;) #endif } @@ -1180,11 +1197,13 @@ assert((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, ""); } -Mutex::Mutex(int Rank, const char * name, bool allow_vm_block) { +Mutex::Mutex(int Rank, const char * name, bool allow_vm_block, + SafepointCheckRequired safepoint_check_required) { ClearMonitor((Monitor *) this, name); #ifdef ASSERT _allow_vm_block = allow_vm_block; _rank = Rank; + NOT_PRODUCT(_safepoint_check_required = safepoint_check_required;) #endif } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/mutex.hpp --- a/hotspot/src/share/vm/runtime/mutex.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/mutex.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -154,6 +154,24 @@ _as_suspend_equivalent_flag = true }; + // Locks can be acquired with or without safepoint check. + // Monitor::lock and Monitor::lock_without_safepoint_check + // checks these flags when acquiring a lock to ensure + // consistent checking for each lock. + // A few existing locks will sometimes have a safepoint check and + // sometimes not, but these locks are set up in such a way to avoid deadlocks. + enum SafepointCheckRequired { + _safepoint_check_never, // Monitors with this value will cause errors + // when acquired with a safepoint check. + _safepoint_check_sometimes, // Certain locks are called sometimes with and + // sometimes without safepoint checks. These + // locks will not produce errors when locked. + _safepoint_check_always // Causes error if locked without a safepoint + // check. + }; + + NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;) + enum WaitResults { CONDVAR_EVENT, // Wait returned because of condition variable notification INTERRUPT_EVENT, // Wait returned because waiting thread was interrupted @@ -175,7 +193,8 @@ Monitor() ; public: - Monitor(int rank, const char *name, bool allow_vm_block=false); + Monitor(int rank, const char *name, bool allow_vm_block = false, + SafepointCheckRequired safepoint_check_required = _safepoint_check_always); ~Monitor(); // Wait until monitor is notified (or times out). @@ -261,7 +280,8 @@ class Mutex : public Monitor { // degenerate Monitor public: - Mutex (int rank, const char *name, bool allow_vm_block=false); + Mutex(int rank, const char *name, bool allow_vm_block = false, + SafepointCheckRequired safepoint_check_required = _safepoint_check_always); ~Mutex () ; private: bool notify () { ShouldNotReachHere(); return false; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/mutexLocker.cpp --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -167,131 +167,133 @@ } #endif -#define def(var, type, pri, vm_block) { \ - var = new type(Mutex::pri, #var, vm_block); \ - assert(_num_mutex < MAX_NUM_MUTEX, \ - "increase MAX_NUM_MUTEX"); \ - _mutex_array[_num_mutex++] = var; \ +#define def(var, type, pri, vm_block, safepoint_check_allowed ) { \ + var = new type(Mutex::pri, #var, vm_block, safepoint_check_allowed); \ + assert(_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX"); \ + _mutex_array[_num_mutex] = var; \ } void mutex_init() { - def(tty_lock , Mutex , event, true ); // allow to lock in VM + def(tty_lock , Mutex , event, true, Monitor::_safepoint_check_never); // allow to lock in VM - def(CGC_lock , Monitor, special, true ); // coordinate between fore- and background GC - def(STS_lock , Monitor, leaf, true ); + def(CGC_lock , Monitor, special, true, Monitor::_safepoint_check_never); // coordinate between fore- and background GC + def(STS_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); + if (UseConcMarkSweepGC || UseG1GC) { - def(FullGCCount_lock , Monitor, leaf, true ); // in support of ExplicitGCInvokesConcurrent + def(FullGCCount_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); // in support of ExplicitGCInvokesConcurrent } if (UseG1GC) { - def(CMark_lock , Monitor, nonleaf, true ); // coordinate concurrent mark thread - def(CMRegionStack_lock , Mutex, leaf, true ); - def(SATB_Q_FL_lock , Mutex , special, true ); - def(SATB_Q_CBL_mon , Monitor, nonleaf, true ); - def(Shared_SATB_Q_lock , Mutex, nonleaf, true ); - def(DirtyCardQ_FL_lock , Mutex , special, true ); - def(DirtyCardQ_CBL_mon , Monitor, nonleaf, true ); - def(Shared_DirtyCardQ_lock , Mutex, nonleaf, true ); + def(CMark_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_never); // coordinate concurrent mark thread + def(CMRegionStack_lock , Mutex, leaf, true, Monitor::_safepoint_check_never); + def(SATB_Q_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never); + def(SATB_Q_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never); + def(Shared_SATB_Q_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never); + + def(DirtyCardQ_FL_lock , Mutex , special, true, Monitor::_safepoint_check_never); + def(DirtyCardQ_CBL_mon , Monitor, nonleaf, true, Monitor::_safepoint_check_never); + def(Shared_DirtyCardQ_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never); - def(FreeList_lock , Mutex, leaf , true ); - def(SecondaryFreeList_lock , Monitor, leaf , true ); - def(OldSets_lock , Mutex , leaf , true ); - def(RootRegionScan_lock , Monitor, leaf , true ); - def(MMUTracker_lock , Mutex , leaf , true ); - def(HotCardCache_lock , Mutex , special , true ); - def(EvacFailureStack_lock , Mutex , nonleaf , true ); + def(FreeList_lock , Mutex, leaf , true, Monitor::_safepoint_check_never); + def(SecondaryFreeList_lock , Monitor, leaf , true, Monitor::_safepoint_check_never); + def(OldSets_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); + def(RootRegionScan_lock , Monitor, leaf , true, Monitor::_safepoint_check_never); + def(MMUTracker_lock , Mutex , leaf , true, Monitor::_safepoint_check_never); + def(HotCardCache_lock , Mutex , special , true, Monitor::_safepoint_check_never); + def(EvacFailureStack_lock , Mutex , nonleaf , true, Monitor::_safepoint_check_never); - def(StringDedupQueue_lock , Monitor, leaf, true ); - def(StringDedupTable_lock , Mutex , leaf, true ); + def(StringDedupQueue_lock , Monitor, leaf, true, Monitor::_safepoint_check_never); + def(StringDedupTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); } - def(ParGCRareEvent_lock , Mutex , leaf , true ); - def(DerivedPointerTableGC_lock , Mutex, leaf, true ); - def(CodeCache_lock , Monitor, special, true ); - def(Interrupt_lock , Monitor, special, true ); // used for interrupt processing - def(RawMonitor_lock , Mutex, special, true ); - def(OopMapCacheAlloc_lock , Mutex, leaf, true ); // used for oop_map_cache allocation. + def(ParGCRareEvent_lock , Mutex , leaf , true, Monitor::_safepoint_check_sometimes); + def(DerivedPointerTableGC_lock , Mutex, leaf, true, Monitor::_safepoint_check_never); + def(CodeCache_lock , Mutex , special, true, Monitor::_safepoint_check_never); + def(Interrupt_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for interrupt processing + def(RawMonitor_lock , Mutex, special, true, Monitor::_safepoint_check_never); + def(OopMapCacheAlloc_lock , Mutex, leaf, true, Monitor::_safepoint_check_always); // used for oop_map_cache allocation. - def(Patching_lock , Mutex , special, true ); // used for safepointing and code patching. - def(ObjAllocPost_lock , Monitor, special, false); - def(Service_lock , Monitor, special, true ); // used for service thread operations - def(JmethodIdCreation_lock , Mutex , leaf, true ); // used for creating jmethodIDs. + def(Patching_lock , Mutex , special, true, Monitor::_safepoint_check_never); // used for safepointing and code patching. + def(ObjAllocPost_lock , Monitor, special, false, Monitor::_safepoint_check_never); + def(Service_lock , Monitor, special, true, Monitor::_safepoint_check_never); // used for service thread operations + def(JmethodIdCreation_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for creating jmethodIDs. - def(SystemDictionary_lock , Monitor, leaf, true ); // lookups done by VM thread - def(PackageTable_lock , Mutex , leaf, false); - def(InlineCacheBuffer_lock , Mutex , leaf, true ); - def(VMStatistic_lock , Mutex , leaf, false); - def(ExpandHeap_lock , Mutex , leaf, true ); // Used during compilation by VM thread - def(JNIHandleBlockFreeList_lock , Mutex , leaf, true ); // handles are used by VM thread - def(SignatureHandlerLibrary_lock , Mutex , leaf, false); - def(SymbolTable_lock , Mutex , leaf+2, true ); - def(StringTable_lock , Mutex , leaf, true ); - def(ProfilePrint_lock , Mutex , leaf, false); // serial profile printing - def(ExceptionCache_lock , Mutex , leaf, false); // serial profile printing - def(OsrList_lock , Mutex , leaf, true ); - def(Debug1_lock , Mutex , leaf, true ); + def(SystemDictionary_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); // lookups done by VM thread + def(PackageTable_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); + def(InlineCacheBuffer_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); + def(VMStatistic_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); + def(ExpandHeap_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // Used during compilation by VM thread + def(JNIHandleBlockFreeList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); // handles are used by VM thread + def(SignatureHandlerLibrary_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); + def(SymbolTable_lock , Mutex , leaf+2, true, Monitor::_safepoint_check_always); + def(StringTable_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); + def(ProfilePrint_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing + def(ExceptionCache_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing + def(OsrList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); + def(Debug1_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); #ifndef PRODUCT - def(FullGCALot_lock , Mutex , leaf, false); // a lock to make FullGCALot MT safe + def(FullGCALot_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe #endif - def(BeforeExit_lock , Monitor, leaf, true ); - def(PerfDataMemAlloc_lock , Mutex , leaf, true ); // used for allocating PerfData memory for performance data - def(PerfDataManager_lock , Mutex , leaf, true ); // used for synchronized access to PerfDataManager resources + def(BeforeExit_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); + def(PerfDataMemAlloc_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for allocating PerfData memory for performance data + def(PerfDataManager_lock , Mutex , leaf, true, Monitor::_safepoint_check_always); // used for synchronized access to PerfDataManager resources // CMS_modUnionTable_lock leaf - // CMS_bitMap_lock leaf + 1 - // CMS_freeList_lock leaf + 2 + // CMS_bitMap_lock leaf 1 + // CMS_freeList_lock leaf 2 - def(Safepoint_lock , Monitor, safepoint, true ); // locks SnippetCache_lock/Threads_lock + def(Safepoint_lock , Monitor, safepoint, true, Monitor::_safepoint_check_sometimes); // locks SnippetCache_lock/Threads_lock - def(Threads_lock , Monitor, barrier, true ); + def(Threads_lock , Monitor, barrier, true, Monitor::_safepoint_check_sometimes); - def(VMOperationQueue_lock , Monitor, nonleaf, true ); // VM_thread allowed to block on these - def(VMOperationRequest_lock , Monitor, nonleaf, true ); - def(RetData_lock , Mutex , nonleaf, false); - def(Terminator_lock , Monitor, nonleaf, true ); - def(VtableStubs_lock , Mutex , nonleaf, true ); - def(Notify_lock , Monitor, nonleaf, true ); - def(JNIGlobalHandle_lock , Mutex , nonleaf, true ); // locks JNIHandleBlockFreeList_lock - def(JNICritical_lock , Monitor, nonleaf, true ); // used for JNI critical regions - def(AdapterHandlerLibrary_lock , Mutex , nonleaf, true); + def(VMOperationQueue_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); // VM_thread allowed to block on these + def(VMOperationRequest_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); + def(RetData_lock , Mutex , nonleaf, false, Monitor::_safepoint_check_always); + def(Terminator_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_sometimes); + def(VtableStubs_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); + def(Notify_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_always); + def(JNIGlobalHandle_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); // locks JNIHandleBlockFreeList_lock + def(JNICritical_lock , Monitor, nonleaf, true, Monitor::_safepoint_check_always); // used for JNI critical regions + def(AdapterHandlerLibrary_lock , Mutex , nonleaf, true, Monitor::_safepoint_check_always); if (UseConcMarkSweepGC) { - def(SLT_lock , Monitor, nonleaf, false ); - // used in CMS GC for locking PLL lock + def(SLT_lock , Monitor, nonleaf, false, Monitor::_safepoint_check_never); // used in CMS GC for locking PLL lock } - def(Heap_lock , Monitor, nonleaf+1, false); - def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation - def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable + + def(Heap_lock , Monitor, nonleaf+1, false, Monitor::_safepoint_check_sometimes); + def(JfieldIdCreation_lock , Mutex , nonleaf+1, true, Monitor::_safepoint_check_always); // jfieldID, Used in VM_Operation + def(MemberNameTable_lock , Mutex , nonleaf+1, false, Monitor::_safepoint_check_always); // Used to protect MemberNameTable - def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock - def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true ); - def(CompileStatistics_lock , Mutex , nonleaf+2, false); - def(MultiArray_lock , Mutex , nonleaf+2, false); // locks SymbolTable_lock + def(CompiledIC_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks VtableStubs_lock, InlineCacheBuffer_lock + def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true, Monitor::_safepoint_check_always); + def(CompileStatistics_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); + def(MultiArray_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // locks SymbolTable_lock - def(JvmtiThreadState_lock , Mutex , nonleaf+2, false); // Used by JvmtiThreadState/JvmtiEventController - def(JvmtiPendingEvent_lock , Monitor, nonleaf, false); // Used by JvmtiCodeBlobEvents - def(Management_lock , Mutex , nonleaf+2, false); // used for JVM management + def(JvmtiThreadState_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // Used by JvmtiThreadState/JvmtiEventController + def(JvmtiPendingEvent_lock , Monitor, nonleaf, false, Monitor::_safepoint_check_never); // Used by JvmtiCodeBlobEvents + def(Management_lock , Mutex , nonleaf+2, false, Monitor::_safepoint_check_always); // used for JVM management - def(Compile_lock , Mutex , nonleaf+3, true ); - def(MethodData_lock , Mutex , nonleaf+3, false); + def(Compile_lock , Mutex , nonleaf+3, true, Monitor::_safepoint_check_sometimes); + def(MethodData_lock , Mutex , nonleaf+3, false, Monitor::_safepoint_check_always); - def(MethodCompileQueue_lock , Monitor, nonleaf+4, true ); - def(Debug2_lock , Mutex , nonleaf+4, true ); - def(Debug3_lock , Mutex , nonleaf+4, true ); - def(ProfileVM_lock , Monitor, special, false); // used for profiling of the VMThread - def(CompileThread_lock , Monitor, nonleaf+5, false ); - def(PeriodicTask_lock , Monitor, nonleaf+5, true); + def(MethodCompileQueue_lock , Monitor, nonleaf+4, true, Monitor::_safepoint_check_always); + def(Debug2_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never); + def(Debug3_lock , Mutex , nonleaf+4, true, Monitor::_safepoint_check_never); + def(ProfileVM_lock , Monitor, special, false, Monitor::_safepoint_check_never); // used for profiling of the VMThread + def(CompileThread_lock , Monitor, nonleaf+5, false, Monitor::_safepoint_check_always); + def(PeriodicTask_lock , Monitor, nonleaf+5, true, Monitor::_safepoint_check_sometimes); if (WhiteBoxAPI) { - def(Compilation_lock , Monitor, leaf, false ); + def(Compilation_lock , Monitor, leaf, false, Monitor::_safepoint_check_never); } + #ifdef INCLUDE_TRACE - def(JfrMsg_lock , Monitor, leaf, true); - def(JfrBuffer_lock , Mutex, leaf, true); - def(JfrThreadGroups_lock , Mutex, leaf, true); - def(JfrStream_lock , Mutex, nonleaf, true); - def(JfrStacktrace_lock , Mutex, special, true); + def(JfrMsg_lock , Monitor, leaf, true, Monitor::_safepoint_check_always); + def(JfrBuffer_lock , Mutex, leaf, true, Monitor::_safepoint_check_never); + def(JfrThreadGroups_lock , Mutex, leaf, true, Monitor::_safepoint_check_always); + def(JfrStream_lock , Mutex, nonleaf, true, Monitor::_safepoint_check_never); + def(JfrStacktrace_lock , Mutex, special, true, Monitor::_safepoint_check_sometimes); #endif #ifndef SUPPORTS_NATIVE_CX8 - def(UnsafeJlong_lock , Mutex, special, false); + def(UnsafeJlong_lock , Mutex, special, false, Monitor::_safepoint_check_never); #endif } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/os.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1588,6 +1588,11 @@ return res; } +void os::pretouch_memory(char* start, char* end) { + for (volatile char *p = start; p < end; p += os::vm_page_size()) { + *p = 0; + } +} char* os::map_memory(int fd, const char* file_name, size_t file_offset, char *addr, size_t bytes, bool read_only, diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/os.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -311,6 +311,12 @@ static bool uncommit_memory(char* addr, size_t bytes); static bool release_memory(char* addr, size_t bytes); + // Touch memory pages that cover the memory range from start to end (exclusive) + // to make the OS back the memory range with actual memory. + // Current implementation may not touch the last page if unaligned addresses + // are passed. + static void pretouch_memory(char* start, char* end); + enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX }; static bool protect_memory(char* addr, size_t bytes, ProtType prot, bool is_committed = true); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/sharedRuntime.cpp --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -456,6 +456,7 @@ address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { assert(frame::verify_return_pc(return_address), err_msg("must be a return address: " INTPTR_FORMAT, return_address)); + assert(thread->frames_to_pop_failed_realloc() == 0 || Interpreter::contains(return_address), "missed frames to pop?"); // Reset method handle flag. thread->set_is_method_handle_return(false); diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/sweeper.cpp --- a/hotspot/src/share/vm/runtime/sweeper.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/sweeper.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -158,7 +158,7 @@ Tickspan NMethodSweeper::_peak_sweep_time; // Peak time for a full sweep Tickspan NMethodSweeper::_peak_sweep_fraction_time; // Peak time sweeping one fraction -Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true); +Monitor* NMethodSweeper::_stat_lock = new Monitor(Mutex::special, "Sweeper::Statistics", true, Monitor::_safepoint_check_sometimes); class MarkActivationClosure: public CodeBlobClosure { public: diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/thread.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -230,7 +230,8 @@ _visited_for_critical_count = false; #endif - _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true); + _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true, + Monitor::_safepoint_check_sometimes); _suspend_flags = 0; // thread-specific hashCode stream generator state - Marsaglia shift-xor form @@ -1448,6 +1449,7 @@ _popframe_condition = popframe_inactive; _popframe_preserved_args = NULL; _popframe_preserved_args_size = 0; + _frames_to_pop_failed_realloc = 0; pd_initialize(); } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/thread.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -908,6 +908,12 @@ // This is set to popframe_pending to signal that top Java frame should be popped immediately int _popframe_condition; + // If reallocation of scalar replaced objects fails, we throw OOM + // and during exception propagation, pop the top + // _frames_to_pop_failed_realloc frames, the ones that reference + // failed reallocations. + int _frames_to_pop_failed_realloc; + #ifndef PRODUCT int _jmp_ring_index; struct { @@ -1567,6 +1573,10 @@ void clr_pop_frame_in_process(void) { _popframe_condition &= ~popframe_processing_bit; } #endif + int frames_to_pop_failed_realloc() const { return _frames_to_pop_failed_realloc; } + void set_frames_to_pop_failed_realloc(int nb) { _frames_to_pop_failed_realloc = nb; } + void dec_frames_to_pop_failed_realloc() { _frames_to_pop_failed_realloc--; } + private: // Saved incoming arguments to popped frame. // Used only when popped interpreted frame returns to deoptimized frame. diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/vframeArray.cpp --- a/hotspot/src/share/vm/runtime/vframeArray.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/vframeArray.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -57,7 +57,7 @@ } } -void vframeArrayElement::fill_in(compiledVFrame* vf) { +void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) { // Copy the information from the compiled vframe to the // interpreter frame we will be creating to replace vf @@ -65,6 +65,9 @@ _method = vf->method(); _bci = vf->raw_bci(); _reexecute = vf->should_reexecute(); +#ifdef ASSERT + _removed_monitors = false; +#endif int index; @@ -82,11 +85,15 @@ // Migrate the BasicLocks from the stack to the monitor chunk for (index = 0; index < list->length(); index++) { MonitorInfo* monitor = list->at(index); - assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already"); - assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased"); + assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already"); BasicObjectLock* dest = _monitors->at(index); - dest->set_obj(monitor->owner()); - monitor->lock()->move_to(monitor->owner(), dest->lock()); + if (monitor->owner_is_scalar_replaced()) { + dest->set_obj(NULL); + } else { + assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased"); + dest->set_obj(monitor->owner()); + monitor->lock()->move_to(monitor->owner(), dest->lock()); + } } } @@ -111,7 +118,7 @@ StackValue* value = locs->at(index); switch(value->type()) { case T_OBJECT: - assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); + assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already"); // preserve object type _locals->add( new StackValue(cast_from_oop((value->get_obj()())), T_OBJECT )); break; @@ -136,7 +143,7 @@ StackValue* value = exprs->at(index); switch(value->type()) { case T_OBJECT: - assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); + assert(!value->obj_is_scalar_replaced() || realloc_failures, "object should be reallocated already"); // preserve object type _expressions->add( new StackValue(cast_from_oop((value->get_obj()())), T_OBJECT )); break; @@ -287,7 +294,7 @@ _frame.patch_pc(thread, pc); - assert (!method()->is_synchronized() || locks > 0, "synchronized methods must have monitors"); + assert (!method()->is_synchronized() || locks > 0 || _removed_monitors, "synchronized methods must have monitors"); BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin(); for (int index = 0; index < locks; index++) { @@ -439,7 +446,8 @@ vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray* chunk, - RegisterMap *reg_map, frame sender, frame caller, frame self) { + RegisterMap *reg_map, frame sender, frame caller, frame self, + bool realloc_failures) { // Allocate the vframeArray vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part @@ -451,19 +459,20 @@ result->_caller = caller; result->_original = self; result->set_unroll_block(NULL); // initialize it - result->fill_in(thread, frame_size, chunk, reg_map); + result->fill_in(thread, frame_size, chunk, reg_map, realloc_failures); return result; } void vframeArray::fill_in(JavaThread* thread, int frame_size, GrowableArray* chunk, - const RegisterMap *reg_map) { + const RegisterMap *reg_map, + bool realloc_failures) { // Set owner first, it is used when adding monitor chunks _frame_size = frame_size; for(int i = 0; i < chunk->length(); i++) { - element(i)->fill_in(chunk->at(i)); + element(i)->fill_in(chunk->at(i), realloc_failures); } // Copy registers for callee-saved registers diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/vframeArray.hpp --- a/hotspot/src/share/vm/runtime/vframeArray.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/vframeArray.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -58,6 +58,9 @@ MonitorChunk* _monitors; // active monitors for this vframe StackValueCollection* _locals; StackValueCollection* _expressions; +#ifdef ASSERT + bool _removed_monitors; +#endif public: @@ -78,7 +81,7 @@ StackValueCollection* expressions(void) const { return _expressions; } - void fill_in(compiledVFrame* vf); + void fill_in(compiledVFrame* vf, bool realloc_failures); // Formerly part of deoptimizedVFrame @@ -99,6 +102,12 @@ bool is_bottom_frame, int exec_mode); +#ifdef ASSERT + void set_removed_monitors() { + _removed_monitors = true; + } +#endif + #ifndef PRODUCT void print(outputStream* st); #endif /* PRODUCT */ @@ -160,13 +169,14 @@ int frames() const { return _frames; } static vframeArray* allocate(JavaThread* thread, int frame_size, GrowableArray* chunk, - RegisterMap* reg_map, frame sender, frame caller, frame self); + RegisterMap* reg_map, frame sender, frame caller, frame self, + bool realloc_failures); vframeArrayElement* element(int index) { assert(is_within_bounds(index), "Bad index"); return &_elements[index]; } // Allocates a new vframe in the array and fills the array with vframe information in chunk - void fill_in(JavaThread* thread, int frame_size, GrowableArray* chunk, const RegisterMap *reg_map); + void fill_in(JavaThread* thread, int frame_size, GrowableArray* chunk, const RegisterMap *reg_map, bool realloc_failures); // Returns the owner of this vframeArray JavaThread* owner_thread() const { return _owner_thread; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/virtualspace.cpp --- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -615,19 +615,7 @@ } if (pre_touch || AlwaysPreTouch) { - int vm_ps = os::vm_page_size(); - for (char* curr = previous_high; - curr < unaligned_new_high; - curr += vm_ps) { - // Note the use of a write here; originally we tried just a read, but - // since the value read was unused, the optimizer removed the read. - // If we ever have a concurrent touchahead thread, we'll want to use - // a read, to avoid the potential of overwriting data (if a mutator - // thread beats the touchahead thread to a page). There are various - // ways of making sure this read is not optimized away: for example, - // generating the code for a read procedure at runtime. - *curr = 0; - } + os::pretouch_memory(previous_high, unaligned_new_high); } _high += bytes; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/vmStructs.cpp --- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -556,9 +556,6 @@ \ nonstatic_field(TenuredGeneration, _min_heap_delta_bytes, size_t) \ nonstatic_field(TenuredGeneration, _the_space, ContiguousSpace*) \ - nonstatic_field(TenuredGeneration, _last_gc, WaterMark) \ - \ - \ \ nonstatic_field(Space, _bottom, HeapWord*) \ nonstatic_field(Space, _end, HeapWord*) \ diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/vmThread.cpp --- a/hotspot/src/share/vm/runtime/vmThread.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/vmThread.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -214,7 +214,8 @@ _vm_queue = new VMOperationQueue(); guarantee(_vm_queue != NULL, "just checking"); - _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true); + _terminate_lock = new Monitor(Mutex::safepoint, "VMThread::_terminate_lock", true, + Monitor::_safepoint_check_never); if (UsePerfData) { // jvmstat performance counters diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/runtime/vm_operations.cpp --- a/hotspot/src/share/vm/runtime/vm_operations.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/runtime/vm_operations.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -391,7 +391,8 @@ assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint already"); Thread * thr_cur = ThreadLocalStorage::get_thread_slow(); - Monitor timer(Mutex::leaf, "VM_Exit timer", true); + Monitor timer(Mutex::leaf, "VM_Exit timer", true, + Monitor::_safepoint_check_never); // Compiler threads need longer wait because they can access VM data directly // while in native. If they are active and some structures being used are diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/services/diagnosticFramework.cpp --- a/hotspot/src/share/vm/services/diagnosticFramework.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -487,7 +487,7 @@ } } -Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); +Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true, Monitor::_safepoint_check_never); bool DCmdFactory::_send_jmx_notification = false; DCmdFactory* DCmdFactory::factory(DCmdSource source, const char* name, size_t len) { diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/services/memoryManager.cpp --- a/hotspot/src/share/vm/services/memoryManager.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/services/memoryManager.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -198,7 +198,8 @@ GCMemoryManager::GCMemoryManager() : MemoryManager() { _num_collections = 0; _last_gc_stat = NULL; - _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true); + _last_gc_lock = new Mutex(Mutex::leaf, "_last_gc_lock", true, + Monitor::_safepoint_check_never); _current_gc_stat = NULL; _num_gc_threads = 1; _notification_enabled = false; diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/trace/trace.xml --- a/hotspot/src/share/vm/trace/trace.xml Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/trace/trace.xml Sat Jan 10 12:38:18 2015 -0800 @@ -314,6 +314,28 @@ + + + + + + + + + + + + + + + + + + diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/utilities/decoder.cpp --- a/hotspot/src/share/vm/utilities/decoder.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/utilities/decoder.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,9 @@ AbstractDecoder* Decoder::_error_handler_decoder = NULL; NullDecoder Decoder::_do_nothing_decoder; Mutex* Decoder::_shared_decoder_lock = new Mutex(Mutex::native, - "SharedDecoderLock"); + "SharedDecoderLock", + false, + Monitor::_safepoint_check_never); AbstractDecoder* Decoder::get_shared_instance() { assert(_shared_decoder_lock != NULL && _shared_decoder_lock->owned_by_self(), diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/utilities/events.hpp --- a/hotspot/src/share/vm/utilities/events.hpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/utilities/events.hpp Sat Jan 10 12:38:18 2015 -0800 @@ -90,7 +90,7 @@ _length(length), _count(0), _index(0), - _mutex(Mutex::event, name) { + _mutex(Mutex::event, name, false, Monitor::_safepoint_check_never) { _records = new EventRecord[length]; } diff -r ad8137d44154 -r 247f60f5808f hotspot/src/share/vm/utilities/workgroup.cpp --- a/hotspot/src/share/vm/utilities/workgroup.cpp Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/src/share/vm/utilities/workgroup.cpp Sat Jan 10 12:38:18 2015 -0800 @@ -46,7 +46,8 @@ // Other initialization. _monitor = new Monitor(/* priority */ Mutex::leaf, /* name */ "WorkGroup monitor", - /* allow_vm_block */ are_GC_task_threads); + /* allow_vm_block */ are_GC_task_threads, + Monitor::_safepoint_check_sometimes); assert(monitor() != NULL, "Failed to allocate monitor"); _terminate = false; _task = NULL; @@ -378,12 +379,13 @@ // *** WorkGangBarrierSync WorkGangBarrierSync::WorkGangBarrierSync() - : _monitor(Mutex::safepoint, "work gang barrier sync", true), + : _monitor(Mutex::safepoint, "work gang barrier sync", true, + Monitor::_safepoint_check_never), _n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) { } WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name) - : _monitor(Mutex::safepoint, name, true), + : _monitor(Mutex::safepoint, name, true, Monitor::_safepoint_check_never), _n_workers(n_workers), _n_completed(0), _should_reset(false), _aborted(false) { } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/Makefile --- a/hotspot/test/Makefile Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/Makefile Sat Jan 10 12:38:18 2015 -0800 @@ -275,6 +275,9 @@ # Ignore tests are not run and completely silent about it JTREG_IGNORE_OPTION = -ignore:quiet JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION) +# Multiply by 4 the timeout factor +JTREG_TIMEOUT_OPTION = -timeoutFactor:4 +JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION) # Add any extra options JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS) # Set other vm and test options diff -r ad8137d44154 -r 247f60f5808f hotspot/test/TEST.groups --- a/hotspot/test/TEST.groups Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/TEST.groups Sat Jan 10 12:38:18 2015 -0800 @@ -50,6 +50,9 @@ # runs those tests that only require compact1 and compact2 API's. # +hotspot_all = \ + / + # Full JDK can run all tests # jdk = \ @@ -202,7 +205,6 @@ compact1_minimal = \ serviceability/ \ compiler/ \ - testlibrary_tests/ \ sanity/ \ runtime/ \ gc/ \ @@ -407,7 +409,9 @@ -closed/compiler/loopopts/8021898 hotspot_gc = \ - sanity/ExecuteInternalVMTests.java + sanity/ExecuteInternalVMTests.java \ + gc/ \ + -gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java hotspot_runtime = \ runtime/ \ @@ -426,19 +430,22 @@ -runtime/7158988/FieldMonitor.java hotspot_runtime_closed = \ - sanity/ExecuteInternalVMTests.java + sanity/ExecuteInternalVMTests.java \ + testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java hotspot_serviceability = \ sanity/ExecuteInternalVMTests.java \ serviceability/dcmd/compiler -hotspot_all = \ +hotspot_jprt = \ + :hotspot_wbapitest \ :hotspot_compiler_1 \ :hotspot_compiler_2 \ :hotspot_compiler_3 \ :hotspot_compiler_closed \ :hotspot_gc \ :hotspot_runtime \ + :hotspot_runtime_closed \ :hotspot_serviceability #All tests that depends on nashorn extension. diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/BMISupportedCPUTest.java --- a/hotspot/test/compiler/arguments/BMISupportedCPUTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/BMISupportedCPUTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -60,8 +60,11 @@ VM will be launched with following flags: -XX:+ -version */ + String errorString = String.format("JVM should start with '-XX:+%s'" + + " flag without any warnings", optionName); CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { warningMessage }, ExitCode.OK, + new String[] { warningMessage }, errorString, errorString, + ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); /* @@ -69,8 +72,11 @@ VM will be launched with following flags: -XX:- -version */ + errorString = String.format("JVM should start with '-XX:-%s'" + + " flag without any warnings", optionName); CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { warningMessage }, ExitCode.OK, + new String[] { warningMessage }, errorString, + errorString, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, false)); /* @@ -78,7 +84,9 @@ VM will be launched with following flags: -version */ - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true"); + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + String.format("Option '%s' is expected to have default value " + + "'true'", optionName)); /* Verify that option could be explicitly turned off. @@ -86,6 +94,8 @@ -XX:- -version */ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' is set to have value 'false'", + optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java --- a/hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/BMIUnsupportedCPUTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -75,9 +75,13 @@ warning. VM will be launched with following options: -XX:+ -version */ + String errorString = String.format("JVM should start with '-XX:+%s' " + + "flag, but output should contain warning.", optionName); CommandLineOptionTest.verifySameJVMStartup( new String[] { warningMessage }, new String[] { errorMessage }, - ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag( + errorString, String.format("Option '%s' is unsupported.%n" + + "Warning expected to be shown.", optionName), ExitCode.OK, + CommandLineOptionTest.prepareBooleanFlag( optionName, true)); /* @@ -85,15 +89,21 @@ VM will be launched with following options: -XX:- -version */ + errorString = String.format("JVM should start with '-XX:-%s' flag " + + "without any warnings", optionName); CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { warningMessage, errorMessage }, ExitCode.OK, + new String[] { warningMessage, errorMessage }, + errorString, errorString, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, false)); /* - Verify that on unsupported CPUs option is off by default. - VM will be launched with following options: -version - */ - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false"); + * Verify that on unsupported CPUs option is off by default. VM will be + * launched with following options: -version + */ + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' is expected to have default value " + + "'false' since feature required is not supported " + + "on CPU", optionName)); /* Verify that on unsupported CPUs option will be off even if @@ -101,6 +111,9 @@ following options: -XX:+ -version */ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' is expected to have default value" + + " 'false' since feature required is not supported on" + + " CPU even if user set another value.", optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, true)); } @@ -118,11 +131,17 @@ with following options: -XX:[+-] -version */ CommandLineOptionTest.verifySameJVMStartup( - new String[] { errorMessage }, null, ExitCode.FAIL, + new String[] { errorMessage }, null, + String.format("JVM startup should fail with '-XX:+%s' flag." + + "%nOption should be unknown (non-X86CPU).", + optionName), "", ExitCode.FAIL, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); CommandLineOptionTest.verifySameJVMStartup( - new String[] { errorMessage }, null, ExitCode.FAIL, + new String[] { errorMessage }, null, + String.format("JVM startup should fail with '-XX:-%s' flag." + + "%nOption should be unknown (non-X86CPU)", + optionName), "", ExitCode.FAIL, CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java --- a/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/CheckCompileThresholdScaling.java Sat Jan 10 12:38:18 2015 -0800 @@ -330,7 +330,7 @@ } catch (RuntimeException e) { // Check if tiered compilation is available in this JVM // Version. Throw exception only if it is available. - if (!(tiered && out.getOutput().contains("Client VM warning: TieredCompilation is disabled in this release."))) { + if (!(tiered && out.getOutput().contains("TieredCompilation is disabled in this release."))) { throw new RuntimeException(e); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java --- a/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031321 * @summary Verify processing of UseBMI1Instructions option on CPU with * BMI1 feature support. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseBMI1InstructionsOnSupportedCPU * BMISupportedCPUTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java --- a/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/TestUseBMI1InstructionsOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031321 * @summary Verify processing of UseBMI1Instructions option on CPU without * BMI1 feature support. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseBMI1InstructionsOnUnsupportedCPU * BMIUnsupportedCPUTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java --- a/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031321 * @summary Verify processing of UseCountLeadingZerosInstruction option * on CPU with LZCNT support. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseCountLeadingZerosInstructionOnSupportedCPU * BMISupportedCPUTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java --- a/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/TestUseCountLeadingZerosInstructionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031321 * @summary Verify processing of UseCountLeadingZerosInstruction option * on CPU without LZCNT support. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseCountLeadingZerosInstructionOnUnsupportedCPU * BMIUnsupportedCPUTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java --- a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031321 * @summary Verify processing of UseCountTrailingZerosInstruction option * on CPU with TZCNT (BMI1 feature) support. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseCountTrailingZerosInstructionOnSupportedCPU * BMISupportedCPUTest * @run main ClassFileInstaller sun.hotspot.WhiteBox @@ -59,6 +59,9 @@ -XX:-UseBMI1Instructions -version */ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + "Option 'UseCountTrailingZerosInstruction' should have " + + "'false' value if all BMI1 instructions are explicitly" + + " disabled (-XX:-UseBMI1Instructions flag used)", TestUseCountTrailingZerosInstructionOnSupportedCPU.DISABLE_BMI); /* @@ -68,6 +71,9 @@ -XX:+UseCountTrailingZerosInstruction -version */ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + "Option 'UseCountTrailingZerosInstruction' should be able to " + + "be turned on even if all BMI1 instructions are " + + "disabled (-XX:-UseBMI1Instructions flag used)", TestUseCountTrailingZerosInstructionOnSupportedCPU.DISABLE_BMI, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java --- a/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/arguments/TestUseCountTrailingZerosInstructionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031321 * @summary Verify processing of UseCountTrailingZerosInstruction option * on CPU without TZCNT instruction (BMI1 feature) support. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseCountTrailingZerosInstructionOnUnsupportedCPU * BMIUnsupportedCPUTest * @run main ClassFileInstaller sun.hotspot.WhiteBox @@ -59,6 +59,9 @@ -XX:+UseBMI1Instructions -version */ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + "Feature bmi1 is not supported on current CPU. Option " + + "UseCountTrailingZerosInstruction should have 'false'" + + " value", TestUseCountTrailingZerosInstructionOnUnsupportedCPU. ENABLE_BMI); @@ -68,6 +71,9 @@ -version */ CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + "Feature bmi1 is not supported on current CPU. Option " + + "UseCountTrailingZerosInstruction should have 'false'" + + " value", CommandLineOptionTest.prepareBooleanFlag(optionName, true), TestUseCountTrailingZerosInstructionOnUnsupportedCPU. ENABLE_BMI); diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/c2/6589834/Test_ia32.java --- a/hotspot/test/compiler/c2/6589834/Test_ia32.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/c2/6589834/Test_ia32.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 6589834 * @summary Safepoint placed between stack pointer increment and decrement leads * to interpreter's stack corruption after deoptimization. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ClassFileInstaller sun.hotspot.WhiteBox com.oracle.java.testlibrary.* * Test_ia32 InlinedArrayCloneTestCase * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java --- a/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/classUnloading/anonymousClass/TestAnonymousClassUnloading.java Sat Jan 10 12:38:18 2015 -0800 @@ -33,7 +33,7 @@ * @test TestAnonymousClassUnloading * @bug 8054402 * @summary "Tests unloading of anonymous classes." - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @compile TestAnonymousClassUnloading.java * @run main ClassFileInstaller TestAnonymousClassUnloading * sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java --- a/hotspot/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/classUnloading/methodUnloading/TestMethodUnloading.java Sat Jan 10 12:38:18 2015 -0800 @@ -31,7 +31,7 @@ * @test MethodUnloadingTest * @bug 8029443 * @summary "Tests the unloading of methods to to class unloading" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestMethodUnloading * @build WorkerClass * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java --- a/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/codecache/CheckSegmentedCodeCache.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ /* * @test CheckSegmentedCodeCache * @bug 8015774 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @summary "Checks VM options related to the segmented code cache" * @build CheckSegmentedCodeCache * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/codecache/OverflowCodeCacheTest.java --- a/hotspot/test/compiler/codecache/OverflowCodeCacheTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/codecache/OverflowCodeCacheTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -34,7 +34,7 @@ /* * @test OverflowCodeCacheTest * @bug 8059550 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build OverflowCodeCacheTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java --- a/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/dependencies/MonomorphicObjectCall/TestMonomorphicObjectCall.java Sat Jan 10 12:38:18 2015 -0800 @@ -61,6 +61,7 @@ String[] vmOpts = new String[] { "-Xbootclasspath/p:" + testClasses, "-Xcomp", + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-VerifyDependencies", "-XX:CompileOnly=TestMonomorphicObjectCall::callFinalize", "-XX:CompileOnly=Object::finalizeObject", diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/exceptions/SumTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/exceptions/SumTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8066900 + * @summary FP registers are not properly restored by C1 when handling exceptions + * @run main/othervm -Xbatch SumTest + * + */ +public class SumTest { + private static class Sum { + + double[] sums; + + /** + * Construct empty Sum + */ + public Sum() { + sums = new double[0]; + } + + /** + * Return the sum of all numbers added to this Sum + * + * @return the sum + */ + final public double getSum() { + double sum = 0; + for (final double s : sums) { + sum += s; + } + + return sum; + } + + /** + * Add a new number to this Sum + * + * @param a number to be added. + */ + final public void add(double a) { + try { + sums[sums.length] = -1; // Cause IndexOutOfBoundsException + } catch (final IndexOutOfBoundsException e) { + final double[] oldSums = sums; + sums = new double[oldSums.length + 1]; // Extend sums + System.arraycopy(oldSums, 0, sums, 0, oldSums.length); + sums[oldSums.length] = a; // Append a + } + } + } + + public static void main(String[] args) throws Exception { + final Sum sum = new Sum(); + for (int i = 1; i <= 10000; ++i) { + sum.add(1); + double ii = sum.getSum(); + if (i != ii) { + throw new Exception("Failure: computed = " + ii + ", expected = " + i); + } + } + } + +} + diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestAndnI.java --- a/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnI.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of ANDN instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestAndnI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestAndnL.java --- a/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestAndnL.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of ANDN instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestAndnL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsiI.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of BLSI instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestBlsiI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsiL.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of BLSI instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestBlsiL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskI.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of BLSMSK instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestBlsmskI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsmskL.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of BLSMSK instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestBlsmskL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsrI.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of BLSR instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestBlsrI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java --- a/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestBlsrL.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of BLSR instruction - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestBlsrL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java --- a/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestLzcntI.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestLzcntI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java --- a/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestLzcntL.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestLzcntL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java --- a/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestTzcntI.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestTzcntI BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java --- a/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/TestTzcntL.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031321 * @summary Verify that results of computations are the same w/ * and w/o usage of intrinsic - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestTzcntL BMITestRunner Expr * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestI.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build AddnTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/AddnTestL.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build AddnTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestI.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build BlsiTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsiTestL.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build BlsiTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestI.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build BlsmskTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsmskTestL.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build BlsmskTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestI.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build BlsrTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/BlsrTestL.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build BlsrTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestI.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build LZcntTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/LZcntTestL.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build LZcntTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestI.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build TZcntTestI * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java --- a/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/bmi/verifycode/TZcntTestL.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8031321 - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox .. + * @library /testlibrary /../../test/lib /compiler/whitebox .. * @build TZcntTestL * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java --- a/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/classcast/NullCheckDroppingsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test NullCheckDroppingsTest * @bug 8054492 * @summary "Casting can result in redundant null checks in generated code" - * @library /testlibrary /testlibrary/whitebox /testlibrary/com/oracle/java/testlibrary + * @library /testlibrary /../../test/lib /testlibrary/com/oracle/java/testlibrary * @build NullCheckDroppingsTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactIntTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build AddExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/AddExactLongTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build AddExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactIntTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build DecrementExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/DecrementExactLongTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build DecrementExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactIntTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build IncrementExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/IncrementExactLongTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build IncrementExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactIntTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build MultiplyExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/MultiplyExactLongTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build MultiplyExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactIntTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build NegateExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/NegateExactLongTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build NegateExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactIntTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build SubtractExactIntTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java --- a/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/mathexact/sanity/SubtractExactLongTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * /compiler/testlibrary * @build SubtractExactLongTest * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA1Intrinsics option processing on supported CPU, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHA1IntrinsicsOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA1IntrinsicsOptionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA1Intrinsics option processing on unsupported CPU, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHA1IntrinsicsOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA256Intrinsics option processing on supported CPU, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHA256IntrinsicsOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA256IntrinsicsOptionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA256Intrinsics option processing on unsupported CPU, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHA256IntrinsicsOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA512Intrinsics option processing on supported CPU. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHA512IntrinsicsOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHA512IntrinsicsOptionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA512Intrinsics option processing on unsupported CPU, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHA512IntrinsicsOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnSupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA option processing on supported CPU, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHAOptionOnSupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/TestUseSHAOptionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify UseSHA option processing on unsupported CPU. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary testcases + * @library /testlibrary /../../test/lib /compiler/testlibrary testcases * @build TestUseSHAOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForOtherCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -41,30 +41,42 @@ @Override protected void verifyWarnings() throws Throwable { + String shouldPassMessage = String.format("JVM should start with " + + "option '%s' without any warnings", optionName); // Verify that on non-x86 and non-SPARC CPU usage of SHA-related // options will not cause any warnings. CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { ".*" + optionName + ".*" }, ExitCode.OK, + new String[] { ".*" + optionName + ".*" }, shouldPassMessage, + shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { ".*" + optionName + ".*" }, ExitCode.OK, + new String[] { ".*" + optionName + ".*" }, shouldPassMessage, + shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } @Override protected void verifyOptionValues() throws Throwable { // Verify that option is disabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false"); + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be disabled by default", + optionName)); // Verify that option is disabled even if it was explicitly enabled // using CLI options. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be off on unsupported " + + "CPU even if set to true directly", optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, true)); // Verify that option is disabled when it explicitly disabled // using CLI options. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be off on unsupported CPU" + + " even if '%s' flag set to JVM", optionName, + CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)), CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForSupportedSparcCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -39,17 +39,24 @@ @Override protected void verifyWarnings() throws Throwable { + + String shouldPassMessage = String.format("JVM should start with option" + + " '%s' without any warnings", optionName); // Verify that there are no warning when option is explicitly enabled. CommandLineOptionTest.verifySameJVMStartup(null, new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, ExitCode.OK, + }, shouldPassMessage, shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); // Verify that option could be disabled even if +UseSHA was passed to // JVM. CommandLineOptionTest.verifySameJVMStartup(null, new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, ExitCode.OK, + }, shouldPassMessage, String.format("It should be able to " + + "disable option '%s' even if %s was passed to JVM", + optionName, CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)), + ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true), CommandLineOptionTest.prepareBooleanFlag(optionName, false)); @@ -58,7 +65,11 @@ // all SHA intrinsics via -UseSHA without any warnings. CommandLineOptionTest.verifySameJVMStartup(null, new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, ExitCode.OK, + }, shouldPassMessage, String.format("It should be able to " + + "enable option '%s' even if %s was passed to JVM", + optionName, CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, false)), + ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, false), CommandLineOptionTest.prepareBooleanFlag(optionName, true)); @@ -66,19 +77,30 @@ @Override protected void verifyOptionValues() throws Throwable { - // Verify that on supported CPU option is enabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true"); + // Verify that "It should be able to disable option " + + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + String.format("Option '%s' should be enabled by default", + optionName)); // Verify that it is possible to explicitly enable the option. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + String.format("Option '%s' was set to have value 'true'", + optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, true)); // Verify that it is possible to explicitly disable the option. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' was set to have value 'false'", + optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, false)); // verify that option is disabled when -UseSHA was passed to JVM. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should have value 'false' when %s" + + " flag set to JVM", optionName, + CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, false)), CommandLineOptionTest.prepareBooleanFlag(optionName, true), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, false)); @@ -86,6 +108,10 @@ // Verify that it is possible to explicitly disable the tested option // even if +UseSHA was passed to JVM. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should have value 'false' if set so" + + " even if %s flag set to JVM", optionName, + CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true), CommandLineOptionTest.prepareBooleanFlag(optionName, false)); diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedSparcCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -41,25 +41,35 @@ @Override protected void verifyWarnings() throws Throwable { + String shouldPassMessage = String.format("JVM startup should pass with" + + "option '-XX:-%s' without any warnings", optionName); //Verify that option could be disabled without any warnings. CommandLineOptionTest.verifySameJVMStartup(null, new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, ExitCode.OK, + }, shouldPassMessage, shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } @Override protected void verifyOptionValues() throws Throwable { // Verify that option is disabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false"); + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be disabled by default", + optionName)); // Verify that option is disabled even if it was explicitly enabled // using CLI options. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be off on unsupported " + + "SparcCPU even if set to true directly", optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, true)); // Verify that option is disabled when +UseSHA was passed to JVM. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be off on unsupported " + + "SparcCPU even if %s flag set to JVM", + optionName, CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true)); } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/GenericTestCaseForUnsupportedX86CPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -38,33 +38,45 @@ @Override protected void verifyWarnings() throws Throwable { + String shouldPassMessage = String.format("JVM should start with '-XX:+" + + "%s' flag, but output should contain warning.", optionName); // Verify that when the tested option is explicitly enabled, then // a warning will occur in VM output. CommandLineOptionTest.verifySameJVMStartup(new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, null, ExitCode.OK, + }, null, shouldPassMessage, shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); + shouldPassMessage = String.format("JVM should start with '-XX:-%s' " + + "flag without any warnings", optionName); // Verify that the tested option could be explicitly disabled without // a warning. CommandLineOptionTest.verifySameJVMStartup(null, new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, ExitCode.OK, + }, shouldPassMessage, shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, false)); } @Override protected void verifyOptionValues() throws Throwable { // Verify that the tested option is disabled by default. - CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false"); + CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be disabled by default", + optionName)); // Verify that it is not possible to explicitly enable the option. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be off on unsupported " + + "X86CPU even if set to true directly", optionName), CommandLineOptionTest.prepareBooleanFlag(optionName, true)); // Verify that the tested option is disabled even if +UseSHA was passed // to JVM. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "false", + String.format("Option '%s' should be off on unsupported " + + "X86CPU even if %s flag set to JVM", + optionName, CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true)); } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHAIntrinsicsSpecificTestCaseForUnsupportedSparcCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -50,10 +50,13 @@ } @Override protected void verifyWarnings() throws Throwable { - // Verify that attempt to enable the tested option will cause a warning. + String shouldPassMessage = String.format("JVM should start with " + + "'-XX:+%s' flag, but output should contain warning.", + optionName); + // Verify that attempt to enable the tested option will cause a warning CommandLineOptionTest.verifySameJVMStartup(new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, null, ExitCode.OK, + }, null, shouldPassMessage, shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForSupportedSparcCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -39,16 +39,22 @@ IntrinsicPredicates.ANY_SHA_INSTRUCTION_AVAILABLE)); Asserts.assertEQ(optionName, SHAOptionsBase.USE_SHA_OPTION, - "Test case should be used for " + SHAOptionsBase.USE_SHA_OPTION - + " option only."); + String.format("Test case should be used for '%s' option only.", + SHAOptionsBase.USE_SHA_OPTION)); } @Override protected void verifyWarnings() throws Throwable { + String shouldPassMessage = String.format("JVM startup should pass when" + + " %s was passed and all UseSHA*Intrinsics options " + + "were disabled", + CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)); // Verify that there will be no warnings when +UseSHA was passed and // all UseSHA*Intrinsics options were disabled. CommandLineOptionTest.verifySameJVMStartup( - null, new String[] { ".*UseSHA.*" }, ExitCode.OK, + null, new String[] { ".*UseSHA.*" }, shouldPassMessage, + shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( @@ -61,10 +67,12 @@ @Override protected void verifyOptionValues() throws Throwable { - // Verify that UseSHA is disabled when all UseSHA*Intrinscs are + // Verify that UseSHA is disabled when all UseSHA*Intrinsics are // disabled. CommandLineOptionTest.verifyOptionValueForSameVM( - SHAOptionsBase.USE_SHA_OPTION, "false", + SHAOptionsBase.USE_SHA_OPTION, "false", String.format( + "'%s' option should be disabled when all UseSHA*Intrinsics are" + + " disabled", SHAOptionsBase.USE_SHA_OPTION), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, false), CommandLineOptionTest.prepareBooleanFlag( @@ -73,9 +81,14 @@ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, false)); CommandLineOptionTest.verifyOptionValueForSameVM( - // Verify that UseSHA is disabled when all UseSHA*Intrinscs are + // Verify that UseSHA is disabled when all UseSHA*Intrinsics are // disabled even if it was explicitly enabled. SHAOptionsBase.USE_SHA_OPTION, "false", + String.format("'%s' option should be disabled when all " + + "UseSHA*Intrinsics are disabled even if %s flag set " + + "to JVM", SHAOptionsBase.USE_SHA_OPTION, + CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, true)), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( @@ -89,6 +102,11 @@ // if all UseSHA*Intrinsics options were enabled. CommandLineOptionTest.verifyOptionValueForSameVM( SHAOptionsBase.USE_SHA_OPTION, "false", + String.format("'%s' option should be disabled if %s flag " + + "set even if all UseSHA*Intrinsics were enabled", + SHAOptionsBase.USE_SHA_OPTION, + CommandLineOptionTest.prepareBooleanFlag( + SHAOptionsBase.USE_SHA_OPTION, false)), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, false), CommandLineOptionTest.prepareBooleanFlag( diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java --- a/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/cli/testcases/UseSHASpecificTestCaseForUnsupportedSparcCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -48,18 +48,24 @@ @Override protected void verifyWarnings() throws Throwable { // Verify that attempt to use UseSHA option will cause a warning. + String shouldPassMessage = String.format("JVM startup should pass with" + + " '%s' option on unsupported SparcCPU, but there should be" + + "the message shown.", optionName); CommandLineOptionTest.verifySameJVMStartup(new String[] { SHAOptionsBase.getWarningForUnsupportedCPU(optionName) - }, null, ExitCode.OK, + }, null, shouldPassMessage, shouldPassMessage, ExitCode.OK, CommandLineOptionTest.prepareBooleanFlag(optionName, true)); } @Override protected void verifyOptionValues() throws Throwable { // Verify that UseSHA option remains disabled even if all - // UseSHA*Intrincs options were enabled. + // UseSHA*Intrinsics were enabled. CommandLineOptionTest.verifyOptionValueForSameVM( - SHAOptionsBase.USE_SHA_OPTION, "false", + SHAOptionsBase.USE_SHA_OPTION, "false", String.format( + "%s option should be disabled on unsupported SparcCPU" + + " even if all UseSHA*Intrinsics options were enabled.", + SHAOptionsBase.USE_SHA_OPTION), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA1_INTRINSICS_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( @@ -68,9 +74,14 @@ SHAOptionsBase.USE_SHA512_INTRINSICS_OPTION, true)); // Verify that UseSHA option remains disabled even if all - // UseSHA*Intrincs options were enabled and UseSHA was enabled as well. + // UseSHA*Intrinsics options were enabled and UseSHA was enabled as well. CommandLineOptionTest.verifyOptionValueForSameVM( - SHAOptionsBase.USE_SHA_OPTION, "false", + SHAOptionsBase.USE_SHA_OPTION, "false", String.format( + "%s option should be disabled on unsupported SparcCPU" + + " even if all UseSHA*Intrinsics options were enabled" + + " and %s was enabled as well", + SHAOptionsBase.USE_SHA_OPTION, + SHAOptionsBase.USE_SHA_OPTION), CommandLineOptionTest.prepareBooleanFlag( SHAOptionsBase.USE_SHA_OPTION, true), CommandLineOptionTest.prepareBooleanFlag( diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1Intrinsics.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8035968 * @summary Verify that SHA-1 intrinsic is actually used. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../ + * @library /testlibrary /../../test/lib /compiler/testlibrary ../ * @build TestSHA intrinsics.Verifier TestSHA1Intrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @test * @bug 8035968 * @summary Verify that SHA-1 multi block intrinsic is actually used. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../ + * @library /testlibrary /../../test/lib /compiler/testlibrary ../ * @build TestSHA intrinsics.Verifier TestSHA1MultiBlockIntrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256Intrinsics.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @test * @bug 8035968 * @summary Verify that SHA-256 intrinsic is actually used. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../ + * @library /testlibrary /../../test/lib /compiler/testlibrary ../ * @build TestSHA intrinsics.Verifier TestSHA256Intrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA256MultiBlockIntrinsics.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @test * @bug 8035968 * @summary Verify that SHA-256 multi block intrinsic is actually used. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../ + * @library /testlibrary /../../test/lib /compiler/testlibrary ../ * @build TestSHA intrinsics.Verifier TestSHA256MultiBlockIntrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512Intrinsics.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @test * @bug 8035968 * @summary Verify that SHA-512 intrinsic is actually used. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../ + * @library /testlibrary /../../test/lib /compiler/testlibrary ../ * @build TestSHA intrinsics.Verifier TestSHA512Intrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java --- a/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @test * @bug 8035968 * @summary Verify that SHA-512 multi block intrinsic is actually used. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary ../ + * @library /testlibrary /../../test/lib /compiler/testlibrary ../ * @build TestSHA intrinsics.Verifier TestSHA512MultiBlockIntrinsics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rangechecks/TestRangeCheckSmearing.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8066103 + * @summary C2's range check smearing allows out of bound array accesses + * @library /testlibrary /../../test/lib /compiler/whitebox + * @build TestRangeCheckSmearing + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main ClassFileInstaller com.oracle.java.testlibrary.Platform + * @run main/othervm -ea -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckSmearing + * + */ + +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.util.*; +import sun.hotspot.WhiteBox; +import sun.hotspot.code.NMethod; +import com.oracle.java.testlibrary.Platform; + +public class TestRangeCheckSmearing { + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + + @Retention(RetentionPolicy.RUNTIME) + @interface Args { int[] value(); } + + // first range check is i + max of all constants + @Args({0, 8}) + static int m1(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+9]; + if (allaccesses) { + res += array[i+8]; + res += array[i+7]; + res += array[i+6]; + res += array[i+5]; + res += array[i+4]; + res += array[i+3]; + res += array[i+2]; + res += array[i+1]; + } + return res; + } + + // first range check is i + min of all constants + @Args({0, -9}) + static int m2(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+1]; + if (allaccesses) { + res += array[i+2]; + res += array[i+3]; + res += array[i+4]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + // first range check is not i + min/max of all constants + @Args({0, 8}) + static int m3(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + if (allaccesses) { + res += array[i+2]; + res += array[i+1]; + res += array[i+4]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + @Args({0, -9}) + static int m4(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + if (allaccesses) { + res += array[i+4]; + res += array[i+1]; + res += array[i+2]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + @Args({0, -3}) + static int m5(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + res += array[i+2]; + if (allaccesses) { + res += array[i+1]; + res += array[i+4]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + @Args({0, 6}) + static int m6(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + res += array[i+4]; + if (allaccesses) { + res += array[i+2]; + res += array[i+1]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + @Args({0, 6}) + static int m7(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + res += array[i+2]; + res += array[i+4]; + if (allaccesses) { + res += array[i+1]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + @Args({0, -3}) + static int m8(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + res += array[i+4]; + res += array[i+2]; + if (allaccesses) { + res += array[i+1]; + res += array[i+5]; + res += array[i+6]; + res += array[i+7]; + res += array[i+8]; + res += array[i+9]; + } + return res; + } + + @Args({6, 15}) + static int m9(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + if (allaccesses) { + res += array[i-2]; + res += array[i-1]; + res += array[i-4]; + res += array[i-5]; + res += array[i-6]; + } + return res; + } + + @Args({3, 12}) + static int m10(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + if (allaccesses) { + res += array[i-2]; + res += array[i-1]; + res += array[i-3]; + res += array[i+4]; + res += array[i+5]; + res += array[i+6]; + } + return res; + } + + @Args({3, -3}) + static int m11(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + res += array[i-2]; + if (allaccesses) { + res += array[i+5]; + res += array[i+6]; + } + return res; + } + + @Args({3, 6}) + static int m12(int[] array, int i, boolean allaccesses) { + int res = 0; + res += array[i+3]; + res += array[i+6]; + if (allaccesses) { + res += array[i-2]; + res += array[i-3]; + } + return res; + } + + // check that identical range check is replaced by dominating one + // only when correct + @Args({0}) + static int m13(int[] array, int i, boolean ignore) { + int res = 0; + res += array[i+3]; + res += array[i+3]; + return res; + } + + @Args({2, 0}) + static int m14(int[] array, int i, boolean ignore) { + int res = 0; + + res += array[i]; + res += array[i-2]; + res += array[i]; // If range check below were to be removed first this cannot be considered identical to first range check + res += array[i-1]; // range check removed so i-1 array access depends on previous check + + return res; + } + + static int[] m15_dummy = new int[10]; + @Args({2, 0}) + static int m15(int[] array, int i, boolean ignore) { + int res = 0; + res += array[i]; + + // When the loop is optimized out we don't want the + // array[i-1] access which is dependent on array[i]'s + // range check to become dependent on the identical range + // check above. + + int[] array2 = m15_dummy; + int j = 0; + for (; j < 10; j++); + if (j == 10) { + array2 = array; + } + + res += array2[i-2]; + res += array2[i]; + res += array2[i-1]; // range check removed so i-1 array access depends on previous check + + return res; + } + + @Args({2, 0}) + static int m16(int[] array, int i, boolean ignore) { + int res = 0; + + res += array[i]; + res += array[i-1]; + res += array[i-1]; + res += array[i-2]; + + return res; + } + + @Args({2, 0}) + static int m17(int[] array, int i, boolean ignore) { + int res = 0; + + res += array[i]; + res += array[i-2]; + res += array[i-2]; + res += array[i+2]; + res += array[i+2]; + res += array[i-1]; + res += array[i-1]; + + return res; + } + + static public void main(String[] args) { + if (WHITE_BOX.getBooleanVMFlag("BackgroundCompilation")) { + throw new AssertionError("Background compilation enabled"); + } + new TestRangeCheckSmearing().doTests(); + } + boolean success = true; + boolean exception = false; + final int[] array = new int[10]; + final HashMap tests = new HashMap<>(); + { + final Class TEST_PARAM_TYPES[] = { int[].class, int.class, boolean.class }; + for (Method m : this.getClass().getDeclaredMethods()) { + if (m.getName().matches("m[0-9]+")) { + assert(Modifier.isStatic(m.getModifiers())) : m; + assert(m.getReturnType() == int.class) : m; + assert(Arrays.equals(m.getParameterTypes(), TEST_PARAM_TYPES)) : m; + tests.put(m.getName(), m); + } + } + } + + void invokeTest(Method m, int[] array, int index, boolean z) { + try { + m.invoke(null, array, index, z); + } catch (ReflectiveOperationException roe) { + Throwable ex = roe.getCause(); + if (ex instanceof ArrayIndexOutOfBoundsException) + throw (ArrayIndexOutOfBoundsException) ex; + throw new AssertionError(roe); + } + } + + void doTest(String name) { + Method m = tests.get(name); + tests.remove(name); + int[] args = m.getAnnotation(Args.class).value(); + int index0 = args[0], index1; + boolean exceptionRequired = true; + if (args.length == 2) { + index1 = args[1]; + } else { + // no negative test for this one + assert(args.length == 1); + assert(name.equals("m13")); + exceptionRequired = false; + index1 = index0; + } + // Get the method compiled. + if (!WHITE_BOX.isMethodCompiled(m)) { + // If not, try to compile it with C2 + if(!WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION)) { + // C2 compiler not available, try to compile with C1 + WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE); + } + } + if (!WHITE_BOX.isMethodCompiled(m)) { + throw new RuntimeException(m + " not compiled"); + } + + // valid access + invokeTest(m, array, index0, true); + + if (!WHITE_BOX.isMethodCompiled(m)) { + throw new RuntimeException(m + " deoptimized on valid array access"); + } + + exception = false; + boolean test_success = true; + try { + invokeTest(m, array, index1, false); + } catch(ArrayIndexOutOfBoundsException aioob) { + exception = true; + System.out.println("ArrayIndexOutOfBoundsException thrown in "+name); + } + if (!exception) { + System.out.println("ArrayIndexOutOfBoundsException was not thrown in "+name); + } + + if (Platform.isServer()) { + if (exceptionRequired == WHITE_BOX.isMethodCompiled(m)) { + System.out.println((exceptionRequired?"Didn't deoptimized":"deoptimized") + " in "+name); + test_success = false; + } + } + + if (exception != exceptionRequired) { + System.out.println((exceptionRequired?"exception required but not thrown":"not exception required but thrown") + " in "+name); + test_success = false; + } + + if (!test_success) { + success = false; + System.out.println("TEST FAILED: "+name); + } + + } + void doTests() { + doTest("m1"); + doTest("m2"); + doTest("m3"); + doTest("m4"); + doTest("m5"); + doTest("m6"); + doTest("m7"); + doTest("m8"); + doTest("m9"); + doTest("m10"); + doTest("m11"); + doTest("m12"); + doTest("m13"); + doTest("m14"); + doTest("m15"); + doTest("m16"); + doTest("m17"); + if (!success) { + throw new RuntimeException("Some tests failed"); + } + assert(tests.isEmpty()) : tests; + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rangechecks/TestRangeCheckSmearingLoopOpts.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/rangechecks/TestRangeCheckSmearingLoopOpts.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8048170 + * @summary Following range check smearing, range check cannot be replaced by dominating identical test. + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestRangeCheckSmearingLoopOpts + * + */ +public class TestRangeCheckSmearingLoopOpts { + + static int dummy; + + static int m1(int[] array, int i) { + for (;;) { + for (;;) { + if (array[i] < 0) { // range check (i+0) dominates equivalent check below + break; + } + i++; + } + + // A control flow that stops IfNode::up_one_dom() + if ((i % 2)== 0) { + if ((array[i] % 2) == 0) { + dummy = i; + } + } + + // IfNode::Ideal will rewrite some range checks if Compile::allow_range_check_smearing + if (array[i-1] == 9) { // range check (i-1) unchanged + int res = array[i-3]; // range check (i-3) unchanged + res += array[i]; // range check (i+0) unchanged + res += array[i-2]; // removed redundant range check + // the previous access might be hoisted by + // PhaseIdealLoop::split_if_with_blocks_post because + // it appears to have the same guard, but it also + // depends on the previous guards + return res; + } + i++; + } + } + + static public void main(String[] args) { + int[] array = { 0, 1, 2, -3, 4, 5, -2, 7, 8, 9, -1 }; + for (int i = 0; i < 20000; i++) { + m1(array, 0); + } + array[0] = -1; + try { + m1(array, 0); + } catch(ArrayIndexOutOfBoundsException aioobe) {} + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java --- a/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/RTMGenericCommandLineOptionTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -121,7 +121,9 @@ */ protected void runNonX86TestCases() throws Throwable { CommandLineOptionTest.verifySameJVMStartup( - new String[] { errorMessage }, null, ExitCode.FAIL, + new String[] { errorMessage }, null, + String.format("Option '%s' should be unknown on non-X86CPUs.%n" + + "JVM startup should fail", optionName), "", ExitCode.FAIL, prepareOptionValue(defaultValue)); } @@ -136,12 +138,18 @@ protected void verifyJVMStartup() throws Throwable { String optionValue = prepareOptionValue(defaultValue); + String shouldFailMessage = String.format("VM option '%s' is " + + "experimental.%nVM startup expected to fail without " + + "-XX:+UnlockExperimentalVMOptions option", optionName); + String shouldPassMessage = String.format("VM option '%s' is " + + "experimental%nVM startup should pass with " + + "-XX:+UnlockExperimentalVMOptions option", optionName); if (isExperimental) { // verify that option is experimental CommandLineOptionTest.verifySameJVMStartup( new String[] { experimentalOptionError }, - new String[] { errorMessage }, ExitCode.FAIL, - optionValue); + new String[] { errorMessage }, shouldFailMessage, + shouldFailMessage, ExitCode.FAIL, optionValue); // verify that it could be passed if experimental options // are unlocked CommandLineOptionTest.verifySameJVMStartup(null, @@ -149,13 +157,19 @@ experimentalOptionError, errorMessage }, + shouldPassMessage, + "JVM should start without any warnings or errors", ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, optionValue); } else { // verify that option could be passed CommandLineOptionTest.verifySameJVMStartup(null, - new String[]{errorMessage}, ExitCode.OK, optionValue); + new String[]{errorMessage}, + String.format("VM startup shuld pass with '%s' option", + optionName), + "JVM should start without any warnings or errors", + ExitCode.OK, optionValue); } } @@ -164,10 +178,14 @@ if (isExperimental) { CommandLineOptionTest.verifyOptionValueForSameVM(optionName, defaultValue, + String.format("Option '%s' is expected to have '%s' " + + "default value", optionName, defaultValue), CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); } else { CommandLineOptionTest.verifyOptionValueForSameVM(optionName, - defaultValue); + defaultValue, + String.format("Option '%s' is expected to have '%s' " + + "default value", optionName, defaultValue)); } // verify other specified option values if (optionValues == null) { @@ -178,11 +196,15 @@ if (isExperimental) { CommandLineOptionTest.verifyOptionValueForSameVM(optionName, value, + String.format("Option '%s' is set to have '%s' value", + optionName, value), CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, prepareOptionValue(value)); } else { CommandLineOptionTest.verifyOptionValueForSameVM(optionName, - value, prepareOptionValue(value)); + value, + String.format("Option '%s' is set to have '%s' value", + optionName, value), prepareOptionValue(value)); } } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java --- a/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/RTMLockingAwareTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -131,10 +131,14 @@ } options.add(prepareOptionValue(value)); + String errorString = String.format("JVM should start with option '%s'" + + "'%nWarnings should be shown: %s", optionName, + isWarningExpected); CommandLineOptionTest.verifySameJVMStartup( (isWarningExpected ? warnings : null), (isWarningExpected ? null : warnings), - ExitCode.OK, options.toArray(new String[options.size()])); + errorString, errorString, ExitCode.OK, + options.toArray(new String[options.size()])); } private void verifyOptionValues(String value, boolean useRTMLocking, @@ -149,6 +153,9 @@ options.add(prepareOptionValue(value)); CommandLineOptionTest.verifyOptionValueForSameVM(optionName, - expectedValue, options.toArray(new String[options.size()])); + expectedValue, String.format("Option '%s' should have '%s' " + + "value if '%s' flag set", + optionName, expectedValue, prepareOptionValue(value)), + options.toArray(new String[options.size()])); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsBase.java Sat Jan 10 12:38:18 2015 -0800 @@ -47,27 +47,42 @@ protected void verifyJVMStartup() throws Throwable { if (Platform.isServer()) { if (!Platform.isDebugBuild()) { + String shouldFailMessage = String.format("VM option '%s' is " + + "diagnostic%nJVM startup should fail without " + + "-XX:\\+UnlockDiagnosticVMOptions flag", optionName); + String shouldPassMessage = String.format("VM option '%s' is " + + "diagnostic%nJVM startup should pass with " + + "-XX:\\+UnlockDiagnosticVMOptions in debug build", + optionName); String errorMessage = CommandLineOptionTest. getDiagnosticOptionErrorMessage(optionName); // verify that option is actually diagnostic CommandLineOptionTest.verifySameJVMStartup( - new String[] { errorMessage }, null, ExitCode.FAIL, + new String[] { errorMessage }, null, shouldFailMessage, + shouldFailMessage, ExitCode.FAIL, prepareOptionValue("true")); CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { errorMessage }, ExitCode.OK, + new String[] { errorMessage }, shouldPassMessage, + shouldPassMessage + "without any warnings", ExitCode.OK, CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, prepareOptionValue("true")); } else { - CommandLineOptionTest.verifySameJVMStartup( - null, null, ExitCode.OK, prepareOptionValue("true")); + String shouldPassMessage = String.format("JVM startup should " + + "pass with '%s' option in debug build", + optionName); + CommandLineOptionTest.verifySameJVMStartup(null, null, + shouldPassMessage, shouldPassMessage, + ExitCode.OK, prepareOptionValue("true")); } } else { String errorMessage = CommandLineOptionTest. getUnrecognizedOptionErrorMessage(optionName); - + String shouldFailMessage = String.format("JVM startup should fail" + + " with '%s' option in not debug build", optionName); CommandLineOptionTest.verifySameJVMStartup( - new String[]{errorMessage}, null, ExitCode.FAIL, + new String[]{errorMessage}, null, shouldFailMessage, + shouldFailMessage, ExitCode.FAIL, CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, prepareOptionValue("true")); } @@ -79,6 +94,9 @@ // Verify default value CommandLineOptionTest.verifyOptionValueForSameVM(optionName, TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, + String.format("Option '%s' should have '%s' default value", + optionName, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE), CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify PrintPreciseRTMLockingStatistics on CPUs with * rtm support and on VM with rtm locking support, - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestPrintPreciseRTMLockingStatisticsOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -53,18 +53,28 @@ // verify default value CommandLineOptionTest.verifyOptionValueForSameVM(optionName, TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, + String.format("Option '%s' should have '%s' default value on" + + " supported CPU", optionName, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE), CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking"); CommandLineOptionTest.verifyOptionValueForSameVM(optionName, TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE, + String.format("Option '%s' should have '%s' default value on" + + " supported CPU when -XX:-UseRTMLocking flag set", + optionName, + TestPrintPreciseRTMLockingStatisticsBase.DEFAULT_VALUE), CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:-UseRTMLocking", prepareOptionValue("true")); // verify that option could be turned on CommandLineOptionTest.verifyOptionValueForSameVM(optionName, "true", + String.format("Option '%s' should have 'true' value when set " + + "on supported CPU and -XX:+UseRTMLocking flag set", + optionName), CommandLineOptionTest.UNLOCK_DIAGNOSTIC_VM_OPTIONS, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking", prepareOptionValue("true")); diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify PrintPreciseRTMLockingStatistics on CPUs without * rtm support and/or unsupported VM. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestPrintPreciseRTMLockingStatisticsOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnSupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify RTMAbortRatio option processing on CPU with rtm * support and on VM with rtm locking support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMAbortRatioOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestRTMAbortRatioOptionOnUnsupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify RTMAbortRatio option processing on CPU without rtm * support or on VM that does not support rtm locking. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMAbortRatioOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnSupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify RTMTotalCountIncrRate option processing on CPU with * rtm support and on VM with rtm locking support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMTotalCountIncrRateOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestRTMTotalCountIncrRateOptionOnUnsupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -32,7 +32,7 @@ * @bug 8031320 * @summary Verify RTMTotalCountIncrRate option processing on CPU without * rtm support and/or on VM without rtm locking support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMTotalCountIncrRateOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnSupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMDeopt option processing on CPUs with rtm support * when rtm locking is supported by VM. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMDeoptOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -51,26 +51,40 @@ @Override public void runTestCases() throws Throwable { + String shouldPassMessage = " JVM should startup with option '" + + "-XX:+UseRTMDeopt' without any warnings"; // verify that option could be turned on CommandLineOptionTest.verifySameJVMStartup( - null, null, ExitCode.OK, "-XX:+UseRTMDeopt"); + null, null, shouldPassMessage, shouldPassMessage, ExitCode.OK, + "-XX:+UseRTMDeopt"); + shouldPassMessage = " JVM should startup with option '" + + "-XX:-UseRTMDeopt' without any warnings"; // verify that option could be turned off CommandLineOptionTest.verifySameJVMStartup( - null, null, ExitCode.OK, "-XX:-UseRTMDeopt"); - // verify default value - CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", - TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE); + null, null, shouldPassMessage, shouldPassMessage, ExitCode.OK, + "-XX:-UseRTMDeopt"); + String defValMessage = String.format("UseRTMDeopt should have '%s'" + + "default value", + TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE); // verify default value CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE, + defValMessage); + // verify default value + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", + TestUseRTMDeoptOptionOnSupportedConfig.DEFAULT_VALUE, + defValMessage, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking"); // verify that option is off when UseRTMLocking is off - CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "false", + CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", + "false", "UseRTMDeopt should be off when UseRTMLocking is off", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:-UseRTMLocking", "-XX:+UseRTMDeopt"); // verify that option could be turned on CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMDeopt", "true", + "UseRTMDeopt should be on when UseRTMLocking is on and " + + "'-XX:+UseRTMDeopt' flag set", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking", "-XX:+UseRTMDeopt"); } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMDeoptOptionOnUnsupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMDeopt option processing on CPUs without rtm support * or on VMs without rtm locking support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMDeoptOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -50,7 +50,8 @@ super(new NotPredicate(new AndPredicate(new SupportedCPU(), new SupportedVM())), "UseRTMDeopt", true, false, - TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, "true"); + TestUseRTMDeoptOptionOnUnsupportedConfig.DEFAULT_VALUE, + "true"); } @Override @@ -58,11 +59,16 @@ super.verifyJVMStartup(); // verify default value CommandLineOptionTest.verifyOptionValueForSameVM(optionName, - defaultValue); + defaultValue, String.format("'%s' should have '%s' " + + "default value on unsupported configs.", + optionName, DEFAULT_VALUE)); // verify that until RTMLocking is not used, value // will be set to default false. CommandLineOptionTest.verifyOptionValueForSameVM(optionName, - defaultValue, "-XX:+UseRTMDeopt"); + defaultValue, String.format("'%s' should be off on unsupported" + + " configs even if '-XX:+%s' flag set", optionName, + optionName), + "-XX:+UseRTMDeopt"); } public static void main(String args[]) throws Throwable { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnSupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMForStackLocks option processing on CPU with * rtm support when VM supports rtm locking. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMForStackLocksOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -58,43 +58,67 @@ String warningMessage = RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING; + String shouldFailMessage = " VM option 'UseRTMForStackLocks' is " + + "experimental%nJVM startup should fail without " + + "-XX:+UnlockExperimentalVMOptions flag"; + CommandLineOptionTest.verifySameJVMStartup( - new String[] { errorMessage }, null, ExitCode.FAIL, + new String[] { errorMessage }, null, shouldFailMessage, + shouldFailMessage + "%nError message expected", ExitCode.FAIL, "-XX:+UseRTMForStackLocks"); + String shouldPassMessage = " VM option 'UseRTMForStackLocks'" + + " is experimental%nJVM startup should pass with " + + "-XX:+UnlockExperimentalVMOptions flag"; // verify that we get a warning when trying to use rtm for stack // lock, but not using rtm locking. CommandLineOptionTest.verifySameJVMStartup( - new String[] { warningMessage }, null, ExitCode.OK, + new String[] { warningMessage }, null, shouldPassMessage, + "There should be warning when trying to use rtm for stack " + + "lock, but not using rtm locking", ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMForStackLocks", "-XX:-UseRTMLocking"); // verify that we don't get a warning when no using rtm for stack // lock and not using rtm locking. CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { warningMessage }, ExitCode.OK, + new String[] { warningMessage }, shouldPassMessage, + "There should not be any warning when use both " + + "-XX:-UseRTMForStackLocks and -XX:-UseRTMLocking " + + "flags", + ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:-UseRTMForStackLocks", "-XX:-UseRTMLocking"); // verify that we don't get a warning when using rtm for stack // lock and using rtm locking. CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { warningMessage }, ExitCode.OK, + new String[] { warningMessage }, shouldPassMessage, + "There should not be any warning when use both " + + "-XX:+UseRTMForStackLocks and -XX:+UseRTMLocking" + + " flags", + ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMForStackLocks", "-XX:+UseRTMLocking"); // verify that default value if false CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks", TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE, + "Default value of option 'UseRTMForStackLocks' should be false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); // verify that default value is false even with +UseRTMLocking CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks", TestUseRTMForStackLocksOptionOnSupportedConfig.DEFAULT_VALUE, + "Default value of option 'UseRTMForStackLocks' should be false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking"); // verify that we can turn the option on CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMForStackLocks", - "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, - "-XX:+UseRTMLocking", "-XX:+UseRTMForStackLocks"); + "true", "Value of option 'UseRTMForStackLocks' should " + + "be able to be set as 'true' when both " + + "-XX:+UseRTMForStackLocks and " + + "-XX:+UseRTMLocking flags used", + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:+UseRTMLocking", "-XX:+UseRTMForStackLocks"); } public static void main(String args[]) throws Throwable { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMForStackLocksOptionOnUnsupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMForStackLocks option processing on CPUs without * rtm support and/or on VMs without rtm locking support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMForStackLocksOptionOnUnsupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -57,33 +57,50 @@ @Override protected void runX86SupportedVMTestCases() throws Throwable { + String shouldFailMessage = String.format("VM option '%s' is " + + "experimental%nJVM startup should fail without " + + "-XX:+UnlockExperimentalVMOptions flag", optionName); + // verify that option is experimental CommandLineOptionTest.verifySameJVMStartup( - new String[]{ experimentalOptionError }, - null, ExitCode.FAIL, prepareOptionValue("true")); + new String[] { experimentalOptionError }, null, + shouldFailMessage, shouldFailMessage + "%nError message " + + "should be shown", ExitCode.FAIL, + prepareOptionValue("true")); CommandLineOptionTest.verifySameJVMStartup( - new String[]{ experimentalOptionError }, - null, ExitCode.FAIL, prepareOptionValue("false")); + new String[]{ experimentalOptionError }, null, + shouldFailMessage, shouldFailMessage + "%nError message " + + "should be shown", ExitCode.FAIL, + prepareOptionValue("false")); + String shouldPassMessage = String.format("VM option '%s' is " + + " experimental%nJVM startup should pass with " + + "-XX:+UnlockExperimentalVMOptions flag", optionName); // verify that if we turn it on, then VM output will contain // warning saying that this option could be turned on only // when we use rtm locking CommandLineOptionTest.verifySameJVMStartup( new String[]{ RTMGenericCommandLineOptionTest.RTM_FOR_STACK_LOCKS_WARNING - }, - null, ExitCode.OK, + }, null, shouldPassMessage, "There should be warning when try " + + "to use rtm for stack lock, but not using rtm locking", + ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, prepareOptionValue("true") ); // verify that options is turned off by default CommandLineOptionTest.verifyOptionValueForSameVM(optionName, TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE, + String.format("Default value of option '%s' should be '%s'", + optionName, DEFAULT_VALUE), CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); // verify that it could not be turned on without rtm locking CommandLineOptionTest.verifyOptionValueForSameVM(optionName, TestUseRTMForStackLocksOptionOnUnsupportedConfig.DEFAULT_VALUE, + String.format("Value of '%s' shouldn't able to be set to " + + "'true' without setting -XX:+UseRTMLocking flag", + optionName), CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, prepareOptionValue("true")); } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnSupportedConfig.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMLocking option processing on CPU with rtm support and * on VM with rtm-locking support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMLockingOptionOnSupportedConfig * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -54,12 +54,16 @@ String unrecongnizedOption = CommandLineOptionTest.getUnrecognizedOptionErrorMessage( "UseRTMLocking"); + String shouldPassMessage = "VM option 'UseRTMLocking' is experimental" + + "%nJVM startup should pass with " + + "-XX:+UnlockExperimentalVMOptions flag"; // verify that there are no warning or error in VM output CommandLineOptionTest.verifySameJVMStartup(null, new String[]{ RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR, unrecongnizedOption - }, ExitCode.OK, + }, shouldPassMessage, "There should not be any warning when use" + + "with -XX:+UnlockExperimentalVMOptions", ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking" ); @@ -68,21 +72,28 @@ new String[]{ RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR, unrecongnizedOption - }, ExitCode.OK, + }, shouldPassMessage, "There should not be any warning when use" + + "with -XX:+UnlockExperimentalVMOptions", ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:-UseRTMLocking" ); // verify that UseRTMLocking is of by default CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE, + String.format("Default value of option 'UseRTMLocking' should " + + "be '%s'", DEFAULT_VALUE), CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); // verify that we can change UseRTMLocking value CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", TestUseRTMLockingOptionOnSupportedConfig.DEFAULT_VALUE, + String.format("Default value of option 'UseRTMLocking' should " + + "be '%s'", DEFAULT_VALUE), CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:-UseRTMLocking"); CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", - "true", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "true", "Value of 'UseRTMLocking' should be set " + + "to 'true' if -XX:+UseRTMLocking flag set", + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking"); } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedCPU.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMLocking option processing on CPU without * rtm support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMLockingOptionOnUnsupportedCPU * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -59,33 +59,44 @@ String errorMessage = RTMGenericCommandLineOptionTest.RTM_INSTR_ERROR; if (Platform.isX86() || Platform.isX64()) { + String shouldFailMessage = "JVM startup should fail with option " + + "-XX:+UseRTMLocking on unsupported CPU"; // verify that we get an error when use +UseRTMLocking // on unsupported CPU CommandLineOptionTest.verifySameJVMStartup( new String[] { errorMessage }, - new String[] { unrecongnizedOption }, + new String[] { unrecongnizedOption }, shouldFailMessage, + shouldFailMessage + ". Error message should be shown", ExitCode.FAIL, "-XX:+UseRTMLocking"); + + String shouldPassMessage = "JVM startup should pass with option " + + "-XX:-UseRTMLocking even on unsupported CPU"; // verify that we can pass -UseRTMLocking without // getting any error messages - CommandLineOptionTest.verifySameJVMStartup( - null, - new String[]{ - errorMessage, - unrecongnizedOption - }, ExitCode.OK, "-XX:-UseRTMLocking"); + CommandLineOptionTest.verifySameJVMStartup(null, new String[] { + errorMessage, unrecongnizedOption }, shouldPassMessage, + shouldPassMessage + " without any warnings", ExitCode.OK, + "-XX:-UseRTMLocking"); // verify that UseRTMLocking is false by default CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", - TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE); + TestUseRTMLockingOptionOnUnsupportedCPU.DEFAULT_VALUE, + String.format("Default value of option 'UseRTMLocking' " + +"should be '%s'", DEFAULT_VALUE)); } else { + String shouldFailMessage = "RTMLocking should be unrecognized" + + " on non-x86 CPUs. JVM startup should fail." + + "Error message should be shown"; // verify that on non-x86 CPUs RTMLocking could not be used CommandLineOptionTest.verifySameJVMStartup( new String[] { unrecongnizedOption }, - null, ExitCode.FAIL, "-XX:+UseRTMLocking"); + null, shouldFailMessage, shouldFailMessage, + ExitCode.FAIL, "-XX:+UseRTMLocking"); CommandLineOptionTest.verifySameJVMStartup( new String[] { unrecongnizedOption }, - null, ExitCode.FAIL, "-XX:-UseRTMLocking"); + null, shouldFailMessage, shouldFailMessage, + ExitCode.FAIL, "-XX:-UseRTMLocking"); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionOnUnsupportedVM.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify UseRTMLocking option processing on CPU with rtm support * in case when VM should not support this option. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMLockingOptionOnUnsupportedVM * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -54,17 +54,26 @@ public void runTestCases() throws Throwable { String errorMessage = RTMGenericCommandLineOptionTest.RTM_UNSUPPORTED_VM_ERROR; + String shouldFailMessage = "JVM startup should fail with option " + + "-XX:+UseRTMLocking even on unsupported VM. Error message" + + " should be shown"; + String shouldPassMessage = "JVM startup should pass with option " + + "-XX:-UseRTMLocking even on unsupported VM"; // verify that we can't use +UseRTMLocking CommandLineOptionTest.verifySameJVMStartup( - new String[] { errorMessage }, null, ExitCode.FAIL, - "-XX:+UseRTMLocking"); + new String[] { errorMessage }, null, shouldFailMessage, + shouldFailMessage, ExitCode.FAIL, + "-XX:+UseRTMLocking"); // verify that we can turn it off CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { errorMessage }, ExitCode.OK, + new String[] { errorMessage }, shouldPassMessage, + shouldPassMessage + " without any warnings", ExitCode.OK, "-XX:-UseRTMLocking"); // verify that it is off by default CommandLineOptionTest.verifyOptionValueForSameVM("UseRTMLocking", - TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE); + TestUseRTMLockingOptionOnUnsupportedVM.DEFAULT_VALUE, + String.format("Default value of option 'UseRTMLocking' should" + + " be '%s'", DEFAULT_VALUE)); } public static void main(String args[]) throws Throwable { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java --- a/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/cli/TestUseRTMLockingOptionWithBiasedLocking.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify processing of UseRTMLocking and UseBiasedLocking * options combination on CPU and VM with rtm support. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMLockingOptionWithBiasedLocking * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -51,25 +51,44 @@ public void runTestCases() throws Throwable { String warningMessage = RTMGenericCommandLineOptionTest.RTM_BIASED_LOCKING_WARNING; + String shouldPassMessage = "JVM startup should pass with both " + + "-XX:+UseRTMLocking and " + + "-XX:-UseBiasedLocking flags set without any warnings"; // verify that we will not get a warning CommandLineOptionTest.verifySameJVMStartup(null, - new String[] { warningMessage }, ExitCode.OK, + new String[] { warningMessage }, shouldPassMessage, + shouldPassMessage, ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking", "-XX:-UseBiasedLocking"); + // verify that we will get a warning CommandLineOptionTest.verifySameJVMStartup( - new String[] { warningMessage }, null, ExitCode.OK, + new String[] { warningMessage }, null, + "JVM startup should pass when both -XX:+UseRTMLocking and " + + "-XX:+UseBiasedLocking flags set", + "Flags -XX:+UseRTMLocking" + + " and -XX:+UseBiasedLocking conflicts. " + + "Warning should be shown.", ExitCode.OK, CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); // verify that UseBiasedLocking is false when we use rtm locking CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking", - "false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "false", + "Value of option 'UseBiasedLocking' should be false if" + + "-XX:+UseRTMLocking flag set.", + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, "-XX:+UseRTMLocking"); // verify that we can't turn on biased locking when // using rtm locking - CommandLineOptionTest.verifyOptionValueForSameVM("UseBiasedLocking", - "false", CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, - "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); + CommandLineOptionTest + .verifyOptionValueForSameVM( + "UseBiasedLocking", + "false", + "Value of option 'UseBiasedLocking' should be false if" + + "both -XX:+UseRTMLocking and " + + "-XX:+UseBiasedLocking flags set.", + CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS, + "-XX:+UseRTMLocking", "-XX:+UseBiasedLocking"); } public static void main(String args[]) throws Throwable { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortRatio.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMAbortRatio affects amount of aborts before * deoptimization. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMAbortRatio * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAbortThreshold.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMAbortThreshold option affects * amount of aborts after which abort ratio is calculated. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMAbortThreshold * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java --- a/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMAfterNonRTMDeopt.java Sat Jan 10 12:38:18 2015 -0800 @@ -29,7 +29,7 @@ * caused by reason other then rtm_state_change will reset * method's RTM state. And if we don't use RTMDeopt, then * RTM state remain the same after such deoptimization. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMAfterNonRTMDeopt * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnHighAbortRatio.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that on high abort ratio method will be recompiled * without rtm locking. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMDeoptOnHighAbortRatio * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java --- a/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMDeoptOnLowAbortRatio.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @test * @bug 8031320 * @summary Verify that on low abort ratio method will be recompiled. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMDeoptOnLowAbortRatio * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingCalculationDelay.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMLockingCalculationDelay affect when * abort ratio calculation is started. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMLockingCalculationDelay * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java --- a/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMLockingThreshold.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMLockingThreshold affects rtm state transition * ProfileRTM => UseRTM. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMLockingThreshold * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java --- a/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMRetryCount.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @test * @bug 8031320 * @summary Verify that RTMRetryCount affects actual amount of retries. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMRetryCount * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java --- a/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMSpinLoopCount.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMSpinLoopCount affects time spent * between locking attempts. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMSpinLoopCount * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java --- a/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestRTMTotalCountIncrRate.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that RTMTotalCountIncrRate option affects * RTM locking statistics. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestRTMTotalCountIncrRate * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMAfterLockInflation.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that rtm locking is used for stack locks before * inflation and after it used for inflated locks. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMAfterLockInflation * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMDeopt.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that UseRTMDeopt affects uncommon trap installation in * copmpiled methods with synchronized block. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMDeopt * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForInflatedLocks.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @test * @bug 8031320 * @summary Verify that rtm locking is used for inflated locks. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMForInflatedLocks * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMForStackLocks.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @test * @bug 8031320 * @summary Verify that rtm locking is used for stack locks. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMForStackLocks * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java --- a/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/locking/TestUseRTMXendForLockBusy.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that UseRTMXendForLockBusy option affects * method behaviour if lock is busy. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMXendForLockBusy * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java --- a/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/method_options/TestNoRTMLockElidingOption.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8031320 * @summary Verify that NoRTMLockEliding option could be applied to * specified method and that such method will not use rtm. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestNoRTMLockElidingOption * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java --- a/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/method_options/TestUseRTMLockElidingOption.java Sat Jan 10 12:38:18 2015 -0800 @@ -28,7 +28,7 @@ * @summary Verify that UseRTMLockEliding option could be applied to * specified method and that such method will not be deoptimized * on high abort ratio. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestUseRTMLockElidingOption * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java --- a/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/rtm/print/TestPrintPreciseRTMLockingStatistics.java Sat Jan 10 12:38:18 2015 -0800 @@ -29,7 +29,7 @@ * on overall aborts and locks count and count of aborts of * different types. Test also verify that VM output does not * contain rtm locking statistics when it should not. - * @library /testlibrary /testlibrary/whitebox /compiler/testlibrary + * @library /testlibrary /../../test/lib /compiler/testlibrary * @build TestPrintPreciseRTMLockingStatistics * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/runtime/8010927/Test8010927.java --- a/hotspot/test/compiler/runtime/8010927/Test8010927.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/runtime/8010927/Test8010927.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @bug 8010927 * @summary Kitchensink crashed with SIGSEGV, Problematic frame: v ~StubRoutines::checkcast_arraycopy - * @library /testlibrary/whitebox /testlibrary + * @library /../../test/lib /testlibrary * @build Test8010927 * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableBoolean.java --- a/hotspot/test/compiler/stable/TestStableBoolean.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableBoolean.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableBoolean * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableBoolean StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableByte.java --- a/hotspot/test/compiler/stable/TestStableByte.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableByte.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableByte * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableByte StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableChar.java --- a/hotspot/test/compiler/stable/TestStableChar.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableChar.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableChar * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableChar StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableDouble.java --- a/hotspot/test/compiler/stable/TestStableDouble.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableDouble.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableDouble * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableDouble StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableFloat.java --- a/hotspot/test/compiler/stable/TestStableFloat.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableFloat.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableFloat * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableFloat StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableInt.java --- a/hotspot/test/compiler/stable/TestStableInt.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableInt.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableInt * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableInt StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableLong.java --- a/hotspot/test/compiler/stable/TestStableLong.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableLong.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableLong * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableLong StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableObject.java --- a/hotspot/test/compiler/stable/TestStableObject.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableObject.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableObject * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableObject StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/stable/TestStableShort.java --- a/hotspot/test/compiler/stable/TestStableShort.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/stable/TestStableShort.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test TestStableShort * @summary tests on stable fields and arrays - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestStableShort StableConfiguration sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission * @run main ClassFileInstaller diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/tiered/ConstantGettersTransitionsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/tiered/ConstantGettersTransitionsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Executable; +import java.util.concurrent.Callable; + +/** + * @test ConstantGettersTransitionsTest + * @library /testlibrary /../../test/lib /compiler/whitebox + * @build TransitionsTestExecutor ConstantGettersTransitionsTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=240 -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+TieredCompilation + * -XX:CompileCommand=compileonly,ConstantGettersTestCase$TrivialMethods::* + * TransitionsTestExecutor ConstantGettersTransitionsTest + * @summary Test the correctness of compilation level transitions for constant getters methods + */ +public class ConstantGettersTransitionsTest extends LevelTransitionTest { + public static void main(String[] args) { + assert (!CompilerWhiteBoxTest.skipOnTieredCompilation(false)); + + // run test cases + for (TestCase testCase : ConstantGettersTestCase.values()) { + new ConstantGettersTransitionsTest(testCase).runTest(); + } + } + + @Override + protected boolean isTrivial() { + return true; + } + + private ConstantGettersTransitionsTest(TestCase testCase) { + super(testCase); + } +} + +enum ConstantGettersTestCase implements CompilerWhiteBoxTest.TestCase { + ICONST_M1, + ICONST_0, + ICONST_1, + ICONST_2, + ICONST_3, + ICONST_4, + ICONST_5, + LCONST_0, + LCONST_1, + FCONST_0, + FCONST_1, + FCONST_2, + DCONST_0, + DCONST_1, + DCONST_W, + BYTE, + SHORT, + CHAR; + + private final Executable executable; + private final Callable callable; + + @Override + public Executable getExecutable() { + return executable; + } + + @Override + public Callable getCallable() { + return callable; + } + + @Override + public boolean isOsr() { + return false; + } + + private ConstantGettersTestCase() { + String name = "make" + this.name(); + this.executable = LevelTransitionTest.Helper.getMethod(TrivialMethods.class, name); + this.callable = LevelTransitionTest.Helper.getCallable(new TrivialMethods(), name); + } + + /** + * Contains methods that load constants with certain types of bytecodes + * See JVMS 2.11.2. Load and Store Instructions + * Note that it doesn't have a method for ldc_w instruction + */ + private static class TrivialMethods { + public static int makeICONST_M1() { + return -1; + } + + public static int makeICONST_0() { + return 0; + } + + public static int makeICONST_1() { + return 1; + } + + public static int makeICONST_2() { + return 2; + } + + public static int makeICONST_3() { + return 3; + } + + public static int makeICONST_4() { + return 4; + } + + public static int makeICONST_5() { + return 5; + } + + public static long makeLCONST_0() { + return 0L; + } + + public static long makeLCONST_1() { + return 1L; + } + + public static float makeFCONST_0() { + return 0F; + } + + public static float makeFCONST_1() { + return 1F; + } + + public static float makeFCONST_2() { + return 2F; + } + + public static double makeDCONST_0() { + return 0D; + } + + public static double makeDCONST_1() { + return 1D; + } + + public static double makeDCONST_W() { + // ldc2_w + return Double.MAX_VALUE; + } + + public static Object makeOBJECT() { + // aconst_null + return null; + } + + public static byte makeBYTE() { + // bipush + return (byte) 0x7F; + } + + public static short makeSHORT() { + // sipush + return (short) 0x7FFF; + } + + public static char makeCHAR() { + // ldc + return (char) 0xFFFF; + } + + public static boolean makeBOOLEAN() { + return true; + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/tiered/LevelTransitionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/tiered/LevelTransitionTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.reflect.Executable; +import java.lang.reflect.Method; +import java.util.Objects; +import java.util.concurrent.Callable; + +/** + * @test LevelTransitionTest + * @library /testlibrary /../../test/lib /compiler/whitebox + * @build TransitionsTestExecutor LevelTransitionTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm/timeout=240 -Xmixed -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -XX:+TieredCompilation + * -XX:CompileCommand=compileonly,SimpleTestCase$Helper::* + * -XX:CompileCommand=compileonly,ExtendedTestCase$CompileMethodHolder::* + * TransitionsTestExecutor LevelTransitionTest + * @summary Test the correctness of compilation level transitions for different methods + */ +public class LevelTransitionTest extends TieredLevelsTest { + /** Shows if method was profiled by being executed on levels 2 or 3 */ + protected boolean isMethodProfiled; + private int transitionCount; + + public static void main(String[] args) throws Throwable { + assert (!CompilerWhiteBoxTest.skipOnTieredCompilation(false)); + + CompilerWhiteBoxTest.main(LevelTransitionTest::new, args); + // run extended test cases + for (TestCase testCase : ExtendedTestCase.values()) { + new LevelTransitionTest(testCase).runTest(); + } + } + + protected LevelTransitionTest(TestCase testCase) { + super(testCase); + isMethodProfiled = testCase.isOsr(); // OSR methods were already profiled by warmup + transitionCount = 0; + } + + @Override + protected void test() throws Exception { + checkTransitions(); + deoptimize(); + printInfo(); + if (testCase.isOsr()) { + // deoptimization makes the following transitions be unstable + // methods go to level 3 before 4 because of uncommon_trap and reprofile + return; + } + checkTransitions(); + } + + /** + * Makes and verifies transitions between compilation levels + */ + protected void checkTransitions() { + checkNotCompiled(); + boolean finish = false; + while (!finish) { + System.out.printf("Level transition #%d%n", ++transitionCount); + int newLevel; + int current = getCompLevel(); + int expected = getNextLevel(current); + if (current == expected) { + // if we are on expected level, just execute it more + // to ensure that the level won't change + System.out.printf("Method %s is already on expected level %d%n", method, expected); + compile(); + newLevel = getCompLevel(); + finish = true; + } else { + newLevel = changeCompLevel(); + finish = false; + } + System.out.printf("Method %s is compiled on level %d. Expected level is %d%n", method, newLevel, expected); + checkLevel(expected, newLevel); + printInfo(); + }; + } + + /** + * Gets next expected level for the test case on each transition. + * + * @param currentLevel a level the test case is compiled on + * @return expected compilation level + */ + protected int getNextLevel(int currentLevel) { + int nextLevel = currentLevel; + switch (currentLevel) { + case CompilerWhiteBoxTest.COMP_LEVEL_NONE: + nextLevel = isMethodProfiled ? CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION + : CompilerWhiteBoxTest.COMP_LEVEL_FULL_PROFILE; + break; + case CompilerWhiteBoxTest.COMP_LEVEL_LIMITED_PROFILE: + case CompilerWhiteBoxTest.COMP_LEVEL_FULL_PROFILE: + nextLevel = CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION; + isMethodProfiled = true; + break; + } + nextLevel = isTrivial() ? CompilerWhiteBoxTest.COMP_LEVEL_SIMPLE : nextLevel; + return Math.min(nextLevel, CompilerWhiteBoxTest.TIERED_STOP_AT_LEVEL); + } + + /** + * Determines if tested method should be handled as trivial + * + * @return {@code true} for trivial methods, {@code false} otherwise + */ + protected boolean isTrivial() { + return testCase == ExtendedTestCase.ACCESSOR_TEST + || testCase == SimpleTestCase.METHOD_TEST + || testCase == SimpleTestCase.STATIC_TEST + || (testCase == ExtendedTestCase.TRIVIAL_CODE_TEST && isMethodProfiled); + } + + /** + * Invokes {@linkplain #method} until its compilation level is changed. + * Note that if the level won't change, it will be an endless loop + * + * @return compilation level the {@linkplain #method} was compiled on + */ + protected int changeCompLevel() { + int currentLevel = getCompLevel(); + int newLevel = currentLevel; + int result = 0; + while (currentLevel == newLevel) { + result = compile(1); + if (WHITE_BOX.isMethodCompiled(method, testCase.isOsr())) { + newLevel = getCompLevel(); + } + } + return newLevel; + } + + protected static class Helper { + /** + * Gets method from a specified class using its name + * + * @param aClass type method belongs to + * @param name the name of the method + * @return {@link Method} that represents corresponding class method + */ + public static Method getMethod(Class aClass, String name) { + Method method; + try { + method = aClass.getDeclaredMethod(name); + } catch (NoSuchMethodException e) { + throw new Error("TESTBUG: Unable to get method " + name, e); + } + return method; + } + + /** + * Gets {@link Callable} that invokes given method from the given object + * + * @param object the object the specified method is invoked from + * @param name the name of the method + */ + public static Callable getCallable(Object object, String name) { + Method method = getMethod(object.getClass(), name); + return () -> { + try { + return Objects.hashCode(method.invoke(object)); + } catch (ReflectiveOperationException e) { + throw new Error("TESTBUG: Invocation failure", e); + } + }; + } + } +} + +enum ExtendedTestCase implements CompilerWhiteBoxTest.TestCase { + ACCESSOR_TEST("accessor"), + NONTRIVIAL_METHOD_TEST("nonTrivialMethod"), + TRIVIAL_CODE_TEST("trivialCode"); + + private final Executable executable; + private final Callable callable; + + @Override + public Executable getExecutable() { + return executable; + } + + @Override + public Callable getCallable() { + return callable; + } + + @Override + public boolean isOsr() { + return false; + } + + private ExtendedTestCase(String methodName) { + this.executable = LevelTransitionTest.Helper.getMethod(CompileMethodHolder.class, methodName); + this.callable = LevelTransitionTest.Helper.getCallable(new CompileMethodHolder(), methodName); + } + + private static class CompileMethodHolder { + private final int iter = 10; + private int field = 42; + + /** Non-trivial method for threshold policy: contains loops */ + public int nonTrivialMethod() { + int acc = 0; + for (int i = 0; i < iter; i++) { + acc += i; + } + return acc; + } + + /** Field accessor method */ + public int accessor() { + return field; + } + + /** Method considered as trivial by amount of code */ + public int trivialCode() { + int var = 0xBAAD_C0DE; + var *= field; + return var; + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/tiered/NonTieredLevelsTest.java --- a/hotspot/test/compiler/tiered/NonTieredLevelsTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/tiered/NonTieredLevelsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ /** * @test NonTieredLevelsTest - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * @build NonTieredLevelsTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -55,9 +55,7 @@ } public static void main(String[] args) throws Exception { - if (TIERED_COMPILATION) { - System.err.println("Test isn't applicable w/ enabled " - + "TieredCompilation. Skip test."); + if (CompilerWhiteBoxTest.skipOnTieredCompilation(true)) { return; } CompilerWhiteBoxTest.main(NonTieredLevelsTest::new, args); diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/tiered/TieredLevelsTest.java --- a/hotspot/test/compiler/tiered/TieredLevelsTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/tiered/TieredLevelsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /** * @test TieredLevelsTest - * @library /testlibrary /testlibrary/whitebox /compiler/whitebox + * @library /testlibrary /../../test/lib /compiler/whitebox * @build TieredLevelsTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -35,16 +35,14 @@ * @author igor.ignatyev@oracle.com */ public class TieredLevelsTest extends CompLevelsTest { - public static void main(String[] args) throws Exception { - if (!TIERED_COMPILATION) { - System.err.println("Test isn't applicable w/ disabled " - + "TieredCompilation. Skip test."); + public static void main(String[] args) throws Exception, Throwable { + if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) { return; } CompilerWhiteBoxTest.main(TieredLevelsTest::new, args); } - private TieredLevelsTest(TestCase testCase) { + protected TieredLevelsTest(TestCase testCase) { super(testCase); // to prevent inlining of #method WHITE_BOX.testSetDontInlineMethod(method, true); @@ -77,14 +75,18 @@ } } - @Override protected void checkLevel(int expected, int actual) { if (expected == COMP_LEVEL_FULL_PROFILE && actual == COMP_LEVEL_LIMITED_PROFILE) { // for simple method full_profile may be replaced by limited_profile + if (IS_VERBOSE) { + System.out.printf("Level check: full profiling was replaced " + + "by limited profiling. Expected: %d, actual:%d", + expected, actual); + } return; } super.checkLevel(expected, actual); - } + } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/tiered/TransitionsTestExecutor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/tiered/TransitionsTestExecutor.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Executes given test in a separate VM with enabled Tiered Compilation for + * CompilationPolicyChoice 2 and 3 + */ +public class TransitionsTestExecutor { + public static void main(String[] args) throws Throwable { + if (CompilerWhiteBoxTest.skipOnTieredCompilation(false)) { + return; + } + if (args.length != 1) { + throw new Error("TESTBUG: Test name should be specified"); + } + executeTestFor(2, args[0]); + executeTestFor(3, args[0]); + } + + private static void executeTestFor(int compilationPolicy, String testName) throws Throwable { + String policy = "-XX:CompilationPolicyChoice=" + compilationPolicy; + + // Get runtime arguments including VM options given to this executor + RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); + List vmArgs = runtime.getInputArguments(); + + // Construct execution command with compilation policy choice and test name + List args = new ArrayList<>(vmArgs); + Collections.addAll(args, policy, testName); + + OutputAnalyzer out = ProcessTools.executeTestJvm(args.toArray(new String[args.size()])); + int exitCode = out.getExitValue(); + if (exitCode != 0) { + throw new Error("Test execution failed with exit code " + exitCode); + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/types/correctness/CorrectnessTest.java --- a/hotspot/test/compiler/types/correctness/CorrectnessTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/types/correctness/CorrectnessTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test CorrectnessTest * @bug 8038418 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @ignore 8066173 * @compile execution/TypeConflict.java execution/TypeProfile.java * execution/MethodHandleDelegate.java diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/types/correctness/OffTest.java --- a/hotspot/test/compiler/types/correctness/OffTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/types/correctness/OffTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test CorrectnessTest * @bug 8038418 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @ignore 8066173 * @compile execution/TypeConflict.java execution/TypeProfile.java * execution/MethodHandleDelegate.java diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/uncommontrap/8009761/Test8009761.java --- a/hotspot/test/compiler/uncommontrap/8009761/Test8009761.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/uncommontrap/8009761/Test8009761.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ /* * @test * @bug 8009761 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates * @build Test8009761 * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/uncommontrap/TestDeoptOOM.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/uncommontrap/TestDeoptOOM.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 6898462 + * @summary failed reallocations of scalar replaced objects during deoptimization causes crash + * @run main/othervm -XX:-BackgroundCompilation -XX:CompileCommand=exclude,TestDeoptOOM::main -XX:CompileCommand=exclude,TestDeoptOOM::m9_1 -Xmx128M TestDeoptOOM + * + */ + +public class TestDeoptOOM { + + long f1; + long f2; + long f3; + long f4; + long f5; + + static class LinkedList { + LinkedList l; + long[] array; + LinkedList(LinkedList l, int size) { + array = new long[size]; + this.l = l; + } + } + + static LinkedList ll; + + static void consume_all_memory() { + int size = 128 * 1024 * 1024; + while(size > 0) { + try { + while(true) { + ll = new LinkedList(ll, size); + } + } catch(OutOfMemoryError oom) { + } + size = size / 2; + } + } + + static void free_memory() { + ll = null; + } + + static TestDeoptOOM m1(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + if (deopt) { + return tdoom; + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m1"); + } + return null; + } + + static TestDeoptOOM m2_1(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + if (deopt) { + return tdoom; + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m2_1"); + } + return null; + } + + static TestDeoptOOM m2(boolean deopt) { + try { + return m2_1(deopt); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m2"); + } + return null; + } + + static TestDeoptOOM m3_3(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + if (deopt) { + return tdoom; + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m3_3"); + } + return null; + } + + static boolean m3_2(boolean deopt) { + try { + return m3_3(deopt) != null; + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m3_2"); + } + return false; + } + + static TestDeoptOOM m3_1(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + if (m3_2(deopt)) { + return tdoom; + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m3_1"); + } + return null; + } + + static TestDeoptOOM m3(boolean deopt) { + try { + return m3_1(deopt); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m3"); + } + return null; + } + + static TestDeoptOOM m4(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + if (deopt) { + tdoom.f1 = 1l; + tdoom.f2 = 2l; + tdoom.f3 = 3l; + return tdoom; + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m4"); + } + return null; + } + + static TestDeoptOOM m5(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + synchronized(tdoom) { + if (deopt) { + return tdoom; + } + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m5"); + } + return null; + } + + synchronized TestDeoptOOM m6_1(boolean deopt) { + if (deopt) { + return this; + } + return null; + } + + static TestDeoptOOM m6(boolean deopt) { + try { + TestDeoptOOM tdoom = new TestDeoptOOM(); + return tdoom.m6_1(deopt); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m6"); + } + return null; + } + + static TestDeoptOOM m7_1(boolean deopt, Object lock) { + try { + synchronized(lock) { + TestDeoptOOM tdoom = new TestDeoptOOM(); + if (deopt) { + return tdoom; + } + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m7_1"); + } + return null; + } + + static TestDeoptOOM m7(boolean deopt, Object lock) { + try { + return m7_1(deopt, lock); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m7"); + } + return null; + } + + static class A { + long f1; + long f2; + long f3; + long f4; + long f5; + } + + static class B { + long f1; + long f2; + long f3; + long f4; + long f5; + + A a; + } + + static B m8(boolean deopt) { + try { + A a = new A(); + B b = new B(); + b.a = a; + if (deopt) { + return b; + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m8"); + } + return null; + } + + static void m9_1(int i) { + if (i > 90000) { + consume_all_memory(); + } + } + + static TestDeoptOOM m9() { + try { + for (int i = 0; i < 100000; i++) { + TestDeoptOOM tdoom = new TestDeoptOOM(); + m9_1(i); + if (i > 90000) { + return tdoom; + } + } + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in m1"); + } + return null; + } + + public static void main(String[] args) { + for (int i = 0; i < 20000; i++) { + m1(false); + } + + consume_all_memory(); + + try { + m1(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main " + oom.getMessage()); + } + + free_memory(); + + for (int i = 0; i < 20000; i++) { + m2(false); + } + + consume_all_memory(); + + try { + m2(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + for (int i = 0; i < 20000; i++) { + m3(false); + } + + consume_all_memory(); + + try { + m3(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + for (int i = 0; i < 20000; i++) { + m4(false); + } + + consume_all_memory(); + + try { + m4(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + for (int i = 0; i < 20000; i++) { + m5(false); + } + + consume_all_memory(); + + try { + m5(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + for (int i = 0; i < 20000; i++) { + m6(false); + } + + consume_all_memory(); + + try { + m6(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + final Object lock = new Object(); + + for (int i = 0; i < 20000; i++) { + m7(false, lock); + } + + consume_all_memory(); + + try { + m7(true, lock); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + Thread thread = new Thread() { + public void run() { + System.out.println("Acquiring lock"); + synchronized(lock) { + System.out.println("Lock acquired"); + } + System.out.println("Lock released"); + } + }; + thread.start(); + try { + thread.join(); + } catch(InterruptedException ie) { + } + + for (int i = 0; i < 20000; i++) { + m8(false); + } + + consume_all_memory(); + + try { + m8(true); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + + try { + m9(); + } catch(OutOfMemoryError oom) { + free_memory(); + System.out.println("OOM caught in main"); + } + + free_memory(); + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/uncommontrap/TraceDeoptimizationNoRealloc.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8067144 + * @summary -XX:+TraceDeoptimization tries to print realloc'ed objects even when there are none + * @run main/othervm -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:+IgnoreUnrecognizedVMOptions -XX:+TraceDeoptimization TraceDeoptimizationNoRealloc + * + */ + +public class TraceDeoptimizationNoRealloc { + + static void m(boolean some_condition) { + if (some_condition) { + return; + } + } + + + static public void main(String[] args) { + for (int i = 0; i < 20000; i++) { + m(false); + } + m(true); + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java --- a/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/AllocationCodeBlobTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -34,7 +34,7 @@ /* * @test AllocationCodeBlobTest * @bug 8059624 8064669 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build AllocationCodeBlobTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/ClearMethodStateTest.java --- a/hotspot/test/compiler/whitebox/ClearMethodStateTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/ClearMethodStateTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ /* * @test ClearMethodStateTest * @bug 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ClearMethodStateTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java --- a/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/CompilerWhiteBoxTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -38,19 +38,19 @@ */ public abstract class CompilerWhiteBoxTest { /** {@code CompLevel::CompLevel_none} -- Interpreter */ - protected static int COMP_LEVEL_NONE = 0; + protected static final int COMP_LEVEL_NONE = 0; /** {@code CompLevel::CompLevel_any}, {@code CompLevel::CompLevel_all} */ - protected static int COMP_LEVEL_ANY = -1; + protected static final int COMP_LEVEL_ANY = -1; /** {@code CompLevel::CompLevel_simple} -- C1 */ - protected static int COMP_LEVEL_SIMPLE = 1; + protected static final int COMP_LEVEL_SIMPLE = 1; /** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */ - protected static int COMP_LEVEL_LIMITED_PROFILE = 2; + protected static final int COMP_LEVEL_LIMITED_PROFILE = 2; /** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */ - protected static int COMP_LEVEL_FULL_PROFILE = 3; + protected static final int COMP_LEVEL_FULL_PROFILE = 3; /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */ - protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4; + protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; /** Maximal value for CompLevel */ - protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; + protected static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION; /** Instance of WhiteBox */ protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); @@ -336,14 +336,22 @@ System.out.printf("%n%s:%n", method); System.out.printf("\tcompilable:\t%b%n", WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, false)); - System.out.printf("\tcompiled:\t%b%n", - WHITE_BOX.isMethodCompiled(method, false)); + boolean isCompiled = WHITE_BOX.isMethodCompiled(method, false); + System.out.printf("\tcompiled:\t%b%n", isCompiled); + if (isCompiled) { + System.out.printf("\tcompile_id:\t%d%n", + NMethod.get(method, false).compile_id); + } System.out.printf("\tcomp_level:\t%d%n", WHITE_BOX.getMethodCompilationLevel(method, false)); System.out.printf("\tosr_compilable:\t%b%n", WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, true)); - System.out.printf("\tosr_compiled:\t%b%n", - WHITE_BOX.isMethodCompiled(method, true)); + isCompiled = WHITE_BOX.isMethodCompiled(method, true); + System.out.printf("\tosr_compiled:\t%b%n", isCompiled); + if (isCompiled) { + System.out.printf("\tosr_compile_id:\t%d%n", + NMethod.get(method, true).compile_id); + } System.out.printf("\tosr_comp_level:\t%d%n", WHITE_BOX.getMethodCompilationLevel(method, true)); System.out.printf("\tin_queue:\t%b%n", @@ -426,6 +434,22 @@ } return result; } + + /** + * Skip the test for the specified value of Tiered Compilation + * @param value of TieredCompilation the test should not run with + * @return {@code true} if the test should be skipped, + * {@code false} otherwise + */ + protected static boolean skipOnTieredCompilation(boolean value) { + if (value == CompilerWhiteBoxTest.TIERED_COMPILATION) { + System.err.println("Test isn't applicable w/ " + + (value ? "enabled" : "disabled") + + "TieredCompilation. Skip test."); + return true; + } + return false; + } } enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/DeoptimizeAllTest.java --- a/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/DeoptimizeAllTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test DeoptimizeAllTest * @bug 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build DeoptimizeAllTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/DeoptimizeFramesTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/whitebox/DeoptimizeFramesTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 DeoptimizeFramesTest + * @bug 8028595 + * @library /testlibrary /../../test/lib + * @build DeoptimizeFramesTest + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xmixed + * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method + * -XX:-DeoptimizeRandom DeoptimizeFramesTest true + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI -Xmixed + * -XX:CompileCommand=compileonly,DeoptimizeFramesTest$TestCaseImpl::method + * -XX:-DeoptimizeRandom DeoptimizeFramesTest false + * @summary testing of WB::deoptimizeFrames() + */ +import java.lang.reflect.Executable; +import java.util.concurrent.Callable; +import java.util.concurrent.Phaser; + +import sun.hotspot.code.NMethod; +import com.oracle.java.testlibrary.Asserts; +import com.oracle.java.testlibrary.InfiniteLoop; + +public class DeoptimizeFramesTest extends CompilerWhiteBoxTest { + private final boolean makeNotEntrant; + private final Phaser phaser; + + private DeoptimizeFramesTest(boolean makeNotEntrant, Phaser phaser) { + super(new TestCaseImpl(phaser)); + // to prevent inlining of #method + WHITE_BOX.testSetDontInlineMethod(method, true); + this.makeNotEntrant = makeNotEntrant; + this.phaser = phaser; + System.out.printf("DeoptimizeFramesTest(makeNotEntrant = %b)%n", + makeNotEntrant); + } + + public static void main(String[] args) throws Exception { + Asserts.assertEQ(args.length, 1, + "[TESTBUG] args should contain 1 element"); + new DeoptimizeFramesTest(Boolean.valueOf(args[0]), new Phaser()).runTest(); + } + + @Override + protected void test() throws Exception { + compile(); + checkCompiled(); + NMethod nm = NMethod.get(method, testCase.isOsr()); + + WHITE_BOX.deoptimizeFrames(makeNotEntrant); + // #method should still be compiled, since it didn't have frames on stack + checkCompiled(); + NMethod nm2 = NMethod.get(method, testCase.isOsr()); + Asserts.assertEQ(nm.compile_id, nm2.compile_id, + "should be the same nmethod"); + + phaser.register(); + Thread t = new Thread(() -> compile(1)); + t.start(); + // pass 1st phase, #method is on stack + int p = phaser.arriveAndAwaitAdvance(); + WHITE_BOX.deoptimizeFrames(makeNotEntrant); + // pass 2nd phase, #method can exit + phaser.awaitAdvance(phaser.arriveAndDeregister()); + + try { + t.join(); + } catch (InterruptedException e) { + throw new Error("method '" + method + "' is still executing", e); + } + + // invoke one more time to recompile not entrant if any + compile(1); + + nm2 = NMethod.get(method, testCase.isOsr()); + if (makeNotEntrant) { + if (nm2 != null) { + Asserts.assertNE(nm.compile_id, nm2.compile_id, + String.format("compilation %d can't be available", nm.compile_id)); + } + } else { + Asserts.assertEQ(nm.compile_id, nm2.compile_id, "should be the same nmethod"); + } + } + + + private static class TestCaseImpl implements TestCase { + private static final Executable EXECUTABLE; + static { + try { + EXECUTABLE = TestCaseImpl.class.getDeclaredMethod("method"); + } catch (NoSuchMethodException e) { + throw new Error("[TESTBUG] method not found", e); + } + } + + private final Phaser phaser; + + public TestCaseImpl(Phaser phaser) { + this.phaser = phaser; + phaser.register(); + } + + @Override + public String name() { + return "2phases"; + } + + @Override + public Executable getExecutable() { + return EXECUTABLE; + } + + @Override + public Callable getCallable() { + return () -> { + return method(); + }; + } + + @Override + public boolean isOsr() { + return false; + } + + private int method() { + phaser.arriveAndAwaitAdvance(); + phaser.arriveAndAwaitAdvance(); + return 0; + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java --- a/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/DeoptimizeMethodTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test DeoptimizeMethodTest * @bug 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build DeoptimizeMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java --- a/hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/DeoptimizeMultipleOSRTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -28,7 +28,7 @@ /* * @test DeoptimizeMultipleOSRTest * @bug 8061817 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build DeoptimizeMultipleOSRTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java --- a/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/EnqueueMethodForCompilationTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test EnqueueMethodForCompilationTest * @bug 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build EnqueueMethodForCompilationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java --- a/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/ForceNMethodSweepTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -34,7 +34,7 @@ /* * @test * @bug 8059624 8064669 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ForceNMethodSweepTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java --- a/hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/GetCodeHeapEntriesTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -33,7 +33,7 @@ /* * @test GetCodeHeapEntriesTest * @bug 8059624 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build GetCodeHeapEntriesTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/GetNMethodTest.java --- a/hotspot/test/compiler/whitebox/GetNMethodTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/GetNMethodTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -29,7 +29,7 @@ /* * @test GetNMethodTest * @bug 8038240 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build GetNMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/IsMethodCompilableTest.java --- a/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/IsMethodCompilableTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test IsMethodCompilableTest * @bug 8007270 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox /testlibrary/com/oracle/java/testlibrary + * @library /testlibrary /../../test/lib /testlibrary/com/oracle/java/testlibrary * @build IsMethodCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/LockCompilationTest.java --- a/hotspot/test/compiler/whitebox/LockCompilationTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/LockCompilationTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test LockCompilationTest * @bug 8059624 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build LockCompilationTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java --- a/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/MakeMethodNotCompilableTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test MakeMethodNotCompilableTest * @bug 8012322 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build MakeMethodNotCompilableTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java --- a/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/SetDontInlineMethodTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test SetDontInlineMethodTest * @bug 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build SetDontInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java --- a/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/compiler/whitebox/SetForceInlineMethodTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test SetForceInlineMethodTest * @bug 8006683 8007288 8022832 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build SetForceInlineMethodTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/TestCardTablePageCommits.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/TestCardTablePageCommits.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* This code is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 only, as +* published by the Free Software Foundation. +* +* This code is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +* version 2 for more details (a copy is included in the LICENSE file that +* accompanied this code). +* +* You should have received a copy of the GNU General Public License version +* 2 along with this work; if not, write to the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +* +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +* or visit www.oracle.com if you need additional information or have any +* questions. +*/ + +import com.oracle.java.testlibrary.JDKToolFinder; +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; +import com.oracle.java.testlibrary.Platform; + +/* + * @test TestCardTablePageCommits + * @key gc + * @bug 8059066 + * @summary Tests that the card table does not commit the same page twice + * @library /testlibrary + * @run driver TestCardTablePageCommits + */ +public class TestCardTablePageCommits { + public static void main(String args[]) throws Exception { + // The test is run with a small heap to make sure all pages in the card + // table gets committed. Need 8 MB heap to trigger the bug on SPARC + // because of 8kB pages, assume 4 KB pages for all other CPUs. + String Xmx = Platform.isSparc() ? "-Xmx8m" : "-Xmx4m"; + + String[] opts = {Xmx, "-XX:NativeMemoryTracking=detail", "-XX:+UseParallelGC", "-version"}; + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(opts); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldHaveExitValue(0); + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/TestSmallHeap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/gc/TestSmallHeap.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 TestSmallHeap + * @bug 8067438 + * @requires vm.gc=="null" + * @summary Verify that starting the VM with a small heap works + * @library /testlibrary + * @run main/othervm -Xmx4m -XX:+UseParallelGC TestSmallHeap + * @run main/othervm -Xmx4m -XX:+UseSerialGC TestSmallHeap + * @run main/othervm -Xmx4m -XX:+UseG1GC TestSmallHeap + * @run main/othervm -Xmx4m -XX:+UseConcMarkSweepGC -XX:CMSMarkStackSizeMax=1032 TestSmallHeap + * + * Note: It would be nice to verify the minimal supported heap size here, + * but that turns out to be quite tricky since we align the heap size based + * on the card table size. And the card table size is aligned based on the + * minimal pages size provided by the os. This means that on most platforms, + * where the minimal page size is 4k, we get a minimal heap size of 2m but + * on Solaris/Sparc we have a page size of 8k and get a minimal heap size + * of 8m. + * There is also no check in the VM for verifying that the maximum heap size + * is larger than the supported minimal heap size. This means that specifying + * -Xmx1m on the command line is fine but will give a heap of 2m (or 4m). + * To work around these rather strange behaviors this test uses 4m for all + * platforms. + */ + +import sun.management.ManagementFactoryHelper; +import static com.oracle.java.testlibrary.Asserts.*; + +public class TestSmallHeap { + + public static void main(String[] args) { + String maxHeap = ManagementFactoryHelper.getDiagnosticMXBean().getVMOption("MaxHeapSize").getValue(); + String expectedMaxHeap = "4194304"; + assertEQ(maxHeap, expectedMaxHeap); + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java --- a/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestCMSHeapSizeFlags.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key gc * @bug 8006088 * @summary Tests argument processing for initial and maximum heap size for the CMS collector - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestCMSHeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestG1HeapSizeFlags.java --- a/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestG1HeapSizeFlags.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key gc * @bug 8006088 * @summary Tests argument processing for initial and maximum heap size for the G1 collector - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestG1HeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestMinInitialErgonomics.java --- a/hotspot/test/gc/arguments/TestMinInitialErgonomics.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestMinInitialErgonomics.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key gc * @bug 8006088 * @summary Test ergonomics decisions related to minimum and initial heap size. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestMinInitialErgonomics TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java --- a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @bug 8006088 * @summary Tests argument processing for initial and maximum heap size for the * parallel collectors. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestParallelHeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java --- a/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestSerialHeapSizeFlags.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key gc * @bug 8006088 * @summary Tests argument processing for initial and maximum heap size for the Serial collector - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestSerialHeapSizeFlags TestMaxHeapSizeTools * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java --- a/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestSurvivorAlignmentInBytesOption.java Sat Jan 10 12:38:18 2015 -0800 @@ -22,29 +22,24 @@ */ import com.oracle.java.testlibrary.ExitCode; -import com.oracle.java.testlibrary.Utils; import com.oracle.java.testlibrary.cli.CommandLineOptionTest; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - /** * @test * @bug 8031323 * @summary Verify SurvivorAlignmentInBytes option processing. * @library /testlibrary + * @requires vm.opt.SurvivorAlignmentInBytes == null + * & vm.opt.ObjectAlignmentInBytes == null + * & vm.opt.UnlockExperimentalVMOptions == null + * & (vm.opt.IgnoreUnrecognizedVMOptions == null + * | vm.opt.IgnoreUnrecognizedVMOptions == "false") * @run main TestSurvivorAlignmentInBytesOption */ public class TestSurvivorAlignmentInBytesOption { - private static final String[] FILTERED_VM_OPTIONS - = Utils.getFilteredTestJavaOpts( - "UnlockExperimentalVMOptions", - "SurvivorAlignmentInBytes", - "ObjectAlignmentInBytes"); - public static void main(String args[]) throws Throwable { String optionName = "SurvivorAlignmentInBytes"; + String unlockExperimentalVMOpts = "UnlockExperimentalVMOptions"; String optionIsExperimental = CommandLineOptionTest.getExperimentalOptionErrorMessage( optionName); @@ -56,65 +51,84 @@ // Verify that without -XX:+UnlockExperimentalVMOptions usage of // SurvivorAlignmentInBytes option will cause JVM startup failure // with the warning message saying that that option is experimental. + String shouldFailMessage = String.format("JVM option '%s' is " + + "experimental.%nJVM startup should fail without " + + "-XX:+UnlockExperimentalVMOptions option", optionName); CommandLineOptionTest.verifyJVMStartup( - new String[]{optionIsExperimental}, null, ExitCode.FAIL, false, - TestSurvivorAlignmentInBytesOption.prepareOptions( - "-XX:-UnlockExperimentalVMOptions", - CommandLineOptionTest.prepareNumericFlag( - optionName, 64))); + new String[]{optionIsExperimental}, null, + shouldFailMessage, shouldFailMessage, + ExitCode.FAIL, false, + "-XX:-UnlockExperimentalVMOptions", + CommandLineOptionTest.prepareBooleanFlag( + unlockExperimentalVMOpts, false), + CommandLineOptionTest.prepareNumericFlag(optionName, 64)); // Verify that with -XX:+UnlockExperimentalVMOptions passed to JVM // usage of SurvivorAlignmentInBytes option won't cause JVM startup // failure. + String shouldPassMessage = String.format("JVM option '%s' is " + + "experimental.%nJVM startup should pass with " + + "-XX:+UnlockExperimentalVMOptions option", optionName); + String noWarningMessage = "There should be no warnings when use " + + "with -XX:+UnlockExperimentalVMOptions option"; CommandLineOptionTest.verifyJVMStartup( - null, new String[]{optionIsExperimental}, ExitCode.OK, false, - TestSurvivorAlignmentInBytesOption.prepareOptions( - CommandLineOptionTest.prepareNumericFlag( - optionName, 64))); + null, new String[]{optionIsExperimental}, + shouldPassMessage, noWarningMessage, + ExitCode.OK, false, + CommandLineOptionTest.prepareBooleanFlag( + unlockExperimentalVMOpts, true), + CommandLineOptionTest.prepareNumericFlag(optionName, 64)); - // Verify that if specified SurvivorAlignmentInBytes is lower then + // Verify that if specified SurvivorAlignmentInBytes is lower than // ObjectAlignmentInBytes, then the JVM startup will fail with // appropriate error message. + shouldFailMessage = String.format("JVM startup should fail with " + + "'%s' option value lower than ObjectAlignmentInBytes", optionName); CommandLineOptionTest.verifyJVMStartup( - new String[]{valueIsTooSmall}, null, ExitCode.FAIL, false, - TestSurvivorAlignmentInBytesOption.prepareOptions( - CommandLineOptionTest.prepareNumericFlag( - optionName, 2))); + new String[]{valueIsTooSmall}, null, + shouldFailMessage, shouldFailMessage, + ExitCode.FAIL, false, + CommandLineOptionTest.prepareBooleanFlag( + unlockExperimentalVMOpts, true), + CommandLineOptionTest.prepareNumericFlag(optionName, 2)); // Verify that if specified SurvivorAlignmentInBytes value is not // a power of 2 then the JVM startup will fail with appropriate error // message. + shouldFailMessage = String.format("JVM startup should fail with " + + "'%s' option value is not a power of 2", optionName); CommandLineOptionTest.verifyJVMStartup( - new String[]{mustBePowerOf2}, null, ExitCode.FAIL, false, - TestSurvivorAlignmentInBytesOption.prepareOptions( - CommandLineOptionTest.prepareNumericFlag( - optionName, 127))); + new String[]{mustBePowerOf2}, null, + shouldFailMessage, shouldFailMessage, + ExitCode.FAIL, false, + CommandLineOptionTest.prepareBooleanFlag( + unlockExperimentalVMOpts, true), + CommandLineOptionTest.prepareNumericFlag(optionName, 127)); // Verify that if SurvivorAlignmentInBytes has correct value, then // the JVM will be started without errors. + shouldPassMessage = String.format("JVM startup should pass with " + + "correct '%s' option value", optionName); + noWarningMessage = String.format("There should be no warnings when use " + + "correct '%s' option value", optionName); CommandLineOptionTest.verifyJVMStartup( null, new String[]{".*SurvivorAlignmentInBytes.*"}, + shouldPassMessage, noWarningMessage, ExitCode.OK, false, - TestSurvivorAlignmentInBytesOption.prepareOptions( - CommandLineOptionTest.prepareNumericFlag( - optionName, 128))); + CommandLineOptionTest.prepareBooleanFlag( + unlockExperimentalVMOpts, true), + CommandLineOptionTest.prepareNumericFlag(optionName, 128)); // Verify that we can setup different SurvivorAlignmentInBytes values. for (int alignment = 32; alignment <= 128; alignment *= 2) { + shouldPassMessage = String.format("JVM startup should pass with " + + "'%s' = %d", optionName, alignment); CommandLineOptionTest.verifyOptionValue(optionName, - Integer.toString(alignment), false, - TestSurvivorAlignmentInBytesOption.prepareOptions( - CommandLineOptionTest.prepareNumericFlag( - optionName, alignment))); + Integer.toString(alignment), shouldPassMessage, + CommandLineOptionTest.prepareBooleanFlag( + unlockExperimentalVMOpts, true), + CommandLineOptionTest.prepareNumericFlag( + optionName, alignment)); } } - - private static String[] prepareOptions(String... options) { - List finalOptions = new LinkedList<>(); - Collections.addAll(finalOptions, - TestSurvivorAlignmentInBytesOption.FILTERED_VM_OPTIONS); - finalOptions.add(CommandLineOptionTest.UNLOCK_EXPERIMENTAL_VM_OPTIONS); - Collections.addAll(finalOptions, options); - return finalOptions.toArray(new String[finalOptions.size()]); - } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java --- a/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/arguments/TestUseCompressedOopsErgo.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key gc * @bug 8010722 * @summary Tests ergonomics for UseCompressedOops. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestUseCompressedOopsErgo TestUseCompressedOopsErgoTools * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java --- a/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/class_unloading/TestCMSClassUnloadingEnabledHWM.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @key gc * @bug 8049831 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestCMSClassUnloadingEnabledHWM * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java --- a/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/class_unloading/TestG1ClassUnloadingHWM.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @key gc * @bug 8049831 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestG1ClassUnloadingHWM * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java --- a/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestHumongousCodeCacheRoots.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key regression * @key gc * @bug 8027756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestHumongousCodeCacheRoots * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData00.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8038423 * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData00 * @run driver/timeout=720 TestShrinkAuxiliaryData00 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData05.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData05 * @run driver/timeout=720 TestShrinkAuxiliaryData05 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData10.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData10 * @run driver/timeout=720 TestShrinkAuxiliaryData10 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData15.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData15 * @run driver/timeout=720 TestShrinkAuxiliaryData15 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData20.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData20 * @run driver/timeout=720 TestShrinkAuxiliaryData20 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData25.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData25 * @run driver/timeout=720 TestShrinkAuxiliaryData25 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java --- a/hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/g1/TestShrinkAuxiliaryData30.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,7 @@ * @summary Checks that decommitment occurs for JVM with different * G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values * @requires vm.gc=="G1" | vm.gc=="null" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestShrinkAuxiliaryData TestShrinkAuxiliaryData30 * @run driver/timeout=720 TestShrinkAuxiliaryData30 */ diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java --- a/hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/metaspace/TestCapacityUntilGCWrapAround.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @key gc * @bug 8049831 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestCapacityUntilGCWrapAround * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/survivorAlignment/TestAllocationInEden.java --- a/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/survivorAlignment/TestAllocationInEden.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031323 * @summary Verify that object's alignment in eden space is not affected by * SurvivorAlignmentInBytes option. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestAllocationInEden SurvivorAlignmentTestMain AlignmentHelper * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission @@ -34,37 +34,43 @@ * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB - * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=128m -XX:MaxHeapSize=192m + * -XX:-ExplicitGCInvokesConcurrent * TestAllocationInEden 10m 9 EDEN * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 -XX:-UseTLAB - * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=128m -XX:MaxHeapSize=192m + * -XX:-ExplicitGCInvokesConcurrent * TestAllocationInEden 10m 47 EDEN * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB - * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=128m -XX:MaxHeapSize=192m + * -XX:-ExplicitGCInvokesConcurrent * TestAllocationInEden 10m 9 EDEN * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 -XX:-UseTLAB - * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=128m -XX:MaxHeapSize=192m + * -XX:-ExplicitGCInvokesConcurrent * TestAllocationInEden 10m 87 EDEN * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB - * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=128m -XX:MaxHeapSize=192m + * -XX:-ExplicitGCInvokesConcurrent * TestAllocationInEden 10m 9 EDEN * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 -XX:-UseTLAB - * -XX:OldSize=128m -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=128m -XX:MaxHeapSize=192m + * -XX:-ExplicitGCInvokesConcurrent * TestAllocationInEden 10m 147 EDEN */ public class TestAllocationInEden { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java --- a/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromEdenToTenured.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,50 +26,50 @@ * @bug 8031323 * @summary Verify that objects promoted from eden space to tenured space during * full GC are not aligned to SurvivorAlignmentInBytes value. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestPromotionFromEdenToTenured SurvivorAlignmentTestMain * AlignmentHelper * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 + * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 * TestPromotionFromEdenToTenured 10m 9 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 + * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 * TestPromotionFromEdenToTenured 10m 47 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=96m + * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 * TestPromotionFromEdenToTenured 10m 9 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=128m + * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 * TestPromotionFromEdenToTenured 10m 87 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32M -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32M -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 + * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 * TestPromotionFromEdenToTenured 10m 9 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=64m -XX:MaxNewSize=64m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=96m -XX:SurvivorRatio=1 + * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 * TestPromotionFromEdenToTenured 10m 147 TENURED diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java --- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterFullGC.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,44 +26,44 @@ * @bug 8031323 * @summary Verify that objects promoted from survivor space to tenured space * during full GC are not aligned to SurvivorAlignmentInBytes value. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestPromotionFromSurvivorToTenuredAfterFullGC * SurvivorAlignmentTestMain AlignmentHelper * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=160m + * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=160m + * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 47 * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m - * -XX:OldSize=32m -XX:InitialHeapSize=232m + * -XX:OldSize=32m -XX:MaxHeapSize=232m * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 * TestPromotionFromSurvivorToTenuredAfterFullGC 10m 9 TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=160m + * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 87 * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m - * -XX:OldSize=32M -XX:InitialHeapSize=288m + * -XX:OldSize=32M -XX:MaxHeapSize=288m * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 @@ -71,8 +71,8 @@ * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32m -XX:SurvivorRatio=1 - * -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32m -XX:MaxHeapSize=160m + * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 * TestPromotionFromSurvivorToTenuredAfterFullGC 20m 147 diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java --- a/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/survivorAlignment/TestPromotionFromSurvivorToTenuredAfterMinorGC.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,14 +27,14 @@ * @summary Verify that objects promoted from survivor space to tenured space * when their age exceeded tenuring threshold are not aligned to * SurvivorAlignmentInBytes value. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestPromotionFromSurvivorToTenuredAfterMinorGC * SurvivorAlignmentTestMain AlignmentHelper * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:SurvivorRatio=1 + * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 @@ -42,7 +42,7 @@ * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:SurvivorRatio=1 + * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 @@ -50,15 +50,15 @@ * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=200m -XX:MaxNewSize=200m - * -XX:OldSize=32M -XX:InitialHeapSize=232m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32M -XX:MaxHeapSize=232m -XX:SurvivorRatio=1 + * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9 * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:SurvivorRatio=1 + * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 @@ -66,15 +66,15 @@ * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m - * -XX:OldSize=32M -XX:InitialHeapSize=288m - * -XX:SurvivorRatio=1 -XX:-ExplicitGCInvokesConcurrent + * -XX:OldSize=32M -XX:MaxHeapSize=288m -XX:SurvivorRatio=1 + * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 * TestPromotionFromSurvivorToTenuredAfterMinorGC 10m 9 * TENURED * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m - * -XX:OldSize=32M -XX:SurvivorRatio=1 + * -XX:OldSize=32M -XX:MaxHeapSize=160m -XX:SurvivorRatio=1 * -XX:-ExplicitGCInvokesConcurrent * -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java --- a/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/survivorAlignment/TestPromotionToSurvivor.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8031323 * @summary Verify that objects promoted from eden space to survivor space after * minor GC are aligned to SurvivorAlignmentInBytes. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestPromotionToSurvivor * SurvivorAlignmentTestMain AlignmentHelper * @run main ClassFileInstaller sun.hotspot.WhiteBox @@ -35,36 +35,37 @@ * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m - * -XX:-ExplicitGCInvokesConcurrent + * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent * TestPromotionToSurvivor 10m 9 SURVIVOR * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=32 -XX:OldSize=128m + * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent * TestPromotionToSurvivor 20m 47 SURVIVOR * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m - * -XX:-ExplicitGCInvokesConcurrent + * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent * TestPromotionToSurvivor 8m 9 SURVIVOR * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=64 -XX:OldSize=128m - * -XX:-ExplicitGCInvokesConcurrent + * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent * TestPromotionToSurvivor 20m 87 SURVIVOR * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=256m -XX:MaxNewSize=256m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions - * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=32m - * -XX:InitialHeapSize=288m -XX:-ExplicitGCInvokesConcurrent + * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m + * -XX:MaxHeapSize=384m -XX:-ExplicitGCInvokesConcurrent * TestPromotionToSurvivor 10m 9 SURVIVOR * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI -XX:NewSize=128m -XX:MaxNewSize=128m * -XX:SurvivorRatio=1 -XX:+UnlockExperimentalVMOptions * -XX:SurvivorAlignmentInBytes=128 -XX:OldSize=128m - * -XX:-ExplicitGCInvokesConcurrent + * -XX:MaxHeapSize=256m -XX:-ExplicitGCInvokesConcurrent * TestPromotionToSurvivor 20m 147 SURVIVOR */ public class TestPromotionToSurvivor { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/whitebox/TestConcMarkCycleWB.java --- a/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/whitebox/TestConcMarkCycleWB.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test TestConMarkCycleWB * @bug 8065579 * @requires vm.gc=="null" | vm.gc=="G1" - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.WhiteBox TestConcMarkCycleWB * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/gc/whitebox/TestWBGC.java --- a/hotspot/test/gc/whitebox/TestWBGC.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/gc/whitebox/TestWBGC.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test TestWBGC * @bug 8055098 * @summary Test verify that WB methods isObjectInOldGen and youngGC works correctly. - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build TestWBGC * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run driver TestWBGC diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/ClassUnload/KeepAliveClass.java --- a/hotspot/test/runtime/ClassUnload/KeepAliveClass.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/ClassUnload/KeepAliveClass.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test KeepAliveClass * @summary This test case uses a java.lang.Class instance to keep a class alive. - * @library /testlibrary /testlibrary/whitebox /runtime/testlibrary + * @library /testlibrary /../../test/lib /runtime/testlibrary * @library classes * @build KeepAliveClass test.Empty * @build ClassUnloadCommon diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/ClassUnload/KeepAliveClassLoader.java --- a/hotspot/test/runtime/ClassUnload/KeepAliveClassLoader.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/ClassUnload/KeepAliveClassLoader.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test KeepAliveClassLoader * @summary This test case uses a java.lang.ClassLoader instance to keep a class alive. - * @library /testlibrary /testlibrary/whitebox /runtime/testlibrary + * @library /testlibrary /../../test/lib /runtime/testlibrary * @library classes * @build KeepAliveClassLoader test.Empty * @build ClassUnloadCommon diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/ClassUnload/KeepAliveObject.java --- a/hotspot/test/runtime/ClassUnload/KeepAliveObject.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/ClassUnload/KeepAliveObject.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test KeepAliveObject * @summary This test case uses a class instance to keep the class alive. - * @library /testlibrary /testlibrary/whitebox /runtime/testlibrary + * @library /testlibrary /../../test/lib /runtime/testlibrary * @library classes * @build KeepAliveObject test.Empty * @build ClassUnloadCommon diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/ClassUnload/KeepAliveSoftReference.java --- a/hotspot/test/runtime/ClassUnload/KeepAliveSoftReference.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/ClassUnload/KeepAliveSoftReference.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test KeepAliveSoftReference * @summary This test case uses a java.lang.ref.SoftReference referencing a class instance to keep a class alive. - * @library /testlibrary /testlibrary/whitebox /runtime/testlibrary + * @library /testlibrary /../../test/lib /runtime/testlibrary * @library classes * @build KeepAliveSoftReference test.Empty * @build ClassUnloadCommon diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/ClassUnload/UnloadTest.java --- a/hotspot/test/runtime/ClassUnload/UnloadTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/ClassUnload/UnloadTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,7 +23,7 @@ /* * @test UnloadTest - * @library /runtime/testlibrary /testlibrary /testlibrary/whitebox + * @library /runtime/testlibrary /testlibrary /../../test/lib * @library classes * @build ClassUnloadCommon test.Empty * @build UnloadTest diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/CommandLine/TraceExceptionsTest.java --- a/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -33,11 +33,6 @@ public class TraceExceptionsTest { public static void main(String[] args) throws Exception { - if (!Platform.isDebugBuild()) { - System.out.println("Skip the test on product builds since XX:+TraceExceptions is not available on product builds"); - return; - } - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( "-XX:+TraceExceptions", "NoClassFound"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/Metaspace/FragmentMetaspace.java --- a/hotspot/test/runtime/Metaspace/FragmentMetaspace.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/Metaspace/FragmentMetaspace.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ * @test * @library /runtime/testlibrary * @build GeneratedClassLoader - * @run main/othervm/timeout=200 FragmentMetaspace + * @run main/othervm/timeout=200 -Xmx300m FragmentMetaspace */ import java.io.IOException; @@ -38,25 +38,34 @@ */ public class FragmentMetaspace { + public static Class c; + public static void main(String... args) { - runGrowing(Long.valueOf(System.getProperty("time", "80000"))); + runGrowing(Long.valueOf(System.getProperty("time", "80000")), + Integer.valueOf(System.getProperty("iterations", "200"))); // try to clean up and unload classes to decrease // class verification time in debug vm System.gc(); } - private static void runGrowing(long time) { + private static void runGrowing(long time, int iterations) { long startTime = System.currentTimeMillis(); - for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) { + for (int i = 0; System.currentTimeMillis() < startTime + time && i < iterations; ++i) { try { GeneratedClassLoader gcl = new GeneratedClassLoader(); - Class c = gcl.getGeneratedClasses(i, 100)[0]; + // getGeneratedClasses throws a RuntimeException in cases where + // the javac exit code is not 0. If the original reason for the exception is + // a "java.lang.OutOfMemoryError: Java heap space", + // increase the heap size in the @run tag and rerun the test. + // The heap can be exhausted by this test, but heap exhaustion + // is not a failure mode of this test and should be ignored. + c = gcl.getGeneratedClasses(i, 100)[0]; c.newInstance(); c = null; gcl = null; - } catch (IOException|InstantiationException|IllegalAccessException ex) { + } catch (IOException | InstantiationException | IllegalAccessException ex) { throw new RuntimeException(ex); } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/ChangeTrackingLevel.java --- a/hotspot/test/runtime/NMT/ChangeTrackingLevel.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/ChangeTrackingLevel.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8059100 * @summary Test that you can decrease NMT tracking level but not increase it. * @key nmt - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ChangeTrackingLevel * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/JcmdDetailDiff.java --- a/hotspot/test/runtime/NMT/JcmdDetailDiff.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/JcmdDetailDiff.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary run NMT baseline, allocate memory and verify output from detail.diff * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @ignore * @build JcmdDetailDiff * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/JcmdSummaryDiff.java --- a/hotspot/test/runtime/NMT/JcmdSummaryDiff.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/JcmdSummaryDiff.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary run NMT baseline, allocate memory and verify output from summary.diff * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build JcmdSummaryDiff * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary JcmdSummaryDiff diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/MallocRoundingReportTest.java --- a/hotspot/test/runtime/NMT/MallocRoundingReportTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/MallocRoundingReportTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary Test consistency of NMT by creating allocations of the Test type with various sizes and verifying visibility with jcmd * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build MallocRoundingReportTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocRoundingReportTest diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/MallocSiteHashOverflow.java --- a/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/MallocSiteHashOverflow.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @summary Test corner case that overflows malloc site hashtable bucket * @requires sun.arch.data.model == "32" * @key nmt jcmd stress - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build MallocSiteHashOverflow * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocSiteHashOverflow diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/MallocStressTest.java --- a/hotspot/test/runtime/NMT/MallocStressTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/MallocStressTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary Stress test for malloc tracking * @key nmt jcmd stress - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build MallocStressTest * @ignore - This test is disabled since it will stress NMT and timeout during normal testing * @run main ClassFileInstaller sun.hotspot.WhiteBox diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/MallocTestType.java --- a/hotspot/test/runtime/NMT/MallocTestType.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/MallocTestType.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @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 /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build MallocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/MallocTrackingVerify.java --- a/hotspot/test/runtime/NMT/MallocTrackingVerify.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/MallocTrackingVerify.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8054836 * @summary Test to verify correctness of malloc tracking * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build MallocTrackingVerify * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail MallocTrackingVerify diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/ReleaseCommittedMemory.java --- a/hotspot/test/runtime/NMT/ReleaseCommittedMemory.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/ReleaseCommittedMemory.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @bug 8013120 * @summary Release committed memory and make sure NMT handles it correctly * @key nmt regression - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ReleaseCommittedMemory * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/ReleaseNoCommit.java --- a/hotspot/test/runtime/NMT/ReleaseNoCommit.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/ReleaseNoCommit.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary Release uncommitted memory and make sure NMT handles it correctly * @key nmt regression - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ReleaseNoCommit * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=summary ReleaseNoCommit diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/SummarySanityCheck.java --- a/hotspot/test/runtime/NMT/SummarySanityCheck.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/SummarySanityCheck.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @key nmt jcmd * @summary Sanity check the output of NMT - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build SummarySanityCheck * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/ThreadedMallocTestType.java --- a/hotspot/test/runtime/NMT/ThreadedMallocTestType.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/ThreadedMallocTestType.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ThreadedMallocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java --- a/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/ThreadedVirtualAllocTestType.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ThreadedVirtualAllocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java --- a/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/VirtualAllocCommitUncommitRecommit.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary Test reserve/commit/uncommit/release of virtual memory and that we track it correctly * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build VirtualAllocCommitUncommitRecommit * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail VirtualAllocCommitUncommitRecommit diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/NMT/VirtualAllocTestType.java --- a/hotspot/test/runtime/NMT/VirtualAllocTestType.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/NMT/VirtualAllocTestType.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @test * @summary Test Reserve/Commit/Uncommit/Release of virtual memory and that we track it correctly * @key nmt jcmd - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build VirtualAllocTestType * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8047290 + * @summary Ensure that a Monitor::lock_without_safepoint_check fires an assert when it incorrectly acquires a lock which must always have safepoint checks. + * @library /testlibrary /../../test/lib + * @build AssertSafepointCheckConsistency1 + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main AssertSafepointCheckConsistency1 + */ + +import com.oracle.java.testlibrary.*; + +import sun.hotspot.WhiteBox; + +public class AssertSafepointCheckConsistency1 { + public static void main(String args[]) throws Exception { + if (args.length > 0) { + WhiteBox.getWhiteBox().assertMatchingSafepointCalls(true, true); + } + if (Platform.isDebugBuild()){ + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-XX:-TransmitErrorReport", + "-Xmx32m", + "AssertSafepointCheckConsistency1", + "test"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("assert").shouldContain("always"); + } + } +} + + diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8047290 + * @summary Ensure that a Monitor::lock fires an assert when it incorrectly acquires a lock which must never have safepoint checks. + * @library /testlibrary /../../test/lib + * @build AssertSafepointCheckConsistency2 + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main AssertSafepointCheckConsistency2 + */ + +import com.oracle.java.testlibrary.*; + +import sun.hotspot.WhiteBox; + +public class AssertSafepointCheckConsistency2 { + public static void main(String args[]) throws Exception { + if (args.length > 0) { + WhiteBox.getWhiteBox().assertMatchingSafepointCalls(false, false); + } + if (Platform.isDebugBuild()){ + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-XX:-TransmitErrorReport", + "-Xmx32m", + "AssertSafepointCheckConsistency2", + "test"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("assert").shouldContain("never"); + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8047290 + * @summary Ensure that Monitor::lock_without_safepoint_check does not assert when it correctly acquires a lock which must never have safepoint checks. + * @library /testlibrary /../../test/lib + * @build AssertSafepointCheckConsistency3 + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main AssertSafepointCheckConsistency3 + */ + +import com.oracle.java.testlibrary.*; + +import sun.hotspot.WhiteBox; + +public class AssertSafepointCheckConsistency3 { + public static void main(String args[]) throws Exception { + if (args.length > 0) { + WhiteBox.getWhiteBox().assertMatchingSafepointCalls(false, true); + } + if (Platform.isDebugBuild()){ + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-XX:-TransmitErrorReport", + "-Xmx32m", + "AssertSafepointCheckConsistency3", + "test"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("assert"); + output.shouldNotContain("never"); + output.shouldNotContain("always"); + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8047290 + * @summary Ensure that Monitor::lock does not assert when it correctly acquires a lock which must always have safepoint checks. + * @library /testlibrary /../../test/lib + * @build AssertSafepointCheckConsistency4 + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main AssertSafepointCheckConsistency4 + */ + +import com.oracle.java.testlibrary.*; + +import sun.hotspot.WhiteBox; + +public class AssertSafepointCheckConsistency4 { + public static void main(String args[]) throws Exception { + if (args.length > 0) { + WhiteBox.getWhiteBox().assertMatchingSafepointCalls(true, false); + } + if (Platform.isDebugBuild()){ + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-Xbootclasspath/a:.", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-XX:-TransmitErrorReport", + "-Xmx32m", + "AssertSafepointCheckConsistency4", + "test"); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("assert"); + output.shouldNotContain("never"); + output.shouldNotContain("always"); + } + } +} + + diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java --- a/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/SharedArchiveFile/LimitSharedSizes.java Sat Jan 10 12:38:18 2015 -0800 @@ -30,40 +30,96 @@ import com.oracle.java.testlibrary.*; public class LimitSharedSizes { + static enum Region { + RO, RW, MD, MC + } + private static class SharedSizeTestData { public String optionName; public String optionValue; public String expectedErrorMsg; - public SharedSizeTestData(String name, String value, String msg) { - optionName = name; + public SharedSizeTestData(Region region, String value, String msg) { + optionName = getName(region); optionValue = value; expectedErrorMsg = msg; } + + public SharedSizeTestData(Region region, String msg) { + optionName = getName(region); + optionValue = getValue(region); + expectedErrorMsg = msg; + } + + private String getName(Region region) { + String name; + switch (region) { + case RO: + name = "-XX:SharedReadOnlySize"; + break; + case RW: + name = "-XX:SharedReadWriteSize"; + break; + case MD: + name = "-XX:SharedMiscDataSize"; + break; + case MC: + name = "-XX:SharedMiscCodeSize"; + break; + default: + name = "Unknown"; + break; + } + return name; + } + + private String getValue(Region region) { + String value; + switch (region) { + case RO: + value = Platform.is64bit() ? "9M" : "8M"; + break; + case RW: + value = Platform.is64bit() ? "12M" : "7M"; + break; + case MD: + value = Platform.is64bit() ? "4M" : "2M"; + break; + case MC: + value = "120k"; + break; + default: + value = "0M"; + break; + } + return value; + } } private static final SharedSizeTestData[] testTable = { - // values in this part of the test table should cause failure - // (shared space sizes are deliberately too small) - new SharedSizeTestData("-XX:SharedReadOnlySize", "4M", "read only"), - new SharedSizeTestData("-XX:SharedReadWriteSize","4M", "read write"), - - // Known issue, JDK-8038422 (assert() on Windows) - // new SharedSizeTestData("-XX:SharedMiscDataSize", "500k", "miscellaneous data"), - - // Too small of a misc code size should not cause a vm crash. - // It should result in the following error message: + // Too small of a region size should not cause a vm crash. + // It should result in an error message like the following: // The shared miscellaneous code space is not large enough // to preload requested classes. Use -XX:SharedMiscCodeSize= // to increase the initial size of shared miscellaneous code space. - new SharedSizeTestData("-XX:SharedMiscCodeSize", "20k", "miscellaneous code"), + new SharedSizeTestData(Region.RO, "4M", "read only"), + new SharedSizeTestData(Region.RW, "4M", "read write"), + new SharedSizeTestData(Region.MD, "50k", "miscellaneous data"), + new SharedSizeTestData(Region.MC, "20k", "miscellaneous code"), // these values are larger than default ones, but should // be acceptable and not cause failure - new SharedSizeTestData("-XX:SharedReadOnlySize", "20M", null), - new SharedSizeTestData("-XX:SharedReadWriteSize", "20M", null), - new SharedSizeTestData("-XX:SharedMiscDataSize", "20M", null), - new SharedSizeTestData("-XX:SharedMiscCodeSize", "20M", null) + new SharedSizeTestData(Region.RO, "20M", null), + new SharedSizeTestData(Region.RW, "20M", null), + new SharedSizeTestData(Region.MD, "20M", null), + new SharedSizeTestData(Region.MC, "20M", null), + + // test with sizes which just meet the minimum required sizes + // the following tests also attempt to use the shared archive + new SharedSizeTestData(Region.RO, "UseArchive"), + new SharedSizeTestData(Region.RW, "UseArchive"), + new SharedSizeTestData(Region.MD, "UseArchive"), + new SharedSizeTestData(Region.MC, "UseArchive") }; public static void main(String[] args) throws Exception { @@ -82,10 +138,39 @@ OutputAnalyzer output = new OutputAnalyzer(pb.start()); if (td.expectedErrorMsg != null) { - output.shouldContain("The shared " + td.expectedErrorMsg - + " space is not large enough"); + if (!td.expectedErrorMsg.equals("UseArchive")) { + output.shouldContain("The shared " + td.expectedErrorMsg + + " space is not large enough"); + + output.shouldHaveExitValue(2); + } else { + output.shouldNotContain("space is not large enough"); + output.shouldHaveExitValue(0); + + // try to use the archive + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", + "-XX:SharedArchiveFile=./" + fileName, + "-XX:+PrintSharedArchiveAndExit", + "-version"); - output.shouldHaveExitValue(2); + try { + output = new OutputAnalyzer(pb.start()); + output.shouldContain("archive is valid"); + } catch (RuntimeException e) { + // if sharing failed due to ASLR or similar reasons, + // check whether sharing was attempted at all (UseSharedSpaces) + if ((output.getOutput().contains("Unable to use shared archive") || + output.getOutput().contains("Unable to map ReadOnly shared space at required address.") || + output.getOutput().contains("Unable to map ReadWrite shared space at required address.") || + output.getOutput().contains("Unable to reserve shared space at required address")) && + output.getExitValue() == 1) { + System.out.println("Unable to use shared archive: test not executed; assumed passed"); + return; + } + } + output.shouldHaveExitValue(0); + } } else { output.shouldNotContain("space is not large enough"); output.shouldHaveExitValue(0); diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/SharedArchiveFile/PrintSharedArchiveAndExit.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8066670 + * @summary Testing -XX:+PrintSharedArchiveAndExit option + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.*; + +public class PrintSharedArchiveAndExit { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", "-Xshare:dump"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + try { + output.shouldContain("Loading classes to share"); + output.shouldHaveExitValue(0); + + // (1) With a valid archive + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", + "-XX:+PrintSharedArchiveAndExit", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("archive is valid"); + output.shouldNotContain("java version"); // Should not print JVM version + output.shouldHaveExitValue(0); // Should report success in error code. + + pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", + "-XX:+PrintSharedArchiveAndExit"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("archive is valid"); + output.shouldNotContain("Usage:"); // Should not print JVM help message + output.shouldHaveExitValue(0); // Should report success in error code. + + // (2) With an invalid archive (boot class path has been prepended) + pb = ProcessTools.createJavaProcessBuilder( + "-Xbootclasspath/p:foo.jar", + "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", + "-XX:+PrintSharedArchiveAndExit", "-version"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("archive is invalid"); + output.shouldNotContain("java version"); // Should not print JVM version + output.shouldHaveExitValue(1); // Should report failure in error code. + + pb = ProcessTools.createJavaProcessBuilder( + "-Xbootclasspath/p:foo.jar", + "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=./sample.jsa", + "-XX:+PrintSharedArchiveAndExit"); + output = new OutputAnalyzer(pb.start()); + output.shouldContain("archive is invalid"); + output.shouldNotContain("Usage:"); // Should not print JVM help message + output.shouldHaveExitValue(1); // Should report failure in error code. + } catch (RuntimeException e) { + e.printStackTrace(); + output.shouldContain("Unable to use shared archive"); + output.shouldHaveExitValue(1); + } + } +} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/interned/SanityTest.java --- a/hotspot/test/runtime/interned/SanityTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/interned/SanityTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test SanityTest * @summary Sanity check of String.intern() & GC - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build SanityTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/memory/ReadFromNoaccessArea.java --- a/hotspot/test/runtime/memory/ReadFromNoaccessArea.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/memory/ReadFromNoaccessArea.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @summary Test that touching noaccess area in class ReservedHeapSpace results in SIGSEGV/ACCESS_VIOLATION - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ReadFromNoaccessArea * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/memory/ReadVMPageSize.java --- a/hotspot/test/runtime/memory/ReadVMPageSize.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/memory/ReadVMPageSize.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @summary Using WhiteBox to get VM page size - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ReadVMPageSize * @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ReadVMPageSize diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/memory/ReserveMemory.java --- a/hotspot/test/runtime/memory/ReserveMemory.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/memory/ReserveMemory.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,7 +26,7 @@ * @key regression * @bug 8012015 * @summary Make sure reserved (but uncommitted) memory is not accessible - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ReserveMemory * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/memory/RunUnitTestsConcurrently.java --- a/hotspot/test/runtime/memory/RunUnitTestsConcurrently.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/memory/RunUnitTestsConcurrently.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @summary Test launches unit tests inside vm concurrently - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build RunUnitTestsConcurrently * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/memory/StressVirtualSpaceResize.java --- a/hotspot/test/runtime/memory/StressVirtualSpaceResize.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/memory/StressVirtualSpaceResize.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @summary Stress test that expands/shrinks VirtualSpace - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build StressVirtualSpaceResize * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/runtime/whitebox/WBStackSize.java --- a/hotspot/test/runtime/whitebox/WBStackSize.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/runtime/whitebox/WBStackSize.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test WBStackSize * @summary verify that whitebox functions getThreadFullStackSize() and getThreadRemainingStackSize are working - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build WBStackSize * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/sanity/WBApi.java --- a/hotspot/test/sanity/WBApi.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/sanity/WBApi.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test WBApi * @summary verify that whitebox functions can be linked and executed - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build WBApi * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/serviceability/ParserTest.java --- a/hotspot/test/serviceability/ParserTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/serviceability/ParserTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @summary Test that the diagnostic command arguemnt parser works - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.parser.* * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java --- a/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/serviceability/sa/jmap-hashcode/Test8028623.java Sat Jan 10 12:38:18 2015 -0800 @@ -41,12 +41,12 @@ public class Test8028623 { - public static int à = 1; + public static int \u00CB = 1; public static String dumpFile = "heap.out"; public static void main (String[] args) { - System.out.println(Ã); + System.out.println(\u00CB); try { if (!Platform.shouldSAAttach()) { diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/Utils.java Sat Jan 10 12:38:18 2015 -0800 @@ -32,13 +32,18 @@ import java.net.InetAddress; import java.net.ServerSocket; import java.net.UnknownHostException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; +import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import sun.misc.Unsafe; /** @@ -88,6 +93,12 @@ TIMEOUT_FACTOR = Double.parseDouble(toFactor); } + /** + * Returns the value of JTREG default test timeout in milliseconds + * converted to {@code long}. + */ + public static final long DEFAULT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(120); + private Utils() { // Private constructor to prevent class instantiation } @@ -318,28 +329,15 @@ * or null if not found. * @param filename name of the file to read * @return String contents of file, or null if file not found. + * @throws IOException + * if an I/O error occurs reading from the file or a malformed or + * unmappable byte sequence is read */ - public static String fileAsString(String filename) { - StringBuilder result = new StringBuilder(); - try { - File file = new File(filename); - if (file.exists()) { - BufferedReader reader = new BufferedReader(new FileReader(file)); - while (true) { - String line = reader.readLine(); - if (line == null) { - break; - } - result.append(line).append("\n"); - } - } else { - // Does not exist: - return null; - } - } catch (Exception e) { - e.printStackTrace(); - } - return result.toString(); + public static String fileAsString(String filename) throws IOException { + Path filePath = Paths.get(filename); + return Files.exists(filePath) + ? Files.lines(filePath).collect(Collectors.joining(NEW_LINE)) + : null; } /** @@ -396,4 +394,14 @@ } return RANDOM_GENERATOR; } + + /** + * Adjusts the provided timeout value for the TIMEOUT_FACTOR + * @param tOut the timeout value to be adjusted + * @return The timeout value adjusted for the value of "test.timeout.factor" + * system property + */ + public static long adjustTimeout(long tOut) { + return Math.round(tOut * Utils.TIMEOUT_FACTOR); + } } diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/cli/CommandLineOptionTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -49,7 +49,7 @@ private static final String PRINT_FLAGS_FINAL_FORMAT = "%s\\s*:?=\\s*%s"; /** - * Verifies that JVM startup behaviour matches our expectations. + * Verifies that JVM startup behavior matches our expectations. * * @param option an option that should be passed to JVM * @param expectedMessages an array of patterns that should occur @@ -58,18 +58,24 @@ * @param unexpectedMessages an array of patterns that should not * occur in JVM output. If {@code null} then * JVM output could be empty. + * @param exitErrorMessage message that will be shown if exit code is not + * as expected. + * @param wrongWarningMessage message that will be shown if warning + * messages are not as expected. * @param exitCode expected exit code. * @throws Throwable if verification fails or some other issues occur. */ public static void verifyJVMStartup(String option, String expectedMessages[], String unexpectedMessages[], + String exitErrorMessage, String wrongWarningMessage, ExitCode exitCode) throws Throwable { CommandLineOptionTest.verifyJVMStartup(expectedMessages, - unexpectedMessages, exitCode, false, option); + unexpectedMessages, exitErrorMessage, + wrongWarningMessage, exitCode, false, option); } /** - * Verifies that JVM startup behaviour matches our expectations. + * Verifies that JVM startup behavior matches our expectations. * * @param expectedMessages an array of patterns that should occur * in JVM output. If {@code null} then @@ -77,6 +83,10 @@ * @param unexpectedMessages an array of patterns that should not * occur in JVM output. If {@code null} then * JVM output could be empty. + * @param exitErrorMessage message that will be shown if exit code is not + * as expected. + * @param wrongWarningMessage message that will be shown if warning + * messages are not as expected. * @param exitCode expected exit code. * @param addTestVMOptions if {@code true} then test VM options will be * passed to VM. @@ -85,8 +95,10 @@ * @throws Throwable if verification fails or some other issues occur. */ public static void verifyJVMStartup(String expectedMessages[], - String unexpectedMessages[], ExitCode exitCode, - boolean addTestVMOptions, String... options) throws Throwable { + String unexpectedMessages[], String exitErrorMessage, + String wrongWarningMessage, ExitCode exitCode, + boolean addTestVMOptions, String... options) + throws Throwable { List finalOptions = new ArrayList<>(); if (addTestVMOptions) { Collections.addAll(finalOptions, Utils.getTestJavaOpts()); @@ -99,23 +111,46 @@ new String[finalOptions.size()])); OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start()); - outputAnalyzer.shouldHaveExitValue(exitCode.value); + + try { + outputAnalyzer.shouldHaveExitValue(exitCode.value); + } catch (RuntimeException e) { + String errorMessage = String.format( + "JVM process should have exit value '%d'.%n%s", + exitCode.value, exitErrorMessage); + throw new AssertionError(errorMessage, e); + } + if (expectedMessages != null) { for (String expectedMessage : expectedMessages) { - outputAnalyzer.shouldMatch(expectedMessage); + try { + outputAnalyzer.shouldMatch(expectedMessage); + } catch (RuntimeException e) { + String errorMessage = String.format( + "Expected message not found: '%s'.%n%s", + expectedMessage, wrongWarningMessage); + throw new AssertionError(errorMessage, e); + } } } if (unexpectedMessages != null) { for (String unexpectedMessage : unexpectedMessages) { - outputAnalyzer.shouldNotMatch(unexpectedMessage); + try { + outputAnalyzer.shouldNotMatch(unexpectedMessage); + } catch (RuntimeException e) { + String errorMessage = String.format( + "Unexpected message found: '%s'.%n%s", + unexpectedMessage, wrongWarningMessage); + throw new AssertionError(errorMessage, e); + } } } } /** - * Verifies that JVM startup behaviour matches our expectations when type + * Verifies that JVM startup behavior matches our expectations when type * of newly started VM is the same as the type of current. * * @param expectedMessages an array of patterns that should occur @@ -124,20 +159,26 @@ * @param unexpectedMessages an array of patterns that should not * occur in JVM output. If {@code null} then * JVM output could be empty. + * @param exitErrorMessage Message that will be shown if exit value is not + * as expected. + * @param wrongWarningMessage message that will be shown if warning + * messages are not as expected. * @param exitCode expected exit code. * @param options options that should be passed to VM in addition to mode * flag. * @throws Throwable if verification fails or some other issues occur. */ public static void verifySameJVMStartup(String expectedMessages[], - String unexpectedMessages[], ExitCode exitCode, String... options) - throws Throwable { + String unexpectedMessages[], String exitErrorMessage, + String wrongWarningMessage, ExitCode exitCode, String... options) + throws Throwable { List finalOptions = new ArrayList<>(); finalOptions.add(CommandLineOptionTest.getVMTypeOption()); Collections.addAll(finalOptions, options); CommandLineOptionTest.verifyJVMStartup(expectedMessages, - unexpectedMessages, exitCode, false, + unexpectedMessages, exitErrorMessage, + wrongWarningMessage, exitCode, false, finalOptions.toArray(new String[finalOptions.size()])); } @@ -149,13 +190,17 @@ * * @param optionName a name of tested option. * @param expectedValue expected value of tested option. + * @param optionErrorString message will be shown if option value is not as + * expected. * @param additionalVMOpts additional options that should be * passed to JVM. * @throws Throwable if verification fails or some other issues occur. */ public static void verifyOptionValue(String optionName, - String expectedValue, String... additionalVMOpts) throws Throwable { - verifyOptionValue(optionName, expectedValue, true, additionalVMOpts); + String expectedValue, String optionErrorString, + String... additionalVMOpts) throws Throwable { + verifyOptionValue(optionName, expectedValue, optionErrorString, + true, additionalVMOpts); } /** @@ -168,14 +213,17 @@ * @param expectedValue expected value of tested option. * @param addTestVmOptions if {@code true}, then test VM options * will be used. + * @param optionErrorString message will be shown if option value is not as + * expected. * @param additionalVMOpts additional options that should be * passed to JVM. * @throws Throwable if verification fails or some other issues * occur. */ public static void verifyOptionValue(String optionName, - String expectedValue, boolean addTestVmOptions, - String... additionalVMOpts) throws Throwable { + String expectedValue, String optionErrorString, + boolean addTestVmOptions, String... additionalVMOpts) + throws Throwable { List vmOpts = new ArrayList<>(); if (addTestVmOptions) { @@ -191,10 +239,25 @@ OutputAnalyzer outputAnalyzer = new OutputAnalyzer(processBuilder.start()); - outputAnalyzer.shouldHaveExitValue(0); + try { + outputAnalyzer.shouldHaveExitValue(0); + } catch (RuntimeException e) { + String errorMessage = String.format( + "JVM should start with option '%s' without errors.", + optionName); + throw new AssertionError(errorMessage, e); + } + try { outputAnalyzer.shouldMatch(String.format( CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT, optionName, expectedValue)); + } catch (RuntimeException e) { + String errorMessage = String.format( + "Option '%s' is expected to have '%s' value%n%s", + optionName, expectedValue, + optionErrorString); + throw new AssertionError(errorMessage, e); + } } /** @@ -207,18 +270,21 @@ * * @param optionName name of tested option. * @param expectedValue expected value of tested option. + * @param optionErrorString message to show if option has another value * @param additionalVMOpts additional options that should be * passed to JVM. * @throws Throwable if verification fails or some other issues occur. */ public static void verifyOptionValueForSameVM(String optionName, - String expectedValue, String... additionalVMOpts) throws Throwable { + String expectedValue, String optionErrorString, + String... additionalVMOpts) throws Throwable { List finalOptions = new ArrayList<>(); finalOptions.add(CommandLineOptionTest.getVMTypeOption()); Collections.addAll(finalOptions, additionalVMOpts); CommandLineOptionTest.verifyOptionValue(optionName, expectedValue, - false, finalOptions.toArray(new String[finalOptions.size()])); + optionErrorString, false, + finalOptions.toArray(new String[finalOptions.size()])); } /** diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/ctw/test/ClassesDirTest.java --- a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/ctw/test/ClassesListTest.java --- a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/ctw/test/JarDirTest.java --- a/hotspot/test/testlibrary/ctw/test/JarDirTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary/ctw/test/JarDirTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/ctw/test/JarsTest.java --- a/hotspot/test/testlibrary/ctw/test/JarsTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary/ctw/test/JarsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/Makefile --- a/hotspot/test/testlibrary/whitebox/Makefile Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -# -# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# 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. -# -# - -ifneq "x$(ALT_BOOTDIR)" "x" - BOOTDIR := $(ALT_BOOTDIR) -endif - -ifeq "x$(BOOTDIR)" "x" - JDK_HOME := $(shell dirname $(shell which java))/.. -else - JDK_HOME := $(BOOTDIR) -endif - -SRC_DIR = ./ -BUILD_DIR = build -OUTPUT_DIR = $(BUILD_DIR)/classes - -JAVAC = $(JDK_HOME)/bin/javac -JAR = $(JDK_HOME)/bin/jar - -SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') - -.PHONY: filelist clean cleantmp - -all: wb.jar cleantmp - -wb.jar: filelist - @mkdir -p $(OUTPUT_DIR) - $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp $(OUTPUT_DIR) @filelist - $(JAR) cf wb.jar -C $(OUTPUT_DIR) . - @rm -rf $(OUTPUT_DIR) - -filelist: $(SRC_FILES) - @rm -f $@ - @echo $(SRC_FILES) > $@ - -clean: cleantmp - @rm -rf wb.jar - -cleantmp: - @rm -rf filelist - @rm -rf $(BUILD_DIR) diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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.Executable; -import java.util.Arrays; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Stream; -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(); - } - - // Get the maximum heap size supporting COOPs - public native long getCompressedOopsMaxHeapSize(); - // Arguments - public native void printHeapSizes(); - - // Memory - public native long getObjectAddress(Object o); - public native int getHeapOopSize(); - public native int getVMPageSize(); - public native boolean isObjectInOldGen(Object o); - public native long getObjectSize(Object o); - - // 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); - - // JVMTI - public native void addToBootstrapClassLoaderSearch(String segment); - public native void addToSystemClassLoaderSearch(String segment); - - // 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, char delim, DiagnosticCommand[] args); - - // NMT - public native long NMTMalloc(long size); - public native void NMTFree(long mem); - public native long NMTReserveMemory(long size); - public native void NMTCommitMemory(long addr, long size); - public native void NMTUncommitMemory(long addr, long size); - public native void NMTReleaseMemory(long addr, long size); - public native long NMTMallocWithPseudoStack(long size, int index); - public native boolean NMTIsDetailSupported(); - public native boolean NMTChangeTrackingLevel(); - public native int NMTGetHashSize(); - - // Compiler - public native void deoptimizeAll(); - public boolean isMethodCompiled(Executable method) { - return isMethodCompiled(method, false /*not osr*/); - } - public native boolean isMethodCompiled(Executable method, boolean isOsr); - public boolean isMethodCompilable(Executable method) { - return isMethodCompilable(method, -1 /*any*/); - } - public boolean isMethodCompilable(Executable method, int compLevel) { - return isMethodCompilable(method, compLevel, false /*not osr*/); - } - public native boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr); - public native boolean isMethodQueuedForCompilation(Executable method); - public int deoptimizeMethod(Executable method) { - return deoptimizeMethod(method, false /*not osr*/); - } - public native int deoptimizeMethod(Executable method, boolean isOsr); - public void makeMethodNotCompilable(Executable method) { - makeMethodNotCompilable(method, -1 /*any*/); - } - public void makeMethodNotCompilable(Executable method, int compLevel) { - makeMethodNotCompilable(method, compLevel, false /*not osr*/); - } - public native void makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr); - public int getMethodCompilationLevel(Executable method) { - return getMethodCompilationLevel(method, false /*not ost*/); - } - public native int getMethodCompilationLevel(Executable method, boolean isOsr); - public native boolean testSetDontInlineMethod(Executable method, boolean value); - public int getCompileQueuesSize() { - return getCompileQueueSize(-1 /*any*/); - } - public native int getCompileQueueSize(int compLevel); - public native boolean testSetForceInlineMethod(Executable method, boolean value); - public boolean enqueueMethodForCompilation(Executable method, int compLevel) { - return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/); - } - public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci); - public native void clearMethodState(Executable method); - public native void lockCompilation(); - public native void unlockCompilation(); - public native int getMethodEntryBci(Executable method); - public native Object[] getNMethod(Executable method, boolean isOsr); - public native long allocateCodeBlob(int size, int type); - public native void freeCodeBlob(long addr); - public void forceNMethodSweep() { - try { - forceNMethodSweep0().join(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - public native Thread forceNMethodSweep0(); - public native Object[] getCodeHeapEntries(int type); - public native int getCompilationActivityMode(); - public native Object[] getCodeBlob(long addr); - - // Intered strings - public native boolean isInStringTable(String str); - - // Memory - public native void readReservedMemory(); - public native long allocateMetaspace(ClassLoader classLoader, long size); - public native void freeMetaspace(ClassLoader classLoader, long addr, long size); - public native long incMetaspaceCapacityUntilGC(long increment); - public native long metaspaceCapacityUntilGC(); - - // Force Young GC - public native void youngGC(); - - // Force Full GC - public native void fullGC(); - - // Method tries to start concurrent mark cycle. - // It returns false if CM Thread is always in concurrent cycle. - public native boolean g1StartConcMarkCycle(); - - // Tests on ReservedSpace/VirtualSpace classes - public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations); - public native void runMemoryUnitTests(); - public native void readFromNoaccessArea(); - public native long getThreadStackSize(); - public native long getThreadRemainingStackSize(); - - // CPU features - public native String getCPUFeatures(); - - // Native extensions - public native long getHeapUsageForContext(int context); - public native long getHeapRegionCountForContext(int context); - public native int getContextForObject(Object obj); - public native void printRegionInfo(int context); - - // VM flags - public native boolean isConstantVMFlag(String name); - public native boolean isLockedVMFlag(String name); - public native void setBooleanVMFlag(String name, boolean value); - public native void setIntxVMFlag(String name, long value); - public native void setUintxVMFlag(String name, long value); - public native void setUint64VMFlag(String name, long value); - public native void setSizeTVMFlag(String name, long value); - public native void setStringVMFlag(String name, String value); - public native void setDoubleVMFlag(String name, double value); - public native Boolean getBooleanVMFlag(String name); - public native Long getIntxVMFlag(String name); - public native Long getUintxVMFlag(String name); - public native Long getUint64VMFlag(String name); - public native Long getSizeTVMFlag(String name); - public native String getStringVMFlag(String name); - public native Double getDoubleVMFlag(String name); - private final List> flagsGetters = Arrays.asList( - this::getBooleanVMFlag, this::getIntxVMFlag, this::getUintxVMFlag, - this::getUint64VMFlag, this::getSizeTVMFlag, this::getStringVMFlag, - this::getDoubleVMFlag); - - public Object getVMFlag(String name) { - return flagsGetters.stream() - .map(f -> f.apply(name)) - .filter(x -> x != null) - .findAny() - .orElse(null); - } - public native int getOffsetForName0(String name); - public int getOffsetForName(String name) throws Exception { - int offset = getOffsetForName0(name); - if (offset == -1) { - throw new RuntimeException(name + " not found"); - } - return offset; - } - -} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/BlobType.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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.code; - -import java.lang.management.ManagementFactory; -import java.lang.management.MemoryPoolMXBean; -import java.util.EnumSet; - -import sun.hotspot.WhiteBox; - -public enum BlobType { - // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) - MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"), - // Execution level 2 and 3 (profiled) nmethods - MethodProfiled(1, "CodeHeap 'profiled nmethods'"), - // Non-nmethods like Buffers, Adapters and Runtime Stubs - NonNMethod(2, "CodeHeap 'non-nmethods'") { - @Override - public boolean allowTypeWhenOverflow(BlobType type) { - return super.allowTypeWhenOverflow(type) - || type == BlobType.MethodNonProfiled; - } - }, - // All types (No code cache segmentation) - All(3, "CodeCache"); - - public final int id; - private final String beanName; - - private BlobType(int id, String beanName) { - this.id = id; - this.beanName = beanName; - } - - public MemoryPoolMXBean getMemoryPool() { - for (MemoryPoolMXBean bean : ManagementFactory.getMemoryPoolMXBeans()) { - String name = bean.getName(); - if (beanName.equals(name)) { - return bean; - } - } - return null; - } - - public boolean allowTypeWhenOverflow(BlobType type) { - return type == this; - } - - public static EnumSet getAvailable() { - WhiteBox whiteBox = WhiteBox.getWhiteBox(); - if (!whiteBox.getBooleanVMFlag("SegmentedCodeCache")) { - // only All for non segmented world - return EnumSet.of(All); - } - if (System.getProperty("java.vm.info").startsWith("interpreted ")) { - // only NonNMethod for -Xint - return EnumSet.of(NonNMethod); - } - - EnumSet result = EnumSet.complementOf(EnumSet.of(All)); - if (!whiteBox.getBooleanVMFlag("TieredCompilation") - || whiteBox.getIntxVMFlag("TieredStopAtLevel") <= 1) { - // there is no MethodProfiled in non tiered world or pure C1 - result.remove(MethodProfiled); - } - return result; - } -} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/CodeBlob.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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.code; - -import sun.hotspot.WhiteBox; - -public class CodeBlob { - private static final WhiteBox WB = WhiteBox.getWhiteBox(); - public static CodeBlob[] getCodeBlobs(BlobType type) { - Object[] obj = WB.getCodeHeapEntries(type.id); - if (obj == null) { - return null; - } - CodeBlob[] result = new CodeBlob[obj.length]; - for (int i = 0, n = result.length; i < n; ++i) { - result[i] = new CodeBlob((Object[]) obj[i]); - } - return result; - } - public static CodeBlob getCodeBlob(long addr) { - Object[] obj = WB.getCodeBlob(addr); - if (obj == null) { - return null; - } - return new CodeBlob(obj); - } - protected CodeBlob(Object[] obj) { - assert obj.length == 3; - name = (String) obj[0]; - size = (Integer) obj[1]; - code_blob_type = BlobType.values()[(Integer) obj[2]]; - assert code_blob_type.id == (Integer) obj[2]; - } - public final String name; - public final int size; - public final BlobType code_blob_type; - - @Override - public String toString() { - return "CodeBlob{" - + "name=" + name - + ", size=" + size - + ", code_blob_type=" + code_blob_type - + '}'; - } -} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/code/NMethod.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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.code; - -import java.lang.reflect.Executable; -import sun.hotspot.WhiteBox; - -public class NMethod extends CodeBlob { - private static final WhiteBox wb = WhiteBox.getWhiteBox(); - public static NMethod get(Executable method, boolean isOsr) { - Object[] obj = wb.getNMethod(method, isOsr); - return obj == null ? null : new NMethod(obj); - } - private NMethod(Object[] obj) { - super((Object[])obj[0]); - assert obj.length == 4; - comp_level = (Integer) obj[1]; - insts = (byte[]) obj[2]; - compile_id = (Integer) obj[3]; - } - public final byte[] insts; - public final int comp_level; - public final int compile_id; - - @Override - public String toString() { - return "NMethod{" - + super.toString() - + ", insts=" + insts - + ", comp_level=" + comp_level - + ", compile_id=" + compile_id - + '}'; - } -} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/sun/hotspot/cpuinfo/CPUInfo.java --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/cpuinfo/CPUInfo.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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.cpuinfo; - -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.regex.Pattern; -import java.util.regex.Matcher; - -import sun.hotspot.WhiteBox; - -/** - * Information about CPU on test box. - * - * CPUInfo uses WhiteBox to gather information, - * so WhiteBox class should be added to bootclasspath - * and option -XX:+WhiteBoxAPI should expclicetly - * specified on command line. - */ -public class CPUInfo { - - private static final List features; - private static final String additionalCPUInfo; - - static { - WhiteBox wb = WhiteBox.getWhiteBox(); - - Pattern additionalCPUInfoRE = - Pattern.compile("([^(]*\\([^)]*\\)[^,]*),\\s*"); - - String cpuFeaturesString = wb.getCPUFeatures(); - Matcher matcher = additionalCPUInfoRE.matcher(cpuFeaturesString); - if (matcher.find()) { - additionalCPUInfo = matcher.group(1); - } else { - additionalCPUInfo = ""; - } - String splittedFeatures[] = matcher.replaceAll("").split("(, )| "); - - features = Collections.unmodifiableList(Arrays. - asList(splittedFeatures)); - } - - /** - * Get additional information about CPU. - * For example, on X86 in will be family/model/stepping - * and number of cores. - * - * @return additional CPU info - */ - public static String getAdditionalCPUInfo() { - return additionalCPUInfo; - } - - /** - * Get all known features supported by CPU. - * - * @return unmodifiable list with names of all known features - * supported by CPU. - */ - public static List getFeatures() { - return features; - } - - /** - * Check if some feature is supported by CPU. - * - * @param feature Name of feature to be tested. - * @return true if tested feature is supported by CPU. - */ - public static boolean hasFeature(String feature) { - return features.contains(feature.toLowerCase()); - } -} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java --- a/hotspot/test/testlibrary/whitebox/sun/hotspot/parser/DiagnosticCommand.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * 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; - private boolean argument; - - public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type, - boolean mandatory, String defaultValue) { - this(name, desc, type, false, mandatory, defaultValue); - } - - public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type, - boolean argument, boolean mandatory, String defaultValue) { - this.name = name; - this.desc = desc; - this.type = type; - this.mandatory = mandatory; - this.defaultValue = defaultValue; - this.argument = argument; - } - - public String getName() { - return name; - } - - public String getDesc() { - return desc; - } - - public DiagnosticArgumentType getType() { - return type; - } - - public boolean isMandatory() { - return mandatory; - } - - public boolean isArgument() { - return argument; - } - - public String getDefaultValue() { - return defaultValue; - } -} diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java --- a/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java Sat Jan 10 12:38:18 2015 -0800 @@ -47,7 +47,8 @@ BITNESS("is32bit", "is64bit"), OS("isLinux", "isSolaris", "isWindows", "isOSX"), VM_TYPE("isClient", "isServer", "isGraal", "isMinimal"), - IGNORED("isEmbedded", "isDebugBuild"); + IGNORED("isEmbedded", "isDebugBuild", "shouldSAAttach", + "canPtraceAttachLinux", "canAttachOSX"); public final List methodNames; diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/ctw/ClassesDirTest.java --- a/hotspot/test/testlibrary_tests/ctw/ClassesDirTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/ctw/ClassesDirTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/ctw/ClassesListTest.java --- a/hotspot/test/testlibrary_tests/ctw/ClassesListTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/ctw/ClassesListTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/ctw/JarDirTest.java --- a/hotspot/test/testlibrary_tests/ctw/JarDirTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/ctw/JarDirTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/ctw/JarsTest.java --- a/hotspot/test/testlibrary_tests/ctw/JarsTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/ctw/JarsTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test * @bug 8012447 - * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @library /testlibrary /../../test/lib /testlibrary/ctw/src * @build ClassFileInstaller com.oracle.java.testlibrary.* sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox Foo Bar * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/BooleanTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test BooleanTest * @bug 8028756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build BooleanTest ClassFileInstaller sun.hotspot.WhiteBox com.oracle.java.testlibrary.* * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/DoubleTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test DoubleTest * @bug 8028756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build DoubleTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/IntxTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test IntxTest * @bug 8028756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build IntxTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/SizeTTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test SizeTTest * @bug 8054823 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build SizeTTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/StringTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test StringTest * @bug 8028756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build StringTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/Uint64Test.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/Uint64Test.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/Uint64Test.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test Uint64Test * @bug 8028756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build Uint64Test * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java --- a/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/hotspot/test/testlibrary_tests/whitebox/vm_flags/UintxTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ /* * @test UintxTest * @bug 8028756 - * @library /testlibrary /testlibrary/whitebox + * @library /testlibrary /../../test/lib * @build UintxTest * @run main ClassFileInstaller sun.hotspot.WhiteBox * sun.hotspot.WhiteBox$WhiteBoxPermission diff -r ad8137d44154 -r 247f60f5808f jaxp/.hgtags --- a/jaxp/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/jaxp/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -285,3 +285,5 @@ 3f46e2196498de33e7c65efa7b372e46f1faba01 jdk9-b40 71dd8f7649428efd3a56ca5fefc80e59d37b8434 jdk9-b41 47b0d3fa4118b9d56870cf4004987438c501f5c0 jdk9-b42 +40b242363040229a05224fbc5dc203a3f46a8f8f jdk9-b43 +0cb0844b58924d6086d2850c22087d06679d5eef jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f jaxp/test/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/Makefile Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,325 @@ +# +# Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# Makefile to run various JAXP tests +# + +.DEFAULT : all + +# Empty these to get rid of some default rules +.SUFFIXES: +.SUFFIXES: .java +CO= +GET= + +# Utilities used +AWK = awk +CAT = cat +CD = cd +CHMOD = chmod +CP = cp +CUT = cut +DIRNAME = dirname +ECHO = echo +EGREP = egrep +EXPAND = expand +FIND = find +MKDIR = mkdir +PWD = pwd +SED = sed +SORT = sort +TEE = tee +UNAME = uname +UNIQ = uniq +WC = wc +ZIP = zip + +# Get OS name from uname (Cygwin inexplicably adds _NT-5.1) +UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_) + +# Commands to run on paths to make mixed paths for java on windows +ifeq ($(UNAME_S), CYGWIN) + # Location of developer shared files + SLASH_JAVA = J: + GETMIXEDPATH = cygpath -m +else + # Location of developer shared files + SLASH_JAVA = /java + + GETMIXEDPATH=$(ECHO) +endif + +# Root of this test area (important to use full paths in some places) +TEST_ROOT := $(shell $(PWD)) + +# Root of all test results +ifdef ALT_OUTPUTDIR + ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD)) +else + ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD)) +endif + +ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR) +ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) + +# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test) +ifndef PRODUCT_HOME + # Try to use j2sdk-image if it exists + ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/j2sdk-image + PRODUCT_HOME := \ + $(shell \ + if [ -d $(ABS_JDK_IMAGE) ] ; then \ + $(ECHO) "$(ABS_JDK_IMAGE)"; \ + else \ + $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)"; \ + fi) + PRODUCT_HOME := $(PRODUCT_HOME) +endif + +# Expect JPRT to set JPRT_PRODUCT_ARGS (e.g. -server etc.) +# Should be passed into 'java' only. +# Could include: -d64 -server -client OR any java option +ifdef JPRT_PRODUCT_ARGS + JAVA_ARGS = $(JPRT_PRODUCT_ARGS) +endif + +# Expect JPRT to set JPRT_PRODUCT_VM_ARGS (e.g. -Xcomp etc.) +# Should be passed into anything running the vm (java, javac, javadoc, ...). +ifdef JPRT_PRODUCT_VM_ARGS + JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS) +endif + +# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results) +ifdef JPRT_ARCHIVE_BUNDLE + ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE) +else + ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip +endif + +# How to create the test bundle (pass or fail, we want to create this) +# Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed. +ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` \ + && $(CD) $(ABS_TEST_OUTPUT_DIR) \ + && $(CHMOD) -R a+r . \ + && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . ) + +# important results files +SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt") +STATS_TXT_NAME = Stats.txt +STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)") +RUNLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt") +PASSLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt") +FAILLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt") +EXITCODE = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt") + +TESTEXIT = \ + if [ ! -s $(EXITCODE) ] ; then \ + $(ECHO) "ERROR: EXITCODE file not filled in."; \ + $(ECHO) "1" > $(EXITCODE); \ + fi ; \ + testExitCode=`$(CAT) $(EXITCODE)`; \ + $(ECHO) "EXIT CODE: $${testExitCode}"; \ + exit $${testExitCode} + +BUNDLE_UP_AND_EXIT = \ +( \ + jtregExitCode=$$? && \ + _summary="$(SUMMARY_TXT)"; \ + $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ + $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ + if [ -r "$${_summary}" ] ; then \ + $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \ + $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \ + $(EGREP) ' Passed\.' $(RUNLIST) \ + | $(EGREP) -v ' Error\.' \ + | $(EGREP) -v ' Failed\.' > $(PASSLIST); \ + ( $(EGREP) ' Failed\.' $(RUNLIST); \ + $(EGREP) ' Error\.' $(RUNLIST); \ + $(EGREP) -v ' Passed\.' $(RUNLIST) ) \ + | $(SORT) | $(UNIQ) > $(FAILLIST); \ + if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \ + $(EXPAND) $(FAILLIST) \ + | $(CUT) -d' ' -f1 \ + | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \ + if [ $${jtregExitCode} = 0 ] ; then \ + jtregExitCode=1; \ + fi; \ + fi; \ + runc="`$(CAT) $(RUNLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ + passc="`$(CAT) $(PASSLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ + failc="`$(CAT) $(FAILLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ + exclc="FIXME CODETOOLS-7900176"; \ + $(ECHO) "TEST STATS: name=$(UNIQUE_DIR) run=$${runc} pass=$${passc} fail=$${failc}" \ + >> $(STATS_TXT); \ + else \ + $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \ + fi; \ + if [ -f $(STATS_TXT) ] ; then \ + $(CAT) $(STATS_TXT); \ + fi; \ + $(ZIP_UP_RESULTS) ; \ + $(TESTEXIT) \ +) + +################################################################ + +# Default make rule (runs default JAXP tests) +all: jaxp_all + @$(ECHO) "Testing completed successfully" + +# Prep for output +# Change execute permissions on shared library files. +# Files in repositories should never have execute permissions, but +# there are some tests that have pre-built shared libraries, and these +# windows dll files must have execute permission. Adding execute +# permission may happen automatically on windows when using certain +# versions of mercurial but it cannot be guaranteed. And blindly +# adding execute permission might be seen as a mercurial 'change', so +# we avoid adding execute permission to repository files. But testing +# from a plain source tree needs the chmod a+rx. Applying the chmod to +# all shared libraries not just dll files. And with CYGWIN and sshd +# service, you may need CYGWIN=ntsec for this to work. +prep: + @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR) + @$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` + @if [ ! -d $(TEST_ROOT)/../.hg ] ; then \ + $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \) \ + -exec $(CHMOD) a+rx {} \; ; \ + fi + +# Cleanup +clean: + @$(RM) -r $(ABS_TEST_OUTPUT_DIR) + @$(RM) $(ARCHIVE_BUNDLE) + +################################################################ + +# jtreg tests + +# Expect JT_HOME to be set for jtreg tests. (home for jtreg) +ifndef JT_HOME + JT_HOME = $(SLASH_JAVA)/re/jtreg/4.1/promoted/latest/binaries/jtreg + ifdef JPRT_JTREG_HOME + JT_HOME = $(JPRT_JTREG_HOME) + endif +endif + +# Problematic tests to be excluded +PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt)) + +# Create exclude list for this platform and arch +ifdef NO_EXCLUDES + JTREG_EXCLUSIONS = +else + JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%) +endif + +# convert list of directories to dos paths +define MixedDirs +$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}")) +endef + +define SummaryInfo +$(ECHO) "########################################################" +$(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME)) +$(ECHO) "########################################################" +endef + +# ------------------------------------------------------------------ + +jaxp_%: + $(ECHO) "Running tests: $@" + for each in $@; do \ + $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \ + done + +# ------------------------------------------------------------------ + +ifdef CONCURRENCY + EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY) +endif + +# Default JTREG to run (win32 script works for everybody) +JTREG = $(JT_HOME)/win32/bin/jtreg +# run in agentvm mode +JTREG_BASIC_OPTIONS += -agentvm +# Only run automatic tests +JTREG_BASIC_OPTIONS += -a +# Always turn on assertions +JTREG_ASSERT_OPTION = -ea -esa +JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION) +# Report details on all failed or error tests, times too +JTREG_BASIC_OPTIONS += -v:fail,error,time +# Retain all files for failing tests +JTREG_BASIC_OPTIONS += -retain:fail,error +# Ignore tests are not run and completely silent about it +JTREG_IGNORE_OPTION = -ignore:quiet +JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION) +# Multiple by 4 the timeout numbers +JTREG_TIMEOUT_OPTION = -timeoutFactor:4 +JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION) +# Set the max memory for jtreg control vm +JTREG_MEMORY_OPTION = -J-Xmx512m +JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION) +# Add any extra options +JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS) +# Set other vm and test options +JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%) +# Set the GC options for test vms +#JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC +#JTREG_TEST_OPTIONS += $(JTREG_GC_OPTION) +# Set the max memory for jtreg target test vms +JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m +JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION) + +# Make sure jtreg exists +$(JTREG): $(JT_HOME) + +# Run jtreg +jtreg_tests: prep $(PRODUCT_HOME) $(JTREG) + ( \ + ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)"); \ + export JT_HOME; \ + $(shell $(GETMIXEDPATH) "$(JTREG)") \ + $(JTREG_BASIC_OPTIONS) \ + -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport") \ + -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork") \ + -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \ + $(JTREG_EXCLUSIONS) \ + $(JTREG_TEST_OPTIONS) \ + $(TEST_SELECTION) \ + ) ; \ + $(BUNDLE_UP_AND_EXIT) \ + ) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT) + +PHONY_LIST += jtreg_tests + +################################################################ + +# Phony targets (e.g. these are not filenames) +.PHONY: all clean prep $(PHONY_LIST) + +################################################################ diff -r ad8137d44154 -r 247f60f5808f jaxp/test/TEST.ROOT --- a/jaxp/test/TEST.ROOT Thu Jan 08 10:44:54 2015 +0100 +++ b/jaxp/test/TEST.ROOT Sat Jan 10 12:38:18 2015 -0800 @@ -2,5 +2,7 @@ # It also contains test-suite configuration information. # Tests that must run in othervm mode -othervm.dirs=javax/xml/jaxp/unittest +othervm.dirs=javax/xml/jaxp +# Group definitions +groups=TEST.groups diff -r ad8137d44154 -r 247f60f5808f jaxp/test/TEST.groups --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jaxp/test/TEST.groups Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,24 @@ +# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# 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. +# + +jaxp_all = \ + javax/xml/jaxp diff -r ad8137d44154 -r 247f60f5808f jaxws/.hgtags --- a/jaxws/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/jaxws/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -288,3 +288,5 @@ 5455969de31f3083bcfd779b7acc3ab758ecb308 jdk9-b40 4f785187377fe4c7ff388a7026dd72fcccdcfe7a jdk9-b41 301ddb4478fb36d1f025d14e7e48c2a434e9e6ff jdk9-b42 +edc13d27dc871be57d7ca77eef77e6d04972fee2 jdk9-b43 +2a03baa4d849818ff6d635f110c2813b12fc2326 jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f jdk/.hgtags --- a/jdk/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -285,3 +285,5 @@ f1ed1540da70a066527fd043413107e47721edbf jdk9-b40 e336cbd8b15e959e70ed02f0f5e93fa76ebd4c07 jdk9-b41 6b2314173433467245261364a52fb8e347fe6342 jdk9-b42 +8c6ad41974f9ab6c33d544b088648314963f2a50 jdk9-b43 +8cc4dc300041eb70a7a40e4b2431a8f4d4965ea4 jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f jdk/make/src/classes/build/tools/module/boot.modules --- a/jdk/make/src/classes/build/tools/module/boot.modules Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/make/src/classes/build/tools/module/boot.modules Sat Jan 10 12:38:18 2015 -0800 @@ -17,10 +17,10 @@ java.smartcardio java.sql java.sql.rowset +java.transaction java.xml java.xml.bind java.xml.crypto -java.xml.soap java.xml.ws jdk.charsets jdk.deploy diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/classes/java/io/FilterOutputStream.java --- a/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/io/FilterOutputStream.java Sat Jan 10 12:38:18 2015 -0800 @@ -48,6 +48,8 @@ */ protected OutputStream out; + private boolean closed; + /** * Creates an output stream filter built on top of the specified * underlying output stream. @@ -144,9 +146,9 @@ * Closes this output stream and releases any system resources * associated with the stream. *

- * The close method of FilterOutputStream - * calls its flush method, and then calls the - * close method of its underlying output stream. + * When not already closed, the {@code close} method of {@code + * FilterOutputStream} calls its {@code flush} method, and then + * calls the {@code close} method of its underlying output stream. * * @exception IOException if an I/O error occurs. * @see java.io.FilterOutputStream#flush() @@ -154,6 +156,9 @@ */ @SuppressWarnings("try") public void close() throws IOException { + if (closed) + return; + closed = true; try (OutputStream ostream = out) { flush(); } diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/classes/java/lang/Deprecated.java --- a/jdk/src/java.base/share/classes/java/lang/Deprecated.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/lang/Deprecated.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,9 +34,13 @@ * or because a better alternative exists. Compilers warn when a * deprecated program element is used or overridden in non-deprecated code. * + *

Use of the @Deprecated annotation on a local variable + * declaration or on a parameter declaration or a package declaration + * has no effect. + * * @author Neal Gafter * @since 1.5 - * @jls 9.6.3.6 @Deprecated + * @jls 9.6.4.6 @Deprecated */ @Documented @Retention(RetentionPolicy.RUNTIME) diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/classes/java/math/BigDecimal.java --- a/jdk/src/java.base/share/classes/java/math/BigDecimal.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/math/BigDecimal.java Sat Jan 10 12:38:18 2015 -0800 @@ -393,7 +393,7 @@ *

Note that if the sequence of characters is already available * within a character array, using this constructor is faster than * converting the {@code char} array to string and using the - * {@code BigDecimal(String)} constructor . + * {@code BigDecimal(String)} constructor. * * @param in {@code char} array that is the source of characters. * @param offset first character in the array to inspect. @@ -466,7 +466,8 @@ } else if (c == '.') { // have dot // have dot if (dot) // two dots - throw new NumberFormatException(); + throw new NumberFormatException("Character array" + + " contains more than one decimal point."); dot = true; } else if (Character.isDigit(c)) { // slow path int digit = Character.digit(c, 10); @@ -488,14 +489,16 @@ exp = parseExp(in, offset, len); // Next test is required for backwards compatibility if ((int) exp != exp) // overflow - throw new NumberFormatException(); + throw new NumberFormatException("Exponent overflow."); break; // [saves a test] } else { - throw new NumberFormatException(); + throw new NumberFormatException("Character " + c + + " is neither a decimal digit number, decimal point, nor" + + " \"e\" notation exponential mark."); } } if (prec == 0) // no digits found - throw new NumberFormatException(); + throw new NumberFormatException("No digits found."); // Adjust scale if exp is not zero. if (exp != 0) { // had significant exponent scl = adjustScale(scl, exp); @@ -541,22 +544,24 @@ if (c == '.') { // have dot if (dot) // two dots - throw new NumberFormatException(); + throw new NumberFormatException("Character array" + + " contains more than one decimal point."); dot = true; continue; } // exponent expected if ((c != 'e') && (c != 'E')) - throw new NumberFormatException(); + throw new NumberFormatException("Character array" + + " is missing \"e\" notation exponential mark."); exp = parseExp(in, offset, len); // Next test is required for backwards compatibility if ((int) exp != exp) // overflow - throw new NumberFormatException(); + throw new NumberFormatException("Exponent overflow."); break; // [saves a test] } // here when no characters left if (prec == 0) // no digits found - throw new NumberFormatException(); + throw new NumberFormatException("No digits found."); // Adjust scale if exp is not zero. if (exp != 0) { // had significant exponent scl = adjustScale(scl, exp); @@ -592,10 +597,10 @@ } } } - } catch (ArrayIndexOutOfBoundsException e) { - throw new NumberFormatException(); - } catch (NegativeArraySizeException e) { - throw new NumberFormatException(); + } catch (ArrayIndexOutOfBoundsException | NegativeArraySizeException e) { + NumberFormatException nfe = new NumberFormatException(); + nfe.initCause(e); + throw nfe; } this.scale = scl; this.precision = prec; @@ -627,7 +632,7 @@ len--; } if (len <= 0) // no exponent digits - throw new NumberFormatException(); + throw new NumberFormatException("No exponent digits."); // skip leading zeros in the exponent while (len > 10 && (c=='0' || (Character.digit(c, 10) == 0))) { offset++; @@ -635,7 +640,7 @@ len--; } if (len > 10) // too many nonzero exponent digits - throw new NumberFormatException(); + throw new NumberFormatException("Too many nonzero exponent digits."); // c now holds first digit of exponent for (;; len--) { int v; @@ -644,7 +649,7 @@ } else { v = Character.digit(c, 10); if (v < 0) // not a digit - throw new NumberFormatException(); + throw new NumberFormatException("Not a digit."); } exp = exp * 10 + v; if (len == 1) diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/classes/java/util/Formatter.java --- a/jdk/src/java.base/share/classes/java/util/Formatter.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/classes/java/util/Formatter.java Sat Jan 10 12:38:18 2015 -0800 @@ -3727,29 +3727,29 @@ exp = new StringBuilder("+00"); } } - return; - } - long adjusted = -(long) scale + (len - 1); - if (form == BigDecimalLayoutForm.DECIMAL_FLOAT) { + } else if (form == BigDecimalLayoutForm.DECIMAL_FLOAT) { // count of padding zeros - int pad = scale - len; - if (pad >= 0) { + + if (scale >= len) { // 0.xxx form mant.append("0."); dot = true; - trailingZeros(mant, pad); + trailingZeros(mant, scale - len); mant.append(coeff); } else { - if (-pad < len) { + if (scale > 0) { // xx.xx form - mant.append(coeff, 0, -pad); + int pad = len - scale; + mant.append(coeff, 0, pad); mant.append('.'); dot = true; - mant.append(coeff, -pad, -pad + scale); - } else { + mant.append(coeff, pad, len); + } else { // scale < 0 // xx form mant.append(coeff, 0, len); - trailingZeros(mant, -scale); + if (intVal.signum() != 0) { + trailingZeros(mant, -scale); + } this.scale = 0; } } @@ -3762,6 +3762,7 @@ mant.append(coeff, 1, len); } exp = new StringBuilder(); + long adjusted = -(long) scale + (len - 1); if (adjusted != 0) { long abs = Math.abs(adjusted); // require sign diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java --- a/jdk/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/classes/javax/crypto/spec/RC5ParameterSpec.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ /** * This class specifies the parameters used with the - * RC5 + * RC5 * algorithm. * *

The parameters consist of a version number, a rounds count, a word @@ -37,7 +37,7 @@ * *

This class can be used to initialize a Cipher object that * implements the RC5 algorithm as supplied by - * RSA Security Inc., + * RSA Security LLC, * or any parties authorized by RSA Security. * * @author Jan Luehe diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/classes/sun/security/provider/DSA.java --- a/jdk/src/java.base/share/classes/sun/security/provider/DSA.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/classes/sun/security/provider/DSA.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,7 +117,6 @@ if (params == null) { throw new InvalidKeyException("DSA private key lacks parameters"); } - checkKey(params); this.params = params; this.presetX = priv.getX(); @@ -149,7 +148,6 @@ if (params == null) { throw new InvalidKeyException("DSA public key lacks parameters"); } - checkKey(params); this.params = params; this.presetY = pub.getY(); @@ -291,16 +289,6 @@ return null; } - protected void checkKey(DSAParams params) throws InvalidKeyException { - // FIPS186-3 states in sec4.2 that a hash function which provides - // a lower security strength than the (L, N) pair ordinarily should - // not be used. - int valueN = params.getQ().bitLength(); - if (valueN > md.getDigestLength()*8) { - throw new InvalidKeyException("Key is too strong for this signature algorithm"); - } - } - private BigInteger generateR(BigInteger p, BigInteger q, BigInteger g, BigInteger k) { BigInteger temp = g.modPow(k, p); @@ -480,14 +468,6 @@ } } - @Override - protected void checkKey(DSAParams params) throws InvalidKeyException { - int valueL = params.getP().bitLength(); - if (valueL > 1024) { - throw new InvalidKeyException("Key is too long for this algorithm"); - } - } - /* * Please read bug report 4044247 for an alternative, faster, * NON-FIPS approved method to generate K diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/share/native/libzip/Deflater.c --- a/jdk/src/java.base/share/native/libzip/Deflater.c Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/share/native/libzip/Deflater.c Sat Jan 10 12:38:18 2015 -0800 @@ -76,10 +76,11 @@ JNU_ThrowOutOfMemoryError(env, 0); return jlong_zero; } else { - char *msg; - switch (deflateInit2(strm, level, Z_DEFLATED, - nowrap ? -MAX_WBITS : MAX_WBITS, - DEF_MEM_LEVEL, strategy)) { + const char *msg; + int ret = deflateInit2(strm, level, Z_DEFLATED, + nowrap ? -MAX_WBITS : MAX_WBITS, + DEF_MEM_LEVEL, strategy); + switch (ret) { case Z_OK: return ptr_to_jlong(strm); case Z_MEM_ERROR: @@ -91,7 +92,11 @@ JNU_ThrowIllegalArgumentException(env, 0); return jlong_zero; default: - msg = strm->msg; + msg = ((strm->msg != NULL) ? strm->msg : + (ret == Z_VERSION_ERROR) ? + "zlib returned Z_VERSION_ERROR: " + "compile time and runtime zlib implementations differ" : + "unknown error initializing zlib library"); free(strm); JNU_ThrowInternalError(env, msg); return jlong_zero; diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java --- a/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java Sat Jan 10 12:38:18 2015 -0800 @@ -123,7 +123,7 @@ new PrivilegedAction() { @Override public String run() { - return System.getProperty("jdk.net.enableFastFileTransfer"); + return System.getProperty("jdk.nio.enableFastFileTransfer"); } }); boolean enable; diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c --- a/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Sat Jan 10 12:38:18 2015 -0800 @@ -81,9 +81,17 @@ DWORD ret, flags; IP_ADAPTER_ADDRESSES *adapterInfo; ULONG len; + char *error_msg_buf = NULL; + size_t error_msg_buf_size = + strlen("IP Helper Library GetAdaptersAddresses function failed" + " with error == ") + 10; + int _ret = 0; + + adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize); if (adapterInfo == NULL) { - JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); + JNU_ThrowByName(env, "java/lang/OutOfMemoryError", + "Native heap allocation failure"); return -1; } @@ -94,10 +102,12 @@ ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); if (ret == ERROR_BUFFER_OVERFLOW) { - IP_ADAPTER_ADDRESSES * newAdapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); + IP_ADAPTER_ADDRESSES * newAdapterInfo = + (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); if (newAdapterInfo == NULL) { free(adapterInfo); - JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); + JNU_ThrowByName(env, "java/lang/OutOfMemoryError", + "Native heap allocation failure"); return -1; } @@ -109,8 +119,32 @@ if (ret != ERROR_SUCCESS) { free (adapterInfo); - JNU_ThrowByName(env, "java/lang/Error", - "IP Helper Library GetAdaptersAddresses function failed"); + if (ret == ERROR_INSUFFICIENT_BUFFER) { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failed " + "with ERROR_INSUFFICIENT_BUFFER"); + } else if (ret == ERROR_ADDRESS_NOT_ASSOCIATED ) { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failed " + "with ERROR_ADDRESS_NOT_ASSOCIATED"); + } else { + error_msg_buf = (char *)malloc(error_msg_buf_size); + if (error_msg_buf != NULL) { + memset(error_msg_buf, 0, error_msg_buf_size); + _ret = _snprintf_s(error_msg_buf, error_msg_buf_size, + _TRUNCATE, "IP Helper Library GetAdaptersAddresses " + "function failed with error == %d", ret); + if (_ret != -1) { + JNU_ThrowByName(env, "java/lang/Error", error_msg_buf); + } else { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failure"); + } + } else { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failed"); + } + } return -1; } *adapters = adapterInfo; @@ -126,9 +160,14 @@ DWORD flags, val; IP_ADAPTER_ADDRESSES *adapterInfo, *ptr, *ret; ULONG len; + char *error_msg_buf = NULL; + size_t error_msg_buf_size = + strlen("IP Helper Library GetAdaptersAddresses function failed with error == ") + 10; + int _ret = 0; adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize); if (adapterInfo == NULL) { - JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); + JNU_ThrowByName(env, "java/lang/OutOfMemoryError", + "Native heap allocation failure"); return NULL; } len = bufsize; @@ -137,10 +176,12 @@ flags |= GAA_FLAG_INCLUDE_PREFIX; val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len); if (val == ERROR_BUFFER_OVERFLOW) { - IP_ADAPTER_ADDRESSES * newAdapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); + IP_ADAPTER_ADDRESSES * newAdapterInfo = + (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len); if (newAdapterInfo == NULL) { free(adapterInfo); - JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); + JNU_ThrowByName(env, "java/lang/OutOfMemoryError", + "Native heap allocation failure"); return NULL; } @@ -152,10 +193,35 @@ if (val != ERROR_SUCCESS) { free (adapterInfo); - JNU_ThrowByName(env, "java/lang/Error", - "IP Helper Library GetAdaptersAddresses function failed"); + if (val == ERROR_INSUFFICIENT_BUFFER) { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failed " + "with ERROR_INSUFFICIENT_BUFFER"); + } else if (val == ERROR_ADDRESS_NOT_ASSOCIATED ) { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failed " + "with ERROR_ADDRESS_NOT_ASSOCIATED"); + } else { + error_msg_buf = (char *)malloc(error_msg_buf_size); + if (error_msg_buf != NULL) { + memset(error_msg_buf, 0, error_msg_buf_size); + _ret = _snprintf_s(error_msg_buf, error_msg_buf_size, + _TRUNCATE, "IP Helper Library GetAdaptersAddresses function failed " + "with error == %d", val); + if (_ret != -1) { + JNU_ThrowByName(env, "java/lang/Error", error_msg_buf); + } else { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failure"); + } + } else { + JNU_ThrowByName(env, "java/lang/Error", + "IP Helper Library GetAdaptersAddresses function failed"); + } + } return NULL; } + ptr = adapterInfo; ret = NULL; while (ptr != NULL) { @@ -168,7 +234,8 @@ ret = (IP_ADAPTER_ADDRESSES *) malloc(sizeof(IP_ADAPTER_ADDRESSES)); if (ret == NULL) { free(adapterInfo); - JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure"); + JNU_ThrowByName(env, "java/lang/OutOfMemoryError", + "Native heap allocation failure"); return NULL; } diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java --- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Sat Jan 10 12:38:18 2015 -0800 @@ -85,7 +85,7 @@ public List getNames(); /** - * Returns the name of the scripting langauge supported by this + * Returns the name of the scripting language supported by this * ScriptEngine. * @return The name of the supported language. */ @@ -104,14 +104,15 @@ *

    *
  • ScriptEngine.ENGINE
  • *
  • ScriptEngine.ENGINE_VERSION
  • - *
  • ScriptEngine.NAME
  • *
  • ScriptEngine.LANGUAGE
  • *
  • ScriptEngine.LANGUAGE_VERSION
  • + *
  • ScriptEngine.NAME
  • *
*

* The values for these keys are the Strings returned by getEngineName, - * getEngineVersion, getName, getLanguageName and - * getLanguageVersion respectively.

+ * getEngineVersion, getLanguageName, + * getLanguageVersion for the first four keys respectively. For NAME, one of the Strings + * returned by getNames is returned.

* A reserved key, THREADING, whose value describes the behavior of the engine * with respect to concurrent execution of scripts and maintenance of state is also defined. * These values for the THREADING key are:

diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.sql/share/classes/javax/transaction/xa/XAException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.sql/share/classes/javax/transaction/xa/XAException.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2000, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.transaction.xa; + +/** + * The XAException is thrown by the Resource Manager (RM) to inform the + * Transaction Manager of an error encountered by the involved transaction. + * + */ +public class XAException extends Exception { + //private static final long serialVersionUID = -8249683284832867751L; + + /** + * The error code with which to create the SystemException. + * + * @serial The error code for the exception + */ + public int errorCode; + + /** + * Create an XAException. + */ + public XAException() { + super(); + } + + /** + * Create an XAException with a given string. + * + * @param s The String object containing the exception + * message. + */ + public XAException(String s) { + super(s); + } + + /** + * Create an XAException with a given error code. + * + * @param errcode The error code identifying the exception. + */ + public XAException(int errcode) { + super(); + errorCode = errcode; + } + + /** + * The inclusive lower bound of the rollback codes. + */ + public final static int XA_RBBASE = 100; + + /** + * Indicates that the rollback was caused by an unspecified reason. + */ + public final static int XA_RBROLLBACK = XA_RBBASE; + + /** + * Indicates that the rollback was caused by a communication failure. + */ + public final static int XA_RBCOMMFAIL = XA_RBBASE + 1; + + /** + * A deadlock was detected. + */ + public final static int XA_RBDEADLOCK = XA_RBBASE + 2; + + /** + * A condition that violates the integrity of the resource was detected. + */ + public final static int XA_RBINTEGRITY = XA_RBBASE + 3; + + /** + * The resource manager rolled back the transaction branch for a reason + * not on this list. + */ + public final static int XA_RBOTHER = XA_RBBASE + 4; + + /** + * A protocol error occurred in the resource manager. + */ + public final static int XA_RBPROTO = XA_RBBASE + 5; + + /** + * A transaction branch took too long. + */ + public final static int XA_RBTIMEOUT = XA_RBBASE + 6; + + /** + * May retry the transaction branch. + */ + public final static int XA_RBTRANSIENT = XA_RBBASE + 7; + + /** + * The inclusive upper bound of the rollback error code. + */ + public final static int XA_RBEND = XA_RBTRANSIENT; + + /** + * Resumption must occur where the suspension occurred. + */ + public final static int XA_NOMIGRATE = 9; + + /** + * The transaction branch may have been heuristically completed. + */ + public final static int XA_HEURHAZ = 8; + + /** + * The transaction branch has been heuristically committed. + */ + public final static int XA_HEURCOM = 7; + + /** + * The transaction branch has been heuristically rolled back. + */ + public final static int XA_HEURRB = 6; + + /** + * The transaction branch has been heuristically committed and + * rolled back. + */ + public final static int XA_HEURMIX = 5; + + /** + * Routine returned with no effect and may be reissued. + */ + public final static int XA_RETRY = 4; + + /** + * The transaction branch was read-only and has been committed. + */ + public final static int XA_RDONLY = 3; + + /** + * There is an asynchronous operation already outstanding. + */ + public final static int XAER_ASYNC = -2; + + /** + * A resource manager error has occurred in the transaction branch. + */ + public final static int XAER_RMERR = -3; + + /** + * The XID is not valid. + */ + public final static int XAER_NOTA = -4; + + /** + * Invalid arguments were given. + */ + public final static int XAER_INVAL = -5; + + /** + * Routine was invoked in an inproper context. + */ + public final static int XAER_PROTO = -6; + + /** + * Resource manager is unavailable. + */ + public final static int XAER_RMFAIL = -7; + + /** + * The XID already exists. + */ + public final static int XAER_DUPID = -8; + + /** + * The resource manager is doing work outside a global transaction. + */ + public final static int XAER_OUTSIDE = -9; +} diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.sql/share/classes/javax/transaction/xa/XAResource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.sql/share/classes/javax/transaction/xa/XAResource.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2000, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.transaction.xa; + +/** + * The XAResource interface is a Java mapping of the industry standard + * XA interface based on the X/Open CAE Specification (Distributed + * Transaction Processing: The XA Specification). + * + *

The XA interface defines the contract between a Resource Manager + * and a Transaction Manager in a distributed transaction processing + * (DTP) environment. A JDBC driver or a JMS provider implements + * this interface to support the association between a global transaction + * and a database or message service connection. + * + *

The XAResource interface can be supported by any transactional + * resource that is intended to be used by application programs in an + * environment where transactions are controlled by an external + * transaction manager. An example of such a resource is a database + * management system. An application may access data through multiple + * database connections. Each database connection is enlisted with + * the transaction manager as a transactional resource. The transaction + * manager obtains an XAResource for each connection participating + * in a global transaction. The transaction manager uses the + * start method + * to associate the global transaction with the resource, and it uses the + * end method to disassociate the transaction from + * the resource. The resource + * manager is responsible for associating the global transaction to all + * work performed on its data between the start and end method invocations. + * + *

At transaction commit time, the resource managers are informed by + * the transaction manager to prepare, commit, or rollback a transaction + * according to the two-phase commit protocol.

+ * + */ +public interface XAResource { + + /** + * Commits the global transaction specified by xid. + * + * @param xid A global transaction identifier + * + * @param onePhase If true, the resource manager should use a one-phase + * commit protocol to commit the work done on behalf of xid. + * + * @exception XAException An error has occurred. Possible XAExceptions + * are XA_HEURHAZ, XA_HEURCOM, XA_HEURRB, XA_HEURMIX, XAER_RMERR, + * XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or XAER_PROTO. + * + *

If the resource manager did not commit the transaction and the + * paramether onePhase is set to true, the resource manager may throw + * one of the XA_RB* exceptions. Upon return, the resource manager has + * rolled back the branch's work and has released all held resources. + */ + void commit(Xid xid, boolean onePhase) throws XAException; + + /** + * Ends the work performed on behalf of a transaction branch. + * The resource manager disassociates the XA resource from the + * transaction branch specified and lets the transaction + * complete. + * + *

If TMSUSPEND is specified in the flags, the transaction branch + * is temporarily suspended in an incomplete state. The transaction + * context is in a suspended state and must be resumed via the + * start method with TMRESUME specified.

+ * + *

If TMFAIL is specified, the portion of work has failed. + * The resource manager may mark the transaction as rollback-only

+ * + *

If TMSUCCESS is specified, the portion of work has completed + * successfully.

+ * + * @param xid A global transaction identifier that is the same as + * the identifier used previously in the start method. + * + * @param flags One of TMSUCCESS, TMFAIL, or TMSUSPEND. + * + * @exception XAException An error has occurred. Possible XAException + * values are XAER_RMERR, XAER_RMFAILED, XAER_NOTA, XAER_INVAL, + * XAER_PROTO, or XA_RB*. + */ + void end(Xid xid, int flags) throws XAException; + + /** + * Tells the resource manager to forget about a heuristically + * completed transaction branch. + * + * @param xid A global transaction identifier. + * + * @exception XAException An error has occurred. Possible exception + * values are XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, or + * XAER_PROTO. + */ + void forget(Xid xid) throws XAException; + + /** + * Obtains the current transaction timeout value set for this + * XAResource instance. If XAResource.setTransactionTimeout + * was not used prior to invoking this method, the return value + * is the default timeout set for the resource manager; otherwise, + * the value used in the previous setTransactionTimeout + * call is returned. + * + * @return the transaction timeout value in seconds. + * + * @exception XAException An error has occurred. Possible exception + * values are XAER_RMERR and XAER_RMFAIL. + */ + int getTransactionTimeout() throws XAException; + + /** + * This method is called to determine if the resource manager + * instance represented by the target object is the same as the + * resouce manager instance represented by the parameter xares. + * + * @param xares An XAResource object whose resource manager instance + * is to be compared with the resource manager instance of the + * target object. + * + * @return true if it's the same RM instance; otherwise + * false. + * + * @exception XAException An error has occurred. Possible exception + * values are XAER_RMERR and XAER_RMFAIL. + */ + boolean isSameRM(XAResource xares) throws XAException; + + /** + * Ask the resource manager to prepare for a transaction commit + * of the transaction specified in xid. + * + * @param xid A global transaction identifier. + * + * @exception XAException An error has occurred. Possible exception + * values are: XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_NOTA, XAER_INVAL, + * or XAER_PROTO. + * + * @return A value indicating the resource manager's vote on the + * outcome of the transaction. The possible values are: XA_RDONLY + * or XA_OK. If the resource manager wants to roll back the + * transaction, it should do so by raising an appropriate XAException + * in the prepare method. + */ + int prepare(Xid xid) throws XAException; + + /** + * Obtains a list of prepared transaction branches from a resource + * manager. The transaction manager calls this method during recovery + * to obtain the list of transaction branches that are currently in + * prepared or heuristically completed states. + * + * @param flag One of TMSTARTRSCAN, TMENDRSCAN, TMNOFLAGS. TMNOFLAGS + * must be used when no other flags are set in the parameter. + * + * @exception XAException An error has occurred. Possible values are + * XAER_RMERR, XAER_RMFAIL, XAER_INVAL, and XAER_PROTO. + * + * @return The resource manager returns zero or more XIDs of the + * transaction branches that are currently in a prepared or + * heuristically completed state. If an error occurs during the + * operation, the resource manager should throw the appropriate + * XAException. + */ + Xid[] recover(int flag) throws XAException; + + /** + * Informs the resource manager to roll back work done on behalf + * of a transaction branch. + * + * @param xid A global transaction identifier. + * + * @exception XAException An error has occurred. + */ + void rollback(Xid xid) throws XAException; + + /** + * Sets the current transaction timeout value for this XAResource + * instance. Once set, this timeout value is effective until + * setTransactionTimeout is invoked again with a different + * value. To reset the timeout value to the default value used by the resource + * manager, set the value to zero. + * + * If the timeout operation is performed successfully, the method returns + * true; otherwise false. If a resource manager does not + * support explicitly setting the transaction timeout value, this method + * returns false. + * + * @param seconds The transaction timeout value in seconds. + * + * @return true if the transaction timeout value is set successfully; + * otherwise false. + * + * @exception XAException An error has occurred. Possible exception values + * are XAER_RMERR, XAER_RMFAIL, or XAER_INVAL. + */ + boolean setTransactionTimeout(int seconds) throws XAException; + + /** + * Starts work on behalf of a transaction branch specified in + * xid. + * + * If TMJOIN is specified, the start applies to joining a transaction + * previously seen by the resource manager. If TMRESUME is specified, + * the start applies to resuming a suspended transaction specified in the + * parameter xid. + * + * If neither TMJOIN nor TMRESUME is specified and the transaction + * specified by xid has previously been seen by the resource + * manager, the resource manager throws the XAException exception with + * XAER_DUPID error code. + * + * @param xid A global transaction identifier to be associated + * with the resource. + * + * @param flags One of TMNOFLAGS, TMJOIN, or TMRESUME. + * + * @exception XAException An error has occurred. Possible exceptions + * are XA_RB*, XAER_RMERR, XAER_RMFAIL, XAER_DUPID, XAER_OUTSIDE, + * XAER_NOTA, XAER_INVAL, or XAER_PROTO. + */ + void start(Xid xid, int flags) throws XAException; + + /** + * Ends a recovery scan. + */ + public final static int TMENDRSCAN = 0x00800000; + + /** + * Disassociates the caller and marks the transaction branch + * rollback-only. + */ + public final static int TMFAIL = 0x20000000; + + /** + * Caller is joining existing transaction branch. + */ + public final static int TMJOIN = 0x00200000; + + /** + * Use TMNOFLAGS to indicate no flags value is selected. + */ + public final static int TMNOFLAGS = 0x00000000; + + /** + * Caller is using one-phase optimization. + */ + public final static int TMONEPHASE = 0x40000000; + + /** + * Caller is resuming association with a suspended + * transaction branch. + */ + public final static int TMRESUME = 0x08000000; + + /** + * Starts a recovery scan. + */ + public final static int TMSTARTRSCAN = 0x01000000; + + /** + * Disassociates caller from a transaction branch. + */ + public final static int TMSUCCESS = 0x04000000; + + /** + * Caller is suspending (not ending) its association with + * a transaction branch. + */ + public final static int TMSUSPEND = 0x02000000; + + /** + * The transaction branch has been read-only and has been committed. + */ + public final static int XA_RDONLY = 0x00000003; + + /** + * The transaction work has been prepared normally. + */ + public final static int XA_OK = 0; +} diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.sql/share/classes/javax/transaction/xa/Xid.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.sql/share/classes/javax/transaction/xa/Xid.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2000, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package javax.transaction.xa; + +/** + * The Xid interface is a Java mapping of the X/Open transaction identifier + * XID structure. This interface specifies three accessor methods to + * retrieve a global transaction format ID, global transaction ID, + * and branch qualifier. The Xid interface is used by the transaction + * manager and the resource managers. This interface is not visible to + * the application programs. + */ +public interface Xid { + + /** + * Maximum number of bytes returned by getGtrid. + */ + final static int MAXGTRIDSIZE = 64; + + /** + * Maximum number of bytes returned by getBqual. + */ + final static int MAXBQUALSIZE = 64; + + /** + * Obtain the format identifier part of the XID. + * + * @return Format identifier. O means the OSI CCR format. + */ + int getFormatId(); + + /** + * Obtain the global transaction identifier part of XID as an array + * of bytes. + * + * @return Global transaction identifier. + */ + byte[] getGlobalTransactionId(); + + /** + * Obtain the transaction branch identifier part of XID as an array + * of bytes. + * + * @return Global transaction identifier. + */ + byte[] getBranchQualifier(); +} diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.sql/share/classes/javax/transaction/xa/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.sql/share/classes/javax/transaction/xa/package.html Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,41 @@ + + + + + + + + +Provides the API that defines the contract between the transaction +manager and the resource manager, which allows the transaction +manager to enlist and delist resource objects (supplied by the +resource manager driver) in JTA transactions. The driver vendor +for a specific resource manager provides the implementation of +this API. +

+@since 1.4 + + diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.transaction/share/classes/javax/transaction/InvalidTransactionException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.transaction/share/classes/javax/transaction/InvalidTransactionException.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * Licensed Materials - Property of IBM + * RMI-IIOP v1.0 + * Copyright IBM Corp. 1998 1999 All Rights Reserved + * + */ + +package javax.transaction; + +/** + * This exception indicates that the request carried an invalid transaction + * context. For example, this exception could be raised if an error + * occured when trying to register a resource. + */ +@SuppressWarnings("serial") // serialVersionUID intentionally omitted +public class InvalidTransactionException extends java.rmi.RemoteException { + + public InvalidTransactionException() { + super(); + } + + public InvalidTransactionException(String msg) { + super(msg); + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.transaction/share/classes/javax/transaction/TransactionRequiredException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRequiredException.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * Licensed Materials - Property of IBM + * RMI-IIOP v1.0 + * Copyright IBM Corp. 1998 1999 All Rights Reserved + * + */ + +package javax.transaction; + +/** + * This exception indicates that a request carried a null transaction context, + * but the target object requires an activate transaction. + */ +@SuppressWarnings("serial") // serialVersionUID intentionally omitted +public class TransactionRequiredException extends java.rmi.RemoteException { + + public TransactionRequiredException() { + super(); + } + + public TransactionRequiredException(String msg) { + super(msg); + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.transaction/share/classes/javax/transaction/TransactionRolledbackException.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.transaction/share/classes/javax/transaction/TransactionRolledbackException.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * Licensed Materials - Property of IBM + * RMI-IIOP v1.0 + * Copyright IBM Corp. 1998 1999 All Rights Reserved + * + */ + +package javax.transaction; + +/** + * This exception indicates that the transaction associated with processing + * of the request has been rolled back, or marked to roll back. Thus the + * requested operation either could not be performed or was not performed + * because further computation on behalf of the transaction would be + * fruitless + */ +@SuppressWarnings("serial") // serialVersionUID intentionally omitted +public class TransactionRolledbackException extends java.rmi.RemoteException { + + public TransactionRolledbackException() { + super(); + } + + public TransactionRolledbackException(String msg) { + super(msg); + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/src/java.transaction/share/classes/javax/transaction/package.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/java.transaction/share/classes/javax/transaction/package.html Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,36 @@ + + + + + + + + +Contains three exceptions thrown by the ORB machinery during unmarshalling. +

+@since 1.3 + + diff -r ad8137d44154 -r 247f60f5808f jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AliasFileParser.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AliasFileParser.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/AliasFileParser.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ */ public class AliasFileParser { private static final String ALIAS = "alias"; - private static final boolean DEBUG = false; + // 8028357 removed old, inefficient debug logging // other variables private URL inputfile; @@ -64,21 +64,12 @@ } } - private void logln(String s) { - if (DEBUG) { - System.err.println(s); - } - } - /** * method to get the next token as a Token type */ private void nextToken() throws IOException { st.nextToken(); currentToken = new Token(st.ttype, st.sval); - - logln("Read token: type = " + currentToken.ttype - + " string = " + currentToken.sval); } /** @@ -90,8 +81,6 @@ if ((currentToken.ttype == ttype) && (currentToken.sval.compareTo(token) == 0)) { - logln("matched type: " + ttype + " and token = " - + currentToken.sval); nextToken(); } else { throw new SyntaxException(st.lineno()); @@ -105,7 +94,6 @@ */ private void match(int ttype) throws IOException, SyntaxException { if (currentToken.ttype == ttype) { - logln("matched type: " + ttype + ", token = " + currentToken.sval); nextToken(); } else { throw new SyntaxException(st.lineno()); @@ -157,8 +145,6 @@ } while ((currentToken.ttype != StreamTokenizer.TT_EOF) && (currentToken.sval.compareTo(ALIAS) != 0)); - logln("adding map entry for " + name + " values = " + aliases); - map.put(name, aliases); } } diff -r ad8137d44154 -r 247f60f5808f jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTaskUtils.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTaskUtils.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/CountedTimerTaskUtils.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ */ public class CountedTimerTaskUtils { - private static final boolean DEBUG = false; + // 8028357 removed old, inefficient debug logging /** * Reschedule a CountedTimeTask at a different interval. Probably not @@ -58,14 +58,6 @@ long lastRun = oldTask.scheduledExecutionTime(); long expired = now - lastRun; - if (DEBUG) { - System.err.println("computing timer delay: " - + " oldInterval = " + oldInterval - + " newInterval = " + newInterval - + " samples = " + oldTask.executionCount() - + " expired = " + expired); - } - /* * check if original task ever ran - if not, then lastRun is * undefined and we simply set the delay to 0. @@ -76,12 +68,6 @@ delay = remainder >= 0 ? remainder : 0; } - if (DEBUG) { - System.err.println("rescheduling sampler task: interval = " - + newInterval - + " delay = " + delay); - } - timer.schedule(newTask, delay, newInterval); } } diff -r ad8137d44154 -r 247f60f5808f jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBuffer.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBuffer.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v1_0/PerfDataBuffer.java Sat Jan 10 12:38:18 2015 -0800 @@ -44,7 +44,8 @@ */ public class PerfDataBuffer extends PerfDataBufferImpl { - private static final boolean DEBUG = false; + // 8028357 removed old, inefficient debug logging + private static final int syncWaitMs = Integer.getInteger("sun.jvmstat.perdata.syncWaitMs", 5000); private static final ArrayList EMPTY_LIST = new ArrayList(0); @@ -268,18 +269,13 @@ * loop waiting for the ticks counter to be non zero. This is * an indication that the jvm is initialized. */ - log("synchWithTarget: " + lvmid + " "); while (ticks.longValue() == 0) { - log("."); - try { Thread.sleep(20); } catch (InterruptedException e) { } if (System.currentTimeMillis() > timeLimit) { - lognl("failed: " + lvmid); throw new MonitorException("Could Not Synchronize with target"); } } - lognl("success: " + lvmid); } /** @@ -291,24 +287,18 @@ throws MonitorException { Monitor monitor = null; - log("polling for: " + lvmid + "," + name + " "); - pollForEntry = nextEntry; while ((monitor = map.get(name)) == null) { - log("."); try { Thread.sleep(20); } catch (InterruptedException e) { } long t = System.currentTimeMillis(); if ((t > timeLimit) || (overflow.intValue() > 0)) { - lognl("failed: " + lvmid + "," + name); - dumpAll(map, lvmid); throw new MonitorException("Could not find expected counter"); } getNewMonitors(map); } - lognl("success: " + lvmid + "," + name); return monitor; } @@ -481,8 +471,6 @@ // check for the end of the buffer if (nextEntry == buffer.limit()) { - lognl("getNextMonitorEntry():" - + " nextEntry == buffer.limit(): returning"); return null; } @@ -614,37 +602,4 @@ nextEntry = entryStart + entryLength; return monitor; } - - /** - * Method to dump debugging information - */ - private void dumpAll(Map map, int lvmid) { - if (DEBUG) { - Set keys = map.keySet(); - - System.err.println("Dump for " + lvmid); - int j = 0; - for (Iterator i = keys.iterator(); i.hasNext(); j++) { - Monitor monitor = map.get(i.next()); - System.err.println(j + "\t" + monitor.getName() - + "=" + monitor.getValue()); - } - System.err.println("nextEntry = " + nextEntry - + " pollForEntry = " + pollForEntry); - System.err.println("Buffer info:"); - System.err.println("buffer = " + buffer); - } - } - - private void lognl(String s) { - if (DEBUG) { - System.err.println(s); - } - } - - private void log(String s) { - if (DEBUG) { - System.err.print(s); - } - } } diff -r ad8137d44154 -r 247f60f5808f jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBuffer.java --- a/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBuffer.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/src/jdk.jvmstat/share/classes/sun/jvmstat/perfdata/monitor/v2_0/PerfDataBuffer.java Sat Jan 10 12:38:18 2015 -0800 @@ -62,7 +62,8 @@ */ public class PerfDataBuffer extends PerfDataBufferImpl { - private static final boolean DEBUG = false; + // 8028357 removed old, inefficient debug logging + private static final int syncWaitMs = Integer.getInteger("sun.jvmstat.perdata.syncWaitMs", 5000); private static final ArrayList EMPTY_LIST = new ArrayList<>(0); @@ -264,20 +265,15 @@ long timeLimit = System.currentTimeMillis() + syncWaitMs; // loop waiting for the accessible indicater to be non-zero - log("synchWithTarget: " + lvmid + " "); while (!prologue.isAccessible()) { - log("."); - // give the target jvm a chance to complete initializatoin try { Thread.sleep(20); } catch (InterruptedException e) { } if (System.currentTimeMillis() > timeLimit) { - logln("failed: " + lvmid); throw new MonitorException("Could not synchronize with target"); } } - logln("success: " + lvmid); } /** @@ -306,8 +302,6 @@ // check for end of the buffer if (nextEntry == buffer.limit()) { - logln("getNextMonitorEntry():" - + " nextEntry == buffer.limit(): returning"); return null; } @@ -346,9 +340,6 @@ byte varByte = buffer.get(); int dataOffset = buffer.getInt(); - dump_entry_fixed(entryStart, nameOffset, vectorLength, typeCodeByte, - flags, unitsByte, varByte, dataOffset); - // convert common attributes to their object types Units units = Units.toUnits(unitsByte); Variability variability = Variability.toVariability(varByte); @@ -439,8 +430,6 @@ // set the position to the start of the data item buffer.position(entryStart + dataOffset); - dump_entry_variable(name, buffer, dataSize); - if (vectorLength == 0) { // create a scalar Monitor object if (typeCode == TypeCode.LONG) { @@ -514,103 +503,4 @@ nextEntry = entryStart + entryLength; return monitor; } - - /** - * Method to dump debugging information - */ - private void dumpAll(Map map, int lvmid) { - if (DEBUG) { - Set keys = map.keySet(); - - System.err.println("Dump for " + lvmid); - int j = 0; - for (Iterator i = keys.iterator(); i.hasNext(); j++) { - Monitor monitor = map.get(i.next()); - System.err.println(j + "\t" + monitor.getName() - + "=" + monitor.getValue()); - } - System.err.println("nextEntry = " + nextEntry); - System.err.println("Buffer info:"); - System.err.println("buffer = " + buffer); - } - } - - /** - * Method to dump the fixed portion of an entry. - */ - private void dump_entry_fixed(int entry_start, int nameOffset, - int vectorLength, byte typeCodeByte, - byte flags, byte unitsByte, byte varByte, - int dataOffset) { - if (DEBUG) { - System.err.println("Entry at offset: 0x" - + Integer.toHexString(entry_start)); - System.err.println("\tname_offset = 0x" - + Integer.toHexString(nameOffset)); - System.err.println("\tvector_length = 0x" - + Integer.toHexString(vectorLength)); - System.err.println("\tdata_type = 0x" - + Integer.toHexString(typeCodeByte)); - System.err.println("\tflags = 0x" - + Integer.toHexString(flags)); - System.err.println("\tdata_units = 0x" - + Integer.toHexString(unitsByte)); - System.err.println("\tdata_variability = 0x" - + Integer.toHexString(varByte)); - System.err.println("\tdata_offset = 0x" - + Integer.toHexString(dataOffset)); - } - } - - private void dump_entry_variable(String name, ByteBuffer bb, int size) { - if (DEBUG) { - char[] toHex = new char[] { '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f' }; - - ByteBuffer data = bb.slice(); - data.limit(size); - - System.err.println("\tname = " + name); - System.err.println("\tdata = "); - - int count=0; - while (data.hasRemaining()) { - byte b = data.get(); - byte high = (byte)((b >> 8) & 0x0f); - byte low = (byte)(b & 0x0f); - - if (count % 16 == 0) { - System.err.print("\t\t" + Integer.toHexString(count / 16) - + ": "); - } - - System.err.print(String.valueOf(toHex[high]) - + String.valueOf(toHex[low])); - - count++; - if (count % 16 == 0) { - System.err.println(); - } else { - System.err.print(" "); - } - } - if (count % 16 != 0) { - System.err.println(); - } - } - } - - private void logln(String s) { - if (DEBUG) { - System.err.println(s); - } - } - - private void log(String s) { - if (DEBUG) { - System.err.print(s); - } - } } diff -r ad8137d44154 -r 247f60f5808f jdk/test/ProblemList.txt --- a/jdk/test/ProblemList.txt Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/ProblemList.txt Sat Jan 10 12:38:18 2015 -0800 @@ -120,6 +120,10 @@ # jdk_lang +# 8029891 +java/lang/ClassLoader/deadlock/GetResource.java generic-all + + ############################################################################ # jdk_instrument @@ -261,7 +265,7 @@ # Tests take too long, on sparcs see 7143279 # also see 8059906 -tools/pack200/CommandLineTests.java +tools/pack200/CommandLineTests.java generic-all tools/pack200/Pack200Test.java solaris-all,macosx-all # 8007410 diff -r ad8137d44154 -r 247f60f5808f jdk/test/com/sun/corba/5036554/TestCorbaBug.sh --- a/jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/com/sun/corba/5036554/TestCorbaBug.sh Sat Jan 10 12:38:18 2015 -0800 @@ -75,13 +75,13 @@ mkdir bug cp ${TESTSRC}${FS}bug.idl . -${TESTJAVA}${FS}bin${FS}idlj bug.idl +${COMPILEJAVA}${FS}bin${FS}idlj bug.idl cp ${TESTSRC}${FS}JavaBug.java bug chmod -fR 777 bug -${TESTJAVA}${FS}bin${FS}javac -d . bug${FS}*.java +${COMPILEJAVA}${FS}bin${FS}javac -d . bug${FS}*.java ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp . bug/JavaBug > test.out 2>&1 diff -r ad8137d44154 -r 247f60f5808f jdk/test/com/sun/corba/cachedSocket/7056731.sh --- a/jdk/test/com/sun/corba/cachedSocket/7056731.sh Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/com/sun/corba/cachedSocket/7056731.sh Sat Jan 10 12:38:18 2015 -0800 @@ -55,8 +55,8 @@ cp -r ${TESTSRC}${FS}*.java ${TESTSRC}${FS}Hello.idl . echo "Testing...please wait" -${TESTJAVA}${FS}bin${FS}idlj -fall Hello.idl -${TESTJAVA}${FS}bin${FS}javac *.java HelloApp/*.java +${COMPILEJAVA}${FS}bin${FS}idlj -fall Hello.idl +${COMPILEJAVA}${FS}bin${FS}javac *.java HelloApp/*.java echo "starting orbd" ${TESTJAVA}${FS}bin${FS}orbd -ORBInitialPort $PORT -ORBInitialHost localhost & diff -r ad8137d44154 -r 247f60f5808f jdk/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java --- a/jdk/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/com/sun/crypto/provider/Cipher/DES/TestUtility.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,39 +27,52 @@ public class TestUtility { - private static final String digits = "0123456789abcdef"; + private static final String DIGITS = "0123456789abcdef"; - public TestUtility() { + private TestUtility() { } public static String hexDump(byte[] bytes) { - StringBuffer buf = new StringBuffer (bytes.length * 2); - int i; + StringBuilder buf = new StringBuilder(bytes.length * 2); + int i; - buf.append (" "); // four spaces + buf.append(" "); // four spaces for (i = 0; i < bytes.length; i++) { - buf.append (digits.charAt ((bytes[i] >> 4) & 0x0f)); - buf.append (digits.charAt (bytes[i] & 0x0f)); - if (((i + 1) % 32) == 0) { - if ((i + 1) != bytes.length) - buf.append ("\n "); // line after four words - } else if (((i + 1) % 4) == 0) - buf.append (' '); // space between words + buf.append(DIGITS.charAt(bytes[i] >> 4 & 0x0f)); + buf.append(DIGITS.charAt(bytes[i] & 0x0f)); + if ((i + 1) % 32 == 0) { + if (i + 1 != bytes.length) { + buf.append("\n "); // line after four words + } + } else if ((i + 1) % 4 == 0) { + buf.append(' '); // space between words + } } - return buf.toString (); + return buf.toString(); } + public static String hexDump(byte[] bytes, int index) { + StringBuilder buf = new StringBuilder(bytes.length * 2); + int i; + + buf.append(" "); // four spaces + buf.append(DIGITS.charAt(bytes[index] >> 4 & 0x0f)); + buf.append(DIGITS.charAt(bytes[index] & 0x0f)); + return buf.toString(); + } public static boolean equalsBlock(byte[] b1, byte[] b2) { - if (b1.length != b2.length) + if (b1.length != b2.length) { return false; + } - for (int i=0; i 0) throw new RuntimeException(failed + " test(s) failed - see log for details"); diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/nio/channels/FileChannel/TransferToChannel.java --- a/jdk/test/java/nio/channels/FileChannel/TransferToChannel.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/nio/channels/FileChannel/TransferToChannel.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,7 @@ * @bug 4652496 * @summary Test transferTo with different target channels * @run main TransferToChannel - * @run main/othervm -Djdk.net.enableFastFileTransfer TransferToChannel + * @run main/othervm -Djdk.nio.enableFastFileTransfer TransferToChannel */ import java.nio.channels.FileChannel; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/checkActivateRef/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,8 +4,8 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; - // test needs to communicate with the activation system - permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; permission java.lang.RuntimePermission "getClassLoader"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/checkAnnotations/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,10 +1,9 @@ /* - * security policy used by activation groups. + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // test needs to communicate with the activation system permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,10 +4,6 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // allow remote objects to be exported on arbitrary ports. - permission java.net.SocketPermission "*:1024-", "connect,accept"; - - // allow exporting object with non-public remote interface - permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/createPrivateActivable/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,13 +1,9 @@ /* - * security policy used activation groups + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // test needs to communicate with the activation system permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; - - // allow exporting object with non-public remote interface - permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/downloadParameterClass/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,14 +1,15 @@ /* - * security policy used exec'ed activation groups + * security policy used by activation groups */ grant { + permission java.io.FilePermission "..${/}..${/}test.props", "read"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; + // need to load custom security manager and activation group from a new codebase permission java.io.FilePermission ".${/}codebase1", "read,write,delete"; permission java.io.FilePermission ".${/}codebase1${/}-", "read,write"; permission java.io.FilePermission ".${/}codebase2", "read,write,delete"; permission java.io.FilePermission ".${/}codebase2${/}-", "read,write,delete"; - - // allow remote objects to be exported on arbitrary ports. - permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,12 +1,13 @@ /* - * security policy used activation groups + * security policy used by activation groups */ grant { + permission java.io.FilePermission "..${/}..${/}test.props", "read"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; + // Needed because of bug#: 4182104 permission java.lang.RuntimePermission "modifyThreadGroup"; permission java.lang.RuntimePermission "modifyThread"; - - // allow remote objects to be exported on arbitrary ports. - permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/extLoadedImpl/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,8 +1,9 @@ /* - * security policy used exec'ed activation groups + * security policy used by activation groups */ grant { - // allow remote objects to be exported on arbitrary ports. + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -3,9 +3,7 @@ */ grant { - // allow remote objects to be exported on arbitrary ports. + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; - - // allow exporting object with non-public remote interface - permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/inactiveGroup/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,10 +4,6 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // allow remote objects to be exported on arbitrary ports. permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; - - // allow exporting object with non-public remote interface - permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/nestedActivate/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/nestedActivate/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/nestedActivate/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,13 +1,9 @@ /* - * security policy used by test activation groups + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // allow remote objects to be exported on arbitrary ports. permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; - - // allow exporting of non-public remote interface - permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,7 +4,6 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // allow remote objects to be exported on arbitrary ports. permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/restartCrashedService/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,8 +1,9 @@ /* - * security policy used by test activation groups + * security policy used by activation groups */ grant { - // test needs to communicate with the activation system + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/restartLatecomer/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -3,6 +3,7 @@ */ grant { - // allow remote objects to be exported on arbitrary ports. + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/restartService/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/restartService/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/restartService/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -3,6 +3,7 @@ */ grant { - // allow remote objects to be exported on arbitrary ports. + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/shutdownGracefully/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,10 +1,9 @@ /* - * security policy used activation groups + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // test needs to communicate with the activation system permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/Activatable/unregisterInactive/group.security.policy --- a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,7 +4,6 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // allow remote objects to be exported on arbitrary ports. permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/ActivateFailedException/activateFails/group.security.policy --- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,8 +1,9 @@ /* - * security policy used activation groups + * security policy used by activation groups */ grant { - // test needs to communicate with the activation system + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/group.security.policy --- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,10 +1,11 @@ /* - * security policy used by downloaded activation group + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server"; - permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/group.security.policy --- a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,10 +4,6 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // accomodate property used by this test. - permission java.util.PropertyPermission "test.message", "read"; - - // test needs to communicate with the activation system permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/group.security.policy --- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,13 +1,11 @@ /* - * security policy used by activation groups. + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // give the group permission to create a class that the main test process can not create - permission java.lang.RuntimePermission "accessClassInPackage.sun.security.provider"; + permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; - // test needs to communicate with the activation system - permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.lang.RuntimePermission "accessClassInPackage.sun.security.provider"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy --- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -4,8 +4,6 @@ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // test needs to communicate with the activation system permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; - permission java.util.PropertyPermission "unregisterGroup.port", "read"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/activation/CommandEnvironment/group.security.policy --- a/jdk/test/java/rmi/activation/CommandEnvironment/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/activation/CommandEnvironment/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,8 +1,9 @@ /* - * security policy used by activation groups. + * security policy used by activation groups */ grant { - // test needs to communicate with the activation system + permission java.io.FilePermission "..${/}..${/}test.props", "read"; permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/group.security.policy --- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/group.security.policy Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/group.security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -1,11 +1,9 @@ /* - * security policy used by the rmid process exec'ed by a running - * instance of the test. + * security policy used by activation groups */ grant { permission java.io.FilePermission "..${/}..${/}test.props", "read"; - - // test needs to communicate with the activation system permission java.net.SocketPermission "*:1024-", "connect,accept,listen"; + permission java.util.PropertyPermission "test.*", "read"; }; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java --- a/jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/server/RemoteServer/setLogPermission/SetLogPermission.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * The RemoteServer.setLog method requires * java.util.log.LoggingPermission("control"). * @author Ann Wollrath - * @run main/othervm/policy=java.policy SetLogPermission + * @run main/othervm/policy=security.policy SetLogPermission */ import java.rmi.server.RemoteServer; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/server/RemoteServer/setLogPermission/java.policy --- a/jdk/test/java/rmi/server/RemoteServer/setLogPermission/java.policy Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -grant { - permission java.util.logging.LoggingPermission "control"; -}; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/server/RemoteServer/setLogPermission/security.policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/rmi/server/RemoteServer/setLogPermission/security.policy Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,3 @@ +grant { + permission java.util.logging.LoggingPermission "control"; +}; diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/testlibrary/ActivationLibrary.java --- a/jdk/test/java/rmi/testlibrary/ActivationLibrary.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/testlibrary/ActivationLibrary.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,20 +40,6 @@ * objects. */ public class ActivationLibrary { - /** time safeDestroy should wait before failing on shutdown rmid */ - private static final int SAFE_WAIT_TIME; - static { - int slopFactor = 1; - try { - slopFactor = Integer.valueOf( - TestLibrary.getExtraProperty("jcov.sleep.multiplier","1")); - } catch (NumberFormatException ignore) {} - SAFE_WAIT_TIME = 60000 * slopFactor; - } - - private static final String SYSTEM_NAME = - ActivationSystem.class.getName(); - private static void mesg(Object mesg) { System.err.println("ACTIVATION_LIBRARY: " + mesg.toString()); } @@ -63,20 +49,19 @@ */ public static void deactivate(Remote remote, ActivationID id) { - // We do as much as 50 deactivation trials, each separated by - // at least 100 milliseconds sleep time (max sleep time of 5 secs). - final long deactivateSleepTime = 100; - long stopTime = System.currentTimeMillis() + deactivateSleepTime * 50; - while (System.currentTimeMillis() < stopTime) { + final long POLLTIME_MS = 100L; + final long DEACTIVATE_TIME_MS = 30_000L; + + long startTime = System.currentTimeMillis(); + long deadline = TestLibrary.computeDeadline(startTime, DEACTIVATE_TIME_MS); + + while (System.currentTimeMillis() < deadline) { try { if (Activatable.inactive(id) == true) { mesg("inactive successful"); return; } else { - mesg("inactive trial failed. Sleeping " + - deactivateSleepTime + - " milliseconds before next trial"); - Thread.sleep(deactivateSleepTime); + Thread.sleep(POLLTIME_MS); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -95,7 +80,8 @@ } } - mesg("unable to inactivate after several attempts"); + mesg("unable to inactivate after " + + (System.currentTimeMillis() - startTime) + "ms."); mesg("unexporting object forcibly instead"); try { diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/testlibrary/JavaVM.java --- a/jdk/test/java/rmi/testlibrary/JavaVM.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/testlibrary/JavaVM.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -194,7 +194,7 @@ throws InterruptedException, TimeoutException { if (vm == null) throw new IllegalStateException("can't wait for JavaVM that isn't running"); - long deadline = computeDeadline(System.currentTimeMillis(), timeout); + long deadline = TestLibrary.computeDeadline(System.currentTimeMillis(), timeout); while (true) { try { @@ -218,21 +218,4 @@ start(); return waitFor(); } - - /** - * Computes a deadline from a timestamp and a timeout value. - * Maximum timeout (before multipliers are applied) is one hour. - */ - public static long computeDeadline(long timestamp, long timeout) { - final long MAX_TIMEOUT_MS = 3_600_000L; - - if (timeout < 0L || timeout > MAX_TIMEOUT_MS) { - throw new IllegalArgumentException("timeout " + timeout + "ms out of range"); - } - - // TODO apply test.timeout.factor (and possibly jcov.sleep.multiplier) - // here instead of upstream - - return timestamp + timeout; - } } diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/testlibrary/RMID.java --- a/jdk/test/java/rmi/testlibrary/RMID.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/testlibrary/RMID.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -249,15 +249,15 @@ mesg("Starting rmid on port " + port + "."); super.start(); - int slopFactor = 1; - try { - slopFactor = Integer.valueOf( - TestLibrary.getExtraProperty("jcov.sleep.multiplier","1")); - } catch (NumberFormatException ignore) {} - waitTime = waitTime * slopFactor; + // int slopFactor = 1; + // try { + // slopFactor = Integer.valueOf( + // TestLibrary.getExtraProperty("jcov.sleep.multiplier","1")); + // } catch (NumberFormatException ignore) {} + // waitTime = waitTime * slopFactor; long startTime = System.currentTimeMillis(); - long deadline = computeDeadline(startTime, waitTime); + long deadline = TestLibrary.computeDeadline(startTime, waitTime); while (true) { try { diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/rmi/testlibrary/TestLibrary.java --- a/jdk/test/java/rmi/testlibrary/TestLibrary.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/rmi/testlibrary/TestLibrary.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,7 +135,8 @@ */ public static boolean checkIfRegistryRunning(int port, int msTimeout) { - long stopTime = System.currentTimeMillis() + msTimeout; + final long POLLTIME_MS = 100L; + long stopTime = computeDeadline(System.currentTimeMillis(), msTimeout); do { try { Registry r = LocateRegistry.getRegistry(port); @@ -145,12 +146,12 @@ } catch (RemoteException e) { // problem - not ready ? Try again try { - Thread.sleep(500); + Thread.sleep(POLLTIME_MS); } catch (InterruptedException ie) { // not expected } } - } while (stopTime > System.currentTimeMillis()); + } while (System.currentTimeMillis() < stopTime); return false; } @@ -169,6 +170,31 @@ } } + public static double getTimeoutFactor() { + String prop = getProperty("test.timeout.factor", "1.0"); + double timeoutFactor = 1.0; + + try { + timeoutFactor = Double.parseDouble(prop); + } catch (NumberFormatException ignore) { } + + return timeoutFactor; + } + + /** + * Computes a deadline from a timestamp and a timeout value. + * Maximum timeout (before multipliers are applied) is one hour. + */ + public static long computeDeadline(long timestamp, long timeout) { + final long MAX_TIMEOUT_MS = 3_600_000L; + + if (timeout < 0L || timeout > MAX_TIMEOUT_MS) { + throw new IllegalArgumentException("timeout " + timeout + "ms out of range"); + } + + return timestamp + (long)(timeout * getTimeoutFactor()); + } + /** * Property mutators */ diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/util/Formatter/Basic-X.java.template --- a/jdk/test/java/util/Formatter/Basic-X.java.template Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/util/Formatter/Basic-X.java.template Sat Jan 10 12:38:18 2015 -0800 @@ -1154,6 +1154,10 @@ test("%.5f", "0.99960", val); test("%.6f", "0.999600", val); + val = new BigDecimal(BigInteger.ZERO, 6); + test("%.4f", "0.0000", val); + val = new BigDecimal(BigInteger.ZERO, -6); + test("%.4f", "0.0000", val); #end[BigDecimal] #if[float] diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/util/Formatter/Basic.java --- a/jdk/test/java/util/Formatter/Basic.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/util/Formatter/Basic.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,6 +26,7 @@ * @bug 4906370 4962433 4973103 4989961 5005818 5031150 4970931 4989491 5002937 * 5005104 5007745 5061412 5055180 5066788 5088703 6317248 6318369 6320122 * 6344623 6369500 6534606 6282094 6286592 6476425 5063507 6469160 6476168 + * 8059175 * * @run shell/timeout=240 Basic.sh */ diff -r ad8137d44154 -r 247f60f5808f jdk/test/java/util/Formatter/BasicBigDecimal.java --- a/jdk/test/java/util/Formatter/BasicBigDecimal.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/java/util/Formatter/BasicBigDecimal.java Sat Jan 10 12:38:18 2015 -0800 @@ -1154,6 +1154,11 @@ test("%.5f", "0.99960", val); test("%.6f", "0.999600", val); + val = new BigDecimal(BigInteger.ZERO, 6); + test("%.4f", "0.0000", val); + + val = new BigDecimal(BigInteger.ZERO, -6); + test("%.4f", "0.0000", val); diff -r ad8137d44154 -r 247f60f5808f jdk/test/javax/crypto/KeyGenerator/TestKGParity.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/crypto/KeyGenerator/TestKGParity.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.PrintStream; +import java.lang.String; +import java.lang.System; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.Security; +import javax.crypto.KeyGenerator; +import static java.lang.System.out; + +/* + * @test + * @bug 8048607 + * @compile ../../../com/sun/crypto/provider/Cipher/DES/TestUtility.java + * @summary Test key generation of DES and DESEDE + */ +public class TestKGParity { + + private static final String[] ALGORITHM_ARR = { + "deS", "DesEDE" + }; + + public static void main(String argv[]) throws Exception { + + TestKGParity test = new TestKGParity(); + test.run(); + } + + private void run() throws Exception { + Provider[] providers = Security.getProviders(); + for (Provider p : providers) { + String prvName = p.getName(); + if (prvName.startsWith("SunJCE") + || prvName.startsWith("SunPKCS11-")) { + for (String algorithm : ALGORITHM_ARR) { + if (!runTest(p, algorithm)) { + throw new RuntimeException( + "Test failed with provider/algorithm:" + + p.getName() + "/" + algorithm); + } else { + out.println("Test passed with provider/algorithm:" + + p.getName() + "/" + algorithm); + } + } + } + } + } + + public boolean runTest(Provider p, String algo) throws Exception { + byte[] keyValue = null; + try { + // Initialization + SecureRandom sRdm = new SecureRandom(); + KeyGenerator kg = KeyGenerator.getInstance(algo, p); + kg.init(sRdm); + + // Generate a SecretKey and retrieve its value + keyValue = kg.generateKey().getEncoded(); + + // Verify its parity in the unit of byte + for (int i = 0; i < keyValue.length; i++) { + if (!checkParity(keyValue[i])) { + out.println("Testing: " + + p.getName() + + "/" + + algo + + " failed when verify its parity in the unit of byte:" + + TestUtility.hexDump(keyValue, i)); + return false; + } + } + return true; + } catch (Exception ex) { + out.println("Testing: " + p.getName() + "/" + algo + + " failed with unexpected exception"); + ex.printStackTrace(); + throw ex; + } + } + + private boolean checkParity(byte keyByte) { + boolean even = false; + byte[] PARITY_BIT_MASK = { + (byte) 0x40, (byte) 0x20, (byte) 0x10, (byte) 0x08, + (byte) 0x04, (byte) 0x02, (byte) 0x01 + }; + + for (int i = 0; i < 7; i++) { + if ((keyByte & PARITY_BIT_MASK[i]) > 0) { + even = !even; + } + } + if (keyByte < 0) { + even = !even; + } + + return even; + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java --- a/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferDeadlockTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,8 @@ /* * @test * @bug 6239400 - * @summary Tests NotificationBuffer doesn't hold locks when adding listeners. + * @summary Tests NotificationBuffer doesn't hold locks when adding listeners, + * if test times out then deadlock is suspected. * @author Eamonn McManus * @run clean NotificationBufferDeadlockTest * @run build NotificationBufferDeadlockTest @@ -38,6 +39,7 @@ import java.util.List; import java.util.Set; import java.util.Vector; +import java.util.concurrent.CountDownLatch; import javax.management.*; import javax.management.remote.*; @@ -173,9 +175,7 @@ for (ObjectName name : names) mbsc.invoke(name, "send", null, null); - if (!countListener.waiting(MAX_WAITING_TIME)) { - return "did not get " + names.size() + " notifs as expected\n"; - } + countListener.waiting(); if (!sources.containsAll(names)) return "missing names: " + sources; @@ -202,13 +202,13 @@ } }; t.start(); + System.out.println("DeadlockTest-addNotificationListener waiting for the sending thread to die..."); try { - t.join(5000L); + t.join(); //if times out here then deadlock is suspected + System.out.println("DeadlockTest-addNotificationListener OK."); } catch (Exception e) { thisFailure = "Join exception: " + e; } - if (t.isAlive()) - thisFailure = "Deadlock detected"; } public void send() { @@ -244,9 +244,9 @@ } }; t.start(); - t.join(5000); - if (t.isAlive()) - failure = "Query deadlock detected"; + System.out.println("CreateDuringQueryInvocationHandler-createMBeanIfQuery waiting for the creating thread to die..."); + t.join(); // if times out here then deadlock is suspected + System.out.println("CreateDuringQueryInvocationHandler-createMBeanIfQuery OK"); } } @@ -264,50 +264,30 @@ private static class MyListener implements NotificationListener { public MyListener(int waitNB) { - this.waitNB= waitNB; + count = new CountDownLatch(waitNB); } public void handleNotification(Notification n, Object h) { - System.out.println("MyListener got: "+n.getSource()+" "+n.getType()); + System.out.println("MyListener got: " + n.getSource() + " " + n.getType()); - synchronized(this) { - if (TESTING_TYPE.equals(n.getType())) { - sources.add((ObjectName) n.getSource()); - - if (sources.size() == waitNB) { - this.notifyAll(); - } - } + if (TESTING_TYPE.equals(n.getType())) { + sources.add((ObjectName) n.getSource()); + count.countDown(); } } - public boolean waiting(long timeout) { - final long startTime = System.currentTimeMillis(); - long toWait = timeout; - - synchronized(this) { - while(sources.size() < waitNB && toWait > 0) { - try { - this.wait(toWait); - } catch (InterruptedException ire) { - break; - } - - toWait = timeout - - (System.currentTimeMillis() - startTime); - } - } - - return sources.size() == waitNB; + public void waiting() throws InterruptedException { + System.out.println("MyListener-waiting ..."); + count.await(); // if times out here then deadlock is suspected + System.out.println("MyListener-waiting done!"); } - private final int waitNB; + private final CountDownLatch count; } static String thisFailure; static String failure; static int nextNameIndex; - static final long MAX_WAITING_TIME = 10000; private static MyListener countListener; private static final List sources = new Vector(); diff -r ad8137d44154 -r 247f60f5808f jdk/test/javax/smartcardio/CommandAPDUTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/smartcardio/CommandAPDUTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8049021 + * @summary Test different constructors for CommandAPDU and check CLA,INS,NC,NE, + * P1,and P2 + * @run testng CommandAPDUTest + */ +import java.nio.ByteBuffer; +import javax.smartcardio.CommandAPDU; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class CommandAPDUTest { + + static final byte[] C1 = {(byte) 0x00, (byte) 0xA4, (byte) 0x04, + (byte) 0x00, (byte) 0x07, (byte) 0xA0, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x62, (byte) 0x81, (byte) 0x01, (byte) 0x00}; + static int cla, ins, nc, ne, p1, p2; + static byte[] apdu, data; + static CommandAPDU cm1, cm2, cm3, cm4, cm5, cm6, cm7, cm8, cm9; + + @BeforeClass + public static void setUpClass() throws Exception { + //expected values of apdu, data, headers, nc, ne + CommandAPDU capdu = new CommandAPDU(C1); + apdu = capdu.getBytes(); + data = capdu.getData(); + + cla = capdu.getCLA(); + if (cla != (C1[0] & 0xff)) { + throw new RuntimeException("Failure: cla is not right"); + } + + ins = capdu.getINS(); + if (ins != (C1[1] & 0xff)) { + throw new RuntimeException("Failure: ins is not right"); + } + + p1 = capdu.getP1(); + if (p1 != (C1[2] & 0xff)) { + throw new RuntimeException("Failure: p1 is not right"); + } + + p2 = capdu.getP2(); + if (p2 != (C1[3] & 0xff)) { + throw new RuntimeException("Failure: p2 is not right"); + } + + nc = capdu.getNc(); + ne = capdu.getNe(); + + //Test on following constructors + cm1 = new CommandAPDU(apdu); + cm2 = new CommandAPDU(cla, ins, p1, p2); + cm3 = new CommandAPDU(cla, ins, p1, p2, data); + cm4 = new CommandAPDU(cla, ins, p1, p2, data, ne); + cm5 = new CommandAPDU(cla, ins, p1, p2, ne); + cm6 = new CommandAPDU(ByteBuffer.wrap(apdu)); + cm7 = new CommandAPDU(apdu, 0, apdu.length); + cm8 = new CommandAPDU(cla, ins, p1, p2, data, 0, nc); + cm9 = new CommandAPDU(cla, ins, p1, p2, data, 0, nc, ne); + } + + @Test(dataProvider = "provider1") + public static void testHeaders(CommandAPDU cm) { + assertEquals(cla, cm.getCLA()); + assertEquals(ins, cm.getINS()); + assertEquals(p1, cm.getP1()); + assertEquals(p2, cm.getP2()); + } + + @Test(dataProvider = "provider2") + public static void testAPDU(CommandAPDU cm) { + assertEquals(apdu, cm.getBytes()); + } + + @Test(dataProvider = "provider3") + public static void testData(CommandAPDU cm) { + assertEquals(data, cm.getData()); + } + + @Test(dataProvider = "provider3") + public static void testNC(CommandAPDU cm) { + assertEquals(nc, cm.getNc()); + } + + @Test(dataProvider = "provider4") + public static void testNE(CommandAPDU cm) { + assertEquals(ne, cm.getNe()); + } + + @DataProvider + public Object[][] provider1() { + return new Object[][]{{cm1}, {cm2}, {cm3}, {cm4}, {cm5}, {cm6}, {cm7}, + {cm8}, {cm9}}; + } + + @DataProvider + public Object[][] provider2() { + return new Object[][]{{cm1}, {cm6}, {cm7}}; + } + + @DataProvider + public Object[][] provider3() { + return new Object[][]{{cm1}, {cm3}, {cm4}, {cm6}, {cm7}, {cm8}, {cm9}}; + } + + @DataProvider + public Object[][] provider4() { + return new Object[][]{{cm1}, {cm4}, {cm5}, {cm6}, {cm7}, {cm9}}; + } + +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/javax/smartcardio/ResponseAPDUTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/smartcardio/ResponseAPDUTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8049021 + * @summary Construct ResponseAPDU from byte array and check NR< SW, SW1 and SW2 + * @run testng ResponseAPDUTest + */ +import javax.smartcardio.ResponseAPDU; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class ResponseAPDUTest { + + static final byte[] R1 = {(byte) 0x07, (byte) 0xA0, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x62, (byte) 0x81, (byte) 0x01, + (byte) 0x04, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x24, + (byte) 0x05, (byte) 0x00, (byte) 0x0B, (byte) 0x04, (byte) 0xB0, + (byte) 0x25, (byte) 0x90, (byte) 0x00}; + static final ResponseAPDU RAPDU = new ResponseAPDU(R1); + static byte[] expectedData; + static int expectedNr, expectedSw1, expectedSw2, expectedSw; + + @BeforeClass + public static void setUpClass() throws Exception { + //expected values for data,nr,sw1,sw2 and sw + + int apduLen = R1.length; + expectedData = new byte[apduLen - 2]; + for (int i = 0; i < (apduLen - 2); i++) { + expectedData[i] = R1[i]; + } + + expectedNr = expectedData.length; + expectedSw1 = R1[apduLen - 2] & 0xff; + expectedSw2 = R1[apduLen - 1] & 0xff; + expectedSw = (expectedSw1 << 8) | expectedSw2; + } + + @Test + public static void test() { + assertEquals(RAPDU.getBytes(), R1); + assertEquals(RAPDU.getData(), expectedData); + assertEquals(RAPDU.getNr(), expectedNr); + assertEquals(RAPDU.getSW(), expectedSw); + assertEquals(RAPDU.getSW1(), expectedSw1); + assertEquals(RAPDU.getSW2(), expectedSw2); + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/javax/smartcardio/TerminalFactorySpiTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/smartcardio/TerminalFactorySpiTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8049021 + * @summary Test if we can write new provider for smart card + * @run main/othervm/policy=policy TerminalFactorySpiTest + */ +import java.security.Provider; +import java.security.Security; +import java.util.Arrays; +import javax.smartcardio.CardTerminals; +import javax.smartcardio.TerminalFactory; +import javax.smartcardio.TerminalFactorySpi; + +public class TerminalFactorySpiTest { + + static boolean callMethod = false; + + public static void main(String[] args) throws Exception { + Provider myProvider = new MyProvider(); + Security.addProvider(myProvider); + System.out.println(Arrays.asList(Security.getProviders())); + + TerminalFactory.getInstance("MyType", new Object()).terminals(); + if (!callMethod) { + throw new RuntimeException("Expected engineTerminals() not called"); + } + } + + public static class MyProvider extends Provider { + + MyProvider() { + super("MyProvider", 1.0d, "smart Card Example"); + put("TerminalFactory.MyType", "TerminalFactorySpiTest$MyTerminalFactorySpi"); + } + } + + public static class MyTerminalFactorySpi extends TerminalFactorySpi { + + public MyTerminalFactorySpi(Object ob) { + } + + protected CardTerminals engineTerminals() { + System.out.println("MyTerminalFactory.engineTerminals()"); + callMethod = true; + return null; + } + + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/javax/smartcardio/policy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/smartcardio/policy Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,4 @@ +grant { + permission java.security.SecurityPermission "insertProvider.MyProvider"; + permission java.security.SecurityPermission "putProviderProperty.MyProvider"; +}; diff -r ad8137d44154 -r 247f60f5808f jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/FilterClassLoader.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 jdk.testlibrary; + +import java.util.function.Predicate; +/** + * A classloader, which using target classloader in case provided condition + * for class name is met, and using parent otherwise + */ +public class FilterClassLoader extends ClassLoader { + + private final ClassLoader target; + private final Predicate condition; + + public FilterClassLoader(ClassLoader target, ClassLoader parent, + Predicate condition) { + super(parent); + this.condition = condition; + this.target = target; + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (condition.test(name)) { + return target.loadClass(name); + } + return super.loadClass(name); + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ParentLastURLClassLoader.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 jdk.testlibrary; + +import java.net.URL; +import java.net.URLClassLoader; + +/** + * An url classloader, which trying to load class from provided URL[] first, + * and using parent classloader in case it failed + */ +public class ParentLastURLClassLoader extends URLClassLoader { + + public ParentLastURLClassLoader(URL urls[], ClassLoader parent) { + super(urls, parent); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + try { + Class c = findClass(name); + if (c != null) { + return c; + } + } catch (ClassNotFoundException e) { + // ignore + } + return super.loadClass(name); + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java Sat Jan 10 12:38:18 2015 -0800 @@ -28,6 +28,15 @@ private static final String dataModel = System.getProperty("sun.arch.data.model"); private static final String vmVersion = System.getProperty("java.vm.version"); private static final String osArch = System.getProperty("os.arch"); + private static final String vmName = System.getProperty("java.vm.name"); + + public static boolean isClient() { + return vmName.endsWith(" Client VM"); + } + + public static boolean isServer() { + return vmName.endsWith(" Server VM"); + } public static boolean is32bit() { return dataModel.equals("32"); diff -r ad8137d44154 -r 247f60f5808f jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java --- a/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java Sat Jan 10 12:38:18 2015 -0800 @@ -39,6 +39,7 @@ import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.concurrent.TimeUnit; +import java.util.function.BooleanSupplier; /** * Common library for various test helper functions. @@ -271,25 +272,6 @@ } /** - * Returns file content as a list of strings - * - * @param file File to operate on - * @return List of strings - * @throws IOException - */ - public static List fileAsList(File file) throws IOException { - assertTrue(file.exists() && file.isFile(), - file.getAbsolutePath() + " does not exist or not a file"); - List output = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) { - while (reader.ready()) { - output.add(reader.readLine().replace(NEW_LINE, "")); - } - } - return output; - } - - /** * Adjusts the provided timeout value for the TIMEOUT_FACTOR * @param tOut the timeout value to be adjusted * @return The timeout value adjusted for the value of "test.timeout.factor" @@ -298,4 +280,50 @@ public static long adjustTimeout(long tOut) { return Math.round(tOut * Utils.TIMEOUT_FACTOR); } + + /** + * Wait for condition to be true + * + * @param condition, a condition to wait for + */ + public static final void waitForCondition(BooleanSupplier condition) { + waitForCondition(condition, -1L, 100L); + } + + /** + * Wait until timeout for condition to be true + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true + * specifying -1 will wait forever + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout) { + return waitForCondition(condition, timeout, 100L); + } + + /** + * Wait until timeout for condition to be true for specified time + * + * @param condition, a condition to wait for + * @param timeout a time in milliseconds to wait for condition to be true, + * specifying -1 will wait forever + * @param sleepTime a time to sleep value in milliseconds + * @return condition value, to determine if wait was successfull + */ + public static final boolean waitForCondition(BooleanSupplier condition, + long timeout, long sleepTime) { + long startTime = System.currentTimeMillis(); + while (!(condition.getAsBoolean() || (timeout != -1L + && ((System.currentTimeMillis() - startTime) > timeout)))) { + try { + Thread.sleep(sleepTime); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new Error(e); + } + } + return condition.getAsBoolean(); + } } diff -r ad8137d44154 -r 247f60f5808f jdk/test/sun/rmi/rmic/iiopCompilation/IIOPCompilation.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/rmi/rmic/iiopCompilation/IIOPCompilation.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8065957 + * @library ../../../../java/rmi/testlibrary + * @build TestLibrary + * @summary Compiles a PortableRemoteObject with rmic -iiop and ensures that stub and tie classes are generated. + * @run main IIOPCompilation + * @author Felix Yang + * + */ +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.rmi.RemoteException; +import java.util.Arrays; +import java.util.List; + +import javax.rmi.PortableRemoteObject; + +public class IIOPCompilation { + + public static void main(String args[]) throws IOException, InterruptedException { + IIOPCompilation test = new IIOPCompilation(); + test.doTest(); + } + + private void doTest() throws IOException, InterruptedException { + String className = DummyImpl.class.getName(); + int exitCode = runRmic(className); + if (exitCode != 0) { + throw new RuntimeException("Rmic failed. The exit code is " + exitCode); + } + + // Check the stub class generated correctly + String stubFile = "_" + Dummy.class.getName() + "_Stub.class"; + assertFileExists(stubFile); + + // Check the tie class generated correctly + String tieFile = "_" + className + "_Tie.class"; + assertFileExists(tieFile); + } + + private void assertFileExists(String fileName) throws FileNotFoundException { + if (!new File(fileName).exists()) { + throw new FileNotFoundException(fileName + " doesn't exist!"); + } + } + + private int runRmic(String classname) throws IOException, InterruptedException { + String rmicProgramStr = TestLibrary.getProperty("java.home", "") + File.separator + "bin" + File.separator + "rmic"; + String testClasses = TestLibrary.getProperty("test.classes", ""); + List command = Arrays.asList(rmicProgramStr, "-iiop", "-classpath", testClasses, classname); + System.out.println("Running command: " + command); + + Process p = null; + try { + p = new ProcessBuilder(command).inheritIO().start(); + p.waitFor(); + return p.exitValue(); + } finally { + if (p != null && p.isAlive()) { + p.destroy(); + } + } + } +} + +interface Dummy extends java.rmi.Remote { +} + +class DummyImpl extends PortableRemoteObject implements Dummy { + public DummyImpl() throws RemoteException { + } +} diff -r ad8137d44154 -r 247f60f5808f jdk/test/sun/security/provider/DSA/TestDSA2.java --- a/jdk/test/sun/security/provider/DSA/TestDSA2.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/sun/security/provider/DSA/TestDSA2.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public static void main(String[] args) throws Exception { boolean[] expectedToPass = { true, true, true }; test(1024, expectedToPass); - boolean[] expectedToPass2 = { false, true, true }; + boolean[] expectedToPass2 = { true, true, true }; test(2048, expectedToPass2); } diff -r ad8137d44154 -r 247f60f5808f jdk/test/sun/tools/jcmd/TestJcmdDefaults.java --- a/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/sun/tools/jcmd/TestJcmdDefaults.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,6 +25,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import jdk.testlibrary.JcmdBase; @@ -95,11 +98,11 @@ } private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { - File file = new File(TEST_SRC, "usage.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(TEST_SRC, "usage.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } } diff -r ad8137d44154 -r 247f60f5808f jdk/test/sun/tools/jcmd/TestJcmdSanity.java --- a/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/sun/tools/jcmd/TestJcmdSanity.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,6 +25,9 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import jdk.testlibrary.JcmdBase; @@ -160,11 +163,11 @@ } private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { - File file = new File(TEST_SRC, "help_help.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(TEST_SRC, "help_help.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } } diff -r ad8137d44154 -r 247f60f5808f jdk/test/sun/tools/jps/JpsHelper.java --- a/jdk/test/sun/tools/jps/JpsHelper.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/sun/tools/jps/JpsHelper.java Sat Jan 10 12:38:18 2015 -0800 @@ -28,6 +28,9 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -189,11 +192,11 @@ */ public static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException { String testSrc = System.getProperty("test.src", "?"); - File file = new File(testSrc, "usage.out"); - List fileOutput = Utils.fileAsList(file); + Path path = Paths.get(testSrc, "usage.out"); + List fileOutput = Files.readAllLines(path); List outputAsLines = output.asLines(); assertTrue(outputAsLines.containsAll(fileOutput), - "The ouput should contain all content of " + file.getAbsolutePath()); + "The ouput should contain all content of " + path.toAbsolutePath()); } private static File getManifest(String className) throws IOException { diff -r ad8137d44154 -r 247f60f5808f jdk/test/tools/pack200/Pack200Test.java --- a/jdk/test/tools/pack200/Pack200Test.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/tools/pack200/Pack200Test.java Sat Jan 10 12:38:18 2015 -0800 @@ -127,7 +127,7 @@ // select the jars carefully, adding more jars will increase the // testing time, especially for jprt. jarList.add(Utils.createRtJar()); - jarList.add(Utils.locateJar("golden.jar")); + jarList.add(Utils.getGoldenJar()); System.out.println(jarList); doPackUnpack(); } diff -r ad8137d44154 -r 247f60f5808f jdk/test/tools/pack200/PackTestZip64.java --- a/jdk/test/tools/pack200/PackTestZip64.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/tools/pack200/PackTestZip64.java Sat Jan 10 12:38:18 2015 -0800 @@ -52,7 +52,7 @@ // make a copy of the test specimen to local directory File testFile = new File("tools_java.jar"); // Add a large number of small files to the golden jar - generateLargeJar(testFile, Utils.locateJar("golden.jar")); + generateLargeJar(testFile, Utils.getGoldenJar()); List cmdsList = new ArrayList<>(); diff -r ad8137d44154 -r 247f60f5808f jdk/test/tools/pack200/RepackTest.java --- a/jdk/test/tools/pack200/RepackTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/tools/pack200/RepackTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ // make a copy of the test specimen to local directory File testFile = new File("src_tools.jar"); - Utils.copyFile(Utils.locateJar("golden.jar"), testFile); + Utils.copyFile(Utils.getGoldenJar(), testFile); List cmdsList = new ArrayList<>(); // case 1: diff -r ad8137d44154 -r 247f60f5808f jdk/test/tools/pack200/TimeStamp.java --- a/jdk/test/tools/pack200/TimeStamp.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/tools/pack200/TimeStamp.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ public static void main(String... args) throws IOException { // make a local copy of our test file - File srcFile = Utils.locateJar("golden.jar"); + File srcFile = Utils.getGoldenJar(); File goldenFile = new File("golden.jar"); Utils.copyFile(srcFile, goldenFile); diff -r ad8137d44154 -r 247f60f5808f jdk/test/tools/pack200/Utils.java --- a/jdk/test/tools/pack200/Utils.java Thu Jan 08 10:44:54 2015 +0100 +++ b/jdk/test/tools/pack200/Utils.java Sat Jan 10 12:38:18 2015 -0800 @@ -63,7 +63,7 @@ System.getProperty("os.name").startsWith("Windows"); static final boolean Is64Bit = System.getProperty("sun.arch.data.model", "32").equals("64"); - static final File JavaSDK = new File(JavaHome).getParentFile(); + static final File JavaSDK = new File(JavaHome); static final String PACK_FILE_EXT = ".pack"; static final String JAVA_FILE_EXT = ".java"; @@ -82,11 +82,7 @@ if (VerifierJar.exists()) { return; } - File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME); - if (!srcDir.exists()) { - // if not available try one level above - srcDir = new File(TEST_SRC_DIR.getParentFile(), VERIFIER_DIR_NAME); - } + File srcDir = new File(getVerifierDir(), "src"); List javaFileList = findFiles(srcDir, createFilter(JAVA_FILE_EXT)); File tmpFile = File.createTempFile("javac", ".tmp"); XCLASSES.mkdirs(); @@ -115,6 +111,18 @@ "."); } + private static File getVerifierDir() { + File srcDir = new File(TEST_SRC_DIR, VERIFIER_DIR_NAME); + if (!srcDir.exists()) { + // if not available try one level above + srcDir = new File(TEST_SRC_DIR.getParentFile(), VERIFIER_DIR_NAME); + } + return srcDir; + } + + static File getGoldenJar() { + return new File(new File(getVerifierDir(), "data"), "golden.jar"); + } static void dirlist(File dir) { File[] files = dir.listFiles(); System.out.println("--listing " + dir.getAbsolutePath() + "---"); @@ -564,7 +572,8 @@ File rtJar = new File("rt.jar"); cmdList.clear(); cmdList.add(getJarCmd()); - cmdList.add("cvf"); + // cmdList.add("cvf"); too noisy + cmdList.add("cf"); cmdList.add(rtJar.getName()); cmdList.add("-C"); cmdList.add("out"); @@ -574,24 +583,4 @@ recursiveDelete(new File("out")); return rtJar; } - private static List locaterCache = null; - // search the source dir and jdk dir for requested file and returns - // the first location it finds. - static File locateJar(String name) { - try { - if (locaterCache == null) { - locaterCache = new ArrayList(); - locaterCache.addAll(findFiles(TEST_SRC_DIR, createFilter(JAR_FILE_EXT))); - locaterCache.addAll(findFiles(JavaSDK, createFilter(JAR_FILE_EXT))); - } - for (File f : locaterCache) { - if (f.getName().equals(name)) { - return f; - } - } - throw new IOException("file not found: " + name); - } catch (IOException e) { - throw new RuntimeException(e); - } - } } diff -r ad8137d44154 -r 247f60f5808f langtools/.hgtags --- a/langtools/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -285,3 +285,5 @@ c286272a81dd8f6005e22fed0238c4a3f75188c7 jdk9-b40 f7ce2cfa4cdbec0ae0f46080484eace66be7987a jdk9-b41 23a3a063a906a91ba696d792f0eeabf157cd2f86 jdk9-b42 +6a06008aec10d32898ca665685f531c681b28f5f jdk9-b43 +de2ce70d907c9f227b802cea29285bece5194cd5 jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Analyzer.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.javac.comp; + +import com.sun.source.tree.LambdaExpressionTree; +import com.sun.tools.javac.code.Source; +import com.sun.tools.javac.code.Type; +import com.sun.tools.javac.code.Types; +import com.sun.tools.javac.tree.JCTree; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop; +import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop; +import com.sun.tools.javac.tree.JCTree.JCForLoop; +import com.sun.tools.javac.tree.JCTree.JCIf; +import com.sun.tools.javac.tree.JCTree.JCLambda; +import com.sun.tools.javac.tree.JCTree.JCLambda.ParameterKind; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; +import com.sun.tools.javac.tree.JCTree.JCNewClass; +import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.tree.JCTree.JCSwitch; +import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.JCTree.JCWhileLoop; +import com.sun.tools.javac.tree.JCTree.Tag; +import com.sun.tools.javac.tree.TreeCopier; +import com.sun.tools.javac.tree.TreeInfo; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.TreeScanner; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.DefinedBy; +import com.sun.tools.javac.util.DefinedBy.Api; +import com.sun.tools.javac.util.Filter; +import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticType; +import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Names; +import com.sun.tools.javac.util.Options; + +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; + +import static com.sun.tools.javac.code.Flags.GENERATEDCONSTR; +import static com.sun.tools.javac.code.Flags.SYNTHETIC; +import static com.sun.tools.javac.code.TypeTag.CLASS; +import static com.sun.tools.javac.tree.JCTree.Tag.APPLY; +import static com.sun.tools.javac.tree.JCTree.Tag.CLASSDEF; +import static com.sun.tools.javac.tree.JCTree.Tag.METHODDEF; +import static com.sun.tools.javac.tree.JCTree.Tag.NEWCLASS; +import static com.sun.tools.javac.tree.JCTree.Tag.TYPEAPPLY; + +/** + * Helper class for defining custom code analysis, such as finding instance creation expression + * that can benefit from diamond syntax. + */ +public class Analyzer { + protected static final Context.Key analyzerKey = new Context.Key<>(); + + final Types types; + final Log log; + final Attr attr; + final DeferredAttr deferredAttr; + final TreeMaker make; + final Names names; + + final EnumSet analyzerModes; + + public static Analyzer instance(Context context) { + Analyzer instance = context.get(analyzerKey); + if (instance == null) + instance = new Analyzer(context); + return instance; + } + + protected Analyzer(Context context) { + context.put(analyzerKey, this); + types = Types.instance(context); + log = Log.instance(context); + attr = Attr.instance(context); + deferredAttr = DeferredAttr.instance(context); + make = TreeMaker.instance(context); + names = Names.instance(context); + Options options = Options.instance(context); + String findOpt = options.get("find"); + //parse modes + Source source = Source.instance(context); + analyzerModes = AnalyzerMode.getAnalyzerModes(findOpt, source); + } + + /** + * This enum defines supported analyzer modes, as well as defining the logic for decoding + * the {@code -XDfind} option. + */ + enum AnalyzerMode { + DIAMOND("diamond", Source::allowDiamond), + LAMBDA("lambda", Source::allowLambda), + METHOD("method", Source::allowGraphInference); + + final String opt; + final Predicate sourceFilter; + + AnalyzerMode(String opt, Predicate sourceFilter) { + this.opt = opt; + this.sourceFilter = sourceFilter; + } + + /** + * This method is used to parse the {@code find} option. + * Possible modes are separated by colon; a mode can be excluded by + * prepending '-' to its name. Finally, the special mode 'all' can be used to + * add all modes to the resulting enum. + */ + static EnumSet getAnalyzerModes(String opt, Source source) { + if (opt == null) { + return EnumSet.noneOf(AnalyzerMode.class); + } + List modes = List.from(opt.split(",")); + EnumSet res = EnumSet.noneOf(AnalyzerMode.class); + if (modes.contains("all")) { + res = EnumSet.allOf(AnalyzerMode.class); + } + for (AnalyzerMode mode : values()) { + if (modes.contains(mode.opt)) { + res.add(mode); + } else if (modes.contains("-" + mode.opt) || !mode.sourceFilter.test(source)) { + res.remove(mode); + } + } + return res; + } + } + + /** + * A statement analyzer is a work-unit that matches certain AST nodes (of given type {@code S}), + * rewrites them to different AST nodes (of type {@code T}) and then generates some meaningful + * messages in case the analysis has been successful. + */ + abstract class StatementAnalyzer { + + AnalyzerMode mode; + JCTree.Tag tag; + + StatementAnalyzer(AnalyzerMode mode, Tag tag) { + this.mode = mode; + this.tag = tag; + } + + /** + * Is this analyzer allowed to run? + */ + boolean isEnabled() { + return analyzerModes.contains(mode); + } + + /** + * Should this analyzer be rewriting the given tree? + */ + abstract boolean match(S tree); + + /** + * Rewrite a given AST node into a new one + */ + abstract T map(S oldTree, S newTree); + + /** + * Entry-point for comparing results and generating diagnostics. + */ + abstract void process(S oldTree, T newTree, boolean hasErrors); + + } + + /** + * This analyzer checks if generic instance creation expression can use diamond syntax. + */ + class DiamondInitializer extends StatementAnalyzer { + + DiamondInitializer() { + super(AnalyzerMode.DIAMOND, NEWCLASS); + } + + @Override + boolean match(JCNewClass tree) { + return tree.clazz.hasTag(TYPEAPPLY) && + !TreeInfo.isDiamond(tree) && + tree.def == null; + } + + @Override + JCNewClass map(JCNewClass oldTree, JCNewClass newTree) { + if (newTree.clazz.hasTag(TYPEAPPLY)) { + ((JCTypeApply)newTree.clazz).arguments = List.nil(); + } + return newTree; + } + + @Override + void process(JCNewClass oldTree, JCNewClass newTree, boolean hasErrors) { + if (!hasErrors) { + List inferredArgs = newTree.type.getTypeArguments(); + List explicitArgs = oldTree.type.getTypeArguments(); + for (Type t : inferredArgs) { + if (!types.isSameType(t, explicitArgs.head)) { + log.warning(oldTree.clazz, "diamond.redundant.args.1", + oldTree.clazz.type, newTree.clazz.type); + return; + } + explicitArgs = explicitArgs.tail; + } + //exact match + log.warning(oldTree.clazz, "diamond.redundant.args"); + } + } + } + + /** + * This analyzer checks if anonymous instance creation expression can replaced by lambda. + */ + class LambdaAnalyzer extends StatementAnalyzer { + + LambdaAnalyzer() { + super(AnalyzerMode.LAMBDA, NEWCLASS); + } + + @Override + boolean match (JCNewClass tree){ + Type clazztype = tree.clazz.type; + return tree.def != null && + clazztype.hasTag(CLASS) && + types.isFunctionalInterface(clazztype.tsym) && + decls(tree.def).length() == 1; + } + //where + private List decls(JCClassDecl decl) { + ListBuffer decls = new ListBuffer<>(); + for (JCTree t : decl.defs) { + if (t.hasTag(METHODDEF)) { + JCMethodDecl md = (JCMethodDecl)t; + if ((md.getModifiers().flags & GENERATEDCONSTR) == 0) { + decls.add(md); + } + } else { + decls.add(t); + } + } + return decls.toList(); + } + + @Override + JCLambda map (JCNewClass oldTree, JCNewClass newTree){ + JCMethodDecl md = (JCMethodDecl)decls(newTree.def).head; + List params = md.params; + JCBlock body = md.body; + return make.Lambda(params, body); + } + @Override + void process (JCNewClass oldTree, JCLambda newTree, boolean hasErrors){ + if (!hasErrors) { + log.warning(oldTree.def, "potential.lambda.found"); + } + } + } + + /** + * This analyzer checks if generic method call has redundant type arguments. + */ + class RedundantTypeArgAnalyzer extends StatementAnalyzer { + + RedundantTypeArgAnalyzer() { + super(AnalyzerMode.METHOD, APPLY); + } + + @Override + boolean match (JCMethodInvocation tree){ + return tree.typeargs != null && + tree.typeargs.nonEmpty(); + } + @Override + JCMethodInvocation map (JCMethodInvocation oldTree, JCMethodInvocation newTree){ + newTree.typeargs = List.nil(); + return newTree; + } + @Override + void process (JCMethodInvocation oldTree, JCMethodInvocation newTree, boolean hasErrors){ + if (!hasErrors) { + //exact match + log.warning(oldTree, "method.redundant.typeargs"); + } + } + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + StatementAnalyzer[] analyzers = new StatementAnalyzer[] { + new DiamondInitializer(), + new LambdaAnalyzer(), + new RedundantTypeArgAnalyzer() + }; + + /** + * Analyze an AST node if needed. + */ + void analyzeIfNeeded(JCTree tree, Env env) { + if (!analyzerModes.isEmpty() && + !env.info.isSpeculative && + TreeInfo.isStatement(tree)) { + JCStatement stmt = (JCStatement)tree; + analyze(stmt, env); + } + } + + /** + * Analyze an AST node; this involves collecting a list of all the nodes that needs rewriting, + * and speculatively type-check the rewritten code to compare results against previously attributed code. + */ + void analyze(JCStatement statement, Env env) { + AnalysisContext context = new AnalysisContext(); + StatementScanner statementScanner = new StatementScanner(context); + statementScanner.scan(statement); + + if (!context.treesToAnalyzer.isEmpty()) { + + //add a block to hoist potential dangling variable declarations + JCBlock fakeBlock = make.Block(SYNTHETIC, List.of(statement)); + + TreeMapper treeMapper = new TreeMapper(context); + //TODO: to further refine the analysis, try all rewriting combinations + deferredAttr.attribSpeculative(fakeBlock, env, attr.statInfo, treeMapper, + t -> new AnalyzeDeferredDiagHandler(context)); + + context.treeMap.entrySet().forEach(e -> { + context.treesToAnalyzer.get(e.getKey()) + .process(e.getKey(), e.getValue(), context.errors.nonEmpty()); + }); + } + } + + /** + * Simple deferred diagnostic handler which filters out all messages and keep track of errors. + */ + class AnalyzeDeferredDiagHandler extends Log.DeferredDiagnosticHandler { + AnalysisContext context; + + public AnalyzeDeferredDiagHandler(AnalysisContext context) { + super(log, d -> { + if (d.getType() == DiagnosticType.ERROR) { + context.errors.add(d); + } + return true; + }); + this.context = context; + } + } + + /** + * This class is used to pass around contextual information bewteen analyzer classes, such as + * trees to be rewritten, errors occurred during the speculative attribution step, etc. + */ + class AnalysisContext { + /** Map from trees to analyzers. */ + Map> treesToAnalyzer = new HashMap<>(); + + /** Map from original AST nodes to rewritten AST nodes */ + Map treeMap = new HashMap<>(); + + /** Errors in rewritten tree */ + ListBuffer errors = new ListBuffer<>(); + } + + /** + * Subclass of {@link com.sun.tools.javac.tree.TreeScanner} which visit AST-nodes w/o crossing + * statement boundaries. + */ + class StatementScanner extends TreeScanner { + + /** context */ + AnalysisContext context; + + StatementScanner(AnalysisContext context) { + this.context = context; + } + + @Override + @SuppressWarnings("unchecked") + public void scan(JCTree tree) { + if (tree != null) { + for (StatementAnalyzer analyzer : analyzers) { + if (analyzer.isEnabled() && + tree.hasTag(analyzer.tag) && + analyzer.match(tree)) { + context.treesToAnalyzer.put(tree, analyzer); + break; //TODO: cover cases where multiple matching analyzers are found + } + } + } + super.scan(tree); + } + + @Override + public void visitClassDef(JCClassDecl tree) { + //do nothing (prevents seeing same stuff twice + } + + @Override + public void visitMethodDef(JCMethodDecl tree) { + //do nothing (prevents seeing same stuff twice + } + + @Override + public void visitBlock(JCBlock tree) { + //do nothing (prevents seeing same stuff twice + } + + @Override + public void visitSwitch(JCSwitch tree) { + scan(tree.getExpression()); + } + + @Override + public void visitForLoop(JCForLoop tree) { + scan(tree.getInitializer()); + scan(tree.getCondition()); + scan(tree.getUpdate()); + } + + @Override + public void visitForeachLoop(JCEnhancedForLoop tree) { + scan(tree.getExpression()); + } + + @Override + public void visitWhileLoop(JCWhileLoop tree) { + scan(tree.getCondition()); + } + + @Override + public void visitDoLoop(JCDoWhileLoop tree) { + scan(tree.getCondition()); + } + + @Override + public void visitIf(JCIf tree) { + scan(tree.getCondition()); + } + } + + /** + * Subclass of TreeCopier that maps nodes matched by analyzers onto new AST nodes. + */ + class TreeMapper extends TreeCopier { + + AnalysisContext context; + + TreeMapper(AnalysisContext context) { + super(make); + this.context = context; + } + + @Override + @SuppressWarnings("unchecked") + public Z copy(Z tree, Void _unused) { + Z newTree = super.copy(tree, _unused); + StatementAnalyzer analyzer = context.treesToAnalyzer.get(tree); + if (analyzer != null) { + newTree = (Z)analyzer.map(tree, newTree); + context.treeMap.put(tree, newTree); + } + return newTree; + } + + @Override @DefinedBy(Api.COMPILER_TREE) + public JCTree visitLambdaExpression(LambdaExpressionTree node, Void _unused) { + JCLambda oldLambda = (JCLambda)node; + JCLambda newLambda = (JCLambda)super.visitLambdaExpression(node, _unused); + if (oldLambda.paramKind == ParameterKind.IMPLICIT) { + //reset implicit lambda parameters (whose type might have been set during attr) + newLambda.paramKind = ParameterKind.IMPLICIT; + newLambda.params.forEach(p -> p.vartype = null); + } + return newLambda; + } + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Sat Jan 10 12:38:18 2015 -0800 @@ -83,6 +83,7 @@ final Symtab syms; final Resolve rs; final Infer infer; + final Analyzer analyzer; final DeferredAttr deferredAttr; final Check chk; final Flow flow; @@ -121,6 +122,7 @@ make = TreeMaker.instance(context); enter = Enter.instance(context); infer = Infer.instance(context); + analyzer = Analyzer.instance(context); deferredAttr = DeferredAttr.instance(context); cfolder = ConstFold.instance(context); target = Target.instance(context); @@ -143,11 +145,8 @@ allowStaticInterfaceMethods = source.allowStaticInterfaceMethods(); sourceName = source.name; relax = (options.isSet("-retrofit") || - options.isSet("-relax")); - findDiamonds = options.get("findDiamond") != null && - source.allowDiamond(); + options.isSet("-relax")); useBeforeDeclarationWarning = options.isSet("useBeforeDeclarationWarning"); - identifyLambdaCandidate = options.getBoolean("identifyLambdaCandidate", false); statInfo = new ResultInfo(KindSelector.NIL, Type.noType); varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType); @@ -156,6 +155,8 @@ unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType); unknownTypeExprInfo = new ResultInfo(KindSelector.VAL_TYP, Type.noType); recoveryInfo = new RecoveryInfo(deferredAttr.emptyDeferredAttrContext); + + noCheckTree = make.at(-1).Skip(); } /** Switch: relax some constraints for retrofit mode. @@ -182,16 +183,6 @@ */ boolean allowStaticInterfaceMethods; - /** Switch: generates a warning if diamond can be safely applied - * to a given new expression - */ - boolean findDiamonds; - - /** - * Internally enables/disables diamond finder feature - */ - static final boolean allowDiamondFinder = true; - /** * Switch: warn about use of variable before declaration? * RFE: 6425594 @@ -199,12 +190,6 @@ boolean useBeforeDeclarationWarning; /** - * Switch: generate warnings whenever an anonymous inner class that is convertible - * to a lambda expression is found - */ - boolean identifyLambdaCandidate; - - /** * Switch: allow strings in switch? */ boolean allowStringsInSwitch; @@ -231,31 +216,32 @@ final ResultInfo resultInfo) { InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); Type owntype; - if (!found.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { - if (!ownkind.subset(resultInfo.pkind)) { - log.error(tree.pos(), "unexpected.type", - resultInfo.pkind.kindNames(), - ownkind.kindNames()); - owntype = types.createErrorType(found); - } else if (allowPoly && inferenceContext.free(found)) { - //delay the check if there are inference variables in the found type - //this means we are dealing with a partially inferred poly expression - owntype = resultInfo.pt; - inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { - @Override - public void typesInferred(InferenceContext inferenceContext) { + boolean shouldCheck = !found.hasTag(ERROR) && + !resultInfo.pt.hasTag(METHOD) && + !resultInfo.pt.hasTag(FORALL); + if (shouldCheck && !ownkind.subset(resultInfo.pkind)) { + log.error(tree.pos(), "unexpected.type", + resultInfo.pkind.kindNames(), + ownkind.kindNames()); + owntype = types.createErrorType(found); + } else if (allowPoly && inferenceContext.free(found)) { + //delay the check if there are inference variables in the found type + //this means we are dealing with a partially inferred poly expression + owntype = shouldCheck ? resultInfo.pt : found; + inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), + instantiatedContext -> { ResultInfo pendingResult = resultInfo.dup(inferenceContext.asInstType(resultInfo.pt)); check(tree, inferenceContext.asInstType(found), ownkind, pendingResult); - } - }); - } else { - owntype = resultInfo.check(tree, found); - } + }); } else { - owntype = found; + owntype = shouldCheck ? + resultInfo.check(tree, found) : + found; } - tree.type = owntype; + if (tree != noCheckTree) { + tree.type = owntype; + } return owntype; } @@ -531,6 +517,10 @@ */ Type result; + /** Synthetic tree to be used during 'fake' checks. + */ + JCTree noCheckTree; + /** Visitor method: attribute a tree, catching any completion failure * exceptions. Return the tree's type. * @@ -610,7 +600,13 @@ /** Derived visitor method: attribute a statement or definition tree. */ public Type attribStat(JCTree tree, Env env) { - return attribTree(tree, env, statInfo); + Env analyzeEnv = + env.dup(tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); + try { + return attribTree(tree, env, statInfo); + } finally { + analyzer.analyzeIfNeeded(tree, analyzeEnv); + } } /** Attribute a list of expressions, returning a list of types. @@ -792,8 +788,8 @@ Type attribIdentAsEnumType(Env env, JCIdent id) { Assert.check((env.enclClass.sym.flags() & ENUM) != 0); - id.type = env.info.scope.owner.type; - id.sym = env.info.scope.owner; + id.type = env.info.scope.owner.enclClass().type; + id.sym = env.info.scope.owner.enclClass(); return id.type; } @@ -2018,7 +2014,7 @@ } }); Type constructorType = tree.constructorType = types.createErrorType(clazztype); - constructorType = checkId(tree, site, + constructorType = checkId(noCheckTree, site, constructor, diamondEnv, diamondResult); @@ -2044,7 +2040,7 @@ tree.constructor = rs.resolveConstructor( tree.pos(), rsEnv, clazztype, argtypes, typeargtypes); if (cdef == null) { //do not check twice! - tree.constructorType = checkId(tree, + tree.constructorType = checkId(noCheckTree, clazztype, tree.constructor, rsEnv, @@ -2052,12 +2048,6 @@ if (rsEnv.info.lastResolveVarargs()) Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null); } - if (cdef == null && - !clazztype.isErroneous() && - clazztype.getTypeArguments().nonEmpty() && - findDiamonds) { - findDiamond(localEnv, tree, clazztype); - } } if (cdef != null) { @@ -2105,8 +2095,6 @@ attribStat(cdef, localEnv); - checkLambdaCandidate(tree, cdef.sym, clazztype); - // If an outer instance is given, // prefix it to the constructor arguments // and delete it from the new expression @@ -2122,7 +2110,7 @@ tree.pos(), localEnv, clazztype, argtypes, typeargtypes); Assert.check(!sym.kind.isOverloadError()); tree.constructor = sym; - tree.constructorType = checkId(tree, + tree.constructorType = checkId(noCheckTree, clazztype, tree.constructor, localEnv, @@ -2133,60 +2121,16 @@ owntype = clazztype; } result = check(tree, owntype, KindSelector.VAL, resultInfo); + InferenceContext inferenceContext = resultInfo.checkContext.inferenceContext(); + if (tree.constructorType != null && inferenceContext.free(tree.constructorType)) { + //we need to wait for inference to finish and then replace inference vars in the constructor type + inferenceContext.addFreeTypeListener(List.of(tree.constructorType), + instantiatedContext -> { + tree.constructorType = instantiatedContext.asInstType(tree.constructorType); + }); + } chk.validate(tree.typeargs, localEnv); } - //where - void findDiamond(Env env, JCNewClass tree, Type clazztype) { - JCTypeApply ta = (JCTypeApply)tree.clazz; - List prevTypeargs = ta.arguments; - try { - //create a 'fake' diamond AST node by removing type-argument trees - ta.arguments = List.nil(); - ResultInfo findDiamondResult = new ResultInfo(KindSelector.VAL, - resultInfo.checkContext.inferenceContext().free(resultInfo.pt) ? Type.noType : pt()); - Type inferred = deferredAttr.attribSpeculative(tree, env, findDiamondResult).type; - Type polyPt = allowPoly ? - syms.objectType : - clazztype; - if (!inferred.isErroneous() && - (allowPoly && pt() == Infer.anyPoly ? - types.isSameType(inferred, clazztype) : - types.isAssignable(inferred, pt().hasTag(NONE) ? polyPt : pt(), types.noWarnings))) { - String key = types.isSameType(clazztype, inferred) ? - "diamond.redundant.args" : - "diamond.redundant.args.1"; - log.warning(tree.clazz.pos(), key, clazztype, inferred); - } - } finally { - ta.arguments = prevTypeargs; - } - } - - private void checkLambdaCandidate(JCNewClass tree, ClassSymbol csym, Type clazztype) { - if (allowLambda && - identifyLambdaCandidate && - clazztype.hasTag(CLASS) && - !pt().hasTag(NONE) && - types.isFunctionalInterface(clazztype.tsym)) { - Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym); - int count = 0; - boolean found = false; - for (Symbol sym : csym.members().getSymbols()) { - if ((sym.flags() & SYNTHETIC) != 0 || - sym.isConstructor()) continue; - count++; - if (sym.kind != MTH || - !sym.name.equals(descriptor.name)) continue; - Type mtype = types.memberType(clazztype, sym); - if (types.overrideEquivalent(mtype, types.memberType(clazztype, descriptor))) { - found = true; - } - } - if (found && count == 1) { - log.note(tree.def, "potential.lambda.found"); - } - } - } /** Make an attributed null check tree. */ @@ -2361,6 +2305,7 @@ preFlow(that); flow.analyzeLambda(env, that, make, isSpeculativeRound); + that.type = currentTarget; //avoids recovery at this stage checkLambdaCompatible(that, lambdaType, resultInfo.checkContext); if (!isSpeculativeRound) { @@ -2801,7 +2746,7 @@ that.kind.isUnbound() ? argtypes.tail : argtypes, typeargtypes), new FunctionalReturnContext(resultInfo.checkContext)); - Type refType = checkId(that, lookupHelper.site, refSym, localEnv, checkInfo); + Type refType = checkId(noCheckTree, lookupHelper.site, refSym, localEnv, checkInfo); if (that.kind.isUnbound() && resultInfo.checkContext.inferenceContext().free(argtypes.head)) { @@ -2823,6 +2768,8 @@ //is a no-op (as this has been taken care during method applicability) boolean isSpeculativeRound = resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; + + that.type = currentTarget; //avoids recovery at this stage checkReferenceCompatible(that, desc, refType, resultInfo.checkContext, isSpeculativeRound); if (!isSpeculativeRound) { checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), desc, currentTarget); @@ -3953,7 +3900,7 @@ all_multicatchTypes.append(ctype); } } - Type t = check(tree, types.lub(multicatchTypes.toList()), + Type t = check(noCheckTree, types.lub(multicatchTypes.toList()), KindSelector.TYP, resultInfo); if (t.hasTag(CLASS)) { List alternatives = diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrContext.java Sat Jan 10 12:38:18 2015 -0800 @@ -59,6 +59,10 @@ */ boolean isSerializable = false; + /** Is this a speculative attribution environment? + */ + boolean isSpeculative = false; + /** Are arguments to current function applications boxed into an array for varargs? */ Resolve.MethodResolutionPhase pendingResolutionPhase = null; @@ -95,6 +99,7 @@ info.returnResult = returnResult; info.defaultSuperCallSite = defaultSuperCallSite; info.isSerializable = isSerializable; + info.isSpeculative = isSpeculative; return info; } diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Sat Jan 10 12:38:18 2015 -0800 @@ -37,15 +37,18 @@ import com.sun.tools.javac.comp.Infer.InferenceContext; import com.sun.tools.javac.comp.Resolve.MethodResolutionPhase; import com.sun.tools.javac.tree.JCTree.*; +import com.sun.tools.javac.util.Log.DeferredDiagnosticHandler; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumMap; import java.util.EnumSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import java.util.function.Function; import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*; @@ -364,28 +367,16 @@ * disabled during speculative type-checking. */ JCTree attribSpeculative(JCTree tree, Env env, ResultInfo resultInfo) { - final JCTree newTree = new TreeCopier<>(make).copy(tree); - Env speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); - Log.DeferredDiagnosticHandler deferredDiagnosticHandler = - new Log.DeferredDiagnosticHandler(log, new Filter() { - public boolean accepts(final JCDiagnostic d) { - class PosScanner extends TreeScanner { - boolean found = false; + return attribSpeculative(tree, env, resultInfo, new TreeCopier<>(make), + (newTree)->new DeferredAttrDiagHandler(log, newTree)); + } - @Override - public void scan(JCTree tree) { - if (tree != null && - tree.pos() == d.getDiagnosticPosition()) { - found = true; - } - super.scan(tree); - } - } - PosScanner posScanner = new PosScanner(); - posScanner.scan(newTree); - return posScanner.found; - } - }); + JCTree attribSpeculative(JCTree tree, Env env, ResultInfo resultInfo, TreeCopier deferredCopier, + Function diagHandlerCreator) { + final JCTree newTree = deferredCopier.copy(tree); + Env speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner))); + speculativeEnv.info.isSpeculative = true; + Log.DeferredDiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator.apply(newTree); try { attr.attribTree(newTree, speculativeEnv, resultInfo); unenterScanner.scan(newTree); @@ -413,6 +404,37 @@ } } + static class DeferredAttrDiagHandler extends Log.DeferredDiagnosticHandler { + + static class PosScanner extends TreeScanner { + DiagnosticPosition pos; + boolean found = false; + + PosScanner(DiagnosticPosition pos) { + this.pos = pos; + } + + @Override + public void scan(JCTree tree) { + if (tree != null && + tree.pos() == pos) { + found = true; + } + super.scan(tree); + } + } + + DeferredAttrDiagHandler(Log log, JCTree newTree) { + super(log, new Filter() { + public boolean accepts(JCDiagnostic d) { + PosScanner posScanner = new PosScanner(d.getDiagnosticPosition()); + posScanner.scan(newTree); + return posScanner.found; + } + }); + } + } + /** * A deferred context is created on each method check. A deferred context is * used to keep track of information associated with the method check, such as @@ -817,6 +839,14 @@ /** an empty deferred attribution context - all methods throw exceptions */ final DeferredAttrContext emptyDeferredAttrContext; + /** The AttrMode to descriptive name mapping */ + private static final EnumMap deferredTypeMapDescriptions; + static { + deferredTypeMapDescriptions = new EnumMap<>(AttrMode.class); + deferredTypeMapDescriptions.put(AttrMode.CHECK, "deferredTypeMap[CHECK]"); + deferredTypeMapDescriptions.put(AttrMode.SPECULATIVE, "deferredTypeMap[SPECULATIVE]"); + } + /** * Map a list of types possibly containing one or more deferred types * into a list of ordinary types. Each deferred type D is mapped into a type T, @@ -824,11 +854,10 @@ * computed for D during a previous deferred attribution round of the given kind. */ class DeferredTypeMap extends Type.Mapping { - DeferredAttrContext deferredAttrContext; protected DeferredTypeMap(AttrMode mode, Symbol msym, MethodResolutionPhase phase) { - super(String.format("deferredTypeMap[%s]", mode)); + super(deferredTypeMapDescriptions.get(mode)); this.deferredAttrContext = new DeferredAttrContext(mode, msym, phase, infer.emptyContext, emptyDeferredAttrContext, types.noWarnings); } @@ -1221,7 +1250,7 @@ @Override public void visitNewClass(JCNewClass tree) { - result = (TreeInfo.isDiamond(tree) || attr.findDiamonds) ? + result = TreeInfo.isDiamond(tree) ? ArgumentExpressionKind.POLY : ArgumentExpressionKind.NO_POLY; } diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Sat Jan 10 12:38:18 2015 -0800 @@ -1176,12 +1176,14 @@ @Override public void visitClassDef(JCClassDecl tree) { List prevStack = frameStack; + int prevLambdaCount = lambdaCount; SyntheticMethodNameCounter prevSyntheticMethodNameCounts = syntheticMethodNameCounts; Map prevClinits = clinits; DiagnosticSource prevSource = log.currentSource(); try { log.useSource(tree.sym.sourcefile); + lambdaCount = 0; syntheticMethodNameCounts = new SyntheticMethodNameCounter(); prevClinits = new HashMap<>(); if (tree.sym.owner.kind == MTH) { @@ -1208,6 +1210,7 @@ finally { log.useSource(prevSource.getFile()); frameStack = prevStack; + lambdaCount = prevLambdaCount; syntheticMethodNameCounts = prevSyntheticMethodNameCounts; clinits = prevClinits; } diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Sat Jan 10 12:38:18 2015 -0800 @@ -251,19 +251,19 @@ * mode = NOPARAMS : no parameters allowed for type * mode = TYPEARG : type argument */ - static final int EXPR = 0x1; - static final int TYPE = 0x2; - static final int NOPARAMS = 0x4; - static final int TYPEARG = 0x8; - static final int DIAMOND = 0x10; + protected static final int EXPR = 0x1; + protected static final int TYPE = 0x2; + protected static final int NOPARAMS = 0x4; + protected static final int TYPEARG = 0x8; + protected static final int DIAMOND = 0x10; /** The current mode. */ - private int mode = 0; + protected int mode = 0; /** The mode of the term that was parsed last. */ - private int lastmode = 0; + protected int lastmode = 0; /* ---------- token management -------------- */ @@ -326,7 +326,7 @@ /** Skip forward until a suitable stop token is found. */ - private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { + protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { while (true) { switch (token.kind) { case SEMI: @@ -403,11 +403,11 @@ } } - private JCErroneous syntaxError(int pos, String key, TokenKind... args) { + protected JCErroneous syntaxError(int pos, String key, TokenKind... args) { return syntaxError(pos, List.nil(), key, args); } - private JCErroneous syntaxError(int pos, List errs, String key, TokenKind... args) { + protected JCErroneous syntaxError(int pos, List errs, String key, TokenKind... args) { setErrorEndPos(pos); JCErroneous err = F.at(pos).Erroneous(errs); reportSyntaxError(err, key, (Object[])args); @@ -427,7 +427,7 @@ * Report a syntax using the given the position parameter and arguments, * unless one was already reported at the same position. */ - private void reportSyntaxError(int pos, String key, Object... args) { + protected void reportSyntaxError(int pos, String key, Object... args) { JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos); reportSyntaxError(diag, key, args); } @@ -436,7 +436,7 @@ * Report a syntax error using the given DiagnosticPosition object and * arguments, unless one was already reported at the same position. */ - private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) { + protected void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) { int pos = diagPos.getPreferredPosition(); if (pos > S.errPos() || pos == Position.NOPOS) { if (token.kind == EOF) { @@ -459,14 +459,14 @@ /** Generate a syntax error at current position unless one was already * reported at the same position. */ - private JCErroneous syntaxError(String key) { + protected JCErroneous syntaxError(String key) { return syntaxError(token.pos, key); } /** Generate a syntax error at current position unless one was * already reported at the same position. */ - private JCErroneous syntaxError(String key, TokenKind arg) { + protected JCErroneous syntaxError(String key, TokenKind arg) { return syntaxError(token.pos, key, arg); } @@ -500,7 +500,7 @@ } /** Diagnose a modifier flag from the set, if any. */ - void checkNoMods(long mods) { + protected void checkNoMods(long mods) { if (mods != 0) { long lowestMod = mods & -mods; error(token.pos, "mod.not.allowed.here", @@ -521,7 +521,7 @@ * @param tree The tree to be used as index in the hashtable * @param dc The doc comment to associate with the tree, or null. */ - void attach(JCTree tree, Comment dc) { + protected void attach(JCTree tree, Comment dc) { if (keepDocComments && dc != null) { // System.out.println("doc comment = ");System.out.println(dc);//DEBUG docComments.putComment(tree, dc); @@ -530,19 +530,19 @@ /* -------- source positions ------- */ - private void setErrorEndPos(int errPos) { + protected void setErrorEndPos(int errPos) { endPosTable.setErrorEndPos(errPos); } - private void storeEnd(JCTree tree, int endpos) { + protected void storeEnd(JCTree tree, int endpos) { endPosTable.storeEnd(tree, endpos); } - private T to(T t) { + protected T to(T t) { return endPosTable.to(t); } - private T toP(T t) { + protected T toP(T t) { return endPosTable.toP(t); } @@ -574,7 +574,7 @@ /** * Ident = IDENTIFIER */ - Name ident() { + protected Name ident() { if (token.kind == IDENTIFIER) { Name name = token.name(); nextToken(); @@ -789,7 +789,7 @@ return term(TYPE); } - JCExpression term(int newmode) { + protected JCExpression term(int newmode) { int prevmode = mode; mode = newmode; JCExpression t = term(); @@ -1669,7 +1669,7 @@ } /** Accepts all identifier-like tokens */ - Filter LAX_IDENTIFIER = new Filter() { + protected Filter LAX_IDENTIFIER = new Filter() { public boolean accepts(TokenKind t) { return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; } @@ -2408,7 +2408,7 @@ * | ASSERT Expression [ ":" Expression ] ";" * | ";" */ - JCStatement parseSimpleStatement() { + public JCStatement parseSimpleStatement() { int pos = token.pos; switch (token.kind) { case LBRACE: @@ -2706,7 +2706,7 @@ * * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION */ - List annotationsOpt(Tag kind) { + protected List annotationsOpt(Tag kind) { if (token.kind != MONKEYS_AT) return List.nil(); // optimization ListBuffer buf = new ListBuffer<>(); int prevmode = mode; @@ -2732,7 +2732,7 @@ * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" * | "@" Annotation */ - JCModifiers modifiersOpt() { + protected JCModifiers modifiersOpt() { return modifiersOpt(null); } protected JCModifiers modifiersOpt(JCModifiers partial) { @@ -2914,7 +2914,7 @@ * @param reqInit Is an initializer always required? * @param dc The documentation comment for the variable declarations, or null. */ - > T variableDeclaratorsRest(int pos, + protected > T variableDeclaratorsRest(int pos, JCModifiers mods, JCExpression type, Name name, @@ -3117,7 +3117,7 @@ /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" */ - JCTree importDeclaration() { + protected JCTree importDeclaration() { int pos = token.pos; nextToken(); boolean importStatic = false; @@ -3159,7 +3159,7 @@ * @param mods Any modifiers starting the class or interface declaration * @param dc The documentation comment for the class, or null. */ - JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) { + protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) { if (token.kind == CLASS) { return classDeclaration(mods, dc); } else if (token.kind == INTERFACE) { @@ -3569,7 +3569,7 @@ * TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] * } */ - List typeParametersOpt() { + protected List typeParametersOpt() { if (token.kind == LT) { ListBuffer typarams = new ListBuffer<>(); nextToken(); @@ -4004,7 +4004,7 @@ allowTypeAnnotations = true; } } - void checkAnnotationsAfterTypeParams(int pos) { + protected void checkAnnotationsAfterTypeParams(int pos) { if (!allowAnnotationsAfterTypeParams) { log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name); allowAnnotationsAfterTypeParams = true; @@ -4092,7 +4092,7 @@ /** * Store the last error position. */ - protected int errorEndPos = Position.NOPOS; + public int errorEndPos = Position.NOPOS; public AbstractEndPosTable(JavacParser parser) { this.parser = parser; @@ -4119,13 +4119,13 @@ * will be set only if it is greater than the last stored error position. * @param errPos The error position */ - protected void setErrorEndPos(int errPos) { + public void setErrorEndPos(int errPos) { if (errPos > errorEndPos) { errorEndPos = errPos; } } - protected void setParser(JavacParser parser) { + public void setParser(JavacParser parser) { this.parser = parser; } } diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Sat Jan 10 12:38:18 2015 -0800 @@ -1196,9 +1196,6 @@ compiler.note.compressed.diags=\ Some messages have been simplified; recompile with -Xdiags:verbose to get full output -compiler.note.potential.lambda.found=\ - This anonymous inner class creation can be turned into a lambda expression. - # 0: boolean, 1: symbol compiler.note.lambda.stat=\ Translating lambda expression\n\ @@ -1640,14 +1637,20 @@ # 0: unused, 1: unused compiler.warn.diamond.redundant.args=\ - redundant type arguments in new expression (use diamond operator instead). - -# 0: type, 1: type + Redundant type arguments in new expression (use diamond operator instead). + +# 0: type, 1: list of type compiler.warn.diamond.redundant.args.1=\ - redundant type arguments in new expression (use diamond operator instead).\n\ + Redundant type arguments in new expression (use diamond operator instead).\n\ explicit: {0}\n\ inferred: {1} +compiler.warn.potential.lambda.found=\ + This anonymous inner class creation can be turned into a lambda expression. + +compiler.warn.method.redundant.typeargs=\ + Redundant type arguments in method call. + # 0: symbol, 1: message segment compiler.warn.varargs.redundant.trustme.anno=\ Redundant {0} annotation. {1} diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeInfo.java Sat Jan 10 12:38:18 2015 -0800 @@ -313,6 +313,14 @@ } } + /** Return true if the tree corresponds to a statement */ + public static boolean isStatement(JCTree tree) { + return (tree instanceof JCStatement) && + !tree.hasTag(CLASSDEF) && + !tree.hasTag(Tag.BLOCK) && + !tree.hasTag(METHODDEF); + } + /** * Return true if the AST corresponds to a static select of the kind A.B */ diff -r ad8137d44154 -r 247f60f5808f langtools/src/jdk.dev/share/classes/com/sun/tools/jdeps/JdepsTask.java --- a/langtools/src/jdk.dev/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/src/jdk.dev/share/classes/com/sun/tools/jdeps/JdepsTask.java Sat Jan 10 12:38:18 2015 -0800 @@ -554,8 +554,9 @@ classpaths.addAll(PlatformClassPath.getModules(options.mpath)); if (options.mpath != null) { initialArchives.addAll(PlatformClassPath.getModules(options.mpath)); + } else { + classpaths.addAll(PlatformClassPath.getJarFiles()); } - classpaths.addAll(PlatformClassPath.getJarFiles()); // add all classpath archives to the source locations for reporting sourceLocations.addAll(classpaths); } diff -r ad8137d44154 -r 247f60f5808f langtools/test/Makefile --- a/langtools/test/Makefile Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/Makefile Sat Jan 10 12:38:18 2015 -0800 @@ -21,7 +21,6 @@ ifeq ($(OSNAME), SunOS) SLASH_JAVA = /java PLATFORM = solaris - JT_PLATFORM = solaris ARCH = $(shell uname -p) ifeq ($(ARCH), i386) ARCH=i586 @@ -30,7 +29,6 @@ ifeq ($(OSNAME), Linux) SLASH_JAVA = /java PLATFORM = linux - JT_PLATFORM = linux ARCH = $(shell uname -m) ifeq ($(ARCH), i386) ARCH=i586 @@ -38,7 +36,6 @@ endif ifeq ($(OSNAME), Darwin) PLATFORM = bsd - JT_PLATFORM = linux ARCH = $(shell uname -m) ifeq ($(ARCH), i386) ARCH=i586 @@ -55,7 +52,6 @@ ifeq ($(PLATFORM), windows) SLASH_JAVA = J: - JT_PLATFORM = win32 ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64) ARCH=ia64 else @@ -93,8 +89,8 @@ else JTREG_HOME = $(SLASH_JAVA)/re/jtreg/4.1/promoted/latest/binaries/jtreg endif -JTREG = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtreg -JTDIFF = $(JTREG_HOME)/$(JT_PLATFORM)/bin/jtdiff +JTREG = $(JTREG_HOME)/bin/jtreg +JTDIFF = $(JTREG_HOME)/bin/jtdiff # Default JCK to run ifdef JPRT_JCK_HOME @@ -105,21 +101,19 @@ # Default JDK for JTREG and JCK # -# JT_JAVA is the version of java used to run jtreg/JCK. Since it is now -# standard to execute tests in sameVM mode, it should normally be set the -# same as TESTJAVA (although not necessarily so.) +# JT_JAVA is the version of java used to run jtreg/JCK. # ifdef JPRT_JAVA_HOME JT_JAVA = $(JPRT_JAVA_HOME) else - JT_JAVA = $(SLASH_JAVA)/re/jdk/1.7.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH) + JT_JAVA = $(SLASH_JAVA)/re/jdk/1.9.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH) endif # Default JDK to test ifdef JPRT_IMPORT_PRODUCT_HOME TESTJAVA = $(JPRT_IMPORT_PRODUCT_HOME) else - TESTJAVA = $(SLASH_JAVA)/re/jdk/1.7.0/promoted/latest/binaries/$(PLATFORM)-$(ARCH) + TESTJAVA = $(SLASH_JAVA)/re/jdk/1.9.0/promoted/latest/binaries/$(PLATFORM)-$(ARCH) endif # PRODUCT_HOME is a JPRT variable pointing to a directory containing the output from @@ -152,7 +146,7 @@ ifdef CONCURRENCY JTREG_OPTIONS += -agentvm -concurrency:$(CONCURRENCY) else - JTREG_OPTIONS += -samevm + JTREG_OPTIONS += -agentvm endif ifdef JCK_CONCURRENCY diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/diags/examples/DiamondRedundantArgs.java --- a/langtools/test/tools/javac/diags/examples/DiamondRedundantArgs.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/diags/examples/DiamondRedundantArgs.java Sat Jan 10 12:38:18 2015 -0800 @@ -22,8 +22,8 @@ */ // key: compiler.warn.diamond.redundant.args -// options: -XDfindDiamond +// options: -XDfind=diamond -class Foo { - Foo fs = new Foo(); +class DiamondRedundantArgs { + DiamondRedundantArgs fs = new DiamondRedundantArgs(); } diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/diags/examples/DiamondRedundantArgs1.java --- a/langtools/test/tools/javac/diags/examples/DiamondRedundantArgs1.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/diags/examples/DiamondRedundantArgs1.java Sat Jan 10 12:38:18 2015 -0800 @@ -22,8 +22,8 @@ */ // key: compiler.warn.diamond.redundant.args.1 -// options: -XDfindDiamond +// options: -XDfind=diamond -class Foo { - Foo fs = new Foo(); +class DiamondRedundantArgs1 { + DiamondRedundantArgs1 fs = new DiamondRedundantArgs1(); } diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/diags/examples/MethodRedundantTypeargs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/MethodRedundantTypeargs.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.warn.method.redundant.typeargs +// options: -XDfind=method + +class MethodRedundantTypeargs { + Z id(Z z) { return z; } + + void test() { + String s = this.id(""); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/diags/examples/PotentialLambdaFound.java --- a/langtools/test/tools/javac/diags/examples/PotentialLambdaFound.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/diags/examples/PotentialLambdaFound.java Sat Jan 10 12:38:18 2015 -0800 @@ -21,8 +21,8 @@ * questions. */ -// key: compiler.note.potential.lambda.found -// options: -XDidentifyLambdaCandidate=true +// key: compiler.warn.potential.lambda.found +// options: -XDfind=lambda class PotentialLambdaFound { diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/generics/diamond/6939780/T6939780.java --- a/langtools/test/tools/javac/generics/diamond/6939780/T6939780.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/generics/diamond/6939780/T6939780.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,11 +1,11 @@ /* * @test /nodynamiccopyright/ - * @bug 6939780 7020044 8009459 8021338 + * @bug 6939780 7020044 8009459 8021338 8064365 * * @summary add a warning to detect diamond sites * @author mcimadamore - * @compile/ref=T6939780_7.out -Xlint:-options -source 7 T6939780.java -XDrawDiagnostics -XDfindDiamond - * @compile/ref=T6939780_8.out T6939780.java -XDrawDiagnostics -XDfindDiamond + * @compile/ref=T6939780_7.out -Xlint:-options -source 7 T6939780.java -XDrawDiagnostics -XDfind=diamond + * @compile/ref=T6939780_8.out T6939780.java -XDrawDiagnostics -XDfind=diamond * */ diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/generics/diamond/6939780/T6939780_7.out --- a/langtools/test/tools/javac/generics/diamond/6939780/T6939780_7.out Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/generics/diamond/6939780/T6939780_7.out Sat Jan 10 12:38:18 2015 -0800 @@ -1,4 +1,5 @@ -T6939780.java:21:28: compiler.warn.diamond.redundant.args: T6939780.Foo, T6939780.Foo +T6939780.java:21:28: compiler.warn.diamond.redundant.args T6939780.java:22:28: compiler.warn.diamond.redundant.args.1: T6939780.Foo, T6939780.Foo -T6939780.java:30:19: compiler.warn.diamond.redundant.args: T6939780.Foo, T6939780.Foo -3 warnings +T6939780.java:30:19: compiler.warn.diamond.redundant.args +T6939780.java:31:19: compiler.warn.diamond.redundant.args.1: T6939780.Foo, T6939780.Foo +4 warnings diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/generics/diamond/6939780/T6939780_8.out --- a/langtools/test/tools/javac/generics/diamond/6939780/T6939780_8.out Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/generics/diamond/6939780/T6939780_8.out Sat Jan 10 12:38:18 2015 -0800 @@ -1,7 +1,7 @@ -T6939780.java:20:33: compiler.warn.diamond.redundant.args: T6939780.Foo, T6939780.Foo -T6939780.java:21:28: compiler.warn.diamond.redundant.args: T6939780.Foo, T6939780.Foo +T6939780.java:20:33: compiler.warn.diamond.redundant.args +T6939780.java:21:28: compiler.warn.diamond.redundant.args T6939780.java:22:28: compiler.warn.diamond.redundant.args.1: T6939780.Foo, T6939780.Foo -T6939780.java:29:19: compiler.warn.diamond.redundant.args: T6939780.Foo, T6939780.Foo -T6939780.java:30:19: compiler.warn.diamond.redundant.args: T6939780.Foo, T6939780.Foo +T6939780.java:29:19: compiler.warn.diamond.redundant.args +T6939780.java:30:19: compiler.warn.diamond.redundant.args T6939780.java:31:19: compiler.warn.diamond.redundant.args.1: T6939780.Foo, T6939780.Foo 6 warnings diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/generics/diamond/7002837/T7002837.java --- a/langtools/test/tools/javac/generics/diamond/7002837/T7002837.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/generics/diamond/7002837/T7002837.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,10 +1,10 @@ /* * @test /nodynamiccopyright/ - * @bug 7002837 + * @bug 7002837 8064365 * * @summary Diamond: javac generates diamond inference errors when in 'finder' mode * @author mcimadamore - * @compile/fail/ref=T7002837.out -Werror -XDrawDiagnostics -XDfindDiamond T7002837.java + * @compile/fail/ref=T7002837.out -Werror -XDrawDiagnostics -XDfind=diamond T7002837.java * */ diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/8066974/T8066974.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8066974/T8066974.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,44 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8066974 + * @summary Compiler doesn't infer method's generic type information in lambda body + * @compile/fail/ref=T8066974.out -XDrawDiagnostics T8066974.java + */ +class T8066974 { + static class Throwing { } + static class RuntimeThrowing extends Throwing { } + static class CheckedThrowing extends Throwing { } + + interface Parameter { + Object m(Throwing tw) throws E; + } + + interface Mapper { + R m(Parameter p); + } + + Z map(Mapper mz) { return null; } + + Mapper> mapper(Throwing tz) throws Z { return null; } + + static class ThrowingMapper implements Mapper> { + ThrowingMapper(Throwing arg) throws X { } + + @Override + public Throwing m(Parameter p) { + return null; + } + } + + void testRuntime(RuntimeThrowing rt) { + map(p->p.m(rt)); + map(mapper(rt)); + map(new ThrowingMapper<>(rt)); + } + + void testChecked(CheckedThrowing ct) { + map(p->p.m(ct)); + map(mapper(ct)); + map(new ThrowingMapper<>(ct)); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/8066974/T8066974.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8066974/T8066974.out Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,4 @@ +T8066974.java:40:19: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception +T8066974.java:41:19: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception +T8066974.java:42:13: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Exception +3 errors diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/8067792/T8067792.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8067792/T8067792.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,19 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8067792 + * @summary Javac crashes in finder mode with nested implicit lambdas + * @compile/fail/ref=T8067792.out -XDrawDiagnostics -Werror -XDfind=lambda T8067792.java + */ + +import java.util.stream.*; +import java.util.*; + +class T8067792 { + void test(Stream> sl) { + Runnable r = new Runnable() { + public void run() { + Stream> constructor = sl.filter(c -> true); + } + }; + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/8067792/T8067792.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/8067792/T8067792.out Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,4 @@ +T8067792.java:13:37: compiler.warn.potential.lambda.found +- compiler.err.warnings.and.werror +1 error +1 warning diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/LambdaConv18.java --- a/langtools/test/tools/javac/lambda/LambdaConv18.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/lambda/LambdaConv18.java Sat Jan 10 12:38:18 2015 -0800 @@ -1,9 +1,9 @@ /* * @test /nodynamiccopyright/ - * @bug 8003280 + * @bug 8003280 8064365 * @summary Add lambda tests * simple test for lambda candidate check - * @compile/fail/ref=LambdaConv18.out -XDrawDiagnostics -XDidentifyLambdaCandidate=true LambdaConv18.java + * @compile/fail/ref=LambdaConv18.out -XDrawDiagnostics -XDfind=lambda LambdaConv18.java */ class LambdaConv18 { diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/LambdaConv18.out --- a/langtools/test/tools/javac/lambda/LambdaConv18.out Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/lambda/LambdaConv18.out Sat Jan 10 12:38:18 2015 -0800 @@ -1,4 +1,5 @@ LambdaConv18.java:23:5: compiler.err.cant.resolve.location: kindname.class, NonExistent, , , (compiler.misc.location: kindname.class, LambdaConv18, null) -LambdaConv18.java:20:24: compiler.note.potential.lambda.found +LambdaConv18.java:20:24: compiler.warn.potential.lambda.found LambdaConv18.java:23:26: compiler.err.cant.resolve.location: kindname.class, NonExistent, , , (compiler.misc.location: kindname.class, LambdaConv18, null) 2 errors +1 warning diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/lambda/lambdaNaming/TestNonSerializableLambdaNameStability.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8067422 + * @summary Check that the lambda names are not unnecessarily unstable + * @library /tools/lib + * @build ToolBox + * @run main TestNonSerializableLambdaNameStability + */ + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.Method; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import javax.tools.StandardLocation; + +public class TestNonSerializableLambdaNameStability { + + public static void main(String... args) throws Exception { + new TestNonSerializableLambdaNameStability().run(); + } + + String lambdaSource = "public class L%d {\n" + + " public static class A {\n" + + " private Runnable r = () -> { };\n" + + " }\n" + + " public static class B {\n" + + " private Runnable r = () -> { };\n" + + " }\n" + + " private Runnable r = () -> { };\n" + + "}\n"; + + String expectedLambdaMethodName = "lambda$new$0"; + + void run() throws Exception { + List sources = new ArrayList<>(); + + for (int i = 0; i < 3; i++) { + sources.add(String.format(lambdaSource, i)); + } + + ToolBox tb = new ToolBox(); + + try (ToolBox.MemoryFileManager fm = new ToolBox.MemoryFileManager()) { + tb.new JavacTask() + .sources(sources.toArray(new String[sources.size()])) + .fileManager(fm) + .run(); + + for (String file : fm.files.get(StandardLocation.CLASS_OUTPUT).keySet()) { + byte[] fileBytes = fm.getFileBytes(StandardLocation.CLASS_OUTPUT, file); + try (InputStream in = new ByteArrayInputStream(fileBytes)) { + boolean foundLambdaMethod = false; + ClassFile cf = ClassFile.read(in); + StringBuilder seenMethods = new StringBuilder(); + String sep = ""; + for (Method m : cf.methods) { + String methodName = m.getName(cf.constant_pool); + if (expectedLambdaMethodName.equals(methodName)) { + foundLambdaMethod = true; + break; + } + seenMethods.append(sep); + seenMethods.append(methodName); + sep = ", "; + } + + if (!foundLambdaMethod) { + throw new AbstractMethodError("Did not find the lambda method, " + + "found methods: " + seenMethods.toString()); + } + } + } + } + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/javac/lambda/speculative/DiamondFinder.java --- a/langtools/test/tools/javac/lambda/speculative/DiamondFinder.java Thu Jan 08 10:44:54 2015 +0100 +++ b/langtools/test/tools/javac/lambda/speculative/DiamondFinder.java Sat Jan 10 12:38:18 2015 -0800 @@ -23,10 +23,10 @@ /* * @test - * @bug 8003280 + * @bug 8003280 8064365 * @summary Add lambda tests * spurious crashes when running in 'diamond finder' mode - * @compile -XDfindDiamond DiamondFinder.java + * @compile -XDfind=diamond DiamondFinder.java */ import java.util.*; diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/CompileCircularSources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/CompileCircularSources.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verify that circular sources split on multiple cores can be compiled + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper CompileCircularSources + */ + +import java.util.*; +import java.nio.file.*; + +public class CompileCircularSources extends SJavacTester { + public static void main(String... args) throws Exception { + CompileCircularSources ccs = new CompileCircularSources(); + ccs.test(); + } + + void test() throws Exception { + Files.createDirectory(BIN); + clean(GENSRC, BIN); + + Map previous_bin_state = collectState(BIN); + + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A { beta.B b; }"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; public class B { gamma.C c; }"); + tb.writeFile(GENSRC.resolve("gamma/C.java"), + "package gamma; public class C { alfa.omega.A a; }"); + + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3", + SERVER_ARG,"--log=debug"); + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/beta/B.class", + "bin/gamma/C.class", + "bin/javac_state"); + clean(GENSRC, BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/CompileExcludingDependency.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/CompileExcludingDependency.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Tests compiling class A that depends on class B without compiling class B + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper CompileExcludingDependency + */ + +import java.util.*; +import java.nio.file.*; + +public class CompileExcludingDependency extends SJavacTester { + public static void main(String... args) throws Exception { + CompileExcludingDependency ced = new CompileExcludingDependency(); + ced.test(); + } + + // Verify that excluding classes from compilation but not from linking works + void test() throws Exception { + Files.createDirectory(BIN); + clean(GENSRC,BIN); + Map previous_bin_state = collectState(BIN); + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A { beta.B b; }"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; public class B { }"); + + compile("-x", "beta", "-src", "gensrc", "-x", "alfa/omega", "-sourcepath", "gensrc", + "-d", "bin", SERVER_ARG); + + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/javac_state"); + clean(GENSRC, BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/CompileWithAtFile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/CompileWithAtFile.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Test \@atfile with command line content + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper CompileWithAtFile + */ + +import java.util.*; +import java.nio.file.*; + +public class CompileWithAtFile extends SJavacTester { + public static void main(String... args) throws Exception { + CompileWithAtFile cwf = new CompileWithAtFile(); + cwf.test(); + } + + void test() throws Exception { + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("list.txt"), + "-if */alfa/omega/A.java\n-if */beta/B.java\ngensrc\n-d bin\n"); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; import beta.B; public class A { B b; }"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; public class B { }"); + tb.writeFile(GENSRC.resolve("beta/C.java"), + "broken"); + + Files.createDirectory(BIN); + Map previous_bin_state = collectState(BIN); + compile("@gensrc/list.txt", "--server:portfile=testserver,background=false"); + + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/javac_state", + "bin/alfa/omega/A.class", + "bin/beta/B.class"); + clean(GENSRC, BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/CompileWithInvisibleSources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/CompileWithInvisibleSources.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verify that we can make sources invisible to linking (sourcepath) + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper CompileWithInvisibleSources + */ + +import java.util.*; +import java.nio.file.*; + +public class CompileWithInvisibleSources extends SJavacTester { + public static void main(String... args) throws Exception { + CompileWithInvisibleSources cis = new CompileWithInvisibleSources(); + cis.test(); + } + + // Compile gensrc and link against gensrc2 and gensrc3 + // gensrc2 contains broken code in beta.B, thus exclude that package + // gensrc3 contains a proper beta.B + void test() throws Exception { + Files.createDirectory(BIN); + clean(GENSRC, GENSRC2, GENSRC3, BIN); + + Map previous_bin_state = collectState(BIN); + + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }"); + tb.writeFile(GENSRC2.resolve("beta/B.java"), + "package beta; public class B { broken"); + tb.writeFile(GENSRC2.resolve("gamma/C.java"), + "package gamma; public class C { }"); + tb.writeFile(GENSRC3.resolve("beta/B.java"), + "package beta; public class B { }"); + + compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2", + "-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG); + + System.out.println("The first compile went well!"); + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/javac_state"); + + System.out.println("----- Compile with exluded beta went well!"); + clean(BIN); + compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3", + "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG); + + System.out.println("----- Compile without exluded beta failed, as expected! Good!"); + clean(GENSRC, BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/CompileWithOverrideSources.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/CompileWithOverrideSources.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary verify that we can override sources to be compiled + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper CompileWithOverrideSources + */ + +import java.util.*; +import java.nio.file.*; + +public class CompileWithOverrideSources extends SJavacTester { + public static void main(String... args) throws Exception { + CompileWithOverrideSources cos = new CompileWithOverrideSources(); + cos.test(); + } + + // Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc, + // only compile ok beta.B in gensrc2 + void test() throws Exception { + Files.createDirectory(BIN); + clean(GENSRC, GENSRC2, GENSRC3, BIN); + + Map previous_bin_state = collectState(BIN); + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; public class B { broken"); + tb.writeFile(GENSRC.resolve("gamma/C.java"), + "package gamma; public class C { }"); + + tb.writeFile(GENSRC2.resolve("beta/B.java"), + "package beta; public class B { }"); + + compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG); + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/beta/B.class", + "bin/gamma/C.class", + "bin/javac_state"); + + System.out.println("----- Compile with exluded beta went well!"); + clean(BIN); + compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG); + + System.out.println("----- Compile without exluded beta failed, as expected! Good!"); + clean(GENSRC, GENSRC2, BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/IncCompileChangeNative.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/IncCompileChangeNative.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 + * @summary Verify native files are removed when native method is removed + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper IncCompileChangeNative + */ + +import java.util.*; +import java.nio.file.*; + +public class IncCompileChangeNative extends SJavacTester { + public static void main(String... args) throws Exception { + IncCompileChangeNative cn = new IncCompileChangeNative(); + cn.test(); + } + + // Remember the previous bin and headers state here. + Map previous_bin_state; + Map previous_headers_state; + ToolBox tb = new ToolBox(); + + void test() throws Exception { + Files.createDirectory(GENSRC); + Files.createDirectory(BIN); + Files.createDirectory(HEADERS); + + initialCompile(); + incrementalCompileDropAllNatives(); + incrementalCompileAddNative(); + + clean(GENSRC, BIN, HEADERS); + } + + // Update B.java with one less native method i.e. it has no longer any methods + // Verify that beta_B.h is removed + void incrementalCompileDropAllNatives() throws Exception { + previous_bin_state = collectState(BIN); + previous_headers_state = collectState(HEADERS); + System.out.println("\nIn incrementalCompileDropAllNatives() "); + System.out.println("Verify that beta_B.h is removed"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; import alfa.omega.A; public class B {"+ + "private int b() { return A.DEFINITION; } }"); + + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + verifyNewerFiles(previous_bin_state, new_bin_state, + "bin/beta/B.class", + "bin/beta/BINT.class", + "bin/javac_state"); + previous_bin_state = new_bin_state; + + Map new_headers_state = collectState(HEADERS); + verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state, + "headers/beta_B.h"); + previous_headers_state = new_headers_state; + } + + // Update the B.java with a final static annotated with @Native + // Verify that beta_B.h is added again + void incrementalCompileAddNative() throws Exception { + System.out.println("\nIn incrementalCompileAddNative() "); + System.out.println("Verify that beta_B.h is added again"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; import alfa.omega.A; public class B {"+ + "private int b() { return A.DEFINITION; } "+ + "@java.lang.annotation.Native final static int alfa = 42; }"); + + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + verifyNewerFiles(previous_bin_state, new_bin_state, + "bin/beta/B.class", + "bin/beta/BINT.class", + "bin/javac_state"); + previous_bin_state = new_bin_state; + + Map new_headers_state = collectState(HEADERS); + verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state, + "headers/beta_B.h"); + previous_headers_state = new_headers_state; + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/IncCompileDropClasses.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/IncCompileDropClasses.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 + * @summary Verify deletion of a source file results in dropping of all .class files including inner classes + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper IncCompileDropClasses + */ + +import java.util.*; +import java.nio.file.*; + +public class IncCompileDropClasses extends SJavacTester { + public static void main(String... args) throws Exception { + IncCompileDropClasses dc = new IncCompileDropClasses(); + dc.test(); + } + + // Remember the previous bin and headers state here. + Map previous_bin_state; + Map previous_headers_state; + ToolBox tb = new ToolBox(); + + void test() throws Exception { + Files.createDirectory(GENSRC); + Files.createDirectory(BIN); + Files.createDirectory(HEADERS); + + initialCompile(); + incrementalCompileDroppingClasses(); + + clean(GENSRC, BIN, HEADERS); + } + + // Testing that deleting AA.java deletes all generated inner class including AA.class + void incrementalCompileDroppingClasses() throws Exception { + previous_bin_state = collectState(BIN); + previous_headers_state = collectState(HEADERS); + System.out.println("\nIn incrementalCompileDroppingClasses() "); + System.out.println("Testing that deleting AA.java deletes all generated inner class including AA.class"); + removeFrom(GENSRC, "alfa/omega/AA.java"); + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state, + "bin/alfa/omega/AA$1.class", + "bin/alfa/omega/AA$AAAA.class", + "bin/alfa/omega/AA$AAA.class", + "bin/alfa/omega/AAAAA.class", + "bin/alfa/omega/AA.class"); + + previous_bin_state = new_bin_state; + Map new_headers_state = collectState(HEADERS); + verifyEqual(previous_headers_state, new_headers_state); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/IncCompileFullyQualifiedRef.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/IncCompileFullyQualifiedRef.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verify that "alfa.omega.A a" does create a proper dependency + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper IncCompileFullyQualifiedRef + */ + +import java.util.*; +import java.nio.file.*; + +public class IncCompileFullyQualifiedRef extends SJavacTester { + public static void main(String... args) throws Exception { + IncCompileFullyQualifiedRef fr = new IncCompileFullyQualifiedRef(); + fr.test(); + } + + void test() throws Exception { + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A { "+ + " public final static int DEFINITION = 18; "+ + " public void hello() { }"+ + "}"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; public class B { "+ + " public void world() { alfa.omega.A a; }"+ + "}"); + + compile("gensrc", "-d", "bin", "-j", "1", + SERVER_ARG, "--log=debug"); + Map previous_bin_state = collectState(BIN); + + // Change pubapi of A, this should trigger a recompile of B. + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A { "+ + " public final static int DEFINITION = 19; "+ + " public void hello() { }"+ + "}"); + + compile("gensrc", "-d", "bin", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + + verifyNewerFiles(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/beta/B.class", + "bin/javac_state"); + clean(GENSRC,BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/IncCompileNoChanges.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/IncCompileNoChanges.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 + * @summary Verify no change in sources implies no change in binaries + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper IncCompileNoChanges + */ + +import java.util.*; +import java.nio.file.*; + +public class IncCompileNoChanges extends SJavacTester { + public static void main(String... args) throws Exception { + IncCompileNoChanges nc = new IncCompileNoChanges(); + nc.test(); + } + + // Remember the previous bin and headers state here. + Map previous_bin_state; + Map previous_headers_state; + + void test() throws Exception { + Files.createDirectory(GENSRC); + Files.createDirectory(BIN); + Files.createDirectory(HEADERS); + + initialCompile(); + incrementalCompileNoChanges(); + + clean(GENSRC, BIN, HEADERS); + } + + // Testing that no change in sources implies no change in binaries + void incrementalCompileNoChanges() throws Exception { + previous_bin_state = collectState(BIN); + previous_headers_state = collectState(HEADERS); + System.out.println("\nIn incrementalCompileNoChanges() "); + System.out.println("Testing that no change in sources implies no change in binaries"); + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + verifyEqual(new_bin_state, previous_bin_state); + Map new_headers_state = collectState(HEADERS); + verifyEqual(previous_headers_state, new_headers_state); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/IncCompileUpdateNative.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/IncCompileUpdateNative.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 + * @summary Verify native files are rewritten + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper IncCompileUpdateNative + */ + +import java.util.*; +import java.nio.file.*; + +public class IncCompileUpdateNative extends SJavacTester { + public static void main(String... args) throws Exception { + IncCompileUpdateNative un = new IncCompileUpdateNative(); + un.test(); + } + + // Remember the previous bin and headers state here. + Map previous_bin_state; + Map previous_headers_state; + ToolBox tb = new ToolBox(); + + void test() throws Exception { + Files.createDirectory(GENSRC); + Files.createDirectory(BIN); + Files.createDirectory(HEADERS); + + initialCompile(); + incrementalCompileChangeNative(); + + clean(GENSRC, BIN, HEADERS); + } + + // Update B.java with a new value for the final static annotated with @Native + // Verify that beta_B.h is rewritten again + void incrementalCompileChangeNative() throws Exception { + previous_bin_state = collectState(BIN); + previous_headers_state = collectState(HEADERS); + System.out.println("\nIn incrementalCompileChangeNative() "); + System.out.println("Verify that beta_B.h is rewritten again"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; import alfa.omega.A; public class B {"+ + "private int b() { return A.DEFINITION; } "+ + "@java.lang.annotation.Native final static int alfa = 43; }"); + + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + verifyNewerFiles(previous_bin_state, new_bin_state, + "bin/beta/B.class", + "bin/beta/BINT.class", + "bin/javac_state"); + previous_bin_state = new_bin_state; + + Map new_headers_state = collectState(HEADERS); + verifyNewerFiles(previous_headers_state, new_headers_state, + "headers/beta_B.h"); + previous_headers_state = new_headers_state; + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/IncCompileWithChanges.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/IncCompileWithChanges.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 + * @summary Verify incremental changes in gensrc are handled as expected + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper IncCompileWithChanges + */ + +import java.util.*; +import java.nio.file.*; + +public class IncCompileWithChanges extends SJavacTester { + public static void main(String... args) throws Exception { + IncCompileWithChanges wc = new IncCompileWithChanges(); + wc.test(); + } + + // Remember the previous bin and headers state here. + Map previous_bin_state; + Map previous_headers_state; + ToolBox tb = new ToolBox(); + + void test() throws Exception { + Files.createDirectory(GENSRC); + Files.createDirectory(BIN); + Files.createDirectory(HEADERS); + + initialCompile(); + incrementalCompileWithChange(); + + clean(GENSRC, BIN, HEADERS); + } + + /* Update A.java with a new timestamp and new final static definition. + * This should trigger a recompile, not only of alfa, but also beta. + * Generated native header should not be updated since native api of B was not modified. + */ + void incrementalCompileWithChange() throws Exception { + previous_bin_state = collectState(BIN); + previous_headers_state = collectState(HEADERS); + System.out.println("\nIn incrementalCompileWithChange() "); + System.out.println("A.java updated to trigger a recompile"); + System.out.println("Generated native header should not be updated since native api of B was not modified"); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A implements AINT { "+ + "public final static int DEFINITION = 18; public void aint() { } private void foo() { } }"); + + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + Map new_bin_state = collectState(BIN); + + verifyNewerFiles(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/alfa/omega/AINT.class", + "bin/alfa/omega/AA$AAAA.class", + "bin/alfa/omega/AAAAA.class", + "bin/alfa/omega/AA$AAA.class", + "bin/alfa/omega/AA.class", + "bin/alfa/omega/AA$1.class", + "bin/beta/B.class", + "bin/beta/BINT.class", + "bin/javac_state"); + previous_bin_state = new_bin_state; + + Map new_headers_state = collectState(HEADERS); + verifyEqual(new_headers_state, previous_headers_state); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/PermittedArtifact.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/PermittedArtifact.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Test white listing of external artifacts inside the destination dir + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper PermittedArtifact + */ + +import java.lang.reflect.Method; +import java.util.*; +import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.charset.*; + +public class PermittedArtifact extends SJavacTester { + public static void main(String... args) throws Exception { + PermittedArtifact pa = new PermittedArtifact(); + pa.test(); + } + + //Verify that --permit-artifact=bin works + void test() throws Exception { + Files.createDirectory(BIN); + clean(GENSRC, BIN); + + Map previous_bin_state = collectState(BIN); + + new ToolBox().writeFile(GENSRC+"/alfa/omega/A.java", + "package alfa.omega; public class A { }"); + + new ToolBox().writeFile(BIN+"/alfa/omega/AA.class", + "Ugh, a messy build system (tobefixed) wrote this class file, " + + "sjavac must not delete it."); + + compile("--log=debug", "--permit-artifact=bin/alfa/omega/AA.class", + "-src", "gensrc", "-d", "bin", SERVER_ARG); + + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class", + "bin/alfa/omega/AA.class", + "bin/javac_state"); + clean(GENSRC, BIN); + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/SJavac.java --- a/langtools/test/tools/sjavac/SJavac.java Thu Jan 08 10:44:54 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,746 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * 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 - * @summary Test all aspects of sjavac. - * @bug 8004658 8042441 8042699 8054461 8054474 8054465 - * - * @build Wrapper - * @run main Wrapper SJavac - */ - -import java.util.*; -import java.io.*; -import java.nio.file.*; -import java.nio.file.attribute.*; -import java.nio.charset.*; - -import com.sun.tools.sjavac.Main; - -public class SJavac { - - public static void main(String... args) throws Exception { - try { - SJavac s = new SJavac(); - s.test(); - } finally { - System.out.println("\ntest complete\n"); - } - } - - FileSystem defaultfs = FileSystems.getDefault(); - String serverArg = "--server:" - + "portfile=testportfile," - + "background=false"; - - // Where to put generated sources that will - // test aspects of sjavac, ie JTWork/scratch/gensrc - Path gensrc; - // More gensrc dirs are used to test merging of serveral source roots. - Path gensrc2; - Path gensrc3; - - // Where to put compiled classes. - Path bin; - // Where to put c-header files. - Path headers; - - // Remember the previous bin and headers state here. - Map previous_bin_state; - Map previous_headers_state; - - public void test() throws Exception { - gensrc = defaultfs.getPath("gensrc"); - gensrc2 = defaultfs.getPath("gensrc2"); - gensrc3 = defaultfs.getPath("gensrc3"); - bin = defaultfs.getPath("bin"); - headers = defaultfs.getPath("headers"); - - Files.createDirectory(gensrc); - Files.createDirectory(gensrc2); - Files.createDirectory(gensrc3); - Files.createDirectory(bin); - Files.createDirectory(headers); - - initialCompile(); - incrementalCompileNoChanges(); - incrementalCompileDroppingClasses(); - incrementalCompileWithChange(); - incrementalCompileDropAllNatives(); - incrementalCompileAddNative(); - incrementalCompileChangeNative(); - compileWithOverrideSource(); - compileWithInvisibleSources(); - compileCircularSources(); - compileExcludingDependency(); - incrementalCompileTestFullyQualifiedRef(); - compileWithAtFile(); - testStateDir(); - testPermittedArtifact(); - - delete(gensrc); - delete(gensrc2); - delete(gensrc3); - delete(bin); - delete(headers); - } - - void initialCompile() throws Exception { - System.out.println("\nInitial compile of gensrc."); - System.out.println("----------------------------"); - populate(gensrc, - "alfa/omega/AINT.java", - "package alfa.omega; public interface AINT { void aint(); }", - - "alfa/omega/A.java", - "package alfa.omega; public class A implements AINT { "+ - "public final static int DEFINITION = 17; public void aint() { } }", - - "alfa/omega/AA.java", - "package alfa.omega;"+ - "// A package private class, not contributing to the public api.\n"+ - "class AA {"+ - " // A properly nested static inner class.\n"+ - " static class AAA { }\n"+ - " // A properly nested inner class.\n"+ - " class AAAA { }\n"+ - " Runnable foo() {\n"+ - " // A proper anonymous class.\n"+ - " return new Runnable() { public void run() { } };\n"+ - " }\n"+ - " AAA aaa;\n"+ - " AAAA aaaa;\n"+ - " AAAAA aaaaa;\n"+ - "}\n"+ - "class AAAAA {\n"+ - " // A bad auxiliary class, but no one is referencing it\n"+ - " // from outside of this source file, therefore it is ok.\n"+ - "}\n", - - "beta/BINT.java", - "package beta;public interface BINT { void foo(); }", - - "beta/B.java", - "package beta; import alfa.omega.A; public class B {"+ - "private int b() { return A.DEFINITION; } native void foo(); }"); - - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - previous_bin_state = collectState(bin); - previous_headers_state = collectState(headers); - } - - void incrementalCompileNoChanges() throws Exception { - System.out.println("\nTesting that no change in sources implies no change in binaries."); - System.out.println("------------------------------------------------------------------"); - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - verifyEqual(new_bin_state, previous_bin_state); - Map new_headers_state = collectState(headers); - verifyEqual(previous_headers_state, new_headers_state); - } - - void incrementalCompileDroppingClasses() throws Exception { - System.out.println("\nTesting that deleting AA.java deletes all"); - System.out.println("generated inner class as well as AA.class"); - System.out.println("-----------------------------------------"); - removeFrom(gensrc, "alfa/omega/AA.java"); - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenRemoved(previous_bin_state, new_bin_state, - "bin/alfa/omega/AA$1.class", - "bin/alfa/omega/AA$AAAA.class", - "bin/alfa/omega/AA$AAA.class", - "bin/alfa/omega/AAAAA.class", - "bin/alfa/omega/AA.class"); - - previous_bin_state = new_bin_state; - Map new_headers_state = collectState(headers); - verifyEqual(previous_headers_state, new_headers_state); - } - - void incrementalCompileWithChange() throws Exception { - System.out.println("\nNow update the A.java file with a new timestamps and"); - System.out.println("new final static definition. This should trigger a recompile,"); - System.out.println("not only of alfa, but also beta."); - System.out.println("But check that the generated native header was not updated!"); - System.out.println("Since we did not modify the native api of B."); - System.out.println("-------------------------------------------------------------"); - - populate(gensrc,"alfa/omega/A.java", - "package alfa.omega; public class A implements AINT { "+ - "public final static int DEFINITION = 18; public void aint() { } private void foo() { } }"); - - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - - verifyNewerFiles(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/alfa/omega/AINT.class", - "bin/beta/B.class", - "bin/beta/BINT.class", - "bin/javac_state"); - previous_bin_state = new_bin_state; - - Map new_headers_state = collectState(headers); - verifyEqual(new_headers_state, previous_headers_state); - } - - void incrementalCompileDropAllNatives() throws Exception { - System.out.println("\nNow update the B.java file with one less native method,"); - System.out.println("ie it has no longer any methods!"); - System.out.println("Verify that beta_B.h is removed!"); - System.out.println("---------------------------------------------------------"); - - populate(gensrc,"beta/B.java", - "package beta; import alfa.omega.A; public class B {"+ - "private int b() { return A.DEFINITION; } }"); - - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - verifyNewerFiles(previous_bin_state, new_bin_state, - "bin/beta/B.class", - "bin/beta/BINT.class", - "bin/javac_state"); - previous_bin_state = new_bin_state; - - Map new_headers_state = collectState(headers); - verifyThatFilesHaveBeenRemoved(previous_headers_state, new_headers_state, - "headers/beta_B.h"); - previous_headers_state = new_headers_state; - } - - void incrementalCompileAddNative() throws Exception { - System.out.println("\nNow update the B.java file with a final static annotated with @Native."); - System.out.println("Verify that beta_B.h is added again!"); - System.out.println("------------------------------------------------------------------------"); - - populate(gensrc,"beta/B.java", - "package beta; import alfa.omega.A; public class B {"+ - "private int b() { return A.DEFINITION; } "+ - "@java.lang.annotation.Native final static int alfa = 42; }"); - - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - verifyNewerFiles(previous_bin_state, new_bin_state, - "bin/beta/B.class", - "bin/beta/BINT.class", - "bin/javac_state"); - previous_bin_state = new_bin_state; - - Map new_headers_state = collectState(headers); - verifyThatFilesHaveBeenAdded(previous_headers_state, new_headers_state, - "headers/beta_B.h"); - previous_headers_state = new_headers_state; - } - - void incrementalCompileChangeNative() throws Exception { - System.out.println("\nNow update the B.java file with a new value for the final static"+ - " annotated with @Native."); - System.out.println("Verify that beta_B.h is rewritten again!"); - System.out.println("-------------------------------------------------------------------"); - - populate(gensrc,"beta/B.java", - "package beta; import alfa.omega.A; public class B {"+ - "private int b() { return A.DEFINITION; } "+ - "@java.lang.annotation.Native final static int alfa = 43; }"); - - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - verifyNewerFiles(previous_bin_state, new_bin_state, - "bin/beta/B.class", - "bin/beta/BINT.class", - "bin/javac_state"); - previous_bin_state = new_bin_state; - - Map new_headers_state = collectState(headers); - verifyNewerFiles(previous_headers_state, new_headers_state, - "headers/beta_B.h"); - previous_headers_state = new_headers_state; - } - - void compileWithOverrideSource() throws Exception { - System.out.println("\nNow verify that we can override sources to be compiled."); - System.out.println("Compile gensrc and gensrc2. However do not compile broken beta.B in gensrc,"); - System.out.println("only compile ok beta.B in gensrc2."); - System.out.println("---------------------------------------------------------------------------"); - - delete(gensrc); - delete(gensrc2); - delete(bin); - previous_bin_state = collectState(bin); - - populate(gensrc,"alfa/omega/A.java", - "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }", - "beta/B.java", - "package beta; public class B { broken", - "gamma/C.java", - "package gamma; public class C { }"); - - populate(gensrc2, - "beta/B.java", - "package beta; public class B { }"); - - compile("-x", "beta", "gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1", - serverArg); - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/beta/B.class", - "bin/gamma/C.class", - "bin/javac_state"); - - System.out.println("----- Compile with exluded beta went well!"); - delete(bin); - compileExpectFailure("gensrc", "gensrc2", "-d", "bin", "-h", "headers", "-j", "1", - serverArg); - - System.out.println("----- Compile without exluded beta failed, as expected! Good!"); - delete(bin); - } - - void compileWithInvisibleSources() throws Exception { - System.out.println("\nNow verify that we can make sources invisible to linking (sourcepath)."); - System.out.println("Compile gensrc and link against gensrc2 and gensrc3, however"); - System.out.println("gensrc2 contains broken code in beta.B, thus we must exclude that package"); - System.out.println("fortunately gensrc3 contains a proper beta.B."); - System.out.println("------------------------------------------------------------------------"); - - // Start with a fresh gensrcs and bin. - delete(gensrc); - delete(gensrc2); - delete(gensrc3); - delete(bin); - previous_bin_state = collectState(bin); - - populate(gensrc,"alfa/omega/A.java", - "package alfa.omega; import beta.B; import gamma.C; public class A { B b; C c; }"); - populate(gensrc2,"beta/B.java", - "package beta; public class B { broken", - "gamma/C.java", - "package gamma; public class C { }"); - populate(gensrc3, "beta/B.java", - "package beta; public class B { }"); - - compile("gensrc", "-x", "beta", "-sourcepath", "gensrc2", - "-sourcepath", "gensrc3", "-d", "bin", "-h", "headers", "-j", "1", - serverArg); - - System.out.println("The first compile went well!"); - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/javac_state"); - - System.out.println("----- Compile with exluded beta went well!"); - delete(bin); - compileExpectFailure("gensrc", "-sourcepath", "gensrc2", "-sourcepath", "gensrc3", - "-d", "bin", "-h", "headers", "-j", "1", - serverArg); - - System.out.println("----- Compile without exluded beta failed, as expected! Good!"); - delete(bin); - } - - void compileCircularSources() throws Exception { - System.out.println("\nNow verify that circular sources split on multiple cores can be compiled."); - System.out.println("---------------------------------------------------------------------------"); - - // Start with a fresh gensrcs and bin. - delete(gensrc); - delete(gensrc2); - delete(gensrc3); - delete(bin); - previous_bin_state = collectState(bin); - - populate(gensrc,"alfa/omega/A.java", - "package alfa.omega; public class A { beta.B b; }", - "beta/B.java", - "package beta; public class B { gamma.C c; }", - "gamma/C.java", - "package gamma; public class C { alfa.omega.A a; }"); - - compile("gensrc", "-d", "bin", "-h", "headers", "-j", "3", - serverArg,"--log=debug"); - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/beta/B.class", - "bin/gamma/C.class", - "bin/javac_state"); - delete(bin); - } - - /** - * Tests compiling class A that depends on class B without compiling class B - * @throws Exception If test fails - */ - void compileExcludingDependency() throws Exception { - System.out.println("\nVerify that excluding classes from compilation but not from linking works."); - System.out.println("---------------------------------------------------------------------------"); - - delete(gensrc); - delete(bin); - previous_bin_state = collectState(bin); - - populate(gensrc, - "alfa/omega/A.java", - "package alfa.omega; public class A { beta.B b; }", - "beta/B.java", - "package beta; public class B { }"); - - compile("-x", "beta", "-src", "gensrc", "-x", "alfa/omega", "-sourcepath", "gensrc", - "-d", "bin", serverArg); - - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/javac_state"); - } - - void incrementalCompileTestFullyQualifiedRef() throws Exception { - System.out.println("\nVerify that \"alfa.omega.A a;\" does create a proper dependency."); - System.out.println("----------------------------------------------------------------"); - - populate(gensrc, - "alfa/omega/A.java", - "package alfa.omega; public class A { "+ - " public final static int DEFINITION = 18; "+ - " public void hello() { }"+ - "}", - "beta/B.java", - "package beta; public class B { "+ - " public void world() { alfa.omega.A a; }"+ - "}"); - - compile("gensrc", "-d", "bin", "-j", "1", - serverArg, "--log=debug"); - Map previous_bin_state = collectState(bin); - - // Change pubapi of A, this should trigger a recompile of B. - populate(gensrc, - "alfa/omega/A.java", - "package alfa.omega; public class A { "+ - " public final static int DEFINITION = 19; "+ - " public void hello() { }"+ - "}"); - - compile("gensrc", "-d", "bin", "-j", "1", - serverArg, "--log=debug"); - Map new_bin_state = collectState(bin); - - verifyNewerFiles(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/beta/B.class", - "bin/javac_state"); - } - - /** - * Tests @atfile - * @throws Exception If test fails - */ - void compileWithAtFile() throws Exception { - System.out.println("\nTest @atfile with command line content."); - System.out.println("---------------------------------------"); - - delete(gensrc); - delete(gensrc2); - delete(bin); - - populate(gensrc, - "list.txt", - "-if */alfa/omega/A.java\n-if */beta/B.java\ngensrc\n-d bin\n", - "alfa/omega/A.java", - "package alfa.omega; import beta.B; public class A { B b; }", - "beta/B.java", - "package beta; public class B { }", - "beta/C.java", - "broken"); - previous_bin_state = collectState(bin); - compile("@gensrc/list.txt", "--server:portfile=testserver,background=false"); - - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/javac_state", - "bin/alfa/omega/A.class", - "bin/beta/B.class"); - } - - /** - * Tests storing javac_state into another directory. - * @throws Exception If test fails - */ - void testStateDir() throws Exception { - System.out.println("\nVerify that --state-dir=bar works."); - System.out.println("----------------------------------"); - - Path bar = defaultfs.getPath("bar"); - Files.createDirectory(bar); - - delete(gensrc); - delete(bin); - delete(bar); - previous_bin_state = collectState(bin); - Map previous_bar_state = collectState(bar); - - populate(gensrc, - "alfa/omega/A.java", - "package alfa.omega; public class A { }"); - - compile("--state-dir=bar", "-src", "gensrc", "-d", "bin", serverArg); - - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class"); - Map new_bar_state = collectState(bar); - verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state, - "bar/javac_state"); - } - - /** - * Test white listing of external artifacts inside the destination dir. - * @throws Exception If test fails - */ - void testPermittedArtifact() throws Exception { - System.out.println("\nVerify that --permit-artifact=bar works."); - System.out.println("-------------------------------------------"); - - delete(gensrc); - delete(bin); - - previous_bin_state = collectState(bin); - - populate(gensrc, - "alfa/omega/A.java", - "package alfa.omega; public class A { }"); - - populate(bin, - "alfa/omega/AA.class", - "Ugh, a messy build system (tobefixed) wrote this class file, sjavac must not delete it."); - - compile("--log=debug", "--permit-artifact=bin/alfa/omega/AA.class", "-src", "gensrc", "-d", "bin", serverArg); - - Map new_bin_state = collectState(bin); - verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, - "bin/alfa/omega/A.class", - "bin/alfa/omega/AA.class", - "bin/javac_state"); - } - - void removeFrom(Path dir, String... args) throws IOException { - for (String filename : args) { - Path p = dir.resolve(filename); - Files.delete(p); - } - } - - void populate(Path src, String... args) throws IOException { - if (!Files.exists(src)) { - Files.createDirectory(src); - } - String[] a = args; - for (int i = 0; i() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException - { - Files.delete(file); - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException - { - if (e == null) { - if (!dir.equals(root)) Files.delete(dir); - return FileVisitResult.CONTINUE; - } else { - // directory iteration failed - throw e; - } - } - }); - } - - void compile(String... args) throws Exception { - int rc = Main.go(args); - if (rc != 0) throw new Exception("Error during compile!"); - - // Wait a second, to get around the (temporary) problem with - // second resolution in the Java file api. But do not do this - // on windows where the timestamps work. - long in_a_sec = System.currentTimeMillis()+1000; - while (in_a_sec > System.currentTimeMillis()) { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - } - } - } - - void compileExpectFailure(String... args) throws Exception { - int rc = Main.go(args); - if (rc == 0) throw new Exception("Expected error during compile! Did not fail!"); - } - - Map collectState(Path dir) throws IOException { - final Map files = new HashMap<>(); - Files.walkFileTree(dir, new SimpleFileVisitor() { - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) - throws IOException - { - files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis())); - return FileVisitResult.CONTINUE; - } - }); - return files; - } - - void verifyThatFilesHaveBeenRemoved(Map from, - Map to, - String... args) throws Exception { - - Set froms = from.keySet(); - Set tos = to.keySet(); - - if (froms.equals(tos)) { - throw new Exception("Expected new state to have fewer files than previous state!"); - } - - for (String t : tos) { - if (!froms.contains(t)) { - throw new Exception("Expected "+t+" to exist in previous state!"); - } - } - - for (String f : args) { - f = f.replace("/", File.separator); - if (!froms.contains(f)) { - throw new Exception("Expected "+f+" to exist in previous state!"); - } - if (tos.contains(f)) { - throw new Exception("Expected "+f+" to have been removed from the new state!"); - } - } - - if (froms.size() - args.length != tos.size()) { - throw new Exception("There are more removed files than the expected list!"); - } - } - - void verifyThatFilesHaveBeenAdded(Map from, - Map to, - String... args) throws Exception { - - Set froms = from.keySet(); - Set tos = to.keySet(); - - if (froms.equals(tos)) { - throw new Exception("Expected new state to have more files than previous state!"); - } - - for (String t : froms) { - if (!tos.contains(t)) { - throw new Exception("Expected "+t+" to exist in new state!"); - } - } - - for (String f : args) { - f = f.replace("/", File.separator); - if (!tos.contains(f)) { - throw new Exception("Expected "+f+" to have been added to new state!"); - } - if (froms.contains(f)) { - throw new Exception("Expected "+f+" to not exist in previous state!"); - } - } - - if (froms.size() + args.length != tos.size()) { - throw new Exception("There are more added files than the expected list!"); - } - } - - void verifyNewerFiles(Map from, - Map to, - String... args) throws Exception { - if (!from.keySet().equals(to.keySet())) { - throw new Exception("Expected the set of files to be identical!"); - } - Set files = new HashSet(); - for (String s : args) { - files.add(s.replace("/", File.separator)); - } - for (String fn : from.keySet()) { - long f = from.get(fn); - long t = to.get(fn); - if (files.contains(fn)) { - if (t <= f) { - throw new Exception("Expected "+fn+" to have a more recent timestamp!"); - } - } else { - if (t != f) { - throw new Exception("Expected "+fn+" to have the same timestamp!"); - } - } - } - } - - String print(Map m) { - StringBuilder b = new StringBuilder(); - Set keys = m.keySet(); - for (String k : keys) { - b.append(k+" "+m.get(k)+"\n"); - } - return b.toString(); - } - - void verifyEqual(Map from, Map to) throws Exception { - if (!from.equals(to)) { - System.out.println("FROM---"+print(from)); - System.out.println("TO-----"+print(to)); - throw new Exception("The dir should not differ! But it does!"); - } - } -} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/SJavacTester.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/SJavacTester.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.*; +import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.nio.charset.*; + +import com.sun.tools.sjavac.Main; + +public class SJavacTester { + + static final String SERVER_ARG = "--server:" + + "portfile=testportfile," + + "background=false"; + + // Generated sources that will test aspects of sjavac + static final Path GENSRC = Paths.get("gensrc"); + // Gensrc dirs used to test merging of serveral source roots. + static final Path GENSRC2 = Paths.get("gensrc2"); + static final Path GENSRC3= Paths.get("gensrc3"); + + // Dir for compiled classes. + static final Path BIN = Paths.get("bin"); + // Dir for c-header files. + Path HEADERS = Paths.get("headers"); + + // Remember the previous bin and headers state here. + Map previous_bin_state; + Map previous_headers_state; + + void initialCompile() throws Exception { + System.out.println("\nInitial compile of gensrc."); + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/AINT.java"), + "package alfa.omega; public interface AINT { void aint(); }"); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A implements AINT { "+ + "public final static int DEFINITION = 17; public void aint() { } }"); + tb.writeFile(GENSRC.resolve("alfa/omega/AA.java"), + "package alfa.omega;"+ + "// A package private class, not contributing to the public api.\n"+ + "class AA {"+ + " // A properly nested static inner class.\n"+ + " static class AAA { }\n"+ + " // A properly nested inner class.\n"+ + " class AAAA { }\n"+ + " Runnable foo() {\n"+ + " // A proper anonymous class.\n"+ + " return new Runnable() { public void run() { } };\n"+ + " }\n"+ + " AAA aaa;\n"+ + " AAAA aaaa;\n"+ + " AAAAA aaaaa;\n"+ + "}\n"+ + "class AAAAA {\n"+ + " // A bad auxiliary class, but no one is referencing it\n"+ + " // from outside of this source file, therefore it is ok.\n"+ + "}\n"); + tb.writeFile(GENSRC.resolve("beta/BINT.java"), + "package beta;public interface BINT { void foo(); }"); + tb.writeFile(GENSRC.resolve("beta/B.java"), + "package beta; import alfa.omega.A; public class B {"+ + "private int b() { return A.DEFINITION; } native void foo(); }"); + + compile("gensrc", "-d", "bin", "-h", "headers", "-j", "1", + SERVER_ARG, "--log=debug"); + } + + void removeFrom(Path dir, String... args) throws IOException { + for (String filename : args) { + Path p = dir.resolve(filename); + Files.delete(p); + } + } + + void delete(final Path root) throws IOException { + if (!Files.exists(root)) return; + Files.walkFileTree(root, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException + { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException + { + if (e == null) { + if (!dir.equals(root)) Files.delete(dir); + return FileVisitResult.CONTINUE; + } else { + // directory iteration failed + throw e; + } + } + }); + } + + void compile(String... args) throws Exception { + int rc = Main.go(args); + if (rc != 0) throw new Exception("Error during compile!"); + + // Wait a second, to get around the (temporary) problem with + // second resolution in the Java file api. But do not do this + // on windows where the timestamps work. + long in_a_sec = System.currentTimeMillis()+1000; + while (in_a_sec > System.currentTimeMillis()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + } + + void compileExpectFailure(String... args) throws Exception { + int rc = Main.go(args); + if (rc == 0) throw new Exception("Expected error during compile! Did not fail!"); + } + + Map collectState(Path dir) throws IOException { + final Map files = new HashMap<>(); + Files.walkFileTree(dir, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) + throws IOException + { + files.put(file.toString(),new Long(Files.getLastModifiedTime(file).toMillis())); + return FileVisitResult.CONTINUE; + } + }); + return files; + } + + void verifyThatFilesHaveBeenRemoved(Map from, + Map to, + String... args) throws Exception { + + Set froms = from.keySet(); + Set tos = to.keySet(); + + if (froms.equals(tos)) { + throw new Exception("Expected new state to have fewer files than previous state!"); + } + + for (String t : tos) { + if (!froms.contains(t)) { + throw new Exception("Expected "+t+" to exist in previous state!"); + } + } + + for (String f : args) { + f = f.replace("/", File.separator); + if (!froms.contains(f)) { + throw new Exception("Expected "+f+" to exist in previous state!"); + } + if (tos.contains(f)) { + throw new Exception("Expected "+f+" to have been removed from the new state!"); + } + } + + if (froms.size() - args.length != tos.size()) { + throw new Exception("There are more removed files than the expected list!"); + } + } + + void verifyThatFilesHaveBeenAdded(Map from, + Map to, + String... args) throws Exception { + + Set froms = from.keySet(); + Set tos = to.keySet(); + + if (froms.equals(tos)) { + throw new Exception("Expected new state to have more files than previous state!"); + } + + for (String t : froms) { + if (!tos.contains(t)) { + throw new Exception("Expected "+t+" to exist in new state!"); + } + } + + for (String f : args) { + f = f.replace("/", File.separator); + if (!tos.contains(f)) { + throw new Exception("Expected "+f+" to have been added to new state!"); + } + if (froms.contains(f)) { + throw new Exception("Expected "+f+" to not exist in previous state!"); + } + } + + if (froms.size() + args.length != tos.size()) { + throw new Exception("There are more added files than the expected list!"); + } + } + + void verifyNewerFiles(Map from, + Map to, + String... args) throws Exception { + if (!from.keySet().equals(to.keySet())) { + throw new Exception("Expected the set of files to be identical!"); + } + Set files = new HashSet(); + for (String s : args) { + files.add(s.replace("/", File.separator)); + } + for (String fn : from.keySet()) { + long f = from.get(fn); + long t = to.get(fn); + if (files.contains(fn)) { + if (t <= f) { + throw new Exception("Expected "+fn+" to have a more recent timestamp!"); + } + } else { + if (t != f) { + throw new Exception("Expected "+fn+" to have the same timestamp!"); + } + } + } + } + + String print(Map m) { + StringBuilder b = new StringBuilder(); + Set keys = m.keySet(); + for (String k : keys) { + b.append(k+" "+m.get(k)+"\n"); + } + return b.toString(); + } + + void verifyEqual(Map from, Map to) throws Exception { + if (!from.equals(to)) { + System.out.println("FROM---"+print(from)); + System.out.println("TO-----"+print(to)); + throw new Exception("The dir should not differ! But it does!"); + } + } + + void clean(Path... listOfDirs) throws Exception { + for (Path dir : listOfDirs) { + delete(dir); + } + } +} diff -r ad8137d44154 -r 247f60f5808f langtools/test/tools/sjavac/StateDir.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/sjavac/StateDir.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Verify that --state-dir=bar works + * @bug 8054689 + * @author Fredrik O + * @author sogoel (rewrite) + * @library /tools/lib + * @build Wrapper ToolBox + * @run main Wrapper StateDir + */ + +import java.util.*; +import java.nio.file.*; + +public class StateDir extends SJavacTester { + public static void main(String... args) throws Exception { + StateDir sd = new StateDir(); + sd.test(); + } + + void test() throws Exception { + Path bar = Paths.get("bar"); + Files.createDirectory(bar); + Files.createDirectory(BIN); + + clean(GENSRC, BIN, bar); + + Map previous_bin_state = collectState(BIN); + Map previous_bar_state = collectState(bar); + + ToolBox tb = new ToolBox(); + tb.writeFile(GENSRC.resolve("alfa/omega/A.java"), + "package alfa.omega; public class A { }"); + + compile("--state-dir=bar", "-src", "gensrc", "-d", "bin", + SJavacTester.SERVER_ARG); + + Map new_bin_state = collectState(BIN); + verifyThatFilesHaveBeenAdded(previous_bin_state, new_bin_state, + "bin/alfa/omega/A.class"); + Map new_bar_state = collectState(bar); + verifyThatFilesHaveBeenAdded(previous_bar_state, new_bar_state, + "bar/javac_state"); + clean(GENSRC, BIN, bar); + } +} diff -r ad8137d44154 -r 247f60f5808f make/Javadoc.gmk --- a/make/Javadoc.gmk Thu Jan 08 10:44:54 2015 +0100 +++ b/make/Javadoc.gmk Sat Jan 10 12:38:18 2015 -0800 @@ -53,8 +53,7 @@ JAVADOC_CMD = $(JAVA) \ -Djava.awt.headless=true \ - $(NEW_JAVADOC) \ - -bootclasspath $(JDK_OUTPUTDIR)/classes + $(NEW_JAVADOC) # Copyright year for beginning of Java and some of the apis # (Needed when creating the javadocs) @@ -231,17 +230,17 @@ # Common echo of option define OptionOnly # opt - if [ "$1" != "" ] ; then \ - $(PRINTF) "%s\n" "$1"; \ + if [ "$(strip $1)" != "" ] ; then \ + $(PRINTF) "%s\n" "$(strip $1)"; \ fi endef define OptionPair # opt arg - $(PRINTF) "%s '%s'\n" "$1" '$2' + $(PRINTF) "%s '%s'\n" "$(strip $1)" '$(strip $2)' endef define OptionTrip # opt arg arg - $(PRINTF) "%s '%s' '%s'\n" "$1" '$2' '$3' + $(PRINTF) "%s '%s' '%s'\n" "$(strip $1)" '$(strip $2)' '$(strip $3)' endef # Core api bottom argument (with special sauce) diff -r ad8137d44154 -r 247f60f5808f make/Main.gmk --- a/make/Main.gmk Thu Jan 08 10:44:54 2015 +0100 +++ b/make/Main.gmk Sat Jan 10 12:38:18 2015 -0800 @@ -257,7 +257,7 @@ test: ($(CD) $(SRC_ROOT)/test && $(MAKE) $(MAKE_ARGS) -j1 -k MAKEFLAGS= \ - JT_HOME=$(JT_HOME) PRODUCT_HOME=$(JDK_OUTPUTDIR) \ + JT_HOME=$(JT_HOME) PRODUCT_HOME=$(JDK_IMAGE_DIR) \ ALT_OUTPUTDIR=$(OUTPUT_ROOT) CONCURRENCY=$(JOBS) $(TEST)) || true test-make: @@ -394,7 +394,7 @@ docs-jvmtidoc: hotspot - test: exploded-image + test: jimages verify-modules: exploded-image diff -r ad8137d44154 -r 247f60f5808f make/StripBinaries.gmk --- a/make/StripBinaries.gmk Thu Jan 08 10:44:54 2015 +0100 +++ b/make/StripBinaries.gmk Sat Jan 10 12:38:18 2015 -0800 @@ -66,11 +66,6 @@ $(shell $(FIND) $(SUPPORT_OUTPUTDIR)/modules_libs \ -name '*$(SHARED_LIBRARY_SUFFIX)' -type f) -# On Windows, don't include debug info for libs either. -ifeq ($(OPENJDK_TARGET_OS), windows) - COPY_LIBS_SRC := $(filter-out %.diz %.map %.pdb, $(COPY_LIBS_SRC)) -endif - $(eval $(call SetupCopyFiles,STRIP_MODULES_CMDS, \ SRC := $(SUPPORT_OUTPUTDIR)/modules_cmds, \ DEST := $(MODULES_CMDS_STRIPPED), \ diff -r ad8137d44154 -r 247f60f5808f make/jprt.properties --- a/make/jprt.properties Thu Jan 08 10:44:54 2015 +0100 +++ b/make/jprt.properties Sat Jan 10 12:38:18 2015 -0800 @@ -188,6 +188,13 @@ ${my.test.target.set:TESTNAME=svc_tools}, \ ${my.make.rule.test.targets.svc.extra} +# JAXP vm test targets (testset=jaxp) +my.test.targets.jaxp= + +# JAXP test targets (testset=jaxp) +my.make.rule.test.targets.jaxp= \ + ${my.test.target.set:TESTNAME=jaxp_all} + # All vm test targets (testset=all) my.test.targets.all= \ ${my.test.targets.default}, \ @@ -211,7 +218,8 @@ my.make.rule.test.targets.pit= \ ${my.test.target.set:TESTNAME=langtools_jtreg}, \ ${my.make.rule.test.targets.core}, \ - ${my.make.rule.test.targets.svc} + ${my.make.rule.test.targets.svc} \ + ${my.make.rule.test.targets.jaxp} # JCK test targets in test/Makefile (no windows) my.test.target.set.jck= \ diff -r ad8137d44154 -r 247f60f5808f nashorn/.hgtags --- a/nashorn/.hgtags Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/.hgtags Sat Jan 10 12:38:18 2015 -0800 @@ -276,3 +276,5 @@ 74dcd8dbef252938d6deb032aefb46b8f452dd9e jdk9-b40 52340a35aec9955d4aeaaf01d6337284f179b31c jdk9-b41 498d1d6c4219086143b764b3bf61afe65dcece47 jdk9-b42 +8ae8dff2a28f3b8831cce97ae0c7a957c5dc650a jdk9-b43 +50ee576062726e536d1bb9a5eadd8fd4470128fc jdk9-b44 diff -r ad8137d44154 -r 247f60f5808f nashorn/make/build.xml --- a/nashorn/make/build.xml Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/make/build.xml Sat Jan 10 12:38:18 2015 -0800 @@ -209,7 +209,7 @@ - diff -r ad8137d44154 -r 247f60f5808f nashorn/make/nbproject/ide-targets.xml --- a/nashorn/make/nbproject/ide-targets.xml Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/make/nbproject/ide-targets.xml Sat Jan 10 12:38:18 2015 -0800 @@ -32,9 +32,8 @@ - + - diff -r ad8137d44154 -r 247f60f5808f nashorn/make/nbproject/project.xml --- a/nashorn/make/nbproject/project.xml Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/make/nbproject/project.xml Sat Jan 10 12:38:18 2015 -0800 @@ -38,10 +38,6 @@ UTF-8 - - ../src - - ../test/src @@ -50,21 +46,25 @@ ../buildtools/nasgen/src + + ../src/jdk.scripting.nashorn/share/classes + + java ../test/src UTF-8 - + java - ../src + ../buildtools/nasgen/src UTF-8 - + java - ../buildtools/nasgen/src + ../src/jdk.scripting.nashorn/share/classes UTF-8 @@ -132,12 +132,12 @@ ../test/src - - ../src + + ../buildtools/nasgen/src - - ../buildtools/nasgen/src + + ../src/jdk.scripting.nashorn/share/classes build.xml @@ -159,11 +159,7 @@ ../test/src - ../test/lib/testng.jar:../build/classes:../src - 1.7 - - - ../src + ../test/lib/testng.jar:../build/classes:../src/jdk.scripting.nashorn/share/classes 1.7 @@ -171,6 +167,10 @@ ../build/classes:../src 1.7 + + ../src/jdk.scripting.nashorn/share/classes + 1.7 + diff -r ad8137d44154 -r 247f60f5808f nashorn/make/project.properties --- a/nashorn/make/project.properties Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/make/project.properties Sat Jan 10 12:38:18 2015 -0800 @@ -24,7 +24,7 @@ application.title=nashorn # location of JDK embedded ASM sources -jdk.asm.src.dir=../jdk/src/share/classes/jdk/internal/org/objectweb/asm +jdk.asm.src.dir=../jdk/src/java.base/share/classes/jdk/internal/org/objectweb/asm # source and target levels build.compiler=modern diff -r ad8137d44154 -r 247f60f5808f nashorn/samples/browser_dom.js --- a/nashorn/samples/browser_dom.js Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/samples/browser_dom.js Sat Jan 10 12:38:18 2015 -0800 @@ -1,4 +1,4 @@ -#// Usage: jjs -fx browser.js +#// Usage: jjs -fx browser_dom.js /* * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. @@ -32,7 +32,7 @@ */ if (!$OPTIONS._fx) { - print("Usage: jjs -fx browser.js"); + print("Usage: jjs -fx browser_dom.js"); exit(1); } @@ -40,7 +40,6 @@ var ChangeListener = Java.type("javafx.beans.value.ChangeListener"); var Scene = Java.type("javafx.scene.Scene"); var WebView = Java.type("javafx.scene.web.WebView"); -var EventListener = Java.type("org.w3c.dom.events.EventListener"); // JavaFX start method function start(stage) { @@ -74,10 +73,10 @@ var btn = document.createElement("button"); var n = 0; // attach a button handler - nashorn function! - btn.onclick = new EventListener(function() { + btn.onclick = function() { n++; print("You clicked " + n + " time(s)"); print("you clicked OK " + wv.engine.executeScript("okCount")); - }); + }; // attach text to button var t = document.createTextNode("Click Me!"); btn.appendChild(t); diff -r ad8137d44154 -r 247f60f5808f nashorn/samples/time_color.fx --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/samples/time_color.fx Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,89 @@ +#// Usage: jjs -fx time_color.js [-- true/false] + +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// A simple javafx program that changes background color +// of scene based on current time value (once per sec). +// inspired by http://whatcolourisit.scn9a.org/ + +if (!$OPTIONS._fx) { + print("Usage: jjs -fx time_color.js"); + print(" jjs -fx time_color.js -- true"); + exit(1); +} + +// JavaFX classes used +var Color = Java.type("javafx.scene.paint.Color"); +var Group = Java.type("javafx.scene.Group"); +var Label = Java.type("javafx.scene.control.Label"); +var Platform = Java.type("javafx.application.Platform"); +var Scene = Java.type("javafx.scene.Scene"); +var Timer = Java.type("java.util.Timer"); + +// execute function periodically once per given time in millisec +function setInterval(func, ms) { + // New timer, run as daemon so the application can quit + var timer = new Timer("setInterval", true); + timer.schedule(function() Platform.runLater(func), ms, ms); + return timer; +} + +// do you want to flip hour/min/sec for RGB? +var flip = arguments.length > 0? "true".equals(arguments[0]) : false; + +// JavaFX start method +function start(stage) { + start.title = "Time Color"; + var root = new Group(); + var label = new Label("time"); + label.textFill = Color.WHITE; + root.children.add(label); + stage.scene = new Scene(root, 700, 500); + + setInterval(function() { + var d = new Date(); + var hours = d.getHours(); + var mins = d.getMinutes(); + var secs = d.getSeconds(); + + if (hours < 10) hours = "0" + hours; + if (mins < 10) mins = "0" + mins; + if (secs < 10) secs = "0" + secs; + + var hex = flip? + "#" + secs + mins + hours : "#" + hours + mins + secs; + label.text = "Color: " + hex; + stage.scene.fill = Color.web(hex); + }, 1000); + + stage.show(); +} diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java Sat Jan 10 12:38:18 2015 -0800 @@ -40,21 +40,22 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.AccessNode; -import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.BreakNode; import jdk.nashorn.internal.ir.BreakableNode; +import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.ContinueNode; import jdk.nashorn.internal.ir.Expression; +import jdk.nashorn.internal.ir.ExpressionStatement; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; +import jdk.nashorn.internal.ir.GetSplitState; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.IfNode; import jdk.nashorn.internal.ir.IndexNode; @@ -65,9 +66,11 @@ import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.LexicalContextNode; import jdk.nashorn.internal.ir.LiteralNode; +import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.LocalVariableConversion; import jdk.nashorn.internal.ir.LoopNode; import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.ObjectNode; import jdk.nashorn.internal.ir.PropertyNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; @@ -82,6 +85,7 @@ import jdk.nashorn.internal.ir.UnaryNode; import jdk.nashorn.internal.ir.VarNode; import jdk.nashorn.internal.ir.WhileNode; +import jdk.nashorn.internal.ir.WithNode; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.parser.TokenType; @@ -131,8 +135,44 @@ OBJECT(Type.OBJECT); private final Type type; + private final TypeHolderExpression typeExpression; + private LvarType(final Type type) { this.type = type; + this.typeExpression = new TypeHolderExpression(type); + } + } + + /** + * A bogus Expression subclass that only reports its type. Used to interrogate BinaryNode and UnaryNode about their + * types by creating temporary copies of them and replacing their operands with instances of these. An alternative + * solution would be to add BinaryNode.getType(Type lhsType, Type rhsType) and UnaryNode.getType(Type exprType) + * methods. For the time being though, this is easier to implement and is in fact fairly clean. It does result in + * generation of higher number of temporary short lived nodes, though. + */ + private static class TypeHolderExpression extends Expression { + private static final long serialVersionUID = 1L; + + private final Type type; + + TypeHolderExpression(final Type type) { + super(0L, 0, 0); + this.type = type; + } + + @Override + public Node accept(final NodeVisitor visitor) { + throw new AssertionError(); + } + + @Override + public Type getType() { + return type; + } + + @Override + public void toString(final StringBuilder sb, final boolean printType) { + throw new AssertionError(); } } @@ -359,6 +399,8 @@ // allocates a new map. Immutability of maps allows for cheap snapshots by just keeping the reference to the current // value. private Map localVariableTypes = new IdentityHashMap<>(); + // Stack for evaluated expression types. + private final Deque typeStack = new ArrayDeque<>(); // Whether the current point in the AST is reachable code private boolean reachable = true; @@ -375,8 +417,6 @@ private final Map identifierLvarTypes = new IdentityHashMap<>(); private final Map symbolConversions = new IdentityHashMap<>(); - private SymbolToType symbolToType = new SymbolToType(); - // Stack of open labels for starts of catch blocks, one for every currently traversed try block; for inserting // control flow edges to them. Note that we currently don't insert actual control flow edges, but instead edges that // help us with type calculations. This means that some operations that can result in an exception being thrown @@ -400,62 +440,56 @@ private void doesNotContinueSequentially() { reachable = false; localVariableTypes = Collections.emptyMap(); + assertTypeStackIsEmpty(); } + private boolean pushExpressionType(final Expression expr) { + typeStack.push(toLvarType(expr.getType())); + return false; + } + + @Override + public boolean enterAccessNode(final AccessNode accessNode) { + visitExpression(accessNode.getBase()); + return pushExpressionType(accessNode); + } @Override public boolean enterBinaryNode(final BinaryNode binaryNode) { // NOTE: regardless of operator's lexical associativity, lhs is always evaluated first. final Expression lhs = binaryNode.lhs(); - final boolean isAssignment = binaryNode.isAssignment(); - LvarType lhsTypeOnLoad = null; - if(isAssignment) { - if(lhs instanceof BaseNode) { - ((BaseNode)lhs).getBase().accept(this); - if(lhs instanceof IndexNode) { - ((IndexNode)lhs).getIndex().accept(this); - } else { - assert lhs instanceof AccessNode; - } - } else { - assert lhs instanceof IdentNode; - if(binaryNode.isSelfModifying()) { - final IdentNode ident = ((IdentNode)lhs); - ident.accept(this); - // Self-assignment can cause a change in the type of the variable. For purposes of evaluating - // the type of the operation, we must use its type as it was when it was loaded. If we didn't - // do this, some awkward expressions would end up being calculated incorrectly, e.g. - // "var x; x += x = 0;". In this case we have undefined+int so the result type is double (NaN). - // However, if we used the type of "x" on LHS after we evaluated RHS, we'd see int+int, so the - // result type would be either optimistic int or pessimistic long, which would be wrong. - lhsTypeOnLoad = getLocalVariableTypeIfBytecode(ident.getSymbol()); - } - } + final LvarType lhsType; + if (!(lhs instanceof IdentNode && binaryNode.tokenType() == TokenType.ASSIGN)) { + lhsType = visitExpression(lhs); } else { - lhs.accept(this); + // Can't visit IdentNode on LHS of a simple assignment, as visits imply use, and this is def. + // The type is irrelevant, as only RHS is used to determine the type anyway. + lhsType = LvarType.UNDEFINED; } final boolean isLogical = binaryNode.isLogical(); - assert !(isAssignment && isLogical); // there are no logical assignment operators in JS final Label joinLabel = isLogical ? new Label("") : null; if(isLogical) { jumpToLabel((JoinPredecessor)lhs, joinLabel); } final Expression rhs = binaryNode.rhs(); - rhs.accept(this); + final LvarType rhsType = visitExpression(rhs); if(isLogical) { jumpToLabel((JoinPredecessor)rhs, joinLabel); } joinOnLabel(joinLabel); - if(isAssignment && lhs instanceof IdentNode) { + final LvarType type = toLvarType(binaryNode.setOperands(lhsType.typeExpression, rhsType.typeExpression).getType()); + + if(binaryNode.isAssignment() && lhs instanceof IdentNode) { if(binaryNode.isSelfModifying()) { - onSelfAssignment((IdentNode)lhs, binaryNode, lhsTypeOnLoad); + onSelfAssignment((IdentNode)lhs, type); } else { - onAssignment((IdentNode)lhs, rhs); + onAssignment((IdentNode)lhs, type); } } + typeStack.push(type); return false; } @@ -475,6 +509,17 @@ } @Override + public boolean enterCallNode(final CallNode callNode) { + visitExpression(callNode.getFunction()); + visitExpressions(callNode.getArgs()); + final CallNode.EvalArgs evalArgs = callNode.getEvalArgs(); + if (evalArgs != null) { + visitExpressions(evalArgs.getArgs()); + } + return pushExpressionType(callNode); + } + + @Override public boolean enterContinueNode(final ContinueNode continueNode) { return enterJumpStatement(continueNode); } @@ -483,6 +528,7 @@ if(!reachable) { return false; } + assertTypeStackIsEmpty(); final BreakableNode target = jump.getTarget(lc); jumpToLabel(jump, jump.getTargetLabel(target), getBreakTargetTypes(target)); doesNotContinueSequentially(); @@ -495,6 +541,7 @@ } private void enterDoWhileLoop(final WhileNode loopNode) { + assertTypeStackIsEmpty(); final JoinPredecessorExpression test = loopNode.getTest(); final Block body = loopNode.getBody(); final Label continueLabel = loopNode.getContinueLabel(); @@ -512,7 +559,7 @@ if(!reachable) { break; } - test.accept(this); + visitExpressionOnEmptyStack(test); jumpToLabel(test, breakLabel); if(isAlwaysFalse(test)) { break; @@ -535,6 +582,45 @@ } @Override + public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) { + if (reachable) { + visitExpressionOnEmptyStack(expressionStatement.getExpression()); + } + return false; + } + + private void assertTypeStackIsEmpty() { + assert typeStack.isEmpty(); + } + + @Override + protected Node leaveDefault(final Node node) { + assert !(node instanceof Expression); // All expressions were handled + assert !(node instanceof Statement) || typeStack.isEmpty(); // No statements leave with a non-empty stack + return node; + } + + private LvarType visitExpressionOnEmptyStack(final Expression expr) { + assertTypeStackIsEmpty(); + return visitExpression(expr); + } + + private LvarType visitExpression(final Expression expr) { + final int stackSize = typeStack.size(); + expr.accept(this); + assert typeStack.size() == stackSize + 1; + return typeStack.pop(); + } + + private void visitExpressions(final List exprs) { + for(final Expression expr: exprs) { + if (expr != null) { + visitExpression(expr); + } + } + } + + @Override public boolean enterForNode(final ForNode forNode) { if(!reachable) { return false; @@ -543,7 +629,7 @@ final Expression init = forNode.getInit(); if(forNode.isForIn()) { final JoinPredecessorExpression iterable = forNode.getModify(); - iterable.accept(this); + visitExpression(iterable); enterTestFirstLoop(forNode, null, init, // If we're iterating over property names, and we can discern from the runtime environment // of the compilation that the object being iterated over must use strings for property @@ -552,16 +638,18 @@ !compiler.useOptimisticTypes() || (!forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression()))); } else { if(init != null) { - init.accept(this); + visitExpressionOnEmptyStack(init); } enterTestFirstLoop(forNode, forNode.getModify(), null, false); } + assertTypeStackIsEmpty(); return false; } @Override public boolean enterFunctionNode(final FunctionNode functionNode) { if(alreadyEnteredTopLevelFunction) { + typeStack.push(LvarType.OBJECT); return false; } int pos = 0; @@ -603,11 +691,20 @@ } @Override + public boolean enterGetSplitState(final GetSplitState getSplitState) { + return pushExpressionType(getSplitState); + } + + @Override public boolean enterIdentNode(final IdentNode identNode) { final Symbol symbol = identNode.getSymbol(); if(symbol.isBytecodeLocal()) { symbolIsUsed(symbol); - setIdentifierLvarType(identNode, getLocalVariableType(symbol)); + final LvarType type = getLocalVariableType(symbol); + setIdentifierLvarType(identNode, type); + typeStack.push(type); + } else { + pushExpressionType(identNode); } return false; } @@ -622,11 +719,12 @@ final Block pass = ifNode.getPass(); final Block fail = ifNode.getFail(); - test.accept(this); + visitExpressionOnEmptyStack(test); final Map afterTestLvarTypes = localVariableTypes; if(!isAlwaysFalse(test)) { pass.accept(this); + assertTypeStackIsEmpty(); } final Map passLvarTypes = localVariableTypes; final boolean reachableFromPass = reachable; @@ -635,6 +733,7 @@ localVariableTypes = afterTestLvarTypes; if(!isAlwaysTrue(test) && fail != null) { fail.accept(this); + assertTypeStackIsEmpty(); final boolean reachableFromFail = reachable; reachable |= reachableFromPass; if(!reachable) { @@ -667,15 +766,54 @@ } @Override - public boolean enterPropertyNode(final PropertyNode propertyNode) { - // Avoid falsely adding property keys to the control flow graph - if(propertyNode.getValue() != null) { - propertyNode.getValue().accept(this); + public boolean enterIndexNode(final IndexNode indexNode) { + visitExpression(indexNode.getBase()); + visitExpression(indexNode.getIndex()); + return pushExpressionType(indexNode); + } + + @Override + public boolean enterJoinPredecessorExpression(final JoinPredecessorExpression joinExpr) { + final Expression expr = joinExpr.getExpression(); + if (expr != null) { + expr.accept(this); + } else { + typeStack.push(LvarType.UNDEFINED); } return false; } @Override + public boolean enterLiteralNode(final LiteralNode literalNode) { + if (literalNode instanceof ArrayLiteralNode) { + final List expressions = ((ArrayLiteralNode)literalNode).getElementExpressions(); + if (expressions != null) { + visitExpressions(expressions); + } + } + pushExpressionType(literalNode); + return false; + } + + @Override + public boolean enterObjectNode(final ObjectNode objectNode) { + for(final PropertyNode propertyNode: objectNode.getElements()) { + // Avoid falsely adding property keys to the control flow graph + final Expression value = propertyNode.getValue(); + if (value != null) { + visitExpression(value); + } + } + return pushExpressionType(objectNode); + } + + @Override + public boolean enterPropertyNode(final PropertyNode propertyNode) { + // Property nodes are only accessible through object literals, and we handled that case above + throw new AssertionError(); + } + + @Override public boolean enterReturnNode(final ReturnNode returnNode) { if(!reachable) { return false; @@ -684,9 +822,9 @@ final Expression returnExpr = returnNode.getExpression(); final Type returnExprType; if(returnExpr != null) { - returnExpr.accept(this); - returnExprType = getType(returnExpr); + returnExprType = visitExpressionOnEmptyStack(returnExpr).type; } else { + assertTypeStackIsEmpty(); returnExprType = Type.UNDEFINED; } returnType = Type.widestReturnType(returnType, returnExprType); @@ -695,6 +833,12 @@ } @Override + public boolean enterRuntimeNode(final RuntimeNode runtimeNode) { + visitExpressions(runtimeNode.getArgs()); + return pushExpressionType(runtimeNode); + } + + @Override public boolean enterSplitReturn(final SplitReturn splitReturn) { doesNotContinueSequentially(); return false; @@ -706,8 +850,7 @@ return false; } - final Expression expr = switchNode.getExpression(); - expr.accept(this); + visitExpressionOnEmptyStack(switchNode.getExpression()); final List cases = switchNode.getCases(); if(cases.isEmpty()) { @@ -724,7 +867,7 @@ for(final CaseNode caseNode: cases) { final Expression test = caseNode.getTest(); if(!isInteger && test != null) { - test.accept(this); + visitExpressionOnEmptyStack(test); if(!tagUsed) { symbolIsUsed(switchNode.getTag(), LvarType.OBJECT); tagUsed = true; @@ -769,29 +912,42 @@ final Expression trueExpr = ternaryNode.getTrueExpression(); final Expression falseExpr = ternaryNode.getFalseExpression(); - test.accept(this); + visitExpression(test); final Map testExitLvarTypes = localVariableTypes; + final LvarType trueType; if(!isAlwaysFalse(test)) { - trueExpr.accept(this); + trueType = visitExpression(trueExpr); + } else { + trueType = null; } final Map trueExitLvarTypes = localVariableTypes; localVariableTypes = testExitLvarTypes; + final LvarType falseType; if(!isAlwaysTrue(test)) { - falseExpr.accept(this); + falseType = visitExpression(falseExpr); + } else { + falseType = null; } final Map falseExitLvarTypes = localVariableTypes; localVariableTypes = getUnionTypes(trueExitLvarTypes, falseExitLvarTypes); setConversion((JoinPredecessor)trueExpr, trueExitLvarTypes, localVariableTypes); setConversion((JoinPredecessor)falseExpr, falseExitLvarTypes, localVariableTypes); + + typeStack.push(trueType != null ? falseType != null ? widestLvarType(trueType, falseType) : trueType : assertNotNull(falseType)); return false; } + private static T assertNotNull(final T t) { + assert t != null; + return t; + } + private void enterTestFirstLoop(final LoopNode loopNode, final JoinPredecessorExpression modify, final Expression iteratorValues, final boolean iteratorValuesAreObject) { final JoinPredecessorExpression test = loopNode.getTest(); if(isAlwaysFalse(test)) { - test.accept(this); + visitExpressionOnEmptyStack(test); return; } @@ -804,7 +960,7 @@ jumpToLabel(loopNode, repeatLabel, beforeLoopTypes); final Map beforeRepeatTypes = localVariableTypes; if(test != null) { - test.accept(this); + visitExpressionOnEmptyStack(test); } if(!isAlwaysTrue(test)) { jumpToLabel(test, breakLabel); @@ -827,7 +983,7 @@ break; } if(modify != null) { - modify.accept(this); + visitExpressionOnEmptyStack(modify); jumpToLabel(modify, repeatLabel); joinOnLabel(repeatLabel); } @@ -853,7 +1009,7 @@ return false; } - throwNode.getExpression().accept(this); + visitExpressionOnEmptyStack(throwNode.getExpression()); jumpToCatchBlock(throwNode); doesNotContinueSequentially(); return false; @@ -892,7 +1048,7 @@ onAssignment(exception, LvarType.OBJECT); final Expression condition = catchNode.getExceptionCondition(); if(condition != null) { - condition.accept(this); + visitExpression(condition); } final Map afterConditionTypes = localVariableTypes; final Block catchBody = catchNode.getBody(); @@ -927,14 +1083,11 @@ @Override public boolean enterUnaryNode(final UnaryNode unaryNode) { final Expression expr = unaryNode.getExpression(); - expr.accept(this); - - if(unaryNode.isSelfModifying()) { - if(expr instanceof IdentNode) { - final IdentNode ident = (IdentNode)expr; - onSelfAssignment(ident, unaryNode, getLocalVariableTypeIfBytecode(ident.getSymbol())); - } + final LvarType unaryType = toLvarType(unaryNode.setExpression(visitExpression(expr).typeExpression).getType()); + if(unaryNode.isSelfModifying() && expr instanceof IdentNode) { + onSelfAssignment((IdentNode)expr, unaryType); } + typeStack.push(unaryType); return false; } @@ -945,8 +1098,7 @@ } final Expression init = varNode.getInit(); if(init != null) { - init.accept(this); - onAssignment(varNode.getName(), init); + onAssignment(varNode.getName(), visitExpression(init)); } return false; } @@ -964,6 +1116,15 @@ return false; } + @Override + public boolean enterWithNode(final WithNode withNode) { + if (reachable) { + visitExpression(withNode.getExpression()); + withNode.getBody().accept(this); + } + return false; + }; + private Map getBreakTargetTypes(final BreakableNode target) { // Remove symbols defined in the the blocks that are being broken out of. Map types = localVariableTypes; @@ -1002,18 +1163,6 @@ } /** - * Gets the type for a local variable if it is a bytecode local, otherwise null. Can be used in circumstances where - * the type is irrelevant if the symbol is not a bytecode local. Note that for bytecode locals, it delegates to - * {@link #getLocalVariableType(Symbol)}, so it will still assert that the type for such variable is already - * defined (that is, not null). - * @param symbol the symbol representing the variable. - * @return the current variable type, if it is a bytecode local, otherwise null. - */ - private LvarType getLocalVariableTypeIfBytecode(final Symbol symbol) { - return symbol.isBytecodeLocal() ? getLocalVariableType(symbol) : null; - } - - /** * Gets the type for a variable represented by a symbol, or null if the type is not know. This is the least strict * of all local variable type getters, and as such its use is discouraged except in initialization scenarios (where * a just-defined symbol might still be null). @@ -1154,6 +1303,7 @@ */ private void leaveBreakable(final BreakableNode breakable) { joinOnLabel(breakable.getBreakLabel()); + assertTypeStackIsEmpty(); } @Override @@ -1329,10 +1479,6 @@ return conv == null || !conv.isLive(); } - private void onAssignment(final IdentNode identNode, final Expression rhs) { - onAssignment(identNode, toLvarType(getType(rhs))); - } - private void onAssignment(final IdentNode identNode, final LvarType type) { final Symbol symbol = identNode.getSymbol(); assert symbol != null : identNode.getName(); @@ -1400,13 +1546,12 @@ jumpToCatchBlock(identNode); } - private void onSelfAssignment(final IdentNode identNode, final Expression assignment, final LvarType typeOnLoad) { + private void onSelfAssignment(final IdentNode identNode, final LvarType type) { final Symbol symbol = identNode.getSymbol(); assert symbol != null : identNode.getName(); if(!symbol.isBytecodeLocal()) { return; } - final LvarType type = toLvarType(getType(assignment, symbol, typeOnLoad.type)); // Self-assignment never produce either a boolean or undefined assert type != null && type != LvarType.UNDEFINED && type != LvarType.BOOLEAN; setType(symbol, type); @@ -1466,7 +1611,6 @@ * @param symbol the symbol representing the variable * @param type the type */ - @SuppressWarnings("unused") private void setType(final Symbol symbol, final LvarType type) { if(getLocalVariableTypeOrNull(symbol) == type) { return; @@ -1486,77 +1630,4 @@ private void symbolIsUsed(final Symbol symbol) { symbolIsUsed(symbol, getLocalVariableType(symbol)); } - - /** - * Gets the type of the expression, dependent on the current types of the local variables. - * - * @param expr the expression - * @return the current type of the expression dependent on the current types of the local variables. - */ - private Type getType(final Expression expr) { - return expr.getType(getSymbolToType()); - } - - /** - * Returns a function object from symbols to their types, used by the expressions to evaluate their type. - * {@link BinaryNode} specifically uses identity of the function to cache type calculations. This method makes - * sure to return the same function object while the local variable types don't change, and create a new function - * object if the local variable types have been changed. - * @return a function object representing a mapping from symbols to their types. - */ - private Function getSymbolToType() { - if(symbolToType.isStale()) { - symbolToType = new SymbolToType(); - } - return symbolToType; - } - - private class SymbolToType implements Function { - private final Object boundTypes = localVariableTypes; - @Override - public Type apply(final Symbol t) { - return getLocalVariableType(t).type; - } - - boolean isStale() { - return boundTypes != localVariableTypes; - } - } - - /** - * Gets the type of the expression, dependent on the current types of the local variables and a single overridden - * symbol type. Used by type calculation on compound operators to ensure the type of the LHS at the time it was - * loaded (which can potentially be different after RHS evaluation, e.g. "var x; x += x = 0;") is preserved for - * the calculation. - * - * @param expr the expression - * @param overriddenSymbol the overridden symbol - * @param overriddenType the overridden type - * @return the current type of the expression dependent on the current types of the local variables and the single - * potentially overridden type. - */ - private Type getType(final Expression expr, final Symbol overriddenSymbol, final Type overriddenType) { - return expr.getType(getSymbolToType(overriddenSymbol, overriddenType)); - } - - private Function getSymbolToType(final Symbol overriddenSymbol, final Type overriddenType) { - return getLocalVariableType(overriddenSymbol).type == overriddenType ? getSymbolToType() : - new SymbolToTypeOverride(overriddenSymbol, overriddenType); - } - - private class SymbolToTypeOverride implements Function { - private final Function originalSymbolToType = getSymbolToType(); - private final Symbol overriddenSymbol; - private final Type overriddenType; - - SymbolToTypeOverride(final Symbol overriddenSymbol, final Type overriddenType) { - this.overriddenSymbol = overriddenSymbol; - this.overriddenType = overriddenType; - } - - @Override - public Type apply(final Symbol symbol) { - return symbol == overriddenSymbol ? overriddenType : originalSymbolToType.apply(symbol); - } - } } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java Sat Jan 10 12:38:18 2015 -0800 @@ -67,7 +67,7 @@ import jdk.nashorn.internal.runtime.options.Options; /** - * Static utility that encapsulates persistence of type information for functions compiled with optimistic + *

Static utility that encapsulates persistence of type information for functions compiled with optimistic * typing. With this feature enabled, when a JavaScript function is recompiled because it gets deoptimized, * the type information for deoptimization is stored in a cache file. If the same function is compiled in a * subsequent JVM invocation, the type information is used for initial compilation, thus allowing the system @@ -83,6 +83,7 @@ * {@code nashorn.typeInfo.cleanupDelaySeconds} system property. You can also specify the word * {@code unlimited} as the value for {@code nashorn.typeInfo.maxFiles} in which case the type info cache is * allowed to grow without limits. + *

*/ public final class OptimisticTypesPersistence { // Default is 0, for disabling the feature when not specified. A reasonable default when enabled is diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BaseNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BaseNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BaseNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,6 @@ import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -98,7 +97,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return type == null ? getMostPessimisticType() : type; } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/BinaryNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -31,7 +31,6 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -57,9 +56,7 @@ private final int programPoint; private final Type type; - private transient Type cachedType; - private transient Object cachedTypeFunction; @Ignore private static final Set CAN_OVERFLOW = @@ -143,24 +140,6 @@ } } - private static final Function UNKNOWN_LOCALS = new Function() { - @Override - public Type apply(final Symbol t) { - return null; - } - }; - - /** - * Return the widest possible type for this operation. This is used for compile time - * static type inference - * - * @return Type - */ - @Override - public Type getWidestOperationType() { - return getWidestOperationType(UNKNOWN_LOCALS); - } - /** * Return the widest possible operand type for this operation. * @@ -181,14 +160,15 @@ } } - private Type getWidestOperationType(final Function localVariableTypes) { + @Override + public Type getWidestOperationType() { switch (tokenType()) { case ADD: case ASSIGN_ADD: { // Compare this logic to decideType(Type, Type); it's similar, but it handles the optimistic type // calculation case while this handles the conservative case. - final Type lhsType = lhs.getType(localVariableTypes); - final Type rhsType = rhs.getType(localVariableTypes); + final Type lhsType = lhs.getType(); + final Type rhsType = rhs.getType(); if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) { // Will always fit in an int, as the value range is [0, 1, 2]. If we didn't treat them specially here, // they'd end up being treated as generic INT operands and their sum would be conservatively considered @@ -238,8 +218,8 @@ case SUB: case ASSIGN_MUL: case ASSIGN_SUB: { - final Type lhsType = lhs.getType(localVariableTypes); - final Type rhsType = rhs.getType(localVariableTypes); + final Type lhsType = lhs.getType(); + final Type rhsType = rhs.getType(); if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) { return Type.INT; } @@ -253,20 +233,20 @@ return Type.UNDEFINED; } case ASSIGN: { - return rhs.getType(localVariableTypes); + return rhs.getType(); } case INSTANCEOF: { return Type.BOOLEAN; } case COMMALEFT: { - return lhs.getType(localVariableTypes); + return lhs.getType(); } case COMMARIGHT: { - return rhs.getType(localVariableTypes); + return rhs.getType(); } case AND: case OR:{ - return Type.widestReturnType(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes)); + return Type.widestReturnType(lhs.getType(), rhs.getType()); } default: if (isComparison()) { @@ -487,7 +467,7 @@ /** * Set the right hand side expression for this node - * @param rhs new left hand side expression + * @param rhs new right hand side expression * @return a node equivalent to this one except for the requested change. */ public BinaryNode setRHS(final Expression rhs) { @@ -497,6 +477,19 @@ return new BinaryNode(this, lhs, rhs, type, programPoint); } + /** + * Set both the left and the right hand side expression for this node + * @param lhs new left hand side expression + * @param rhs new left hand side expression + * @return a node equivalent to this one except for the requested change. + */ + public BinaryNode setOperands(final Expression lhs, final Expression rhs) { + if (this.lhs == lhs && this.rhs == rhs) { + return this; + } + return new BinaryNode(this, lhs, rhs, type, programPoint); + } + @Override public int getProgramPoint() { return programPoint; @@ -541,24 +534,22 @@ } @Override - public Type getType(final Function localVariableTypes) { - if(localVariableTypes == cachedTypeFunction) { - return cachedType; + public Type getType() { + if (cachedType == null) { + cachedType = getTypeUncached(); } - cachedType = getTypeUncached(localVariableTypes); - cachedTypeFunction = localVariableTypes; return cachedType; } - private Type getTypeUncached(final Function localVariableTypes) { + private Type getTypeUncached() { if(type == OPTIMISTIC_UNDECIDED_TYPE) { - return decideType(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes)); + return decideType(lhs.getType(), rhs.getType()); } - final Type widest = getWidestOperationType(localVariableTypes); + final Type widest = getWidestOperationType(); if(type == null) { return widest; } - return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(localVariableTypes), rhs.getType(localVariableTypes)))); + return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(), rhs.getType()))); } private static Type decideType(final Type lhsType, final Type rhsType) { diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/CallNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/CallNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/CallNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -30,7 +30,6 @@ import java.io.Serializable; import java.util.Collections; import java.util.List; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -154,7 +153,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return optimisticType == null ? Type.OBJECT : optimisticType; } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Expression.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Expression.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/Expression.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,6 @@ package jdk.nashorn.internal.ir; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; @@ -39,14 +38,7 @@ static final String OPT_IDENTIFIER = "%"; - private static final Function UNKNOWN_LOCALS = new Function() { - @Override - public Type apply(final Symbol t) { - return null; - } - }; - - Expression(final long token, final int start, final int finish) { + protected Expression(final long token, final int start, final int finish) { super(token, start, finish); } @@ -63,18 +55,7 @@ * * @return the type of the expression. */ - public final Type getType() { - return getType(UNKNOWN_LOCALS); - } - - /** - * Returns the type of the expression under the specified symbol-to-type mapping. By default delegates to - * {@link #getType()} but expressions whose type depends on their subexpressions' types and expressions whose type - * depends on symbol type ({@link IdentNode}) will have a special implementation. - * @param localVariableTypes a mapping from symbols to their types, used for type calculation. - * @return the type of the expression under the specified symbol-to-type mapping. - */ - public abstract Type getType(final Function localVariableTypes); + public abstract Type getType(); /** * Returns {@code true} if this expression depends exclusively on state that is constant diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/FunctionNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -36,7 +36,6 @@ import java.util.EnumSet; import java.util.Iterator; import java.util.List; -import java.util.function.Function; import jdk.nashorn.internal.AssertsEnabled; import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.Compiler; @@ -1101,7 +1100,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return FUNCTION_TYPE; } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/GetSplitState.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/GetSplitState.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/GetSplitState.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,6 @@ package jdk.nashorn.internal.ir; -import java.util.function.Function; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -47,7 +46,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.INT; } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/IdentNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -30,7 +30,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.__LINE__; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -118,14 +117,13 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { if(type != null) { return type; } else if(symbol != null && symbol.isScope()) { return Type.OBJECT; } - final Type symbolType = localVariableTypes.apply(symbol); - return symbolType == null ? Type.UNDEFINED : symbolType; + return Type.UNDEFINED; } /** diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/JoinPredecessorExpression.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/JoinPredecessorExpression.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/JoinPredecessorExpression.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,6 @@ package jdk.nashorn.internal.ir; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -71,8 +70,8 @@ } @Override - public Type getType(final Function localVariableTypes) { - return expression.getType(localVariableTypes); + public Type getType() { + return expression.getType(); } @Override diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/LiteralNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -29,7 +29,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.function.Function; import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.types.ArrayType; import jdk.nashorn.internal.codegen.types.Type; @@ -109,7 +108,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.typeFor(value.getClass()); } @@ -164,16 +163,6 @@ } /** - * Get the array value of the node - * - * @return the array value - */ - public Node[] getArray() { - assert false : "not an array node"; - return null; - } - - /** * Fetch String value of node. * * @return String value of node. @@ -325,7 +314,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.BOOLEAN; } @@ -389,7 +378,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return type; } @@ -519,7 +508,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.OBJECT; } @@ -589,7 +578,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.OBJECT; } @@ -840,9 +829,13 @@ this.units = units; } - @Override - public Node[] getArray() { - return value; + /** + * Returns a list of array element expressions. Note that empty array elements manifest themselves as + * null. + * @return a list of array element expressions. + */ + public List getElementExpressions() { + return Collections.unmodifiableList(Arrays.asList(value)); } /** @@ -879,7 +872,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.typeFor(NativeArray.class); } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ObjectNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ObjectNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/ObjectNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -27,7 +27,6 @@ import java.util.Collections; import java.util.List; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -69,7 +68,7 @@ } @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return Type.OBJECT; } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/RuntimeNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/RuntimeNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/RuntimeNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -30,7 +30,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -460,7 +459,7 @@ * Return type for the ReferenceNode */ @Override - public Type getType(final Function localVariableTypes) { + public Type getType() { return request.getReturnType(); } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/TernaryNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/TernaryNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/TernaryNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -25,7 +25,6 @@ package jdk.nashorn.internal.ir; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; @@ -122,8 +121,8 @@ } @Override - public Type getType(final Function localVariableTypes) { - return Type.widestReturnType(getTrueExpression().getType(localVariableTypes), getFalseExpression().getType(localVariableTypes)); + public Type getType() { + return Type.widestReturnType(getTrueExpression().getType(), getFalseExpression().getType()); } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/UnaryNode.java Sat Jan 10 12:38:18 2015 -0800 @@ -33,7 +33,6 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.function.Function; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Ignore; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -123,23 +122,11 @@ return isAssignment(); } - private static final Function UNKNOWN_LOCALS = new Function() { - @Override - public Type apply(final Symbol t) { - return null; - } - }; - - @Override public Type getWidestOperationType() { - return getWidestOperationType(UNKNOWN_LOCALS); - } - - private Type getWidestOperationType(final Function localVariableTypes) { switch (tokenType()) { case ADD: - final Type operandType = getExpression().getType(localVariableTypes); + final Type operandType = getExpression().getType(); if(operandType == Type.BOOLEAN) { return Type.INT; } else if(operandType.isObject()) { @@ -326,12 +313,12 @@ } @Override - public Type getType(final Function localVariableTypes) { - final Type widest = getWidestOperationType(localVariableTypes); + public Type getType() { + final Type widest = getWidestOperationType(); if(type == null) { return widest; } - return Type.narrowest(widest, Type.widest(type, expression.getType(localVariableTypes))); + return Type.narrowest(widest, Type.widest(type, expression.getType())); } @Override diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/JSONWriter.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/JSONWriter.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/ir/debug/JSONWriter.java Sat Jan 10 12:38:18 2015 -0800 @@ -28,7 +28,6 @@ import static jdk.nashorn.internal.runtime.Source.sourceFor; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BinaryNode; @@ -553,8 +552,7 @@ type("ArrayExpression"); comma(); - final Node[] value = literalNode.getArray(); - array("elements", Arrays.asList(value)); + array("elements", ((LiteralNode.ArrayLiteralNode)literalNode).getElementExpressions()); } else { type("Literal"); comma(); diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Sat Jan 10 12:38:18 2015 -0800 @@ -275,7 +275,7 @@ final PropertyDescriptor newLenDesc = desc; // Step 3c and 3d - get new length and convert to long - final long newLen = NativeArray.validLength(newLenDesc.getValue(), true); + final long newLen = NativeArray.validLength(newLenDesc.getValue()); // Step 3e newLenDesc.setValue(newLen); @@ -348,8 +348,8 @@ final PropertyDescriptor oldLenDesc = (PropertyDescriptor) super.getOwnPropertyDescriptor("length"); // Step 2 - // get old length and convert to long - final long oldLen = NativeArray.validLength(oldLenDesc.getValue(), true); + // get old length and convert to long. Always a Long/Uint32 but we take the safe road. + final long oldLen = JSType.toUint32(oldLenDesc.getValue()); // Step 3 if ("length".equals(key)) { @@ -471,7 +471,7 @@ @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) public static void length(final Object self, final Object length) { if (isArray(self)) { - ((ScriptObject)self).setLength(validLength(length, true)); + ((ScriptObject)self).setLength(validLength(length)); } } @@ -495,18 +495,13 @@ length(self, length); // Same as instance setter but we can't make nasgen use the same method for prototype } - static long validLength(final Object length, final boolean reject) { + static long validLength(final Object length) { + // ES5 15.4.5.1, steps 3.c and 3.d require two ToNumber conversions here final double doubleLength = JSType.toNumber(length); - if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) { - final long len = (long) doubleLength; - if (len >= 0 && len <= JSType.MAX_UINT) { - return len; - } - } - if (reject) { + if (doubleLength != JSType.toUint32(length)) { throw rangeError("inappropriate.array.length", ScriptRuntime.safeToString(length)); } - return -1; + return (long) doubleLength; } /** diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExpExecResult.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExpExecResult.java Sat Jan 10 12:38:18 2015 -0800 @@ -88,7 +88,7 @@ @Setter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) public static void length(final Object self, final Object length) { if (self instanceof ScriptObject) { - ((ScriptObject)self).setLength(NativeArray.validLength(length, true)); + ((ScriptObject)self).setLength(NativeArray.validLength(length)); } } } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CodeInstaller.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CodeInstaller.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/CodeInstaller.java Sat Jan 10 12:38:18 2015 -0800 @@ -86,7 +86,7 @@ * @param source the script source * @param mainClassName the main class name * @param classBytes map of class names to class bytes - * @param initializers compilation id -> FunctionInitializer map + * @param initializers compilation id -> FunctionInitializer map * @param constants constants array * @param compilationId compilation id */ diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java Sat Jan 10 12:38:18 2015 -0800 @@ -180,10 +180,10 @@ /** Div exact wrapper for potentially integer division that turns into float point */ public static final Call DIV_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class); - /** Div zero wrapper for long division that handles (0/0) >>> 0 == 0 */ + /** Div zero wrapper for long division that handles (0/0) >>> 0 == 0 */ public static final Call DIV_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class); - /** Mod zero wrapper for long division that handles (0%0) >>> 0 == 0 */ + /** Mod zero wrapper for long division that handles (0%0) >>> 0 == 0 */ public static final Call REM_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class); /** Mod exact wrapper for potentially integer remainders that turns into float point */ diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StoredScript.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StoredScript.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StoredScript.java Sat Jan 10 12:38:18 2015 -0800 @@ -58,7 +58,7 @@ * @param compilationId compilation id * @param mainClassName main class name * @param classBytes map of class names to class bytes - * @param initializers initializer map, id -> FunctionInitializer + * @param initializers initializer map, id -> FunctionInitializer * @param constants constants array */ public StoredScript(final int compilationId, final String mainClassName, final Map classBytes, final Map initializers, final Object[] constants) { diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java Sat Jan 10 12:38:18 2015 -0800 @@ -275,7 +275,7 @@ /** * Align an array size up to the nearest array chunk size * @param size size required - * @return size given, always >= size + * @return size given, always >= size */ protected final static int alignUp(final int size) { return size + CHUNK_SIZE - 1 & ~(CHUNK_SIZE - 1); diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BoundCallableLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BoundCallableLinker.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BoundCallableLinker.java Sat Jan 10 12:38:18 2015 -0800 @@ -99,7 +99,7 @@ MethodType newMethodType = descriptor.getMethodType().changeParameterType(0, callable.getClass()); if (isCall) { // R(callable.class, T1, ...) => R(callable.class, boundThis.class, ...) - newMethodType = newMethodType.changeParameterType(1, boundThis.getClass()); + newMethodType = newMethodType.changeParameterType(1, boundThis == null? Object.class : boundThis.getClass()); } // R(callable.class[, boundThis.class], T2, ...) => R(callable.class[, boundThis.class], boundArg0.class, ..., boundArgn.class, T2, ...) for(int i = boundArgs.length; i-- > 0;) { diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/BrowserJSObjectLinker.java Sat Jan 10 12:38:18 2015 -0800 @@ -40,6 +40,7 @@ import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.lookup.MethodHandleFunctionality; +import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.JSType; /** @@ -118,20 +119,21 @@ private GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request, final LinkerServices linkerServices) throws Exception { final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); final int c = desc.getNameTokenCount(); + GuardedInvocation inv; + try { + inv = nashornBeansLinker.getGuardedInvocation(request, linkerServices); + } catch (Throwable th) { + inv = null; + } switch (operator) { case "getProp": case "getElem": case "getMethod": - if (c > 2) { - return findGetMethod(desc); - } - // For indexed get, we want GuardedInvocation from beans linker and pass it. - // BrowserJSObjectLinker.get uses this fallback getter for explicit signature method access. - return findGetIndexMethod(nashornBeansLinker.getGuardedInvocation(request, linkerServices)); + return c > 2? findGetMethod(desc, inv) : findGetIndexMethod(inv); case "setProp": case "setElem": - return c > 2 ? findSetMethod(desc) : findSetIndexMethod(); + return c > 2? findSetMethod(desc, inv) : findSetIndexMethod(); case "call": return findCallMethod(desc); default: @@ -139,7 +141,10 @@ } } - private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) { + private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final GuardedInvocation inv) { + if (inv != null) { + return inv; + } final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, name); return new GuardedInvocation(getter, IS_JSOBJECT_GUARD); @@ -150,7 +155,10 @@ return inv.replaceMethods(getter, inv.getGuard()); } - private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) { + private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final GuardedInvocation inv) { + if (inv != null) { + return inv; + } final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, IS_JSOBJECT_GUARD); } @@ -178,12 +186,12 @@ if (index > -1) { return JSOBJECT_GETSLOT.invokeExact(jsobj, index); } - } else if (key instanceof String) { - final String name = (String)key; + } else if (key instanceof String || key instanceof ConsString) { + final String name = key.toString(); if (name.indexOf('(') != -1) { - return fallback.invokeExact(jsobj, key); + return fallback.invokeExact(jsobj, (Object) name); } - return JSOBJECT_GETMEMBER.invokeExact(jsobj, (String)key); + return JSOBJECT_GETMEMBER.invokeExact(jsobj, name); } return null; } @@ -194,8 +202,8 @@ JSOBJECT_SETSLOT.invokeExact(jsobj, (int)key, value); } else if (key instanceof Number) { JSOBJECT_SETSLOT.invokeExact(jsobj, getIndex((Number)key), value); - } else if (key instanceof String) { - JSOBJECT_SETMEMBER.invokeExact(jsobj, (String)key, value); + } else if (key instanceof String || key instanceof ConsString) { + JSOBJECT_SETMEMBER.invokeExact(jsobj, key.toString(), value); } } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java Sat Jan 10 12:38:18 2015 -0800 @@ -42,6 +42,7 @@ import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.lookup.MethodHandleFunctionality; +import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.JSType; /** @@ -185,11 +186,11 @@ if (index > -1) { return ((JSObject)jsobj).getSlot(index); } - } else if (key instanceof String) { - final String name = (String)key; + } else if (key instanceof String || key instanceof ConsString) { + final String name = key.toString(); // get with method name and signature. delegate it to beans linker! if (name.indexOf('(') != -1) { - return fallback.invokeExact(jsobj, key); + return fallback.invokeExact(jsobj, (Object) name); } return ((JSObject)jsobj).getMember(name); } @@ -202,8 +203,8 @@ ((JSObject)jsobj).setSlot((Integer)key, value); } else if (key instanceof Number) { ((JSObject)jsobj).setSlot(getIndex((Number)key), value); - } else if (key instanceof String) { - ((JSObject)jsobj).setMember((String)key, value); + } else if (key instanceof String || key instanceof ConsString) { + ((JSObject)jsobj).setMember(key.toString(), value); } } diff -r ad8137d44154 -r 247f60f5808f nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java Sat Jan 10 12:38:18 2015 -0800 @@ -26,17 +26,23 @@ package jdk.nashorn.internal.runtime.linker; import static jdk.nashorn.internal.lookup.Lookup.MH; +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; + import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.invoke.SwitchPoint; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; +import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.internal.dynalink.support.Guards; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.FindProperty; import jdk.nashorn.internal.runtime.GlobalConstants; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.UserAccessorProperty; /** @@ -46,6 +52,11 @@ */ public final class PrimitiveLookup { + /** Method handle to link setters on primitive base. See ES5 8.7.2. */ + private static final MethodHandle PRIMITIVE_SETTER = findOwnMH("primitiveSetter", + MH.type(void.class, ScriptObject.class, Object.class, Object.class, boolean.class, Object.class)); + + private PrimitiveLookup() { } @@ -87,40 +98,58 @@ final ScriptObject wrappedReceiver, final MethodHandle wrapFilter, final MethodHandle protoFilter) { final CallSiteDescriptor desc = request.getCallSiteDescriptor(); + final String name; + final FindProperty find; - //checks whether the property name is hard-coded in the call-site (i.e. a getProp vs a getElem, or setProp vs setElem) - //if it is we can make assumptions on the property: that if it is not defined on primitive wrapper itself it never will be. - //so in that case we can skip creation of primitive wrapper and start our search with the prototype. if (desc.getNameTokenCount() > 2) { - final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); - final FindProperty find = wrappedReceiver.findProperty(name, true); + name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); + find = wrappedReceiver.findProperty(name, true); + } else { + name = null; + find = null; + } - if (find == null) { - // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it. - return null; - } + final String firstOp = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); - final SwitchPoint sp = find.getProperty().getBuiltinSwitchPoint(); //can use this instead of proto filter - if (sp instanceof Context.BuiltinSwitchPoint && !sp.hasBeenInvalidated()) { - return new GuardedInvocation(GlobalConstants.staticConstantGetter(find.getObjectValue()), guard, sp, null); - } + switch (firstOp) { + case "getProp": + case "getElem": + case "getMethod": + //checks whether the property name is hard-coded in the call-site (i.e. a getProp vs a getElem, or setProp vs setElem) + //if it is we can make assumptions on the property: that if it is not defined on primitive wrapper itself it never will be. + //so in that case we can skip creation of primitive wrapper and start our search with the prototype. + if (name != null) { + if (find == null) { + // Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it. + return null; + } - if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { - // If property is found in the prototype object bind the method handle directly to - // the proto filter instead of going through wrapper instantiation below. - final ScriptObject proto = wrappedReceiver.getProto(); - final GuardedInvocation link = proto.lookup(desc, request); + final SwitchPoint sp = find.getProperty().getBuiltinSwitchPoint(); //can use this instead of proto filter + if (sp instanceof Context.BuiltinSwitchPoint && !sp.hasBeenInvalidated()) { + return new GuardedInvocation(GlobalConstants.staticConstantGetter(find.getObjectValue()), guard, sp, null); + } - if (link != null) { - final MethodHandle invocation = link.getInvocation(); //this contains the builtin switchpoint + if (find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { + // If property is found in the prototype object bind the method handle directly to + // the proto filter instead of going through wrapper instantiation below. + final ScriptObject proto = wrappedReceiver.getProto(); + final GuardedInvocation link = proto.lookup(desc, request); - final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class)); - final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter); - final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter); - - return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard)); + if (link != null) { + final MethodHandle invocation = link.getInvocation(); //this contains the builtin switchpoint + final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class)); + final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter); + final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter); + return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard)); + } } } + break; + case "setProp": + case "setElem": + return getPrimitiveSetter(name, guard, wrapFilter, NashornCallSiteDescriptor.isStrict(desc)); + default: + break; } final GuardedInvocation link = wrappedReceiver.lookup(desc, request); @@ -138,4 +167,41 @@ return null; } + + private static GuardedInvocation getPrimitiveSetter(final String name, final MethodHandle guard, + final MethodHandle wrapFilter, final boolean isStrict) { + MethodHandle filter = MH.asType(wrapFilter, wrapFilter.type().changeReturnType(ScriptObject.class)); + final MethodHandle target; + + if (name == null) { + filter = MH.dropArguments(filter, 1, Object.class, Object.class); + target = MH.insertArguments(PRIMITIVE_SETTER, 3, isStrict); + } else { + filter = MH.dropArguments(filter, 1, Object.class); + target = MH.insertArguments(PRIMITIVE_SETTER, 2, name, isStrict); + } + + return new GuardedInvocation(MH.foldArguments(target, filter), guard); + } + + + @SuppressWarnings("unused") + private static void primitiveSetter(final ScriptObject wrappedSelf, final Object self, final Object key, + final boolean strict, final Object value) { + // See ES5.1 8.7.2 PutValue (V, W) + final String name = JSType.toString(key); + final FindProperty find = wrappedSelf.findProperty(name, true); + if (find == null || !(find.getProperty() instanceof UserAccessorProperty) || !find.getProperty().isWritable()) { + if (strict) { + throw typeError("property.not.writable", name, ScriptRuntime.safeToString(self)); + } + return; + } + // property found and is a UserAccessorProperty + find.setValue(value, strict); + } + + private static MethodHandle findOwnMH(final String name, final MethodType type) { + return MH.findStatic(MethodHandles.lookup(), PrimitiveLookup.class, name, type); + } } diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8055762.js --- a/nashorn/test/script/basic/JDK-8055762.js Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/test/script/basic/JDK-8055762.js Sat Jan 10 12:38:18 2015 -0800 @@ -74,9 +74,12 @@ } }; + var a = "a"; print(obj["foo"]); + print(obj[a + "bc"]); print(obj[2]); obj.bar = 23; + obj[a + "bc"] = 23; obj[3] = 23; obj.func("hello"); } diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8055762.js.EXPECTED --- a/nashorn/test/script/basic/JDK-8055762.js.EXPECTED Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/test/script/basic/JDK-8055762.js.EXPECTED Sat Jan 10 12:38:18 2015 -0800 @@ -1,5 +1,7 @@ FOO +ABC 0 bar set to 23 +abc set to 23 [3] set to 23 func called with hello diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8066215.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8066215.js Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + */ + +/** + * JDK-8066215: Fuzzing bug: length valueOf bug + * + * @test + * @run + */ + +function defineLength(arr, length) { + Object.defineProperty(arr, "length", { + value: { + valueOf: function() { + print("value retrieved: " + length); + return length; + } + } + }); + print("done: " + arr.length + ", " + typeof arr.length); +} + +var a = []; +defineLength(a, 3); +defineLength(a, 6); +defineLength(a, 3); diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8066215.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8066215.js.EXPECTED Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,9 @@ +value retrieved: 3 +value retrieved: 3 +done: 3, number +value retrieved: 6 +value retrieved: 6 +done: 6, number +value retrieved: 3 +value retrieved: 3 +done: 3, number diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8066226.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8066226.js Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + */ + +/** + * + JDK-8066226: Fuzzing bug: parameter counts differ in TypeConverterFactory + * + * @test + * @run + */ + +Object.defineProperty(Object.prototype, "accessor", { + set: function(value) { + print("Setting accessor on " + this + " to " + value); + } +}); + +Object.defineProperty(Object.prototype, "getterOnly", { + get: function() { + return 1; + } +}); + +function set(o) { + print("set(" + o + ")"); + o.foo = 1; + o.constructor = 1; + o.accessor = 1; + o.getterOnly = 1; + print(); +} + +function setStrict(o) { + "use strict"; + print("setStrict(" + o + ")") + try { + o.foo = 1; + } catch (e) { + print(e); + } + try { + o.constructor = 1; + } catch (e) { + print(e); + } + try { + o.accessor = 1; + } catch (e) { + print(e); + } + try { + o.getterOnly = 1; + } catch (e) { + print(e); + } + print(); +} + +function setAttr(o, id) { + print("setAttr(" + o + ", " + id + ")") + o[id] = 1; + print(); +} + +function setAttrStrict(o, id) { + "use strict"; + print("setAttrStrict(" + o + ", " + id + ")") + try { + o[id] = 1; + } catch (e) { + print(e); + } + print(); +} + +set(1); +set("str"); +set(true); +set({}); +set([]); + +setStrict(1); +setStrict("str"); +setStrict(true); +setStrict({}); +setStrict([]); + +setAttr(1, "foo"); +setAttr(1, "constructor"); +setAttr(1, "accessor"); +setAttr(1, "getterOnly"); +setAttr("str", "foo"); +setAttr("str", "constructor"); +setAttr("str", "accessor"); +setAttr("str", "getterOnly"); +setAttr(true, "foo"); +setAttr(true, "constructor"); +setAttr(true, "accessor"); +setAttr(true, "getterOnly"); + +setAttrStrict(1, "foo"); +setAttrStrict(1, "constructor"); +setAttrStrict(1, "accessor"); +setAttrStrict(1, "getterOnly"); +setAttrStrict("str", "foo"); +setAttrStrict("str", "constructor"); +setAttrStrict("str", "accessor"); +setAttrStrict("str", "getterOnly"); +setAttrStrict(true, "foo"); +setAttrStrict(true, "constructor"); +setAttrStrict(true, "accessor"); +setAttrStrict(true, "getterOnly"); diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8066226.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8066226.js.EXPECTED Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,104 @@ +set(1) +Setting accessor on 1 to 1 + +set(str) +Setting accessor on str to 1 + +set(true) +Setting accessor on true to 1 + +set([object Object]) +Setting accessor on [object Object] to 1 + +set() +Setting accessor on to 1 + +setStrict(1) +TypeError: "foo" is not a writable property of 1 +TypeError: "constructor" is not a writable property of 1 +Setting accessor on 1 to 1 +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + +setStrict(str) +TypeError: "foo" is not a writable property of str +TypeError: "constructor" is not a writable property of str +Setting accessor on str to 1 +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + +setStrict(true) +TypeError: "foo" is not a writable property of true +TypeError: "constructor" is not a writable property of true +Setting accessor on true to 1 +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + +setStrict([object Object]) +Setting accessor on [object Object] to 1 +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + +setStrict() +Setting accessor on to 1 +TypeError: Cannot set property "getterOnly" of [object Array] that has only a getter + +setAttr(1, foo) + +setAttr(1, constructor) + +setAttr(1, accessor) +Setting accessor on 1 to 1 + +setAttr(1, getterOnly) + +setAttr(str, foo) + +setAttr(str, constructor) + +setAttr(str, accessor) +Setting accessor on str to 1 + +setAttr(str, getterOnly) + +setAttr(true, foo) + +setAttr(true, constructor) + +setAttr(true, accessor) +Setting accessor on true to 1 + +setAttr(true, getterOnly) + +setAttrStrict(1, foo) +TypeError: "foo" is not a writable property of 1 + +setAttrStrict(1, constructor) +TypeError: "constructor" is not a writable property of 1 + +setAttrStrict(1, accessor) +Setting accessor on 1 to 1 + +setAttrStrict(1, getterOnly) +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + +setAttrStrict(str, foo) +TypeError: "foo" is not a writable property of str + +setAttrStrict(str, constructor) +TypeError: "constructor" is not a writable property of str + +setAttrStrict(str, accessor) +Setting accessor on str to 1 + +setAttrStrict(str, getterOnly) +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + +setAttrStrict(true, foo) +TypeError: "foo" is not a writable property of true + +setAttrStrict(true, constructor) +TypeError: "constructor" is not a writable property of true + +setAttrStrict(true, accessor) +Setting accessor on true to 1 + +setAttrStrict(true, getterOnly) +TypeError: Cannot set property "getterOnly" of [object Object] that has only a getter + diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8067774.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8067774.js Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + */ + +/** + * JDK-8067774: Use a stack of types when calculating local variable types + * + * @test + * @run + */ + +print((function (p) { + var a, b; + + a = p ? ((b = 1), b) : 0; + + return a; +})(true)); diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/basic/JDK-8067774.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/basic/JDK-8067774.js.EXPECTED Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,1 @@ +1 diff -r ad8137d44154 -r 247f60f5808f nashorn/test/script/trusted/JDK-8067854.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nashorn/test/script/trusted/JDK-8067854.js Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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. + */ + +/** + * JDK-8067854: bound java static method throws NPE when 'null' is used for this argument + * + * @test + * @run + */ + +getProp = java.lang.System.getProperty; + +// bind this and an argument. "null" for this as getProperty is a +// static method of java.lang.System +getHome = Function.prototype.bind.call(getProp, null, "java.home"); + +if (getHome() != getProp("java.home")) { + fail("getHome() failed to get java.home"); +} diff -r ad8137d44154 -r 247f60f5808f nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java --- a/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Thu Jan 08 10:44:54 2015 +0100 +++ b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Sat Jan 10 12:38:18 2015 -0800 @@ -109,6 +109,35 @@ } } + // @bug 8062030: Nashorn bug retrieving array property after key string concatenation + @Test + // ConsString attribute access on a JSObject + public void consStringTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + e.put("obj", obj); + e.put("f", "f"); + e.eval("obj[f + 'oo'] = 'bar';"); + + assertEquals(obj.getMap().get("foo"), "bar"); + assertEquals(e.eval("obj[f + 'oo']"), "bar"); + assertEquals(e.eval("obj['foo']"), "bar"); + assertEquals(e.eval("f + 'oo' in obj"), Boolean.TRUE); + assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); + e.eval("delete obj[f + 'oo']"); + assertFalse(obj.getMap().containsKey("foo")); + assertEquals(e.eval("obj[f + 'oo']"), null); + assertEquals(e.eval("obj['foo']"), null); + assertEquals(e.eval("f + 'oo' in obj"), Boolean.FALSE); + assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + public static class BufferObject extends AbstractJSObject { private final IntBuffer buf; diff -r ad8137d44154 -r 247f60f5808f test/Makefile --- a/test/Makefile Thu Jan 08 10:44:54 2015 +0100 +++ b/test/Makefile Sat Jan 10 12:38:18 2015 -0800 @@ -33,6 +33,7 @@ # This makefile depends on the availability of sibling directories. LANGTOOLS_DIR=$(TOPDIR)/langtools JDK_DIR=$(TOPDIR)/jdk +JAXP_DIR=$(TOPDIR)/jaxp HOTSPOT_DIR=$(TOPDIR)/hotspot # Macro to run a test target in a subdir @@ -51,10 +52,10 @@ endef # Default test target (core) -default: jdk_core langtools_jtreg +default: jdk_core langtools_jtreg jaxp_all # All testing -all: jdk_all langtools_all +all: jdk_all langtools_all jaxp_all # Test targets langtools_% : @@ -63,6 +64,9 @@ jdk_% core_%s svc_%: @$(NO_STOPPING)$(call SUBDIR_TEST, $(JDK_DIR), TEST="$@" $@) +jaxp_%: + @$(NO_STOPPING)$(call SUBDIR_TEST, $(JAXP_DIR), TEST="$@" $@) + hotspot_%: @$(NO_STOPPING)$(call SUBDIR_TEST, $(HOTSPOT_DIR), TEST="$@" $@) diff -r ad8137d44154 -r 247f60f5808f test/lib/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/Makefile Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,65 @@ +# +# Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# 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. +# + +# Utility Makefile that creates wb.jar, which is used to simplify using +# the Whitebox API outside the jtreg-testbase. + +ifneq "x$(ALT_BOOTDIR)" "x" + BOOTDIR := $(ALT_BOOTDIR) +endif + +ifeq "x$(BOOTDIR)" "x" + JDK_HOME := $(shell dirname $(shell which java))/.. +else + JDK_HOME := $(BOOTDIR) +endif + +SRC_DIR = ./ +BUILD_DIR = build +OUTPUT_DIR = $(BUILD_DIR)/classes + +JAVAC = $(JDK_HOME)/bin/javac +JAR = $(JDK_HOME)/bin/jar + +SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') + +.PHONY: filelist clean cleantmp + +all: wb.jar cleantmp + +wb.jar: filelist + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp $(OUTPUT_DIR) @filelist + $(JAR) cf wb.jar -C $(OUTPUT_DIR) . + @rm -rf $(OUTPUT_DIR) + +filelist: $(SRC_FILES) + @rm -f $@ + @echo $(SRC_FILES) > $@ + +clean: cleantmp + @rm -rf wb.jar + +cleantmp: + @rm -rf filelist + @rm -rf $(BUILD_DIR) diff -r ad8137d44154 -r 247f60f5808f test/lib/sun/hotspot/WhiteBox.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/sun/hotspot/WhiteBox.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.Executable; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Stream; +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(); + } + + // Get the maximum heap size supporting COOPs + public native long getCompressedOopsMaxHeapSize(); + // Arguments + public native void printHeapSizes(); + + // Memory + public native long getObjectAddress(Object o); + public native int getHeapOopSize(); + public native int getVMPageSize(); + public native boolean isObjectInOldGen(Object o); + public native long getObjectSize(Object o); + + // 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); + + // JVMTI + public native void addToBootstrapClassLoaderSearch(String segment); + public native void addToSystemClassLoaderSearch(String segment); + + // 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, char delim, DiagnosticCommand[] args); + + // NMT + public native long NMTMalloc(long size); + public native void NMTFree(long mem); + public native long NMTReserveMemory(long size); + public native void NMTCommitMemory(long addr, long size); + public native void NMTUncommitMemory(long addr, long size); + public native void NMTReleaseMemory(long addr, long size); + public native long NMTMallocWithPseudoStack(long size, int index); + public native boolean NMTIsDetailSupported(); + public native boolean NMTChangeTrackingLevel(); + public native int NMTGetHashSize(); + + // Compiler + public native int deoptimizeFrames(boolean makeNotEntrant); + public native void deoptimizeAll(); + public boolean isMethodCompiled(Executable method) { + return isMethodCompiled(method, false /*not osr*/); + } + public native boolean isMethodCompiled(Executable method, boolean isOsr); + public boolean isMethodCompilable(Executable method) { + return isMethodCompilable(method, -1 /*any*/); + } + public boolean isMethodCompilable(Executable method, int compLevel) { + return isMethodCompilable(method, compLevel, false /*not osr*/); + } + public native boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr); + public native boolean isMethodQueuedForCompilation(Executable method); + public int deoptimizeMethod(Executable method) { + return deoptimizeMethod(method, false /*not osr*/); + } + public native int deoptimizeMethod(Executable method, boolean isOsr); + public void makeMethodNotCompilable(Executable method) { + makeMethodNotCompilable(method, -1 /*any*/); + } + public void makeMethodNotCompilable(Executable method, int compLevel) { + makeMethodNotCompilable(method, compLevel, false /*not osr*/); + } + public native void makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr); + public int getMethodCompilationLevel(Executable method) { + return getMethodCompilationLevel(method, false /*not ost*/); + } + public native int getMethodCompilationLevel(Executable method, boolean isOsr); + public native boolean testSetDontInlineMethod(Executable method, boolean value); + public int getCompileQueuesSize() { + return getCompileQueueSize(-1 /*any*/); + } + public native int getCompileQueueSize(int compLevel); + public native boolean testSetForceInlineMethod(Executable method, boolean value); + public boolean enqueueMethodForCompilation(Executable method, int compLevel) { + return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/); + } + public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci); + public native void clearMethodState(Executable method); + public native void lockCompilation(); + public native void unlockCompilation(); + public native int getMethodEntryBci(Executable method); + public native Object[] getNMethod(Executable method, boolean isOsr); + public native long allocateCodeBlob(int size, int type); + public long allocateCodeBlob(long size, int type) { + int intSize = (int) size; + if ((long) intSize != size || size < 0) { + throw new IllegalArgumentException( + "size argument has illegal value " + size); + } + return allocateCodeBlob( intSize, type); + } + public native void freeCodeBlob(long addr); + public void forceNMethodSweep() { + try { + forceNMethodSweep0().join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + public native Thread forceNMethodSweep0(); + public native Object[] getCodeHeapEntries(int type); + public native int getCompilationActivityMode(); + public native Object[] getCodeBlob(long addr); + + // Intered strings + public native boolean isInStringTable(String str); + + // Memory + public native void readReservedMemory(); + public native long allocateMetaspace(ClassLoader classLoader, long size); + public native void freeMetaspace(ClassLoader classLoader, long addr, long size); + public native long incMetaspaceCapacityUntilGC(long increment); + public native long metaspaceCapacityUntilGC(); + + // Force Young GC + public native void youngGC(); + + // Force Full GC + public native void fullGC(); + + // Method tries to start concurrent mark cycle. + // It returns false if CM Thread is always in concurrent cycle. + public native boolean g1StartConcMarkCycle(); + + // Tests on ReservedSpace/VirtualSpace classes + public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations); + public native void runMemoryUnitTests(); + public native void readFromNoaccessArea(); + public native long getThreadStackSize(); + public native long getThreadRemainingStackSize(); + + // CPU features + public native String getCPUFeatures(); + + // Native extensions + public native long getHeapUsageForContext(int context); + public native long getHeapRegionCountForContext(int context); + public native int getContextForObject(Object obj); + public native void printRegionInfo(int context); + + // VM flags + public native boolean isConstantVMFlag(String name); + public native boolean isLockedVMFlag(String name); + public native void setBooleanVMFlag(String name, boolean value); + public native void setIntxVMFlag(String name, long value); + public native void setUintxVMFlag(String name, long value); + public native void setUint64VMFlag(String name, long value); + public native void setSizeTVMFlag(String name, long value); + public native void setStringVMFlag(String name, String value); + public native void setDoubleVMFlag(String name, double value); + public native Boolean getBooleanVMFlag(String name); + public native Long getIntxVMFlag(String name); + public native Long getUintxVMFlag(String name); + public native Long getUint64VMFlag(String name); + public native Long getSizeTVMFlag(String name); + public native String getStringVMFlag(String name); + public native Double getDoubleVMFlag(String name); + private final List> flagsGetters = Arrays.asList( + this::getBooleanVMFlag, this::getIntxVMFlag, this::getUintxVMFlag, + this::getUint64VMFlag, this::getSizeTVMFlag, this::getStringVMFlag, + this::getDoubleVMFlag); + + public Object getVMFlag(String name) { + return flagsGetters.stream() + .map(f -> f.apply(name)) + .filter(x -> x != null) + .findAny() + .orElse(null); + } + public native int getOffsetForName0(String name); + public int getOffsetForName(String name) throws Exception { + int offset = getOffsetForName0(name); + if (offset == -1) { + throw new RuntimeException(name + " not found"); + } + return offset; + } + + // Safepoint Checking + public native void assertMatchingSafepointCalls(boolean mutexSafepointValue, boolean attemptedNoSafepointValue); +} diff -r ad8137d44154 -r 247f60f5808f test/lib/sun/hotspot/code/BlobType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/sun/hotspot/code/BlobType.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.code; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.util.EnumSet; + +import sun.hotspot.WhiteBox; + +public enum BlobType { + // Execution level 1 and 4 (non-profiled) nmethods (including native nmethods) + MethodNonProfiled(0, "CodeHeap 'non-profiled nmethods'"), + // Execution level 2 and 3 (profiled) nmethods + MethodProfiled(1, "CodeHeap 'profiled nmethods'"), + // Non-nmethods like Buffers, Adapters and Runtime Stubs + NonNMethod(2, "CodeHeap 'non-nmethods'") { + @Override + public boolean allowTypeWhenOverflow(BlobType type) { + return super.allowTypeWhenOverflow(type) + || type == BlobType.MethodNonProfiled; + } + }, + // All types (No code cache segmentation) + All(3, "CodeCache"); + + public final int id; + private final String beanName; + + private BlobType(int id, String beanName) { + this.id = id; + this.beanName = beanName; + } + + public MemoryPoolMXBean getMemoryPool() { + for (MemoryPoolMXBean bean : ManagementFactory.getMemoryPoolMXBeans()) { + String name = bean.getName(); + if (beanName.equals(name)) { + return bean; + } + } + return null; + } + + public boolean allowTypeWhenOverflow(BlobType type) { + return type == this; + } + + public static EnumSet getAvailable() { + WhiteBox whiteBox = WhiteBox.getWhiteBox(); + if (!whiteBox.getBooleanVMFlag("SegmentedCodeCache")) { + // only All for non segmented world + return EnumSet.of(All); + } + if (System.getProperty("java.vm.info").startsWith("interpreted ")) { + // only NonNMethod for -Xint + return EnumSet.of(NonNMethod); + } + + EnumSet result = EnumSet.complementOf(EnumSet.of(All)); + if (!whiteBox.getBooleanVMFlag("TieredCompilation") + || whiteBox.getIntxVMFlag("TieredStopAtLevel") <= 1) { + // there is no MethodProfiled in non tiered world or pure C1 + result.remove(MethodProfiled); + } + return result; + } +} diff -r ad8137d44154 -r 247f60f5808f test/lib/sun/hotspot/code/CodeBlob.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/sun/hotspot/code/CodeBlob.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.code; + +import sun.hotspot.WhiteBox; + +public class CodeBlob { + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + public static CodeBlob[] getCodeBlobs(BlobType type) { + Object[] obj = WB.getCodeHeapEntries(type.id); + if (obj == null) { + return null; + } + CodeBlob[] result = new CodeBlob[obj.length]; + for (int i = 0, n = result.length; i < n; ++i) { + result[i] = new CodeBlob((Object[]) obj[i]); + } + return result; + } + public static CodeBlob getCodeBlob(long addr) { + Object[] obj = WB.getCodeBlob(addr); + if (obj == null) { + return null; + } + return new CodeBlob(obj); + } + protected CodeBlob(Object[] obj) { + assert obj.length == 3; + name = (String) obj[0]; + size = (Integer) obj[1]; + code_blob_type = BlobType.values()[(Integer) obj[2]]; + assert code_blob_type.id == (Integer) obj[2]; + } + public final String name; + public final int size; + public final BlobType code_blob_type; + + @Override + public String toString() { + return "CodeBlob{" + + "name=" + name + + ", size=" + size + + ", code_blob_type=" + code_blob_type + + '}'; + } +} diff -r ad8137d44154 -r 247f60f5808f test/lib/sun/hotspot/code/NMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/sun/hotspot/code/NMethod.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.code; + +import java.lang.reflect.Executable; +import sun.hotspot.WhiteBox; + +public class NMethod extends CodeBlob { + private static final WhiteBox wb = WhiteBox.getWhiteBox(); + public static NMethod get(Executable method, boolean isOsr) { + Object[] obj = wb.getNMethod(method, isOsr); + return obj == null ? null : new NMethod(obj); + } + private NMethod(Object[] obj) { + super((Object[])obj[0]); + assert obj.length == 4; + comp_level = (Integer) obj[1]; + insts = (byte[]) obj[2]; + compile_id = (Integer) obj[3]; + } + public final byte[] insts; + public final int comp_level; + public final int compile_id; + + @Override + public String toString() { + return "NMethod{" + + super.toString() + + ", insts=" + insts + + ", comp_level=" + comp_level + + ", compile_id=" + compile_id + + '}'; + } +} diff -r ad8137d44154 -r 247f60f5808f test/lib/sun/hotspot/cpuinfo/CPUInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/sun/hotspot/cpuinfo/CPUInfo.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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.cpuinfo; + +import java.util.List; +import java.util.Arrays; +import java.util.Collections; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +import sun.hotspot.WhiteBox; + +/** + * Information about CPU on test box. + * + * CPUInfo uses WhiteBox to gather information, + * so WhiteBox class should be added to bootclasspath + * and option -XX:+WhiteBoxAPI should expclicetly + * specified on command line. + */ +public class CPUInfo { + + private static final List features; + private static final String additionalCPUInfo; + + static { + WhiteBox wb = WhiteBox.getWhiteBox(); + + Pattern additionalCPUInfoRE = + Pattern.compile("([^(]*\\([^)]*\\)[^,]*),\\s*"); + + String cpuFeaturesString = wb.getCPUFeatures(); + Matcher matcher = additionalCPUInfoRE.matcher(cpuFeaturesString); + if (matcher.find()) { + additionalCPUInfo = matcher.group(1); + } else { + additionalCPUInfo = ""; + } + String splittedFeatures[] = matcher.replaceAll("").split("(, )| "); + + features = Collections.unmodifiableList(Arrays. + asList(splittedFeatures)); + } + + /** + * Get additional information about CPU. + * For example, on X86 in will be family/model/stepping + * and number of cores. + * + * @return additional CPU info + */ + public static String getAdditionalCPUInfo() { + return additionalCPUInfo; + } + + /** + * Get all known features supported by CPU. + * + * @return unmodifiable list with names of all known features + * supported by CPU. + */ + public static List getFeatures() { + return features; + } + + /** + * Check if some feature is supported by CPU. + * + * @param feature Name of feature to be tested. + * @return true if tested feature is supported by CPU. + */ + public static boolean hasFeature(String feature) { + return features.contains(feature.toLowerCase()); + } +} diff -r ad8137d44154 -r 247f60f5808f test/lib/sun/hotspot/parser/DiagnosticCommand.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/lib/sun/hotspot/parser/DiagnosticCommand.java Sat Jan 10 12:38:18 2015 -0800 @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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; + private boolean argument; + + public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type, + boolean mandatory, String defaultValue) { + this(name, desc, type, false, mandatory, defaultValue); + } + + public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type, + boolean argument, boolean mandatory, String defaultValue) { + this.name = name; + this.desc = desc; + this.type = type; + this.mandatory = mandatory; + this.defaultValue = defaultValue; + this.argument = argument; + } + + public String getName() { + return name; + } + + public String getDesc() { + return desc; + } + + public DiagnosticArgumentType getType() { + return type; + } + + public boolean isMandatory() { + return mandatory; + } + + public boolean isArgument() { + return argument; + } + + public String getDefaultValue() { + return defaultValue; + } +}