Merge
This commit is contained in:
commit
726b299ae0
@ -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.DebuggerException;
|
||||
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 @@ public class HotSpotAgent {
|
||||
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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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 @@ public class PlatformInfo {
|
||||
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 {
|
||||
|
@ -350,21 +350,25 @@ jprt.make.rule.test.targets.standard.internalvmtests = \
|
||||
${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}
|
||||
|
@ -297,27 +297,23 @@ ifeq ($(JVM_VARIANT_MINIMAL1),true)
|
||||
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))
|
||||
|
||||
|
||||
|
@ -251,6 +251,49 @@ void VM_Version::initialize() {
|
||||
// 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 @@ void VM_Version::initialize() {
|
||||
|
||||
#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");
|
||||
|
@ -394,6 +394,8 @@ void VM_Version::get_processor_features() {
|
||||
_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 @@ void VM_Version::get_processor_features() {
|
||||
// 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 @@ void VM_Version::get_processor_features() {
|
||||
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);
|
||||
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
static intx prefetch_data_size() {
|
||||
return L1_line_size();
|
||||
}
|
||||
|
||||
//
|
||||
// Feature identification
|
||||
//
|
||||
|
@ -1213,10 +1213,6 @@ void os::die() {
|
||||
::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
|
||||
|
||||
|
@ -1172,10 +1172,6 @@ void os::die() {
|
||||
::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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
// 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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(saved_jvm_path, buf);
|
||||
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
||||
}
|
||||
|
||||
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
|
||||
|
@ -1553,9 +1553,6 @@ void os::die() {
|
||||
::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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
// 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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(saved_jvm_path, buf);
|
||||
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
||||
}
|
||||
|
||||
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
|
||||
|
@ -1543,9 +1543,6 @@ void os::die() {
|
||||
::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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
// 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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(saved_jvm_path, buf);
|
||||
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1824,7 +1824,9 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
// 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 @@ void os::jvm_path(char *buf, jint buflen) {
|
||||
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 @@ LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||
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);
|
||||
|
@ -919,7 +919,7 @@ void ClassFileParser::parse_field_attributes(u2 attributes_count,
|
||||
"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 @@ methodHandle ClassFileParser::parse_method(bool is_interface,
|
||||
"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 @@ intArray* ClassFileParser::sort_methods(Array<Method*>* methods) {
|
||||
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 @@ void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_b
|
||||
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:
|
||||
|
@ -266,6 +266,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC {
|
||||
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,
|
||||
|
@ -1239,6 +1239,16 @@ oop java_lang_Throwable::message(Handle throwable) {
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -520,6 +520,7 @@ class java_lang_Throwable: AllStatic {
|
||||
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);
|
||||
|
@ -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 @@ void StackMapTable::check_jump_target(
|
||||
}
|
||||
// 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(
|
||||
|
@ -633,6 +633,9 @@ void ClassVerifier::verify_method(methodHandle m, TRAPS) {
|
||||
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 @@ void ClassVerifier::verify_invoke_init(
|
||||
"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 @@ void ClassVerifier::verify_invoke_init(
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +258,9 @@ class ClassVerifier : public StackObj {
|
||||
|
||||
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 @@ class ClassVerifier : public StackObj {
|
||||
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(
|
||||
|
@ -2132,6 +2132,7 @@ void CompileBroker::set_last_compile(CompilerThread* thread, methodHandle method
|
||||
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;
|
||||
|
||||
|
@ -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 @@ void VM_GenCollectFull::doit() {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -430,9 +430,18 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -244,10 +244,8 @@ void InterpreterOopMap::print() const {
|
||||
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 @@ void OopMapCacheEntry::set_mask(CellTypeState *vars, CellTypeState *stack, int s
|
||||
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
|
||||
|
@ -66,19 +66,15 @@ class InterpreterOopMap: ResourceObj {
|
||||
|
||||
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 @@ class InterpreterOopMap: ResourceObj {
|
||||
|
||||
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 @@ class InterpreterOopMap: ResourceObj {
|
||||
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; }
|
||||
|
@ -520,13 +520,9 @@ bool ConstantPool::resolve_class_constants(TRAPS) {
|
||||
|
||||
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
|
||||
|
@ -251,6 +251,17 @@ void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) {
|
||||
// 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 @@ bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle tar
|
||||
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 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
|
||||
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 @@ bool klassVtable::needs_new_vtable_entry(methodHandle target_method,
|
||||
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;
|
||||
|
@ -247,15 +247,6 @@ void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
|
||||
"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 @@ JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
|
||||
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 @@ JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
|
||||
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 @@ void execute_internal_vm_tests() {
|
||||
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
|
||||
|
@ -185,6 +185,9 @@ static void NativeReportJNIWarning(JavaThread* thr, const char *msg) {
|
||||
* 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 @@ check_pending_exception(JavaThread* thr) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ functionExit(JavaThread* thr)
|
||||
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 @@ JNI_ENTRY_CHECKED(jint,
|
||||
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 @@ JNI_ENTRY_CHECKED(jint,
|
||||
}
|
||||
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 @@ JNI_ENTRY_CHECKED(jobject,
|
||||
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 @@ JNI_ENTRY_CHECKED(void,
|
||||
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 @@ JNI_ENTRY_CHECKED(void, \
|
||||
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 @@ JNI_ENTRY_CHECKED(void, \
|
||||
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 @@ JNI_ENTRY_CHECKED(void,
|
||||
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 @@ JNI_ENTRY_CHECKED(void,
|
||||
checkString(thr, str);
|
||||
)
|
||||
UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf);
|
||||
thr->set_pending_jni_exception_check("GetStringUTFRegion");
|
||||
functionExit(thr);
|
||||
JNI_END
|
||||
|
||||
|
@ -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 @@ bool VM_GetOrSetLocal::doit_prologue() {
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -35,6 +35,18 @@ class Atomic : AllStatic {
|
||||
// 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 @@ class Atomic : AllStatic {
|
||||
// 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 @@ class Atomic : AllStatic {
|
||||
// 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
|
||||
|
@ -1216,6 +1216,11 @@ class CommandLineFlags {
|
||||
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 " \
|
||||
|
@ -2497,6 +2497,10 @@ void ObjectMonitor::DeferredInitialize() {
|
||||
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 @@ void ObjectMonitor::DeferredInitialize() {
|
||||
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() {
|
||||
}
|
||||
|
@ -189,6 +189,8 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
// 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
|
||||
|
@ -469,9 +469,6 @@ class os: AllStatic {
|
||||
// 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);
|
||||
|
||||
|
@ -392,19 +392,22 @@ void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
|
||||
// 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 @@ void ObjectSynchronizer::release_monitors_owned_by_thread(TRAPS) {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
|
@ -121,6 +121,9 @@ class ObjectSynchronizer : AllStatic {
|
||||
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;
|
||||
|
||||
|
@ -50,6 +50,7 @@ bool Abstract_VM_Version::_supports_atomic_getset8 = false;
|
||||
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
|
||||
|
@ -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 @@ class Abstract_VM_Version: AllStatic {
|
||||
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 @@ class Abstract_VM_Version: AllStatic {
|
||||
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() {
|
||||
|
@ -989,7 +989,6 @@ void VMError::report_and_die() {
|
||||
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 {
|
||||
|
@ -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 @@ ifeq ($(OSNAME), SunOS)
|
||||
ARCH=i586
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OSNAME), Linux)
|
||||
ifeq ($(UNAME_S), Linux)
|
||||
PLATFORM = linux
|
||||
SLASH_JAVA = /java
|
||||
ARCH = $(shell uname -m)
|
||||
@ -46,7 +68,7 @@ ifeq ($(OSNAME), Linux)
|
||||
ARCH = i586
|
||||
endif
|
||||
endif
|
||||
ifeq ($(OSNAME), Darwin)
|
||||
ifeq ($(UNAME_S), Darwin)
|
||||
PLATFORM = bsd
|
||||
SLASH_JAVA = /java
|
||||
ARCH = $(shell uname -m)
|
||||
@ -54,7 +76,7 @@ ifeq ($(OSNAME), Darwin)
|
||||
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 @@ ifeq ($(findstring BSD,$(OSNAME)), BSD)
|
||||
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 @@ ifdef ALT_SLASH_JAVA
|
||||
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 @@ ifdef JPRT_ARCHIVE_BUNDLE
|
||||
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 @@ clean:
|
||||
|
||||
# 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 @@ PHONY_LIST += jtreg_tests
|
||||
|
||||
# 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 @@ clienttest: prep $(PRODUCT_HOME)
|
||||
$(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_LIST += packtest packtest_stress
|
||||
.PHONY: all clean prep $(PHONY_LIST)
|
||||
|
||||
################################################################
|
||||
|
||||
|
@ -257,6 +257,7 @@ needs_cmsgc = \
|
||||
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 @@ applicable_cmsgc = \
|
||||
-: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
|
||||
|
48
hotspot/test/runtime/CommandLine/TraceExceptionsTest.java
Normal file
48
hotspot/test/runtime/CommandLine/TraceExceptionsTest.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user