--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Sat Jul 19 13:43:02 2014 +0400
@@ -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
@@ -33,6 +33,7 @@
import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.debugger.MachineDescription;
import sun.jvm.hotspot.debugger.MachineDescriptionAMD64;
+import sun.jvm.hotspot.debugger.MachineDescriptionPPC64;
import sun.jvm.hotspot.debugger.MachineDescriptionIA64;
import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86;
import sun.jvm.hotspot.debugger.MachineDescriptionSPARC32Bit;
@@ -588,6 +589,8 @@
machDesc = new MachineDescriptionIA64();
} else if (cpu.equals("amd64")) {
machDesc = new MachineDescriptionAMD64();
+ } else if (cpu.equals("ppc64")) {
+ machDesc = new MachineDescriptionPPC64();
} else if (cpu.equals("sparc")) {
if (LinuxDebuggerLocal.getAddressSize()==8) {
machDesc = new MachineDescriptionSPARC64Bit();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionPPC64.java Sat Jul 19 13:43:02 2014 +0400
@@ -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.
+ *
+ */
+
+package sun.jvm.hotspot.debugger;
+
+public class MachineDescriptionPPC64 extends MachineDescriptionTwosComplement implements MachineDescription {
+ public long getAddressSize() {
+ return 8;
+ }
+
+ public boolean isLP64() {
+ return true;
+ }
+
+ public boolean isBigEndian() {
+ return true;
+ }
+}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java Sat Jul 19 13:43:02 2014 +0400
@@ -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
@@ -61,7 +61,7 @@
return "x86";
} else if (cpu.equals("sparc") || cpu.equals("sparcv9")) {
return "sparc";
- } else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64")) {
+ } else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64") || cpu.equals("ppc64")) {
return cpu;
} else {
try {
--- a/hotspot/make/jprt.properties Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/make/jprt.properties Sat Jul 19 13:43:02 2014 +0400
@@ -350,21 +350,25 @@
${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
-jprt.make.rule.test.targets.standard.wbapi = \
- ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-wbapitest, \
- ${jprt.my.solaris.x64}-{product|fastdebug}-c2-wbapitest, \
- ${jprt.my.linux.i586}-{product|fastdebug}-c2-wbapitest, \
- ${jprt.my.linux.x64}-{product|fastdebug}-c2-wbapitest, \
- ${jprt.my.windows.i586}-{product|fastdebug}-c2-wbapitest, \
- ${jprt.my.windows.x64}-{product|fastdebug}-c2-wbapitest, \
- ${jprt.my.linux.i586}-{product|fastdebug}-c1-wbapitest, \
- ${jprt.my.windows.i586}-{product|fastdebug}-c1-wbapitest
+jprt.make.rule.test.targets.standard.reg.group = \
+ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GROUP, \
+ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GROUP, \
+ ${jprt.my.linux.i586}-{product|fastdebug}-c2-GROUP, \
+ ${jprt.my.linux.x64}-{product|fastdebug}-c2-GROUP, \
+ ${jprt.my.windows.i586}-{product|fastdebug}-c2-GROUP, \
+ ${jprt.my.windows.x64}-{product|fastdebug}-c2-GROUP, \
+ ${jprt.my.linux.i586}-{product|fastdebug}-c1-GROUP, \
+ ${jprt.my.windows.i586}-{product|fastdebug}-c1-GROUP
jprt.make.rule.test.targets.standard = \
${jprt.make.rule.test.targets.standard.client}, \
${jprt.make.rule.test.targets.standard.server}, \
${jprt.make.rule.test.targets.standard.internalvmtests}, \
- ${jprt.make.rule.test.targets.standard.wbapi}
+ ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_wbapitest}, \
+ ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_compiler}, \
+ ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_gc}, \
+ ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_runtime}, \
+ ${jprt.make.rule.test.targets.standard.reg.group:GROUP=hotspot_serviceability}
jprt.make.rule.test.targets.embedded = \
${jprt.make.rule.test.targets.standard.client}
--- a/hotspot/make/linux/makefiles/defs.make Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/make/linux/makefiles/defs.make Sat Jul 19 13:43:02 2014 +0400
@@ -297,27 +297,23 @@
endif
# Serviceability Binaries
-# No SA Support for PPC, IA64, ARM or zero
-ADD_SA_BINARIES/x86 = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
- $(EXPORT_LIB_DIR)/sa-jdi.jar
-ADD_SA_BINARIES/sparc = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
- $(EXPORT_LIB_DIR)/sa-jdi.jar
+
+ADD_SA_BINARIES/DEFAULT = $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.$(LIBRARY_SUFFIX) \
+ $(EXPORT_LIB_DIR)/sa-jdi.jar
+
ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
ifeq ($(ZIP_DEBUGINFO_FILES),1)
- ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
- ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
+ ADD_SA_BINARIES/DEFAULT += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.diz
else
- ADD_SA_BINARIES/x86 += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
- ADD_SA_BINARIES/sparc += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
+ ADD_SA_BINARIES/DEFAULT += $(EXPORT_JRE_LIB_ARCH_DIR)/libsaproc.debuginfo
endif
endif
-ADD_SA_BINARIES/ppc =
-ADD_SA_BINARIES/ia64 =
-ADD_SA_BINARIES/arm =
+
+ADD_SA_BINARIES/$(HS_ARCH) = $(ADD_SA_BINARIES/DEFAULT)
+
+# No SA Support for zero
ADD_SA_BINARIES/zero =
-include $(HS_ALT_MAKE)/linux/makefiles/defs.make
EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH))
-
-
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -251,6 +251,49 @@
// buf is started with ", " or is empty
_features_str = strdup(strlen(buf) > 2 ? buf + 2 : buf);
+ // There are three 64-bit SPARC families that do not overlap, e.g.,
+ // both is_ultra3() and is_sparc64() cannot be true at the same time.
+ // Within these families, there can be more than one chip, e.g.,
+ // is_T4() and is_T7() machines are also is_niagara().
+ if (is_ultra3()) {
+ assert(_L1_data_cache_line_size == 0, "overlap with Ultra3 family");
+ // Ref: UltraSPARC III Cu Processor
+ _L1_data_cache_line_size = 64;
+ }
+ if (is_niagara()) {
+ assert(_L1_data_cache_line_size == 0, "overlap with niagara family");
+ // All Niagara's are sun4v's, but not all sun4v's are Niagaras, e.g.,
+ // Fujitsu SPARC64 is sun4v, but we don't want it in this block.
+ //
+ // Ref: UltraSPARC T1 Supplement to the UltraSPARC Architecture 2005
+ // Appendix F.1.3.1 Cacheable Accesses
+ // -> 16-byte L1 cache line size
+ //
+ // Ref: UltraSPARC T2: A Highly-Threaded, Power-Efficient, SPARC SOC
+ // Section III: SPARC Processor Core
+ // -> 16-byte L1 cache line size
+ //
+ // Ref: Oracle's SPARC T4-1, SPARC T4-2, SPARC T4-4, and SPARC T4-1B Server Architecture
+ // Section SPARC T4 Processor Cache Architecture
+ // -> 32-byte L1 cache line size (no longer see that info on this ref)
+ //
+ // XXX - still need a T7 reference here
+ //
+ if (is_T7()) { // T7 or newer
+ _L1_data_cache_line_size = 64;
+ } else if (is_T4()) { // T4 or newer (until T7)
+ _L1_data_cache_line_size = 32;
+ } else { // T1 or newer (until T4)
+ _L1_data_cache_line_size = 16;
+ }
+ }
+ if (is_sparc64()) {
+ guarantee(_L1_data_cache_line_size == 0, "overlap with SPARC64 family");
+ // Ref: Fujitsu SPARC64 VII Processor
+ // Section 4 Cache System
+ _L1_data_cache_line_size = 64;
+ }
+
// UseVIS is set to the smallest of what hardware supports and what
// the command line requires. I.e., you cannot set UseVIS to 3 on
// older UltraSparc which do not support it.
@@ -356,6 +399,7 @@
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
+ tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
tty->print("Allocation");
if (AllocatePrefetchStyle <= 0) {
tty->print_cr(": no prefetching");
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -394,6 +394,8 @@
_stepping = 0;
_cpuFeatures = 0;
_logical_processors_per_package = 1;
+ // i486 internal cache is both I&D and has a 16-byte line size
+ _L1_data_cache_line_size = 16;
if (!Use486InstrsOnly) {
// Get raw processor info
@@ -412,6 +414,7 @@
// Logical processors are only available on P4s and above,
// and only if hyperthreading is available.
_logical_processors_per_package = logical_processor_count();
+ _L1_data_cache_line_size = L1_line_size();
}
}
@@ -924,6 +927,7 @@
if (PrintMiscellaneous && Verbose) {
tty->print_cr("Logical CPUs per core: %u",
logical_processors_per_package());
+ tty->print_cr("L1 data cache line size: %u", L1_data_cache_line_size());
tty->print("UseSSE=%d", (int) UseSSE);
if (UseAVX > 0) {
tty->print(" UseAVX=%d", (int) UseAVX);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -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
@@ -581,7 +581,7 @@
return result;
}
- static intx prefetch_data_size() {
+ static intx L1_line_size() {
intx result = 0;
if (is_intel()) {
result = (_cpuid_info.dcp_cpuid4_ebx.bits.L1_line_size + 1);
@@ -593,6 +593,10 @@
return result;
}
+ static intx prefetch_data_size() {
+ return L1_line_size();
+ }
+
//
// Feature identification
//
--- a/hotspot/src/os/aix/vm/os_aix.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/os/aix/vm/os_aix.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1213,10 +1213,6 @@
::abort();
}
-// Unused on Aix for now.
-void os::set_error_file(const char *logfile) {}
-
-
// This method is a copy of JDK's sysGetLastErrorString
// from src/solaris/hpi/src/system_md.c
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1172,10 +1172,6 @@
::abort();
}
-// unused on bsd for now.
-void os::set_error_file(const char *logfile) {}
-
-
// This method is a copy of JDK's sysGetLastErrorString
// from src/solaris/hpi/src/system_md.c
@@ -1832,6 +1828,7 @@
// determine if this is a legacy image or modules image
// modules image doesn't have "jre" subdirectory
len = strlen(buf);
+ assert(len < buflen, "Ran out of buffer space");
jrelib_p = buf + len;
// Add the appropriate library subdir
@@ -1865,7 +1862,7 @@
}
}
- strcpy(saved_jvm_path, buf);
+ strncpy(saved_jvm_path, buf, MAXPATHLEN);
}
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
--- a/hotspot/src/os/linux/vm/os_linux.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1553,9 +1553,6 @@
::abort();
}
-// unused on linux for now.
-void os::set_error_file(const char *logfile) {}
-
// This method is a copy of JDK's sysGetLastErrorString
// from src/solaris/hpi/src/system_md.c
@@ -2345,6 +2342,7 @@
// determine if this is a legacy image or modules image
// modules image doesn't have "jre" subdirectory
len = strlen(buf);
+ assert(len < buflen, "Ran out of buffer room");
jrelib_p = buf + len;
snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
if (0 != access(buf, F_OK)) {
@@ -2365,7 +2363,7 @@
}
}
- strcpy(saved_jvm_path, buf);
+ strncpy(saved_jvm_path, buf, MAXPATHLEN);
}
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1543,9 +1543,6 @@
::abort(); // dump core (for debugging)
}
-// unused
-void os::set_error_file(const char *logfile) {}
-
// DLL functions
const char* os::dll_file_extension() { return ".so"; }
@@ -2185,6 +2182,7 @@
// determine if this is a legacy image or modules image
// modules image doesn't have "jre" subdirectory
len = strlen(buf);
+ assert(len < buflen, "Ran out of buffer space");
jrelib_p = buf + len;
snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
if (0 != access(buf, F_OK)) {
@@ -2203,7 +2201,7 @@
}
}
- strcpy(saved_jvm_path, buf);
+ strncpy(saved_jvm_path, buf, MAXPATHLEN);
}
--- a/hotspot/src/os/windows/vm/os_windows.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1824,7 +1824,9 @@
// looks like jvm.dll is installed there (append a fake suffix
// hotspot/jvm.dll).
char* java_home_var = ::getenv("JAVA_HOME");
- if (java_home_var != NULL && java_home_var[0] != 0) {
+ if (java_home_var != NULL && java_home_var[0] != 0 &&
+ strlen(java_home_var) < (size_t)buflen) {
+
strncpy(buf, java_home_var, buflen);
// determine if this is a legacy image or modules image
@@ -1843,7 +1845,7 @@
if (buf[0] == '\0') {
GetModuleFileName(vm_lib_handle, buf, buflen);
}
- strcpy(saved_jvm_path, buf);
+ strncpy(saved_jvm_path, buf, MAX_PATH);
}
@@ -2291,17 +2293,6 @@
return EXCEPTION_CONTINUE_SEARCH;
}
-// Fatal error reporting is single threaded so we can make this a
-// static and preallocated. If it's more than MAX_PATH silently ignore
-// it.
-static char saved_error_file[MAX_PATH] = {0};
-
-void os::set_error_file(const char *logfile) {
- if (strlen(logfile) <= MAX_PATH) {
- strncpy(saved_error_file, logfile, MAX_PATH);
- }
-}
-
static inline void report_error(Thread* t, DWORD exception_code,
address addr, void* siginfo, void* context) {
VMError err(t, exception_code, addr, siginfo, context);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -919,7 +919,7 @@
"Wrong size %u for field's Signature attribute in class file %s",
attribute_length, CHECK);
}
- generic_signature_index = cfs->get_u2(CHECK);
+ generic_signature_index = parse_generic_signature_attribute(CHECK);
} else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
if (runtime_visible_annotations != NULL) {
classfile_parse_error(
@@ -2306,8 +2306,7 @@
"Invalid Signature attribute length %u in class file %s",
method_attribute_length, CHECK_(nullHandle));
}
- cfs->guarantee_more(2, CHECK_(nullHandle)); // generic_signature_index
- generic_signature_index = cfs->get_u2_fast();
+ generic_signature_index = parse_generic_signature_attribute(CHECK_(nullHandle));
} else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
if (runtime_visible_annotations != NULL) {
classfile_parse_error(
@@ -2644,6 +2643,17 @@
return method_ordering;
}
+// Parse generic_signature attribute for methods and fields
+u2 ClassFileParser::parse_generic_signature_attribute(TRAPS) {
+ ClassFileStream* cfs = stream();
+ cfs->guarantee_more(2, CHECK_0); // generic_signature_index
+ u2 generic_signature_index = cfs->get_u2_fast();
+ check_property(
+ valid_symbol_at(generic_signature_index),
+ "Invalid Signature attribute at constant pool index %u in class file %s",
+ generic_signature_index, CHECK_0);
+ return generic_signature_index;
+}
void ClassFileParser::parse_classfile_sourcefile_attribute(TRAPS) {
ClassFileStream* cfs = stream();
@@ -2798,17 +2808,19 @@
ClassFileStream* cfs = stream();
u1* current_start = cfs->current();
- cfs->guarantee_more(2, CHECK); // length
+ guarantee_property(attribute_byte_length >= sizeof(u2),
+ "Invalid BootstrapMethods attribute length %u in class file %s",
+ attribute_byte_length,
+ CHECK);
+
+ cfs->guarantee_more(attribute_byte_length, CHECK);
+
int attribute_array_length = cfs->get_u2_fast();
guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,
"Short length on BootstrapMethods in class file %s",
CHECK);
- guarantee_property(attribute_byte_length >= sizeof(u2),
- "Invalid BootstrapMethods attribute length %u in class file %s",
- attribute_byte_length,
- CHECK);
// The attribute contains a counted array of counted tuples of shorts,
// represending bootstrap specifiers:
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -266,6 +266,7 @@
u1* parse_stackmap_table(u4 code_attribute_length, TRAPS);
// Classfile attribute parsing
+ u2 parse_generic_signature_attribute(TRAPS);
void parse_classfile_sourcefile_attribute(TRAPS);
void parse_classfile_source_debug_extension_attribute(int length, TRAPS);
u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1239,6 +1239,16 @@
}
+// Return Symbol for detailed_message or NULL
+Symbol* java_lang_Throwable::detail_message(oop throwable) {
+ PRESERVE_EXCEPTION_MARK; // Keep original exception
+ oop detailed_message = java_lang_Throwable::message(throwable);
+ if (detailed_message != NULL) {
+ return java_lang_String::as_symbol(detailed_message, THREAD);
+ }
+ return NULL;
+}
+
void java_lang_Throwable::set_message(oop throwable, oop value) {
throwable->obj_field_put(detailMessage_offset, value);
}
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -520,6 +520,7 @@
static oop message(oop throwable);
static oop message(Handle throwable);
static void set_message(oop throwable, oop value);
+ static Symbol* detail_message(oop throwable);
static void print_stack_element(outputStream *st, Handle mirror, int method,
int version, int bci);
static void print_stack_element(outputStream *st, methodHandle method, int bci);
--- a/hotspot/src/share/vm/classfile/stackMapTable.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/stackMapTable.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,6 +134,7 @@
}
// check if uninitialized objects exist on backward branches
check_new_object(frame, target, CHECK_VERIFY(frame->verifier()));
+ frame->verifier()->update_furthest_jump(target);
}
void StackMapTable::check_new_object(
--- a/hotspot/src/share/vm/classfile/verifier.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -633,6 +633,9 @@
bool no_control_flow = false; // Set to true when there is no direct control
// flow from current instruction to the next
// instruction in sequence
+
+ set_furthest_jump(0);
+
Bytecodes::Code opcode;
while (!bcs.is_last_bytecode()) {
// Check for recursive re-verification before each bytecode.
@@ -2248,6 +2251,29 @@
"Bad <init> method call");
return;
}
+
+ // Make sure that this call is not jumped over.
+ if (bci < furthest_jump()) {
+ verify_error(ErrorContext::bad_code(bci),
+ "Bad <init> method call from inside of a branch");
+ return;
+ }
+
+ // Make sure that this call is not done from within a TRY block because
+ // that can result in returning an incomplete object. Simply checking
+ // (bci >= start_pc) also ensures that this call is not done after a TRY
+ // block. That is also illegal because this call must be the first Java
+ // statement in the constructor.
+ ExceptionTable exhandlers(_method());
+ int exlength = exhandlers.length();
+ for(int i = 0; i < exlength; i++) {
+ if (bci >= exhandlers.start_pc(i)) {
+ verify_error(ErrorContext::bad_code(bci),
+ "Bad <init> method call from after the start of a try block");
+ return;
+ }
+ }
+
current_frame->initialize_object(type, current_type());
*this_uninit = true;
} else if (type.is_uninitialized()) {
@@ -2285,16 +2311,19 @@
vmSymbols::object_initializer_name(),
cp->signature_ref_at(bcs->get_index_u2()),
Klass::normal);
- instanceKlassHandle mh(THREAD, m->method_holder());
- if (m->is_protected() && !mh->is_same_class_package(_klass())) {
- bool assignable = current_type().is_assignable_from(
- objectref_type, this, CHECK_VERIFY(this));
- if (!assignable) {
- verify_error(ErrorContext::bad_type(bci,
- TypeOrigin::cp(new_class_index, objectref_type),
- TypeOrigin::implicit(current_type())),
- "Bad access to protected <init> method");
- return;
+ // Do nothing if method is not found. Let resolution detect the error.
+ if (m != NULL) {
+ instanceKlassHandle mh(THREAD, m->method_holder());
+ if (m->is_protected() && !mh->is_same_class_package(_klass())) {
+ bool assignable = current_type().is_assignable_from(
+ objectref_type, this, CHECK_VERIFY(this));
+ if (!assignable) {
+ verify_error(ErrorContext::bad_type(bci,
+ TypeOrigin::cp(new_class_index, objectref_type),
+ TypeOrigin::implicit(current_type())),
+ "Bad access to protected <init> method");
+ return;
+ }
}
}
}
--- a/hotspot/src/share/vm/classfile/verifier.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/classfile/verifier.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -258,6 +258,9 @@
ErrorContext _error_context; // contains information about an error
+ // Used to detect illegal jumps over calls to super() nd this() in ctors.
+ int32_t _furthest_jump;
+
void verify_method(methodHandle method, TRAPS);
char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
void verify_exception_handler_table(u4 code_length, char* code_data,
@@ -403,6 +406,20 @@
Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
TypeOrigin ref_ctx(const char* str, TRAPS);
+
+ // Keep track of the furthest branch done in a method to make sure that
+ // there are no branches over calls to super() or this() from inside of
+ // a constructor.
+ int32_t furthest_jump() { return _furthest_jump; }
+
+ void set_furthest_jump(int32_t target) {
+ _furthest_jump = target;
+ }
+
+ void update_furthest_jump(int32_t target) {
+ if (target > _furthest_jump) _furthest_jump = target;
+ }
+
};
inline int ClassVerifier::change_sig_to_verificationType(
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -2132,6 +2132,7 @@
ResourceMark rm;
char* method_name = method->name()->as_C_string();
strncpy(_last_method_compiled, method_name, CompileBroker::name_buffer_length);
+ _last_method_compiled[CompileBroker::name_buffer_length - 1] = '\0'; // ensure null terminated
char current_method[CompilerCounters::cmname_buffer_length];
size_t maxLen = CompilerCounters::cmname_buffer_length;
--- a/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -197,28 +197,29 @@
bool VM_CollectForMetadataAllocation::initiate_concurrent_GC() {
#if INCLUDE_ALL_GCS
- if (UseConcMarkSweepGC || UseG1GC) {
- if (UseConcMarkSweepGC && CMSClassUnloadingEnabled) {
- MetaspaceGC::set_should_concurrent_collect(true);
- } else if (UseG1GC) {
- G1CollectedHeap* g1h = G1CollectedHeap::heap();
- g1h->g1_policy()->set_initiate_conc_mark_if_possible();
+ if (UseConcMarkSweepGC && CMSClassUnloadingEnabled) {
+ MetaspaceGC::set_should_concurrent_collect(true);
+ return true;
+ }
- GCCauseSetter x(g1h, _gc_cause);
+ if (UseG1GC) {
+ G1CollectedHeap* g1h = G1CollectedHeap::heap();
+ g1h->g1_policy()->set_initiate_conc_mark_if_possible();
- // At this point we are supposed to start a concurrent cycle. We
- // will do so if one is not already in progress.
- bool should_start = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
+ GCCauseSetter x(g1h, _gc_cause);
- if (should_start) {
- double pause_target = g1h->g1_policy()->max_pause_time_ms();
- g1h->do_collection_pause_at_safepoint(pause_target);
- }
+ // At this point we are supposed to start a concurrent cycle. We
+ // will do so if one is not already in progress.
+ bool should_start = g1h->g1_policy()->force_initial_mark_if_outside_cycle(_gc_cause);
+
+ if (should_start) {
+ double pause_target = g1h->g1_policy()->max_pause_time_ms();
+ g1h->do_collection_pause_at_safepoint(pause_target);
}
-
return true;
}
#endif
+
return false;
}
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -430,9 +430,18 @@
// tracing
if (TraceExceptions) {
- ttyLocker ttyl;
ResourceMark rm(thread);
- tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", h_exception->print_value_string(), (address)h_exception());
+ Symbol* message = java_lang_Throwable::detail_message(h_exception());
+ ttyLocker ttyl; // Lock after getting the detail message
+ if (message != NULL) {
+ tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")",
+ h_exception->print_value_string(), message->as_C_string(),
+ (address)h_exception());
+ } else {
+ tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")",
+ h_exception->print_value_string(),
+ (address)h_exception());
+ }
tty->print_cr(" thrown in interpreter method <%s>", h_method->print_value_string());
tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, thread);
}
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -244,10 +244,8 @@
method()->print_value();
tty->print(" @ %d = [%d] { ", bci(), n);
for (int i = 0; i < n; i++) {
-#ifdef ENABLE_ZAP_DEAD_LOCALS
if (is_dead(i)) tty->print("%d+ ", i);
else
-#endif
if (is_oop(i)) tty->print("%d ", i);
}
tty->print_cr("}");
@@ -402,13 +400,11 @@
value |= (mask << oop_bit_number );
}
- #ifdef ENABLE_ZAP_DEAD_LOCALS
// set dead bit
if (!cell->is_live()) {
value |= (mask << dead_bit_number);
assert(!cell->is_reference(), "dead value marked as oop");
}
- #endif
}
// make sure last word is stored
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -66,19 +66,15 @@
public:
enum {
- N = 2, // the number of words reserved
+ N = 4, // the number of words reserved
// for inlined mask storage
small_mask_limit = N * BitsPerWord, // the maximum number of bits
// available for small masks,
// small_mask_limit can be set to 0
// for testing bit_mask allocation
-#ifdef ENABLE_ZAP_DEAD_LOCALS
bits_per_entry = 2,
dead_bit_number = 1,
-#else
- bits_per_entry = 1,
-#endif
oop_bit_number = 0
};
@@ -119,10 +115,6 @@
void set_expression_stack_size(int sz) { _expression_stack_size = sz; }
-#ifdef ENABLE_ZAP_DEAD_LOCALS
- bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; }
-#endif
-
// Lookup
bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; }
bool is_empty() const;
@@ -144,6 +136,7 @@
void print() const;
int number_of_entries() const { return mask_size() / bits_per_entry; }
+ bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; }
bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; }
int expression_stack_size() const { return _expression_stack_size; }
--- a/hotspot/src/share/vm/oops/constantPool.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -520,13 +520,9 @@
Symbol* ConstantPool::exception_message(constantPoolHandle this_cp, int which, constantTag tag, oop pending_exception) {
// Dig out the detailed message to reuse if possible
- Symbol* message = NULL;
- oop detailed_message = java_lang_Throwable::message(pending_exception);
- if (detailed_message != NULL) {
- message = java_lang_String::as_symbol_or_null(detailed_message);
- if (message != NULL) {
- return message;
- }
+ Symbol* message = java_lang_Throwable::detail_message(pending_exception);
+ if (message != NULL) {
+ return message;
}
// Return specific message for the tag
--- a/hotspot/src/share/vm/oops/klassVtable.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -251,6 +251,17 @@
// For bytecodes not produced by javac together it is possible that a method does not override
// the superclass's method, but might indirectly override a super-super class's vtable entry
// If none found, return a null superk, else return the superk of the method this does override
+// For public and protected methods: if they override a superclass, they will
+// also be overridden themselves appropriately.
+// Private methods do not override and are not overridden.
+// Package Private methods are trickier:
+// e.g. P1.A, pub m
+// P2.B extends A, package private m
+// P1.C extends B, public m
+// P1.C.m needs to override P1.A.m and can not override P2.B.m
+// Therefore: all package private methods need their own vtable entries for
+// them to be the root of an inheritance overriding decision
+// Package private methods may also override other vtable entries
InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method,
int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
InstanceKlass* superk = initialsuper;
@@ -398,8 +409,11 @@
target_classname, THREAD))
!= (InstanceKlass*)NULL))))
{
- // overriding, so no new entry
- allocate_new = false;
+ // Package private methods always need a new entry to root their own
+ // overriding. They may also override other methods.
+ if (!target_method()->is_package_private()) {
+ allocate_new = false;
+ }
if (checkconstraints) {
// Override vtable entry if passes loader constraint check
@@ -543,8 +557,9 @@
AccessFlags class_flags,
TRAPS) {
if (class_flags.is_interface()) {
- // Interfaces do not use vtables, so there is no point to assigning
- // a vtable index to any of their methods. If we refrain from doing this,
+ // Interfaces do not use vtables, except for java.lang.Object methods,
+ // so there is no point to assigning
+ // a vtable index to any of their local methods. If we refrain from doing this,
// we can use Method::_vtable_index to hold the itable index
return false;
}
@@ -582,6 +597,12 @@
return true;
}
+ // Package private methods always need a new entry to root their own
+ // overriding. This allows transitive overriding to work.
+ if (target_method()->is_package_private()) {
+ return true;
+ }
+
// search through the super class hierarchy to see if we need
// a new entry
ResourceMark rm;
--- a/hotspot/src/share/vm/prims/jni.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/prims/jni.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -247,15 +247,6 @@
"Bug in native code: jfieldID offset must address interior of object");
}
-// Pick a reasonable higher bound for local capacity requested
-// for EnsureLocalCapacity and PushLocalFrame. We don't want it too
-// high because a test (or very unusual application) may try to allocate
-// that many handles and run out of swap space. An implementation is
-// permitted to allocate more handles than the ensured capacity, so this
-// value is set high enough to prevent compatibility problems.
-const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K;
-
-
// Wrapper to trace JNI functions
#ifdef ASSERT
@@ -741,7 +732,8 @@
HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(env, capacity);
//%note jni_11
- if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
+ if (capacity < 0 ||
+ ((MaxJNILocalCapacity > 0) && (capacity > MaxJNILocalCapacity))) {
HOTSPOT_JNI_PUSHLOCALFRAME_RETURN((uint32_t)JNI_ERR);
return JNI_ERR;
}
@@ -844,7 +836,8 @@
HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(env, capacity);
jint ret;
- if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
+ if (capacity >= 0 &&
+ ((MaxJNILocalCapacity <= 0) || (capacity <= MaxJNILocalCapacity))) {
ret = JNI_OK;
} else {
ret = JNI_ERR;
@@ -3893,6 +3886,7 @@
run_unit_test(TestKlass_test());
run_unit_test(TestBitMap_test());
run_unit_test(TestAsUtf8());
+ run_unit_test(ObjectMonitor::sanity_checks());
#if INCLUDE_VM_STRUCTS
run_unit_test(VMStructs::test());
#endif
--- a/hotspot/src/share/vm/prims/jniCheck.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -185,6 +185,9 @@
* throw an ArrayIndexOutOfBoundsException or ArrayStoreException.
*
* In all other cases, a non-error return value guarantees that no exceptions have been thrown.
+ *
+ * Programmers often defend against ArrayIndexOutOfBoundsException, so warning
+ * for these functions would be pedantic.
*/
static inline void
check_pending_exception(JavaThread* thr) {
@@ -201,6 +204,16 @@
}
}
+/**
+ * Add to the planned number of handles. I.e. plus current live & warning threshold
+ */
+static inline void
+add_planned_handle_capacity(JNIHandleBlock* handles, size_t capacity) {
+ handles->set_planned_capacity(capacity +
+ handles->get_number_of_live_handles() +
+ CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+}
+
static inline void
functionEnterCritical(JavaThread* thr)
@@ -243,7 +256,7 @@
thr->print_stack();
)
// Complain just the once, reset to current + warn threshold
- handles->set_planned_capacity(live_handles + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ add_planned_handle_capacity(handles, 0);
}
}
@@ -720,7 +733,7 @@
NativeReportJNIFatalError(thr, "negative capacity");
jint result = UNCHECKED()->PushLocalFrame(env, capacity);
if (result == JNI_OK) {
- thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ add_planned_handle_capacity(thr->active_handles(), capacity);
}
functionExit(thr);
return result;
@@ -824,7 +837,7 @@
}
jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity);
if (result == JNI_OK) {
- thr->active_handles()->set_planned_capacity(capacity + CHECK_JNI_LOCAL_REF_CAP_WARN_THRESHOLD);
+ add_planned_handle_capacity(thr->active_handles(), capacity);
}
functionExit(thr);
return result;
@@ -1628,7 +1641,6 @@
check_is_obj_array(thr, array);
)
jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index);
- thr->set_pending_jni_exception_check("GetObjectArrayElement");
functionExit(thr);
return result;
JNI_END
@@ -1643,7 +1655,6 @@
check_is_obj_array(thr, array);
)
UNCHECKED()->SetObjectArrayElement(env,array,index,val);
- thr->set_pending_jni_exception_check("SetObjectArrayElement");
functionExit(thr);
JNI_END
@@ -1733,7 +1744,6 @@
check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \
- thr->set_pending_jni_exception_check("Get"#Result"ArrayRegion"); \
functionExit(thr); \
JNI_END
@@ -1758,7 +1768,6 @@
check_primitive_array_type(thr, array, ElementTag); \
) \
UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \
- thr->set_pending_jni_exception_check("Set"#Result"ArrayRegion"); \
functionExit(thr); \
JNI_END
@@ -1835,7 +1844,6 @@
checkString(thr, str);
)
UNCHECKED()->GetStringRegion(env, str, start, len, buf);
- thr->set_pending_jni_exception_check("GetStringRegion");
functionExit(thr);
JNI_END
@@ -1850,7 +1858,6 @@
checkString(thr, str);
)
UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
- thr->set_pending_jni_exception_check("GetStringUTFRegion");
functionExit(thr);
JNI_END
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "interpreter/interpreter.hpp"
+#include "interpreter/oopMapCache.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
#include "memory/resourceArea.hpp"
#include "oops/instanceKlass.hpp"
@@ -744,6 +745,13 @@
}
void VM_GetOrSetLocal::doit() {
+ InterpreterOopMap oop_mask;
+ _jvf->method()->mask_for(_jvf->bci(), &oop_mask);
+ if (oop_mask.is_dead(_index)) {
+ // The local can be invalid and uninitialized in the scope of current bci
+ _result = JVMTI_ERROR_INVALID_SLOT;
+ return;
+ }
if (_set) {
// Force deoptimization of frame if compiled because it's
// possible the compiler emitted some locals as constant values,
--- a/hotspot/src/share/vm/runtime/atomic.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/atomic.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -35,6 +35,18 @@
// can provide an alternative action if not - see supports_cx8() for
// a means to test availability.
+ // The memory operations that are mentioned with each of the atomic
+ // function families come from src/share/vm/runtime/orderAccess.hpp,
+ // e.g., <fence> is described in that file and is implemented by the
+ // OrderAccess::fence() function. See that file for the gory details
+ // on the Memory Access Ordering Model.
+
+ // All of the atomic operations that imply a read-modify-write action
+ // guarantee a two-way memory barrier across that operation. Historically
+ // these semantics reflect the strength of atomic operations that are
+ // provided on SPARC/X86. We assume that strength is necessary unless
+ // we can prove that a weaker form is sufficiently safe.
+
// Atomically store to a location
inline static void store (jbyte store_value, jbyte* dest);
inline static void store (jshort store_value, jshort* dest);
@@ -55,7 +67,8 @@
// See comment above about using jlong atomics on 32-bit platforms
inline static jlong load(volatile jlong* src);
- // Atomically add to a location, return updated value
+ // Atomically add to a location. Returns updated value. add*() provide:
+ // <fence> add-value-to-dest <membar StoreLoad|StoreStore>
inline static jint add (jint add_value, volatile jint* dest);
inline static size_t add (size_t add_value, volatile size_t* dest);
inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
@@ -63,30 +76,35 @@
// See comment above about using jlong atomics on 32-bit platforms
static jlong add (jlong add_value, volatile jlong* dest);
- // Atomically increment location
+ // Atomically increment location. inc*() provide:
+ // <fence> increment-dest <membar StoreLoad|StoreStore>
inline static void inc (volatile jint* dest);
static void inc (volatile jshort* dest);
inline static void inc (volatile size_t* dest);
inline static void inc_ptr(volatile intptr_t* dest);
inline static void inc_ptr(volatile void* dest);
- // Atomically decrement a location
+ // Atomically decrement a location. dec*() provide:
+ // <fence> decrement-dest <membar StoreLoad|StoreStore>
inline static void dec (volatile jint* dest);
static void dec (volatile jshort* dest);
inline static void dec (volatile size_t* dest);
inline static void dec_ptr(volatile intptr_t* dest);
inline static void dec_ptr(volatile void* dest);
- // Performs atomic exchange of *dest with exchange_value. Returns old prior value of *dest.
+ // Performs atomic exchange of *dest with exchange_value. Returns old
+ // prior value of *dest. xchg*() provide:
+ // <fence> exchange-value-with-dest <membar StoreLoad|StoreStore>
inline static jint xchg(jint exchange_value, volatile jint* dest);
static unsigned int xchg(unsigned int exchange_value, volatile unsigned int* dest);
inline static intptr_t xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest);
inline static void* xchg_ptr(void* exchange_value, volatile void* dest);
- // Performs atomic compare of *dest and compare_value, and exchanges *dest with exchange_value
- // if the comparison succeeded. Returns prior value of *dest. Guarantees a two-way memory
- // barrier across the cmpxchg. I.e., it's really a 'fence_cmpxchg_acquire'.
+ // Performs atomic compare of *dest and compare_value, and exchanges
+ // *dest with exchange_value if the comparison succeeded. Returns prior
+ // value of *dest. cmpxchg*() provide:
+ // <fence> compare-and-exchange <membar StoreLoad|StoreStore>
static jbyte cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value);
inline static jint cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value);
// See comment above about using jlong atomics on 32-bit platforms
--- a/hotspot/src/share/vm/runtime/globals.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/globals.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -1216,6 +1216,11 @@
product(bool, UseFastJNIAccessors, true, \
"Use optimized versions of Get<Primitive>Field") \
\
+ product(intx, MaxJNILocalCapacity, 65536, \
+ "Maximum allowable local JNI handle capacity to " \
+ "EnsureLocalCapacity() and PushLocalFrame(), " \
+ "where <= 0 is unlimited, default: 65536") \
+ \
product(bool, EagerXrunInit, false, \
"Eagerly initialize -Xrun libraries; allows startup profiling, " \
"but not all -Xrun libraries may support the state of the VM " \
--- a/hotspot/src/share/vm/runtime/objectMonitor.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -2497,6 +2497,10 @@
SETKNOB(FastHSSEC);
#undef SETKNOB
+ if (Knob_Verbose) {
+ sanity_checks();
+ }
+
if (os::is_MP()) {
BackOffMask = (1 << Knob_SpinBackOff) - 1;
if (Knob_ReportSettings) ::printf("BackOffMask=%X\n", BackOffMask);
@@ -2517,6 +2521,66 @@
InitDone = 1;
}
+void ObjectMonitor::sanity_checks() {
+ int error_cnt = 0;
+ int warning_cnt = 0;
+ bool verbose = Knob_Verbose != 0 NOT_PRODUCT(|| VerboseInternalVMTests);
+
+ if (verbose) {
+ tty->print_cr("INFO: sizeof(ObjectMonitor)=" SIZE_FORMAT,
+ sizeof(ObjectMonitor));
+ }
+
+ uint cache_line_size = VM_Version::L1_data_cache_line_size();
+ if (verbose) {
+ tty->print_cr("INFO: L1_data_cache_line_size=%u", cache_line_size);
+ }
+
+ ObjectMonitor dummy;
+ u_char *addr_begin = (u_char*)&dummy;
+ u_char *addr_header = (u_char*)&dummy._header;
+ u_char *addr_owner = (u_char*)&dummy._owner;
+
+ uint offset_header = (uint)(addr_header - addr_begin);
+ if (verbose) tty->print_cr("INFO: offset(_header)=%u", offset_header);
+
+ uint offset_owner = (uint)(addr_owner - addr_begin);
+ if (verbose) tty->print_cr("INFO: offset(_owner)=%u", offset_owner);
+
+ if ((uint)(addr_header - addr_begin) != 0) {
+ tty->print_cr("ERROR: offset(_header) must be zero (0).");
+ error_cnt++;
+ }
+
+ if (cache_line_size != 0) {
+ // We were able to determine the L1 data cache line size so
+ // do some cache line specific sanity checks
+
+ if ((offset_owner - offset_header) < cache_line_size) {
+ tty->print_cr("WARNING: the _header and _owner fields are closer "
+ "than a cache line which permits false sharing.");
+ warning_cnt++;
+ }
+
+ if ((sizeof(ObjectMonitor) % cache_line_size) != 0) {
+ tty->print_cr("WARNING: ObjectMonitor size is not a multiple of "
+ "a cache line which permits false sharing.");
+ warning_cnt++;
+ }
+ }
+
+ ObjectSynchronizer::sanity_checks(verbose, cache_line_size, &error_cnt,
+ &warning_cnt);
+
+ if (verbose || error_cnt != 0 || warning_cnt != 0) {
+ tty->print_cr("INFO: error_cnt=%d", error_cnt);
+ tty->print_cr("INFO: warning_cnt=%d", warning_cnt);
+ }
+
+ guarantee(error_cnt == 0,
+ "Fatal error(s) found in ObjectMonitor::sanity_checks()");
+}
+
#ifndef PRODUCT
void ObjectMonitor::verify() {
}
--- a/hotspot/src/share/vm/runtime/objectMonitor.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/objectMonitor.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -189,6 +189,8 @@
bool check(TRAPS); // true if the thread owns the monitor.
void check_slow(TRAPS);
void clear();
+ static void sanity_checks(); // public for -XX:+ExecuteInternalVMTests
+ // in PRODUCT for -XX:SyncKnobs=Verbose=1
#ifndef PRODUCT
void verify();
void print();
@@ -234,8 +236,6 @@
// WARNING: this must be the very first word of ObjectMonitor
// This means this class can't use any virtual member functions.
- // TODO-FIXME: assert that offsetof(_header) is 0 or get rid of the
- // implicit 0 offset in emitted code.
volatile markOop _header; // displaced object header word - mark
void* volatile _object; // backward object pointer - strong root
--- a/hotspot/src/share/vm/runtime/os.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/os.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -469,9 +469,6 @@
// run cmd in a separate process and return its exit code; or -1 on failures
static int fork_and_exec(char *cmd);
- // Set file to send error reports.
- static void set_error_file(const char *logfile);
-
// os::exit() is merged with vm_exit()
// static void exit(int num);
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -392,19 +392,22 @@
// Hash Code handling
//
// Performance concern:
-// OrderAccess::storestore() calls release() which STs 0 into the global volatile
-// OrderAccess::Dummy variable. This store is unnecessary for correctness.
-// Many threads STing into a common location causes considerable cache migration
-// or "sloshing" on large SMP system. As such, I avoid using OrderAccess::storestore()
-// until it's repaired. In some cases OrderAccess::fence() -- which incurs local
-// latency on the executing processor -- is a better choice as it scales on SMP
-// systems. See http://blogs.sun.com/dave/entry/biased_locking_in_hotspot for a
-// discussion of coherency costs. Note that all our current reference platforms
-// provide strong ST-ST order, so the issue is moot on IA32, x64, and SPARC.
+// OrderAccess::storestore() calls release() which at one time stored 0
+// into the global volatile OrderAccess::dummy variable. This store was
+// unnecessary for correctness. Many threads storing into a common location
+// causes considerable cache migration or "sloshing" on large SMP systems.
+// As such, I avoided using OrderAccess::storestore(). In some cases
+// OrderAccess::fence() -- which incurs local latency on the executing
+// processor -- is a better choice as it scales on SMP systems.
+//
+// See http://blogs.oracle.com/dave/entry/biased_locking_in_hotspot for
+// a discussion of coherency costs. Note that all our current reference
+// platforms provide strong ST-ST order, so the issue is moot on IA32,
+// x64, and SPARC.
//
// As a general policy we use "volatile" to control compiler-based reordering
-// and explicit fences (barriers) to control for architectural reordering performed
-// by the CPU(s) or platform.
+// and explicit fences (barriers) to control for architectural reordering
+// performed by the CPU(s) or platform.
struct SharedGlobals {
// These are highly shared mostly-read variables.
@@ -1596,7 +1599,55 @@
}
//------------------------------------------------------------------------------
-// Non-product code
+// Debugging code
+
+void ObjectSynchronizer::sanity_checks(const bool verbose,
+ const uint cache_line_size,
+ int *error_cnt_ptr,
+ int *warning_cnt_ptr) {
+ u_char *addr_begin = (u_char*)&GVars;
+ u_char *addr_stwRandom = (u_char*)&GVars.stwRandom;
+ u_char *addr_hcSequence = (u_char*)&GVars.hcSequence;
+
+ if (verbose) {
+ tty->print_cr("INFO: sizeof(SharedGlobals)=" SIZE_FORMAT,
+ sizeof(SharedGlobals));
+ }
+
+ uint offset_stwRandom = (uint)(addr_stwRandom - addr_begin);
+ if (verbose) tty->print_cr("INFO: offset(stwRandom)=%u", offset_stwRandom);
+
+ uint offset_hcSequence = (uint)(addr_hcSequence - addr_begin);
+ if (verbose) {
+ tty->print_cr("INFO: offset(_hcSequence)=%u", offset_hcSequence);
+ }
+
+ if (cache_line_size != 0) {
+ // We were able to determine the L1 data cache line size so
+ // do some cache line specific sanity checks
+
+ if (offset_stwRandom < cache_line_size) {
+ tty->print_cr("WARNING: the SharedGlobals.stwRandom field is closer "
+ "to the struct beginning than a cache line which permits "
+ "false sharing.");
+ (*warning_cnt_ptr)++;
+ }
+
+ if ((offset_hcSequence - offset_stwRandom) < cache_line_size) {
+ tty->print_cr("WARNING: the SharedGlobals.stwRandom and "
+ "SharedGlobals.hcSequence fields are closer than a cache "
+ "line which permits false sharing.");
+ (*warning_cnt_ptr)++;
+ }
+
+ if ((sizeof(SharedGlobals) - offset_hcSequence) < cache_line_size) {
+ tty->print_cr("WARNING: the SharedGlobals.hcSequence field is closer "
+ "to the struct end than a cache line which permits false "
+ "sharing.");
+ (*warning_cnt_ptr)++;
+ }
+ }
+}
#ifndef PRODUCT
--- a/hotspot/src/share/vm/runtime/synchronizer.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/synchronizer.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -121,6 +121,9 @@
static void oops_do(OopClosure* f);
// debugging
+ static void sanity_checks(const bool verbose,
+ const unsigned int cache_line_size,
+ int *error_cnt_ptr, int *warning_cnt_ptr);
static void verify() PRODUCT_RETURN;
static int verify_objmon_isinpool(ObjectMonitor *addr) PRODUCT_RETURN0;
--- a/hotspot/src/share/vm/runtime/vm_version.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -50,6 +50,7 @@
bool Abstract_VM_Version::_supports_atomic_getadd4 = false;
bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
+unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
int Abstract_VM_Version::_reserve_for_allocation_prefetch = 0;
#ifndef HOTSPOT_RELEASE_VERSION
--- a/hotspot/src/share/vm/runtime/vm_version.hpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/runtime/vm_version.hpp Sat Jul 19 13:43:02 2014 +0400
@@ -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,6 +42,7 @@
static bool _supports_atomic_getadd4;
static bool _supports_atomic_getadd8;
static unsigned int _logical_processors_per_package;
+ static unsigned int _L1_data_cache_line_size;
static int _vm_major_version;
static int _vm_minor_version;
static int _vm_micro_version;
@@ -98,6 +99,10 @@
return _logical_processors_per_package;
}
+ static unsigned int L1_data_cache_line_size() {
+ return _L1_data_cache_line_size;
+ }
+
// Need a space at the end of TLAB for prefetch instructions
// which may fault when accessing memory outside of heap.
static int reserve_for_allocation_prefetch() {
--- a/hotspot/src/share/vm/utilities/vmError.cpp Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Sat Jul 19 13:43:02 2014 +0400
@@ -989,7 +989,6 @@
if (fd != -1) {
out.print_raw("# An error report file with more information is saved as:\n# ");
out.print_raw_cr(buffer);
- os::set_error_file(buffer);
log.set_fd(fd);
} else {
--- a/hotspot/test/Makefile Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/test/Makefile Sat Jul 19 13:43:02 2014 +0400
@@ -23,14 +23,36 @@
#
#
-# Makefile to run various jdk tests
+# Makefile to run various hotspot tests
#
GETMIXEDPATH=echo
-# Get OS/ARCH specifics
-OSNAME = $(shell uname -s)
-ifeq ($(OSNAME), SunOS)
+# 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_)
+ifeq ($(UNAME_S), SunOS)
PLATFORM = solaris
SLASH_JAVA = /java
ARCH = $(shell uname -p)
@@ -38,7 +60,7 @@
ARCH=i586
endif
endif
-ifeq ($(OSNAME), Linux)
+ifeq ($(UNAME_S), Linux)
PLATFORM = linux
SLASH_JAVA = /java
ARCH = $(shell uname -m)
@@ -46,7 +68,7 @@
ARCH = i586
endif
endif
-ifeq ($(OSNAME), Darwin)
+ifeq ($(UNAME_S), Darwin)
PLATFORM = bsd
SLASH_JAVA = /java
ARCH = $(shell uname -m)
@@ -54,7 +76,7 @@
ARCH = i586
endif
endif
-ifeq ($(findstring BSD,$(OSNAME)), BSD)
+ifeq ($(findstring BSD,$(UNAME_S)), BSD)
PLATFORM = bsd
SLASH_JAVA = /java
ARCH = $(shell uname -m)
@@ -63,12 +85,12 @@
endif
endif
ifeq ($(PLATFORM),)
- # detect wether we're running in MKS or cygwin
- ifeq ($(OSNAME), Windows_NT) # MKS
+ # detect whether we're running in MKS or cygwin
+ ifeq ($(UNAME_S), Windows_NT) # MKS
GETMIXEDPATH=dosname -s
endif
- ifeq ($(findstring CYGWIN,$(OSNAME)), CYGWIN)
- GETMIXEDPATH=cygpath -m -s
+ ifeq ($(findstring CYGWIN,$(UNAME_S)), CYGWIN)
+ GETMIXEDPATH=cygpath -m
endif
PLATFORM = windows
SLASH_JAVA = J:
@@ -92,13 +114,6 @@
SLASH_JAVA = $(ALT_SLASH_JAVA)
endif
-# Utilities used
-CD = cd
-CP = cp
-ECHO = echo
-MKDIR = mkdir
-ZIP = zip
-
# Root of this test area (important to use full paths in some places)
TEST_ROOT := $(shell pwd)
@@ -136,21 +151,82 @@
endif
# How to create the test bundle (pass or fail, we want to create this)
-BUNDLE_UP = ( $(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` \
- && $(CD) $(ABS_TEST_OUTPUT_DIR) \
- && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . )
-BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} )
+# 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 jtreg_tests)
-all: jtreg_tests
+all: hotspot_all
@$(ECHO) "Testing completed successfully"
-# Support "hotspot_" prefixed test make targets too
-# The hotspot_% targets are for example invoked by the top level Makefile
+# Support "hotspot_" prefixed test make targets (too)
+# The hotspot_% targets are used by the top level Makefile
+# Unless explicitly defined below, hotspot_<x> is interpreted as a jtreg test group name
hotspot_%:
- $(MAKE) $*
+ $(ECHO) "Running tests: $@"
+ $(MAKE) -j 1 TEST_SELECTION=":$@" UNIQUE_DIR=$@ jtreg_tests;
# Prep for output
prep: clean
@@ -168,41 +244,64 @@
# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
ifndef JT_HOME
- JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
-endif
-ifdef JPRT_JTREG_HOME
- JT_HOME = $(JPRT_JTREG_HOME)
+ JT_HOME = $(SLASH_JAVA)/re/jtreg/4.1/promoted/latest/binaries/jtreg
+ ifdef JPRT_JTREG_HOME
+ JT_HOME = $(JPRT_JTREG_HOME)
+ endif
endif
-# Expect JPRT to set TESTDIRS to the jtreg test dirs
-JTREG_TESTDIRS = demo/jvmti/gctest demo/jvmti/hprof
+# When called from JPRT the TESTDIRS variable is set to the jtreg tests to run
ifdef TESTDIRS
- JTREG_TESTDIRS = $(TESTDIRS)
+ TEST_SELECTION = $(TESTDIRS)
+endif
+
+ifdef CONCURRENCY
+ EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY)
endif
# Default JTREG to run (win32 script works for everybody)
JTREG = $(JT_HOME)/win32/bin/jtreg
+# Only run automatic tests
+JTREG_BASIC_OPTIONS += -a
+# 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)
+# Add any extra options
+JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS)
+# Set other vm and test options
+JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)
+
# Option to tell jtreg to not run tests marked with "ignore"
ifeq ($(PLATFORM), windows)
JTREG_KEY_OPTION = -k:!ignore
else
JTREG_KEY_OPTION = -k:\!ignore
endif
+JTREG_BASIC_OPTIONS += $(JTREG_KEY_OPTION)
-#EXTRA_JTREG_OPTIONS =
+# Make sure jtreg exists
+$(JTREG): $(JT_HOME)
-jtreg_tests: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
- $(JTREG) -a -v:fail,error \
- $(JTREG_KEY_OPTION) \
- $(EXTRA_JTREG_OPTIONS) \
- -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport \
- -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork \
- -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \
- $(JAVA_OPTIONS:%=-vmoption:%) \
- $(JTREG_TESTDIRS) \
- || $(BUNDLE_UP_FAILED)
- $(BUNDLE_UP)
+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
@@ -210,7 +309,7 @@
# clienttest (make sure various basic java client options work)
-clienttest: prep $(PRODUCT_HOME)
+hotspot_clienttest clienttest: prep $(PRODUCT_HOME)
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
@@ -218,73 +317,27 @@
$(RM) $(PRODUCT_HOME)/jre/bin/client/classes.jsa
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -Xshare:dump
-PHONY_LIST += clienttest
+PHONY_LIST += hotspot_clienttest clienttest
################################################################
# servertest (make sure various basic java server options work)
-servertest: prep $(PRODUCT_HOME)
+hotspot_servertest servertest: prep $(PRODUCT_HOME)
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -version
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -help
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -X
-PHONY_LIST += servertest
+PHONY_LIST += hotspot_servertest servertest
################################################################
# internalvmtests (run internal unit tests inside the VM)
-internalvmtests: prep $(PRODUCT_HOME)
+hotspot_internalvmtests internalvmtests: prep $(PRODUCT_HOME)
$(PRODUCT_HOME)/bin/java $(JAVA_OPTIONS) -XX:+ExecuteInternalVMTests -version
-PHONY_LIST += internalvmtests
-
-################################################################
-
-# wbapitest (make sure the whitebox testing api classes work
-
-wbapitest: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
- $(JTREG) -a -v:fail,error \
- $(JTREG_KEY_OPTION) \
- $(EXTRA_JTREG_OPTIONS) \
- -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport \
- -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork \
- -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \
- $(JAVA_OPTIONS:%=-vmoption:%) \
- $(shell $(GETMIXEDPATH) "$(TEST_ROOT)")/sanity \
- || $(BUNDLE_UP_FAILED)
- $(BUNDLE_UP)
-
-PHONY_LIST += wbapitest
-
-################################################################
-
-# packtest
-
-# Expect JPRT to set JPRT_PACKTEST_HOME.
-PACKTEST_HOME = /net/jprt-web.sfbay.sun.com/jprt/allproducts/packtest
-ifdef JPRT_PACKTEST_HOME
- PACKTEST_HOME = $(JPRT_PACKTEST_HOME)
-endif
-
-#EXTRA_PACKTEST_OPTIONS =
-
-packtest: prep $(PACKTEST_HOME)/ptest $(PRODUCT_HOME)
- ( $(CD) $(PACKTEST_HOME) && \
- $(PACKTEST_HOME)/ptest \
- -t "$(PRODUCT_HOME)" \
- $(PACKTEST_STRESS_OPTION) \
- $(EXTRA_PACKTEST_OPTIONS) \
- -W $(ABS_TEST_OUTPUT_DIR) \
- $(JAVA_OPTIONS:%=-J %) \
- ) || $(BUNDLE_UP_FAILED)
- $(BUNDLE_UP)
-
-packtest_stress: PACKTEST_STRESS_OPTION=-s
-packtest_stress: packtest
-
-PHONY_LIST += packtest packtest_stress
+PHONY_LIST += hotspot_internalvmtests internalvmtests
################################################################
@@ -292,4 +345,3 @@
.PHONY: all clean prep $(PHONY_LIST)
################################################################
-
--- a/hotspot/test/TEST.groups Sat Jul 19 00:34:40 2014 +0400
+++ b/hotspot/test/TEST.groups Sat Jul 19 13:43:02 2014 +0400
@@ -257,6 +257,7 @@
gc/arguments/TestCMSHeapSizeFlags.java \
gc/arguments/TestMaxNewSize.java \
gc/arguments/TestUseCompressedOopsErgo.java \
+ gc/class_unloading/TestCMSClassUnloadingDisabledHWM.java \
gc/concurrentMarkSweep/ \
gc/startup_warnings/TestCMS.java \
gc/startup_warnings/TestCMSIncrementalMode.java \
@@ -311,3 +312,24 @@
-:needs_parallelgc
+# When called from top level the test suites use the hotspot_ prefix
+hotspot_wbapitest = \
+ sanity/
+
+hotspot_compiler = \
+ sanity/ExecuteInternalVMTests.java
+
+hotspot_gc = \
+ sanity/ExecuteInternalVMTests.java
+
+hotspot_runtime = \
+ sanity/ExecuteInternalVMTests.java
+
+hotspot_serviceability = \
+ sanity/ExecuteInternalVMTests.java
+
+hotspot_all = \
+ :hotspot_compiler \
+ :hotspot_gc \
+ :hotspot_runtime \
+ :hotspot_serviceability
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/TraceExceptionsTest.java Sat Jul 19 13:43:02 2014 +0400
@@ -0,0 +1,48 @@
+/*
+ * 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 8048933
+ * @summary TraceExceptions output should have the exception message - useful for ClassNotFoundExceptions especially
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+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());
+ output.shouldContain("<a 'java/lang/ClassNotFoundException': NoClassFound>");
+ output.shouldNotContain("<a 'java/lang/ClassNotFoundException'>");
+ output.shouldHaveExitValue(1);
+ }
+}