--- a/.hgtags-top-repo Wed Jan 30 13:04:22 2013 -0800
+++ b/.hgtags-top-repo Wed Jul 05 18:38:03 2017 +0200
@@ -195,3 +195,4 @@
51ad2a34342055333eb5f36e2fb514b027895708 jdk8-b71
c1be681d80a1f1c848dc671d664fccb19e046a12 jdk8-b72
93b9664f97eeb6f89397a8842318ebacaac9feb9 jdk8-b73
+b43aa5bd8ca5c8121336495382d35ecfa7a71536 jdk8-b74
--- a/common/autoconf/generated-configure.sh Wed Jan 30 13:04:22 2013 -0800
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 18:38:03 2017 +0200
@@ -3723,7 +3723,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1358499442
+DATE_WHEN_GENERATED=1359376859
###############################################################################
#
--- a/common/autoconf/jdk-options.m4 Wed Jan 30 13:04:22 2013 -0800
+++ b/common/autoconf/jdk-options.m4 Wed Jul 05 18:38:03 2017 +0200
@@ -389,7 +389,8 @@
AC_MSG_ERROR([Milestone must have a value])
elif test "x$with_milestone" != x; then
MILESTONE="$with_milestone"
-else
+fi
+if test "x$MILESTONE" = x; then
MILESTONE=internal
fi
--- a/common/autoconf/libraries.m4 Wed Jan 30 13:04:22 2013 -0800
+++ b/common/autoconf/libraries.m4 Wed Jul 05 18:38:03 2017 +0200
@@ -136,6 +136,12 @@
AC_PATH_X
AC_PATH_XTRA
+# AC_PATH_XTRA creates X_LIBS and sometimes adds -R flags. When cross compiling
+# this doesn't make sense so we remove it.
+if test "x$COMPILE_TYPE" = xcross; then
+ X_LIBS=`$ECHO $X_LIBS | $SED 's/-R \{0,1\}[[^ ]]*//g'`
+fi
+
if test "x$no_x" = xyes && test "x$X11_NOT_NEEDED" != xyes; then
HELP_MSG_MISSING_DEPENDENCY([x11])
AC_MSG_ERROR([Could not find X11 libraries. $HELP_MSG])
--- a/common/bin/compare.sh Wed Jan 30 13:04:22 2013 -0800
+++ b/common/bin/compare.sh Wed Jul 05 18:38:03 2017 +0200
@@ -350,9 +350,15 @@
OTHER_DIR=$2
WORK_DIR=$3
ZIP_FILE=$4
+ # Optionally provide different name for other zipfile
+ OTHER_ZIP_FILE=$5
THIS_ZIP=$THIS_DIR/$ZIP_FILE
- OTHER_ZIP=$OTHER_DIR/$ZIP_FILE
+ if [ -n "$OTHER_ZIP_FILE" ]; then
+ OTHER_ZIP=$OTHER_DIR/$OTHER_ZIP_FILE
+ else
+ OTHER_ZIP=$OTHER_DIR/$ZIP_FILE
+ fi
THIS_SUFFIX="${THIS_ZIP##*.}"
OTHER_SUFFIX="${OTHER_ZIP##*.}"
@@ -962,6 +968,9 @@
echo "[FILTER] List filenames in the image to compare, works for jars, zips, libs and execs"
echo "Example:"
echo "bash ./common/bin/compareimages.sh CodePointIM.jar"
+ echo ""
+ echo "-2zips <file1> <file2> Compare two zip files only"
+ echo ""
exit 10
fi
@@ -1023,6 +1032,13 @@
-execs)
CMP_EXECS=true
;;
+ -2zips)
+ CMP_2_ZIPS=true
+ THIS_FILE=$2
+ OTHER_FILE=$3
+ shift
+ shift
+ ;;
*)
CMP_NAMES=false
CMP_PERMS=false
@@ -1041,6 +1057,18 @@
shift
done
+if [ "$CMP_2_ZIPS" = "true" ]; then
+ THIS_DIR="$(dirname $THIS_FILE)"
+ THIS_DIR="$(cd "$THIS_DIR" && pwd )"
+ OTHER_DIR="$(dirname $OTHER_FILE)"
+ OTHER_DIR="$(cd "$OTHER_DIR" && pwd )"
+ THIS_FILE_NAME="$(basename $THIS_FILE)"
+ OTHER_FILE_NAME="$(basename $OTHER_FILE)"
+ echo Comparing $THIS_DIR/$THIS_FILE_NAME and $OTHER_DIR/$OTHER_FILE_NAME
+ compare_zip_file $THIS_DIR $OTHER_DIR $COMPARE_ROOT/2zips $THIS_FILE_NAME $OTHER_FILE_NAME
+ exit
+fi
+
if [ "$CMP_NAMES" = "false" ] && [ "$CMP_TYPES" = "false" ] && [ "$CMP_PERMS" = "false" ] && [ "$CMP_GENERAL" = "false" ] && [ "$CMP_ZIPS" = "false" ] && [ "$CMP_JARS" = "false" ] && [ "$CMP_LIBS" = "false" ] && [ "$CMP_EXECS" = "false" ]; then
CMP_NAMES=true
CMP_PERMS=true
--- a/common/bin/compare_exceptions.sh.incl Wed Jan 30 13:04:22 2013 -0800
+++ b/common/bin/compare_exceptions.sh.incl Wed Jul 05 18:38:03 2017 +0200
@@ -887,6 +887,17 @@
./jre/bin/unpack200.exe
"
+# jabswitch.exe is compiled and linked with incremental turned on in the old
+# build. This makes no sense, so it's turned off in the new build.
+ACCEPTED_SIZE_DIFF="
+./bin/jabswitch.exe
+./jre/bin/jabswitch.exe
+"
+ACCEPTED_DIS_DIFF="
+./bin/jabswitch.exe
+./jre/bin/jabswitch.exe
+"
+
# On windows, there are unavoidable allignment issues making
# a perfect disasm diff impossible. Filter out the following:
# * Random parts of C++ symbols (this is a bit greedy, but does the trick)
--- a/common/makefiles/javadoc/CORE_PKGS.gmk Wed Jan 30 13:04:22 2013 -0800
+++ b/common/makefiles/javadoc/CORE_PKGS.gmk Wed Jul 05 18:38:03 2017 +0200
@@ -127,6 +127,11 @@
java.sql \
java.text \
java.text.spi \
+ java.time \
+ java.time.temporal \
+ java.time.calendar \
+ java.time.format \
+ java.time.zone \
java.util \
java.util.concurrent \
java.util.concurrent.atomic \
--- a/common/makefiles/javadoc/Javadoc.gmk Wed Jan 30 13:04:22 2013 -0800
+++ b/common/makefiles/javadoc/Javadoc.gmk Wed Jul 05 18:38:03 2017 +0200
@@ -1,4 +1,4 @@
-# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -269,6 +269,7 @@
-quiet \
-use \
-keywords \
+ -Xdoclint:none \
$(ADDITIONAL_JAVADOCFLAGS)
ifdef OPENJDK
--- a/hotspot/.hgtags Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/.hgtags Wed Jul 05 18:38:03 2017 +0200
@@ -308,3 +308,6 @@
d5cb5830f570d1304ea4b196dde672a291b55f29 jdk8-b72
1e129851479e4f5df439109fca2c7be1f1613522 hs25-b15
11619f33cd683c2f1d6ef72f1c6ff3dacf5a9f1c jdk8-b73
+70c89bd6b895a10d25ca70e08093c09ff2005fda hs25-b16
+1a3e54283c54aaa8b3437813e8507fbdc966e5b6 jdk8-b74
+b4391649e91ea8d37f66317a03d6d2573a93d10d hs25-b17
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Wed Jul 05 18:38:03 2017 +0200
@@ -52,6 +52,9 @@
private static int LOW_OFFSET;
private static int HIGH_OFFSET;
private static int FIELD_SLOTS;
+ private static short FIELDINFO_TAG_SIZE;
+ private static short FIELDINFO_TAG_MASK;
+ private static short FIELDINFO_TAG_OFFSET;
// ClassState constants
private static int CLASS_STATE_ALLOCATED;
@@ -96,9 +99,13 @@
NAME_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::name_index_offset").intValue();
SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::signature_index_offset").intValue();
INITVAL_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
- LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_offset").intValue();
- HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_offset").intValue();
+ LOW_OFFSET = db.lookupIntConstant("FieldInfo::low_packed_offset").intValue();
+ HIGH_OFFSET = db.lookupIntConstant("FieldInfo::high_packed_offset").intValue();
FIELD_SLOTS = db.lookupIntConstant("FieldInfo::field_slots").intValue();
+ FIELDINFO_TAG_SIZE = db.lookupIntConstant("FIELDINFO_TAG_SIZE").shortValue();
+ FIELDINFO_TAG_MASK = db.lookupIntConstant("FIELDINFO_TAG_MASK").shortValue();
+ FIELDINFO_TAG_OFFSET = db.lookupIntConstant("FIELDINFO_TAG_OFFSET").shortValue();
+
// read ClassState constants
CLASS_STATE_ALLOCATED = db.lookupIntConstant("InstanceKlass::allocated").intValue();
CLASS_STATE_LOADED = db.lookupIntConstant("InstanceKlass::loaded").intValue();
@@ -314,8 +321,12 @@
public int getFieldOffset(int index) {
U2Array fields = getFields();
- return VM.getVM().buildIntFromShorts(fields.at(index * FIELD_SLOTS + LOW_OFFSET),
- fields.at(index * FIELD_SLOTS + HIGH_OFFSET));
+ short lo = fields.at(index * FIELD_SLOTS + LOW_OFFSET);
+ short hi = fields.at(index * FIELD_SLOTS + HIGH_OFFSET);
+ if ((lo & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET) {
+ return VM.getVM().buildIntFromShorts(lo, hi) >> FIELDINFO_TAG_SIZE;
+ }
+ throw new RuntimeException("should not reach here");
}
// Accessors for declared fields
--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jul 05 18:38:03 2017 +0200
@@ -3,7 +3,7 @@
#
#
-# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -205,7 +205,6 @@
JVM_NewMultiArray;
JVM_OnExit;
JVM_Open;
- JVM_PrintStackTrace;
JVM_RaiseSignal;
JVM_RawMonitorCreate;
JVM_RawMonitorDestroy;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jul 05 18:38:03 2017 +0200
@@ -3,7 +3,7 @@
#
#
-# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -205,7 +205,6 @@
JVM_NewMultiArray;
JVM_OnExit;
JVM_Open;
- JVM_PrintStackTrace;
JVM_RaiseSignal;
JVM_RawMonitorCreate;
JVM_RawMonitorDestroy;
--- a/hotspot/make/hotspot_version Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/make/hotspot_version Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,11 @@
#
# Don't put quotes (fail windows build).
-HOTSPOT_VM_COPYRIGHT=Copyright 2012
+HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=15
+HS_BUILD_NUMBER=17
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -201,7 +201,6 @@
JVM_NewMultiArray;
JVM_OnExit;
JVM_Open;
- JVM_PrintStackTrace;
JVM_RaiseSignal;
JVM_RawMonitorCreate;
JVM_RawMonitorDestroy;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -201,7 +201,6 @@
JVM_NewMultiArray;
JVM_OnExit;
JVM_Open;
- JVM_PrintStackTrace;
JVM_RaiseSignal;
JVM_RawMonitorCreate;
JVM_RawMonitorDestroy;
--- a/hotspot/make/solaris/makefiles/mapfile-vers Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/make/solaris/makefiles/mapfile-vers Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -201,7 +201,6 @@
JVM_NewMultiArray;
JVM_OnExit;
JVM_Open;
- JVM_PrintStackTrace;
JVM_RaiseSignal;
JVM_RawMonitorCreate;
JVM_RawMonitorDestroy;
--- a/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/sparc/vm/vmStructs_sparc.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* JavaCallWrapper */ \
@@ -37,22 +37,12 @@
/******************************/ \
/* JavaFrameAnchor */ \
/******************************/ \
- volatile_nonstatic_field(JavaFrameAnchor, _flags, int) \
- \
+ volatile_nonstatic_field(JavaFrameAnchor, _flags, int)
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
-#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
- /* be present there) */
-
-
-#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
/******************************/ \
/* Register numbers (C2 only) */ \
/******************************/ \
@@ -90,15 +80,6 @@
declare_c2_constant(R_G6_num) \
declare_c2_constant(R_G7_num)
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
- /* be present there) */
-
-#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_SPARC_VM_VMSTRUCTS_SPARC_HPP
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -259,6 +259,10 @@
if (!has_vis1()) // Drop to 0 if no VIS1 support
UseVIS = 0;
+ if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
+ (cache_line_size > ContendedPaddingWidth))
+ ContendedPaddingWidth = cache_line_size;
+
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
tty->print("Allocation");
@@ -286,6 +290,9 @@
if (PrefetchFieldsAhead > 0) {
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
}
+ if (ContendedPaddingWidth > 0) {
+ tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
+ }
}
#endif // PRODUCT
}
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -2263,6 +2263,18 @@
emit_simd_arith(0x67, dst, src, VEX_SIMD_66);
}
+void Assembler::vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+ assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+ emit_vex_arith(0x67, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpermq(XMMRegister dst, XMMRegister src, int imm8, bool vector256) {
+ int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A, true, vector256);
+ emit_int8(0x00);
+ emit_int8(0xC0 | encode);
+ emit_int8(imm8);
+}
+
void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
assert(VM_Version::supports_sse4_2(), "");
InstructionMark im(this);
@@ -2475,7 +2487,7 @@
assert(dst != xnoreg, "sanity");
int dst_enc = dst->encoding();
// swap src<->dst for encoding
- vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256);
+ vex_prefix(src, 0, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256);
emit_int8(0x17);
emit_operand(dst, src);
}
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1395,6 +1395,10 @@
// Pack with unsigned saturation
void packuswb(XMMRegister dst, XMMRegister src);
void packuswb(XMMRegister dst, Address src);
+ void vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+
+ // Pemutation of 64bit words
+ void vpermq(XMMRegister dst, XMMRegister src, int imm8, bool vector256);
// SSE4.2 string instructions
void pcmpestri(XMMRegister xmm1, XMMRegister xmm2, int imm8);
--- a/hotspot/src/cpu/x86/vm/jni_x86.h Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/jni_x86.h Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,14 +38,9 @@
#define JNICALL
typedef int jint;
-#if defined(_LP64) && !defined(__APPLE__)
+#if defined(_LP64)
typedef long jlong;
#else
- /*
- * On _LP64 __APPLE__ "long" and "long long" are both 64 bits,
- * but we use the "long long" typedef to avoid complaints from
- * the __APPLE__ compiler about fprintf formats.
- */
typedef long long jlong;
#endif
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -6209,6 +6209,128 @@
}
BIND(L_exit);
}
+
+// encode char[] to byte[] in ISO_8859_1
+void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
+ XMMRegister tmp1Reg, XMMRegister tmp2Reg,
+ XMMRegister tmp3Reg, XMMRegister tmp4Reg,
+ Register tmp5, Register result) {
+ // rsi: src
+ // rdi: dst
+ // rdx: len
+ // rcx: tmp5
+ // rax: result
+ ShortBranchVerifier sbv(this);
+ assert_different_registers(src, dst, len, tmp5, result);
+ Label L_done, L_copy_1_char, L_copy_1_char_exit;
+
+ // set result
+ xorl(result, result);
+ // check for zero length
+ testl(len, len);
+ jcc(Assembler::zero, L_done);
+ movl(result, len);
+
+ // Setup pointers
+ lea(src, Address(src, len, Address::times_2)); // char[]
+ lea(dst, Address(dst, len, Address::times_1)); // byte[]
+ negptr(len);
+
+ if (UseSSE42Intrinsics || UseAVX >= 2) {
+ Label L_chars_8_check, L_copy_8_chars, L_copy_8_chars_exit;
+ Label L_chars_16_check, L_copy_16_chars, L_copy_16_chars_exit;
+
+ if (UseAVX >= 2) {
+ Label L_chars_32_check, L_copy_32_chars, L_copy_32_chars_exit;
+ movl(tmp5, 0xff00ff00); // create mask to test for Unicode chars in vector
+ movdl(tmp1Reg, tmp5);
+ vpbroadcastd(tmp1Reg, tmp1Reg);
+ jmpb(L_chars_32_check);
+
+ bind(L_copy_32_chars);
+ vmovdqu(tmp3Reg, Address(src, len, Address::times_2, -64));
+ vmovdqu(tmp4Reg, Address(src, len, Address::times_2, -32));
+ vpor(tmp2Reg, tmp3Reg, tmp4Reg, /* vector256 */ true);
+ vptest(tmp2Reg, tmp1Reg); // check for Unicode chars in vector
+ jccb(Assembler::notZero, L_copy_32_chars_exit);
+ vpackuswb(tmp3Reg, tmp3Reg, tmp4Reg, /* vector256 */ true);
+ vpermq(tmp4Reg, tmp3Reg, 0xD8, /* vector256 */ true);
+ vmovdqu(Address(dst, len, Address::times_1, -32), tmp4Reg);
+
+ bind(L_chars_32_check);
+ addptr(len, 32);
+ jccb(Assembler::lessEqual, L_copy_32_chars);
+
+ bind(L_copy_32_chars_exit);
+ subptr(len, 16);
+ jccb(Assembler::greater, L_copy_16_chars_exit);
+
+ } else if (UseSSE42Intrinsics) {
+ movl(tmp5, 0xff00ff00); // create mask to test for Unicode chars in vector
+ movdl(tmp1Reg, tmp5);
+ pshufd(tmp1Reg, tmp1Reg, 0);
+ jmpb(L_chars_16_check);
+ }
+
+ bind(L_copy_16_chars);
+ if (UseAVX >= 2) {
+ vmovdqu(tmp2Reg, Address(src, len, Address::times_2, -32));
+ vptest(tmp2Reg, tmp1Reg);
+ jccb(Assembler::notZero, L_copy_16_chars_exit);
+ vpackuswb(tmp2Reg, tmp2Reg, tmp1Reg, /* vector256 */ true);
+ vpermq(tmp3Reg, tmp2Reg, 0xD8, /* vector256 */ true);
+ } else {
+ if (UseAVX > 0) {
+ movdqu(tmp3Reg, Address(src, len, Address::times_2, -32));
+ movdqu(tmp4Reg, Address(src, len, Address::times_2, -16));
+ vpor(tmp2Reg, tmp3Reg, tmp4Reg, /* vector256 */ false);
+ } else {
+ movdqu(tmp3Reg, Address(src, len, Address::times_2, -32));
+ por(tmp2Reg, tmp3Reg);
+ movdqu(tmp4Reg, Address(src, len, Address::times_2, -16));
+ por(tmp2Reg, tmp4Reg);
+ }
+ ptest(tmp2Reg, tmp1Reg); // check for Unicode chars in vector
+ jccb(Assembler::notZero, L_copy_16_chars_exit);
+ packuswb(tmp3Reg, tmp4Reg);
+ }
+ movdqu(Address(dst, len, Address::times_1, -16), tmp3Reg);
+
+ bind(L_chars_16_check);
+ addptr(len, 16);
+ jccb(Assembler::lessEqual, L_copy_16_chars);
+
+ bind(L_copy_16_chars_exit);
+ subptr(len, 8);
+ jccb(Assembler::greater, L_copy_8_chars_exit);
+
+ bind(L_copy_8_chars);
+ movdqu(tmp3Reg, Address(src, len, Address::times_2, -16));
+ ptest(tmp3Reg, tmp1Reg);
+ jccb(Assembler::notZero, L_copy_8_chars_exit);
+ packuswb(tmp3Reg, tmp1Reg);
+ movq(Address(dst, len, Address::times_1, -8), tmp3Reg);
+ addptr(len, 8);
+ jccb(Assembler::lessEqual, L_copy_8_chars);
+
+ bind(L_copy_8_chars_exit);
+ subptr(len, 8);
+ jccb(Assembler::zero, L_done);
+ }
+
+ bind(L_copy_1_char);
+ load_unsigned_short(tmp5, Address(src, len, Address::times_2, 0));
+ testl(tmp5, 0xff00); // check if Unicode char
+ jccb(Assembler::notZero, L_copy_1_char_exit);
+ movb(Address(dst, len, Address::times_1, 0), tmp5);
+ addptr(len, 1);
+ jccb(Assembler::less, L_copy_1_char);
+
+ bind(L_copy_1_char_exit);
+ addptr(result, len); // len is negative count of not processed elements
+ bind(L_done);
+}
+
#undef BIND
#undef BLOCK_COMMENT
--- a/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/macroAssembler_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1135,6 +1135,10 @@
Register to, Register value, Register count,
Register rtmp, XMMRegister xtmp);
+ void encode_iso_array(Register src, Register dst, Register len,
+ XMMRegister tmp1, XMMRegister tmp2, XMMRegister tmp3,
+ XMMRegister tmp4, Register tmp5, Register result);
+
#undef VIRTUAL
};
--- a/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/vmStructs_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* JavaCallWrapper */ \
@@ -37,31 +37,14 @@
/******************************/ \
/* JavaFrameAnchor */ \
/******************************/ \
- volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*) \
- \
+ volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
- /* be present there) */
-#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
- /* be present there) */
-
-
-#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -661,6 +661,14 @@
}
}
}
+#if defined(COMPILER2) && defined(_ALLBSD_SOURCE)
+ if (MaxVectorSize > 16) {
+ // Limit vectors size to 16 bytes on BSD until it fixes
+ // restoring upper 128bit of YMM registers on return
+ // from signal handler.
+ FLAG_SET_DEFAULT(MaxVectorSize, 16);
+ }
+#endif // COMPILER2
// Use population count instruction if available.
if (supports_popcnt()) {
@@ -745,6 +753,10 @@
PrefetchFieldsAhead = prefetch_fields_ahead();
#endif
+ if (FLAG_IS_DEFAULT(ContendedPaddingWidth) &&
+ (cache_line_size > ContendedPaddingWidth))
+ ContendedPaddingWidth = cache_line_size;
+
#ifndef PRODUCT
if (PrintMiscellaneous && Verbose) {
tty->print_cr("Logical CPUs per core: %u",
@@ -791,6 +803,9 @@
if (PrefetchFieldsAhead > 0) {
tty->print_cr("PrefetchFieldsAhead %d", PrefetchFieldsAhead);
}
+ if (ContendedPaddingWidth > 0) {
+ tty->print_cr("ContendedPaddingWidth %d", ContendedPaddingWidth);
+ }
}
#endif // !PRODUCT
}
--- a/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad Wed Jul 05 18:38:03 2017 +0200
@@ -11687,6 +11687,23 @@
ins_pipe( pipe_slow );
%}
+// encode char[] to byte[] in ISO_8859_1
+instruct encode_iso_array(eSIRegP src, eDIRegP dst, eDXRegI len,
+ regD tmp1, regD tmp2, regD tmp3, regD tmp4,
+ eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{
+ match(Set result (EncodeISOArray src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
+
+ format %{ "Encode array $src,$dst,$len -> $result // KILL ECX, EDX, $tmp1, $tmp2, $tmp3, $tmp4, ESI, EDI " %}
+ ins_encode %{
+ __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
+ $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+
//----------Control Flow Instructions------------------------------------------
// Signed compare Instructions
instruct compI_eReg(eFlagsReg cr, rRegI op1, rRegI op2) %{
--- a/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad Wed Jul 05 18:38:03 2017 +0200
@@ -10495,6 +10495,23 @@
ins_pipe( pipe_slow );
%}
+// encode char[] to byte[] in ISO_8859_1
+instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
+ regD tmp1, regD tmp2, regD tmp3, regD tmp4,
+ rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
+ match(Set result (EncodeISOArray src (Binary dst len)));
+ effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
+
+ format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
+ ins_encode %{
+ __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
+ $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
+ $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
+ %}
+ ins_pipe( pipe_slow );
+%}
+
+
//----------Control Flow Instructions------------------------------------------
// Signed compare Instructions
--- a/hotspot/src/cpu/zero/vm/frame_zero.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -98,10 +98,20 @@
#endif // CC_INTERP
void frame::patch_pc(Thread* thread, address pc) {
- // We borrow this call to set the thread pointer in the interpreter
- // state; the hook to set up deoptimized frames isn't supplied it.
- assert(pc == NULL, "should be");
- get_interpreterState()->set_thread((JavaThread *) thread);
+
+ if (pc != NULL) {
+ _cb = CodeCache::find_blob(pc);
+ SharkFrame* sharkframe = zeroframe()->as_shark_frame();
+ sharkframe->set_pc(pc);
+ _pc = pc;
+ _deopt_state = is_deoptimized;
+
+ } else {
+ // We borrow this call to set the thread pointer in the interpreter
+ // state; the hook to set up deoptimized frames isn't supplied it.
+ assert(pc == NULL, "should be");
+ get_interpreterState()->set_thread((JavaThread *) thread);
+ }
}
bool frame::safe_for_sender(JavaThread *thread) {
--- a/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -45,27 +45,36 @@
case ZeroFrame::ENTRY_FRAME:
_pc = StubRoutines::call_stub_return_pc();
_cb = NULL;
+ _deopt_state = not_deoptimized;
break;
case ZeroFrame::INTERPRETER_FRAME:
_pc = NULL;
_cb = NULL;
+ _deopt_state = not_deoptimized;
break;
- case ZeroFrame::SHARK_FRAME:
+ case ZeroFrame::SHARK_FRAME: {
_pc = zero_sharkframe()->pc();
_cb = CodeCache::find_blob_unsafe(pc());
+ address original_pc = nmethod::get_deopt_original_pc(this);
+ if (original_pc != NULL) {
+ _pc = original_pc;
+ _deopt_state = is_deoptimized;
+ } else {
+ _deopt_state = not_deoptimized;
+ }
break;
-
+ }
case ZeroFrame::FAKE_STUB_FRAME:
_pc = NULL;
_cb = NULL;
+ _deopt_state = not_deoptimized;
break;
default:
ShouldNotReachHere();
}
- _deopt_state = not_deoptimized;
}
// Accessors
--- a/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -68,6 +68,10 @@
return (address) value_of_word(pc_off);
}
+ void set_pc(address pc) const {
+ *((address*) addr_of_word(pc_off)) = pc;
+ }
+
intptr_t* unextended_sp() const {
return (intptr_t *) value_of_word(unextended_sp_off);
}
--- a/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/cpu/zero/vm/vmStructs_zero.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -30,28 +30,12 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_STRUCTS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
-#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must */
- /* be present there) */
+#define VM_TYPES_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
-#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_INT_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and must */
- /* be present there) */
+#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // CPU_ZERO_VM_VMSTRUCTS_ZERO_HPP
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -243,29 +243,32 @@
int mib[2];
size_t len;
int cpu_val;
- u_long mem_val;
+ julong mem_val;
/* get processors count via hw.ncpus sysctl */
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
len = sizeof(cpu_val);
if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) {
+ assert(len == sizeof(cpu_val), "unexpected data size");
set_processor_count(cpu_val);
}
else {
set_processor_count(1); // fallback
}
- /* get physical memory via hw.usermem sysctl (hw.usermem is used
- * instead of hw.physmem because we need size of allocatable memory
+ /* get physical memory via hw.memsize sysctl (hw.memsize is used
+ * since it returns a 64 bit value)
*/
mib[0] = CTL_HW;
- mib[1] = HW_USERMEM;
+ mib[1] = HW_MEMSIZE;
len = sizeof(mem_val);
- if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1)
+ if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) {
+ assert(len == sizeof(mem_val), "unexpected data size");
_physical_memory = mem_val;
- else
+ } else {
_physical_memory = 256*1024*1024; // fallback (XXXBSD?)
+ }
#ifdef __OpenBSD__
{
@@ -4091,11 +4094,12 @@
}
-- _nParked ;
- // In theory we could move the ST of 0 into _Event past the unlock(),
- // but then we'd need a MEMBAR after the ST.
_Event = 0 ;
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other.
+ OrderAccess::fence();
}
guarantee (_Event >= 0, "invariant") ;
}
@@ -4158,40 +4162,44 @@
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
assert (_nParked == 0, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other.
+ OrderAccess::fence();
return ret;
}
void os::PlatformEvent::unpark() {
- int v, AnyWaiters ;
- for (;;) {
- v = _Event ;
- if (v > 0) {
- // The LD of _Event could have reordered or be satisfied
- // by a read-aside from this processor's write buffer.
- // To avoid problems execute a barrier and then
- // ratify the value.
- OrderAccess::fence() ;
- if (_Event == v) return ;
- continue ;
- }
- if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
+ // Transitions for _Event:
+ // 0 :=> 1
+ // 1 :=> 1
+ // -1 :=> either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
+ // unpark() calls.
+ // See also: "Semaphores in Plan 9" by Mullender & Cox
+ //
+ // Note: Forcing a transition from "-1" to "1" on an unpark() means
+ // that it will take two back-to-back park() calls for the owning
+ // thread to block. This has the benefit of forcing a spurious return
+ // from the first park() call after an unpark() call which will help
+ // shake out uses of park() and unpark() without condition variables.
+
+ if (Atomic::xchg(1, &_Event) >= 0) return;
+
+ // Wait for the thread associated with the event to vacate
+ int status = pthread_mutex_lock(_mutex);
+ assert_status(status == 0, status, "mutex_lock");
+ int AnyWaiters = _nParked;
+ assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
+ if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
+ AnyWaiters = 0;
+ pthread_cond_signal(_cond);
}
- if (v < 0) {
- // Wait for the thread associated with the event to vacate
- int status = pthread_mutex_lock(_mutex);
- assert_status(status == 0, status, "mutex_lock");
- AnyWaiters = _nParked ;
- assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
- if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
- AnyWaiters = 0 ;
- pthread_cond_signal (_cond);
- }
- status = pthread_mutex_unlock(_mutex);
- assert_status(status == 0, status, "mutex_unlock");
- if (AnyWaiters != 0) {
- status = pthread_cond_signal(_cond);
- assert_status(status == 0, status, "cond_signal");
- }
+ status = pthread_mutex_unlock(_mutex);
+ assert_status(status == 0, status, "mutex_unlock");
+ if (AnyWaiters != 0) {
+ status = pthread_cond_signal(_cond);
+ assert_status(status == 0, status, "cond_signal");
}
// Note that we signal() _after dropping the lock for "immortal" Events.
@@ -4277,13 +4285,14 @@
}
void Parker::park(bool isAbsolute, jlong time) {
+ // Ideally we'd do something useful while spinning, such
+ // as calling unpackTime().
+
// Optional fast-path check:
// Return immediately if a permit is available.
- if (_counter > 0) {
- _counter = 0 ;
- OrderAccess::fence();
- return ;
- }
+ // We depend on Atomic::xchg() having full barrier semantics
+ // since we are doing a lock-free update to _counter.
+ if (Atomic::xchg(0, &_counter) > 0) return;
Thread* thread = Thread::current();
assert(thread->is_Java_thread(), "Must be JavaThread");
@@ -4324,6 +4333,8 @@
_counter = 0;
status = pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other and Java-level accesses.
OrderAccess::fence();
return;
}
@@ -4360,12 +4371,14 @@
_counter = 0 ;
status = pthread_mutex_unlock(_mutex) ;
assert_status(status == 0, status, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other and Java-level accesses.
+ OrderAccess::fence();
+
// If externally suspended while waiting, re-suspend
if (jt->handle_special_suspend_equivalent_condition()) {
jt->java_suspend_self();
}
-
- OrderAccess::fence();
}
void Parker::unpark() {
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,14 +59,6 @@
return ":";
}
-inline const char* os::jlong_format_specifier() {
- return "%lld";
-}
-
-inline const char* os::julong_format_specifier() {
- return "%llu";
-}
-
// File names are case-sensitive on windows only
inline int os::file_name_strcmp(const char* s1, const char* s2) {
return strcmp(s1, s2);
--- a/hotspot/src/os/linux/vm/os_linux.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -5001,11 +5001,12 @@
}
-- _nParked ;
- // In theory we could move the ST of 0 into _Event past the unlock(),
- // but then we'd need a MEMBAR after the ST.
_Event = 0 ;
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other.
+ OrderAccess::fence();
}
guarantee (_Event >= 0, "invariant") ;
}
@@ -5068,40 +5069,44 @@
status = pthread_mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
assert (_nParked == 0, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other.
+ OrderAccess::fence();
return ret;
}
void os::PlatformEvent::unpark() {
- int v, AnyWaiters ;
- for (;;) {
- v = _Event ;
- if (v > 0) {
- // The LD of _Event could have reordered or be satisfied
- // by a read-aside from this processor's write buffer.
- // To avoid problems execute a barrier and then
- // ratify the value.
- OrderAccess::fence() ;
- if (_Event == v) return ;
- continue ;
- }
- if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
- }
- if (v < 0) {
- // Wait for the thread associated with the event to vacate
- int status = pthread_mutex_lock(_mutex);
- assert_status(status == 0, status, "mutex_lock");
- AnyWaiters = _nParked ;
- assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
- if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
- AnyWaiters = 0 ;
- pthread_cond_signal (_cond);
- }
- status = pthread_mutex_unlock(_mutex);
- assert_status(status == 0, status, "mutex_unlock");
- if (AnyWaiters != 0) {
- status = pthread_cond_signal(_cond);
- assert_status(status == 0, status, "cond_signal");
- }
+ // Transitions for _Event:
+ // 0 :=> 1
+ // 1 :=> 1
+ // -1 :=> either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
+ // unpark() calls.
+ // See also: "Semaphores in Plan 9" by Mullender & Cox
+ //
+ // Note: Forcing a transition from "-1" to "1" on an unpark() means
+ // that it will take two back-to-back park() calls for the owning
+ // thread to block. This has the benefit of forcing a spurious return
+ // from the first park() call after an unpark() call which will help
+ // shake out uses of park() and unpark() without condition variables.
+
+ if (Atomic::xchg(1, &_Event) >= 0) return;
+
+ // Wait for the thread associated with the event to vacate
+ int status = pthread_mutex_lock(_mutex);
+ assert_status(status == 0, status, "mutex_lock");
+ int AnyWaiters = _nParked;
+ assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
+ if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
+ AnyWaiters = 0;
+ pthread_cond_signal(_cond);
+ }
+ status = pthread_mutex_unlock(_mutex);
+ assert_status(status == 0, status, "mutex_unlock");
+ if (AnyWaiters != 0) {
+ status = pthread_cond_signal(_cond);
+ assert_status(status == 0, status, "cond_signal");
}
// Note that we signal() _after dropping the lock for "immortal" Events.
@@ -5187,13 +5192,14 @@
}
void Parker::park(bool isAbsolute, jlong time) {
+ // Ideally we'd do something useful while spinning, such
+ // as calling unpackTime().
+
// Optional fast-path check:
// Return immediately if a permit is available.
- if (_counter > 0) {
- _counter = 0 ;
- OrderAccess::fence();
- return ;
- }
+ // We depend on Atomic::xchg() having full barrier semantics
+ // since we are doing a lock-free update to _counter.
+ if (Atomic::xchg(0, &_counter) > 0) return;
Thread* thread = Thread::current();
assert(thread->is_Java_thread(), "Must be JavaThread");
@@ -5234,6 +5240,8 @@
_counter = 0;
status = pthread_mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other and Java-level accesses.
OrderAccess::fence();
return;
}
@@ -5270,12 +5278,14 @@
_counter = 0 ;
status = pthread_mutex_unlock(_mutex) ;
assert_status(status == 0, status, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other and Java-level accesses.
+ OrderAccess::fence();
+
// If externally suspended while waiting, re-suspend
if (jt->handle_special_suspend_equivalent_condition()) {
jt->java_suspend_self();
}
-
- OrderAccess::fence();
}
void Parker::unpark() {
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,14 +68,6 @@
return ":";
}
-inline const char* os::jlong_format_specifier() {
- return "%lld";
-}
-
-inline const char* os::julong_format_specifier() {
- return "%llu";
-}
-
// File names are case-sensitive on windows only
inline int os::file_name_strcmp(const char* s1, const char* s2) {
return strcmp(s1, s2);
--- a/hotspot/src/os/posix/launcher/java_md.c Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/posix/launcher/java_md.c Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1876,11 +1876,6 @@
}
}
-const char *
-jlong_format_specifier() {
- return "%lld";
-}
-
/*
* Block current thread and continue execution in a new thread
*/
--- a/hotspot/src/os/posix/launcher/java_md.h Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/posix/launcher/java_md.h Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -64,6 +64,12 @@
#define Counter2Micros(counts) (1)
#endif /* HAVE_GETHRTIME */
+#ifdef _LP64
+#define JLONG_FORMAT "%ld"
+#else
+#define JLONG_FORMAT "%lld"
+#endif
+
/*
* Function prototypes.
*/
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -6014,6 +6014,9 @@
_Event = 0 ;
status = os::Solaris::mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other.
+ OrderAccess::fence();
}
}
@@ -6055,51 +6058,43 @@
_Event = 0 ;
status = os::Solaris::mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock");
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other.
+ OrderAccess::fence();
return ret;
}
void os::PlatformEvent::unpark() {
- int v, AnyWaiters;
-
- // Increment _Event.
- // Another acceptable implementation would be to simply swap 1
- // into _Event:
- // if (Swap (&_Event, 1) < 0) {
- // mutex_lock (_mutex) ; AnyWaiters = nParked; mutex_unlock (_mutex) ;
- // if (AnyWaiters) cond_signal (_cond) ;
- // }
-
- for (;;) {
- v = _Event ;
- if (v > 0) {
- // The LD of _Event could have reordered or be satisfied
- // by a read-aside from this processor's write buffer.
- // To avoid problems execute a barrier and then
- // ratify the value. A degenerate CAS() would also work.
- // Viz., CAS (v+0, &_Event, v) == v).
- OrderAccess::fence() ;
- if (_Event == v) return ;
- continue ;
- }
- if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
- }
+ // Transitions for _Event:
+ // 0 :=> 1
+ // 1 :=> 1
+ // -1 :=> either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
+ // unpark() calls.
+ // See also: "Semaphores in Plan 9" by Mullender & Cox
+ //
+ // Note: Forcing a transition from "-1" to "1" on an unpark() means
+ // that it will take two back-to-back park() calls for the owning
+ // thread to block. This has the benefit of forcing a spurious return
+ // from the first park() call after an unpark() call which will help
+ // shake out uses of park() and unpark() without condition variables.
+
+ if (Atomic::xchg(1, &_Event) >= 0) return;
// If the thread associated with the event was parked, wake it.
- if (v < 0) {
- int status ;
- // Wait for the thread assoc with the PlatformEvent to vacate.
- status = os::Solaris::mutex_lock(_mutex);
- assert_status(status == 0, status, "mutex_lock");
- AnyWaiters = _nParked ;
- status = os::Solaris::mutex_unlock(_mutex);
- assert_status(status == 0, status, "mutex_unlock");
- guarantee (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
- if (AnyWaiters != 0) {
- // We intentional signal *after* dropping the lock
- // to avoid a common class of futile wakeups.
- status = os::Solaris::cond_signal(_cond);
- assert_status(status == 0, status, "cond_signal");
- }
+ // Wait for the thread assoc with the PlatformEvent to vacate.
+ int status = os::Solaris::mutex_lock(_mutex);
+ assert_status(status == 0, status, "mutex_lock");
+ int AnyWaiters = _nParked;
+ status = os::Solaris::mutex_unlock(_mutex);
+ assert_status(status == 0, status, "mutex_unlock");
+ guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
+ if (AnyWaiters != 0) {
+ // We intentional signal *after* dropping the lock
+ // to avoid a common class of futile wakeups.
+ status = os::Solaris::cond_signal(_cond);
+ assert_status(status == 0, status, "cond_signal");
}
}
@@ -6177,14 +6172,14 @@
}
void Parker::park(bool isAbsolute, jlong time) {
+ // Ideally we'd do something useful while spinning, such
+ // as calling unpackTime().
// Optional fast-path check:
// Return immediately if a permit is available.
- if (_counter > 0) {
- _counter = 0 ;
- OrderAccess::fence();
- return ;
- }
+ // We depend on Atomic::xchg() having full barrier semantics
+ // since we are doing a lock-free update to _counter.
+ if (Atomic::xchg(0, &_counter) > 0) return;
// Optional fast-exit: Check interrupt before trying to wait
Thread* thread = Thread::current();
@@ -6226,6 +6221,8 @@
_counter = 0;
status = os::Solaris::mutex_unlock(_mutex);
assert (status == 0, "invariant") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other and Java-level accesses.
OrderAccess::fence();
return;
}
@@ -6267,12 +6264,14 @@
_counter = 0 ;
status = os::Solaris::mutex_unlock(_mutex);
assert_status(status == 0, status, "mutex_unlock") ;
+ // Paranoia to ensure our locked and lock-free paths interact
+ // correctly with each other and Java-level accesses.
+ OrderAccess::fence();
// If externally suspended while waiting, re-suspend
if (jt->handle_special_suspend_equivalent_condition()) {
jt->java_suspend_self();
}
- OrderAccess::fence();
}
void Parker::unpark() {
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -50,9 +50,6 @@
inline const char* os::line_separator() { return "\n"; }
inline const char* os::path_separator() { return ":"; }
-inline const char* os::jlong_format_specifier() { return "%lld"; }
-inline const char* os::julong_format_specifier() { return "%llu"; }
-
// File names are case-sensitive on windows only
inline int os::file_name_strcmp(const char* s1, const char* s2) {
return strcmp(s1, s2);
--- a/hotspot/src/os/windows/launcher/java_md.c Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/windows/launcher/java_md.c Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1323,11 +1323,6 @@
}
}
-const char *
-jlong_format_specifier() {
- return "%I64d";
-}
-
/*
* Block current thread and continue execution in a new thread
*/
--- a/hotspot/src/os/windows/launcher/java_md.h Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/windows/launcher/java_md.h Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,8 @@
extern int _main(int argc, char **argv);
#endif
+#define JLONG_FORMAT "%I64d"
+
/*
* Function prototypes.
*/
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -49,7 +49,7 @@
pfn_SymSetOptions _pfnSymSetOptions = (pfn_SymSetOptions)::GetProcAddress(handle, "SymSetOptions");
pfn_SymInitialize _pfnSymInitialize = (pfn_SymInitialize)::GetProcAddress(handle, "SymInitialize");
_pfnSymGetSymFromAddr64 = (pfn_SymGetSymFromAddr64)::GetProcAddress(handle, "SymGetSymFromAddr64");
- _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)GetProcAddress(handle, "UnDecorateSymbolName");
+ _pfnUndecorateSymbolName = (pfn_UndecorateSymbolName)::GetProcAddress(handle, "UnDecorateSymbolName");
if (_pfnSymSetOptions == NULL || _pfnSymInitialize == NULL || _pfnSymGetSymFromAddr64 == NULL) {
_pfnSymGetSymFromAddr64 = NULL;
@@ -60,8 +60,9 @@
return;
}
- _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
- if (!_pfnSymInitialize(GetCurrentProcess(), NULL, TRUE)) {
+ HANDLE hProcess = ::GetCurrentProcess();
+ _pfnSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS | SYMOPT_EXACT_SYMBOLS);
+ if (!_pfnSymInitialize(hProcess, NULL, TRUE)) {
_pfnSymGetSymFromAddr64 = NULL;
_pfnUndecorateSymbolName = NULL;
::FreeLibrary(handle);
@@ -70,6 +71,77 @@
return;
}
+ // set pdb search paths
+ pfn_SymSetSearchPath _pfn_SymSetSearchPath =
+ (pfn_SymSetSearchPath)::GetProcAddress(handle, "SymSetSearchPath");
+ pfn_SymGetSearchPath _pfn_SymGetSearchPath =
+ (pfn_SymGetSearchPath)::GetProcAddress(handle, "SymGetSearchPath");
+ if (_pfn_SymSetSearchPath != NULL && _pfn_SymGetSearchPath != NULL) {
+ char paths[MAX_PATH];
+ int len = sizeof(paths);
+ if (!_pfn_SymGetSearchPath(hProcess, paths, len)) {
+ paths[0] = '\0';
+ } else {
+ // available spaces in path buffer
+ len -= (int)strlen(paths);
+ }
+
+ char tmp_path[MAX_PATH];
+ DWORD dwSize;
+ HMODULE hJVM = ::GetModuleHandle("jvm.dll");
+ tmp_path[0] = '\0';
+ // append the path where jvm.dll is located
+ if (hJVM != NULL && (dwSize = ::GetModuleFileName(hJVM, tmp_path, sizeof(tmp_path))) > 0) {
+ while (dwSize > 0 && tmp_path[dwSize] != '\\') {
+ dwSize --;
+ }
+
+ tmp_path[dwSize] = '\0';
+
+ if (dwSize > 0 && len > (int)dwSize + 1) {
+ strncat(paths, os::path_separator(), 1);
+ strncat(paths, tmp_path, dwSize);
+ len -= dwSize + 1;
+ }
+ }
+
+ // append $JRE/bin. Arguments::get_java_home actually returns $JRE
+ // path
+ char *p = Arguments::get_java_home();
+ assert(p != NULL, "empty java home");
+ size_t java_home_len = strlen(p);
+ if (len > (int)java_home_len + 5) {
+ strncat(paths, os::path_separator(), 1);
+ strncat(paths, p, java_home_len);
+ strncat(paths, "\\bin", 4);
+ len -= (int)(java_home_len + 5);
+ }
+
+ // append $JDK/bin path if it exists
+ assert(java_home_len < MAX_PATH, "Invalid path length");
+ // assume $JRE is under $JDK, construct $JDK/bin path and
+ // see if it exists or not
+ if (strncmp(&p[java_home_len - 3], "jre", 3) == 0) {
+ strncpy(tmp_path, p, java_home_len - 3);
+ tmp_path[java_home_len - 3] = '\0';
+ strncat(tmp_path, "bin", 3);
+
+ // if the directory exists
+ DWORD dwAttrib = GetFileAttributes(tmp_path);
+ if (dwAttrib != INVALID_FILE_ATTRIBUTES &&
+ (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
+ // tmp_path should have the same length as java_home_len, since we only
+ // replaced 'jre' with 'bin'
+ if (len > (int)java_home_len + 1) {
+ strncat(paths, os::path_separator(), 1);
+ strncat(paths, tmp_path, java_home_len);
+ }
+ }
+ }
+
+ _pfn_SymSetSearchPath(hProcess, paths);
+ }
+
// find out if jvm.dll contains private symbols, by decoding
// current function and comparing the result
address addr = (address)Decoder::demangle;
--- a/hotspot/src/os/windows/vm/decoder_windows.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -35,6 +35,8 @@
typedef BOOL (WINAPI *pfn_SymInitialize)(HANDLE, PCTSTR, BOOL);
typedef BOOL (WINAPI *pfn_SymGetSymFromAddr64)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
typedef DWORD (WINAPI *pfn_UndecorateSymbolName)(const char*, char*, DWORD, DWORD);
+typedef BOOL (WINAPI *pfn_SymSetSearchPath)(HANDLE, PCTSTR);
+typedef BOOL (WINAPI *pfn_SymGetSearchPath)(HANDLE, PTSTR, int);
class WindowsDecoder : public AbstractDecoder {
--- a/hotspot/src/os/windows/vm/os_windows.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1874,8 +1874,22 @@
}
return TRUE;
break;
+ case CTRL_LOGOFF_EVENT: {
+ // Don't terminate JVM if it is running in a non-interactive session,
+ // such as a service process.
+ USEROBJECTFLAGS flags;
+ HANDLE handle = GetProcessWindowStation();
+ if (handle != NULL &&
+ GetUserObjectInformation(handle, UOI_FLAGS, &flags,
+ sizeof( USEROBJECTFLAGS), NULL)) {
+ // If it is a non-interactive session, let next handler to deal
+ // with it.
+ if ((flags.dwFlags & WSF_VISIBLE) == 0) {
+ return FALSE;
+ }
+ }
+ }
case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
os::signal_raise(SIGTERM);
return TRUE;
@@ -2946,7 +2960,7 @@
}
if( Verbose && PrintMiscellaneous ) {
reserveTimer.stop();
- tty->print_cr("reserve_memory of %Ix bytes took %ld ms (%ld ticks)", bytes,
+ tty->print_cr("reserve_memory of %Ix bytes took " JLONG_FORMAT " ms (" JLONG_FORMAT " ticks)", bytes,
reserveTimer.milliseconds(), reserveTimer.ticks());
}
}
@@ -4305,7 +4319,7 @@
if (hFile == NULL) {
if (PrintMiscellaneous && Verbose) {
DWORD err = GetLastError();
- tty->print_cr("CreateFile() failed: GetLastError->%ld.");
+ tty->print_cr("CreateFile() failed: GetLastError->%ld.", err);
}
return NULL;
}
@@ -4355,7 +4369,7 @@
if (hMap == NULL) {
if (PrintMiscellaneous && Verbose) {
DWORD err = GetLastError();
- tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.");
+ tty->print_cr("CreateFileMapping() failed: GetLastError->%ld.", err);
}
CloseHandle(hFile);
return NULL;
@@ -4565,6 +4579,7 @@
}
v = _Event ;
_Event = 0 ;
+ // see comment at end of os::PlatformEvent::park() below:
OrderAccess::fence() ;
// If we encounter a nearly simultanous timeout expiry and unpark()
// we return OS_OK indicating we awoke via unpark().
@@ -4602,25 +4617,25 @@
void os::PlatformEvent::unpark() {
guarantee (_ParkHandle != NULL, "Invariant") ;
- int v ;
- for (;;) {
- v = _Event ; // Increment _Event if it's < 1.
- if (v > 0) {
- // If it's already signaled just return.
- // The LD of _Event could have reordered or be satisfied
- // by a read-aside from this processor's write buffer.
- // To avoid problems execute a barrier and then
- // ratify the value. A degenerate CAS() would also work.
- // Viz., CAS (v+0, &_Event, v) == v).
- OrderAccess::fence() ;
- if (_Event == v) return ;
- continue ;
- }
- if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
- }
- if (v < 0) {
- ::SetEvent (_ParkHandle) ;
- }
+
+ // Transitions for _Event:
+ // 0 :=> 1
+ // 1 :=> 1
+ // -1 :=> either 0 or 1; must signal target thread
+ // That is, we can safely transition _Event from -1 to either
+ // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
+ // unpark() calls.
+ // See also: "Semaphores in Plan 9" by Mullender & Cox
+ //
+ // Note: Forcing a transition from "-1" to "1" on an unpark() means
+ // that it will take two back-to-back park() calls for the owning
+ // thread to block. This has the benefit of forcing a spurious return
+ // from the first park() call after an unpark() call which will help
+ // shake out uses of park() and unpark() without condition variables.
+
+ if (Atomic::xchg(1, &_Event) >= 0) return;
+
+ ::SetEvent(_ParkHandle);
}
--- a/hotspot/src/os/windows/vm/os_windows.inline.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,6 @@
inline const char* os::path_separator() { return ";"; }
inline const char* os::dll_file_extension() { return ".dll"; }
-inline const char* os::jlong_format_specifier() { return "%I64d"; }
-inline const char* os::julong_format_specifier() { return "%I64u"; }
-
inline const int os::default_file_open_flags() { return O_BINARY | O_NOINHERIT;}
// File names are case-insensitive on windows only
--- a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,37 +29,26 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
- nonstatic_field(OSThread, _pthread_id, pthread_t) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ nonstatic_field(OSThread, _pthread_id, pthread_t)
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Posix Thread IDs */ \
/**********************/ \
\
declare_unsigned_integer_type(OSThread::thread_id_t) \
- declare_unsigned_integer_type(pthread_t) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_unsigned_integer_type(pthread_t)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_BSD_X86_VM_VMSTRUCTS_BSD_X86_HPP
--- a/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/bsd_zero/vm/vmStructs_bsd_zero.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -30,21 +30,13 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_BSD_ZERO_VM_VMSTRUCTS_BSD_ZERO_HPP
--- a/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,7 +29,7 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
@@ -37,38 +37,27 @@
\
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
- nonstatic_field(OSThread, _pthread_id, pthread_t) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ nonstatic_field(OSThread, _pthread_id, pthread_t)
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* POSIX Thread IDs */ \
/**********************/ \
\
declare_integer_type(OSThread::thread_id_t) \
- declare_unsigned_integer_type(pthread_t) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_unsigned_integer_type(pthread_t)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/************************/ \
/* JavaThread constants */ \
/************************/ \
\
- declare_constant(JavaFrameAnchor::flushed) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_constant(JavaFrameAnchor::flushed)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_SPARC_VM_VMSTRUCTS_LINUX_SPARC_HPP
--- a/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,37 +29,26 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
- nonstatic_field(OSThread, _pthread_id, pthread_t) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ nonstatic_field(OSThread, _pthread_id, pthread_t)
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Posix Thread IDs */ \
/**********************/ \
\
declare_integer_type(OSThread::thread_id_t) \
- declare_unsigned_integer_type(pthread_t) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_unsigned_integer_type(pthread_t)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_X86_VM_VMSTRUCTS_LINUX_X86_HPP
--- a/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/linux_zero/vm/vmStructs_linux_zero.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -30,21 +30,12 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field)
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type)
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
-
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_LINUX_ZERO_VM_VMSTRUCTS_LINUX_ZERO_HPP
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,44 +29,32 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
nonstatic_field(JavaThread, _base_of_stack_pointer, intptr_t*) \
- nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
-
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Solaris Thread IDs */ \
/**********************/ \
\
- declare_unsigned_integer_type(OSThread::thread_id_t) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_unsigned_integer_type(OSThread::thread_id_t)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/************************/ \
/* JavaThread constants */ \
/************************/ \
\
- declare_constant(JavaFrameAnchor::flushed) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_constant(JavaFrameAnchor::flushed)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_SOLARIS_SPARC_VM_VMSTRUCTS_SOLARIS_SPARC_HPP
--- a/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,36 +29,24 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
- nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t)
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
/**********************/ \
/* Solaris Thread IDs */ \
/**********************/ \
\
- declare_unsigned_integer_type(OSThread::thread_id_t) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_unsigned_integer_type(OSThread::thread_id_t)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_SOLARIS_X86_VM_VMSTRUCTS_SOLARIS_X86_HPP
--- a/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -29,32 +29,21 @@
// constants required by the Serviceability Agent. This file is
// referenced by vmStructs.cpp.
-#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
+#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \
\
/******************************/ \
/* Threads (NOTE: incomplete) */ \
/******************************/ \
\
nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \
- unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */
-#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
+#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \
\
- declare_unsigned_integer_type(OSThread::thread_id_t) \
- /* This must be the last entry, and must be present */ \
- last_entry()
+ declare_unsigned_integer_type(OSThread::thread_id_t)
-#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
-#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
- \
- /* This must be the last entry, and must be present */ \
- last_entry()
+#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#endif // OS_CPU_WINDOWS_X86_VM_VMSTRUCTS_WINDOWS_X86_HPP
--- a/hotspot/src/share/tools/launcher/java.c Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/tools/launcher/java.c Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -808,7 +808,7 @@
static int
parse_stack_size(const char *s, jlong *result) {
jlong n = 0;
- int args_read = sscanf(s, jlong_format_specifier(), &n);
+ int args_read = sscanf(s, JLONG_FORMAT, &n);
if (args_read != 1) {
return 0;
}
--- a/hotspot/src/share/tools/launcher/java.h Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/tools/launcher/java.h Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,6 @@
jboolean RemovableMachineDependentOption(char * option);
void PrintMachineDependentOptions();
-const char *jlong_format_specifier();
/*
* Block current thread and continue execution in new thread
*/
--- a/hotspot/src/share/vm/adlc/formssel.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/adlc/formssel.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -862,8 +862,10 @@
( strcmp(_matrule->_rChild->_opType,"AryEq" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrComp" )==0 ||
strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
- strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 )) {
+ strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
+ strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
// String.(compareTo/equals/indexOf) and Arrays.equals
+ // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
// take 1 control and 1 memory edges.
return 2;
}
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -3223,7 +3223,12 @@
}
if (try_inline_full(callee, holder_known, bc, receiver))
return true;
- print_inlining(callee, _inline_bailout_msg, /*success*/ false);
+
+ // Entire compilation could fail during try_inline_full call.
+ // In that case printing inlining decision info is useless.
+ if (!bailed_out())
+ print_inlining(callee, _inline_bailout_msg, /*success*/ false);
+
return false;
}
@@ -3753,7 +3758,8 @@
push_scope(callee, cont);
// the BlockListBuilder for the callee could have bailed out
- CHECK_BAILOUT_(false);
+ if (bailed_out())
+ return false;
// Temporarily set up bytecode stream so we can append instructions
// (only using the bci of this stream)
@@ -3819,7 +3825,8 @@
iterate_all_blocks(callee_start_block == NULL);
// If we bailed out during parsing, return immediately (this is bad news)
- if (bailed_out()) return false;
+ if (bailed_out())
+ return false;
// iterate_all_blocks theoretically traverses in random order; in
// practice, we have only traversed the continuation if we are
@@ -3828,9 +3835,6 @@
!continuation()->is_set(BlockBegin::was_visited_flag),
"continuation should not have been parsed yet if we created it");
- // If we bailed out during parsing, return immediately (this is bad news)
- CHECK_BAILOUT_(false);
-
// At this point we are almost ready to return and resume parsing of
// the caller back in the GraphBuilder. The only thing we want to do
// first is an optimization: during parsing of the callee we
@@ -4171,7 +4175,10 @@
else
log->inline_success("receiver is statically known");
} else {
- log->inline_fail(msg);
+ if (msg != NULL)
+ log->inline_fail(msg);
+ else
+ log->inline_fail("reason unknown");
}
}
--- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -360,7 +360,7 @@
ValueType* t = x->type();
switch (t->tag()) {
case intTag : output()->print("%d" , t->as_IntConstant ()->value()); break;
- case longTag : output()->print(os::jlong_format_specifier(), t->as_LongConstant()->value()); output()->print("L"); break;
+ case longTag : output()->print(JLONG_FORMAT, t->as_LongConstant()->value()); output()->print("L"); break;
case floatTag : output()->print("%g" , t->as_FloatConstant ()->value()); break;
case doubleTag : output()->print("%gD" , t->as_DoubleConstant()->value()); break;
case objectTag : print_object(x); break;
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1563,7 +1563,7 @@
switch (type()) {
case T_ADDRESS:out->print("address:%d",as_jint()); break;
case T_INT: out->print("int:%d", as_jint()); break;
- case T_LONG: out->print("lng:%lld", as_jlong()); break;
+ case T_LONG: out->print("lng:" JLONG_FORMAT, as_jlong()); break;
case T_FLOAT: out->print("flt:%f", as_jfloat()); break;
case T_DOUBLE: out->print("dbl:%f", as_jdouble()); break;
case T_OBJECT: out->print("obj:0x%x", as_jobject()); break;
--- a/hotspot/src/share/vm/c1/c1_globals.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -147,7 +147,7 @@
"Inline methods containing exception handlers " \
"(NOTE: does not work with current backend)") \
\
- develop(bool, InlineSynchronizedMethods, true, \
+ product(bool, InlineSynchronizedMethods, true, \
"Inline synchronized methods") \
\
develop(bool, InlineNIOCheckIndex, true, \
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -645,7 +645,7 @@
java_mirror->bool_field_put(fd.offset(), value);
} else if (strcmp(field_signature, "J") == 0) {
jlong value;
- if (sscanf(string_value, INT64_FORMAT, &value) != 1) {
+ if (sscanf(string_value, JLONG_FORMAT, &value) != 1) {
fprintf(stderr, "Error parsing long: %s\n", string_value);
return;
}
--- a/hotspot/src/share/vm/ci/ciType.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/ci/ciType.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -60,6 +60,19 @@
}
// ------------------------------------------------------------------
+// ciType::name
+//
+// Return the name of this type
+const char* ciType::name() {
+ if (is_primitive_type()) {
+ return type2name(basic_type());
+ } else {
+ assert(is_klass(), "must be");
+ return as_klass()->name()->as_utf8();
+ }
+}
+
+// ------------------------------------------------------------------
// ciType::print_impl
//
// Implementation of the print method.
@@ -73,7 +86,8 @@
//
// Print the name of this type
void ciType::print_name_on(outputStream* st) {
- st->print(type2name(basic_type()));
+ ResourceMark rm;
+ st->print(name());
}
--- a/hotspot/src/share/vm/ci/ciType.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/ci/ciType.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -77,6 +77,7 @@
bool is_type() const { return true; }
bool is_classless() const { return is_primitive_type(); }
+ const char* name();
virtual void print_name_on(outputStream* st);
void print_name() {
print_name_on(tty);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,6 +59,7 @@
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/array.hpp"
+#include "utilities/globalDefinitions.hpp"
// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
@@ -970,6 +971,12 @@
runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
+ parse_annotations(loader_data,
+ runtime_visible_annotations,
+ runtime_visible_annotations_length,
+ cp,
+ parsed_annotations,
+ CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
} else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = attribute_length;
@@ -1216,19 +1223,16 @@
field->initialize(access_flags.as_short(),
name_index,
signature_index,
- constantvalue_index,
- 0);
- if (parsed_annotations.has_any_annotations())
- parsed_annotations.apply_to(field);
-
+ constantvalue_index);
BasicType type = cp->basic_type_for_signature_at(signature_index);
// Remember how many oops we encountered and compute allocation type
FieldAllocationType atype = fac->update(is_static, type);
-
- // The correct offset is computed later (all oop fields will be located together)
- // We temporarily store the allocation type in the offset field
- field->set_offset(atype);
+ field->set_allocation_type(atype);
+
+ // After field is initialized with type, we can augment it with aux info
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(field);
}
int index = length;
@@ -1259,17 +1263,13 @@
field->initialize(JVM_ACC_FIELD_INTERNAL,
injected[n].name_index,
injected[n].signature_index,
- 0,
0);
BasicType type = FieldType::basic_type(injected[n].signature());
// Remember how many oops we encountered and compute allocation type
FieldAllocationType atype = fac->update(false, type);
-
- // The correct offset is computed later (all oop fields will be located together)
- // We temporarily store the allocation type in the offset field
- field->set_offset(atype);
+ field->set_allocation_type(atype);
index++;
}
}
@@ -1735,7 +1735,8 @@
}
// Sift through annotations, looking for those significant to the VM:
-void ClassFileParser::parse_annotations(u1* buffer, int limit,
+void ClassFileParser::parse_annotations(ClassLoaderData* loader_data,
+ u1* buffer, int limit,
constantPoolHandle cp,
ClassFileParser::AnnotationCollector* coll,
TRAPS) {
@@ -1752,9 +1753,12 @@
e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
e_size = 11, // end of 'e' annotation
- c_tag_val = 'c',
- c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;'
+ c_tag_val = 'c', // payload is type
+ c_con_off = 7, // utf8 payload, such as 'I'
c_size = 9, // end of 'c' annotation
+ s_tag_val = 's', // payload is String
+ s_con_off = 7, // utf8 payload, such as 'Ljava/lang/String;'
+ s_size = 9,
min_size = 6 // smallest possible size (zero members)
};
while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
@@ -1773,57 +1777,63 @@
}
// Here is where parsing particular annotations will take place.
- AnnotationCollector::ID id = coll->annotation_index(aname);
+ AnnotationCollector::ID id = coll->annotation_index(loader_data, aname);
if (id == AnnotationCollector::_unknown) continue;
coll->set_annotation(id);
- // If there are no values, just set the bit and move on:
- if (count == 0) continue;
-
- // For the record, here is how annotation payloads can be collected.
- // Suppose we want to capture @Retention.value. Here is how:
- //if (id == AnnotationCollector::_class_Retention) {
- // Symbol* payload = NULL;
- // if (count == 1
- // && e_size == (index0 - index) // match size
- // && e_tag_val == *(abase + tag_off)
- // && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
- // == vmSymbols::RetentionPolicy_signature())
- // && member == vmSymbols::value_name()) {
- // payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
- // }
- // check_property(payload != NULL,
- // "Invalid @Retention annotation at offset %u in class file %s",
- // index0, CHECK);
- // if (payload != NULL) {
- // payload->increment_refcount();
- // coll->_class_RetentionPolicy = payload;
- // }
- //}
+
+ if (id == AnnotationCollector::_sun_misc_Contended) {
+ if (count == 1
+ && s_size == (index - index0) // match size
+ && s_tag_val == *(abase + tag_off)
+ && member == vmSymbols::value_name()) {
+ u2 group_index = Bytes::get_Java_u2(abase + s_con_off);
+ coll->set_contended_group(group_index);
+ } else {
+ coll->set_contended_group(0); // default contended group
+ }
+ coll->set_contended(true);
+ } else {
+ coll->set_contended(false);
+ }
}
}
-ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) {
+ClassFileParser::AnnotationCollector::ID
+ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_data,
+ Symbol* name) {
vmSymbols::SID sid = vmSymbols::find_sid(name);
+ // Privileged code can use all annotations. Other code silently drops some.
+ bool privileged = loader_data->is_the_null_class_loader_data() ||
+ loader_data->is_anonymous();
switch (sid) {
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
if (_location != _in_method) break; // only allow for methods
+ if (!privileged) break; // only allow in privileged code
return _method_ForceInline;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature):
if (_location != _in_method) break; // only allow for methods
+ if (!privileged) break; // only allow in privileged code
return _method_DontInline;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature):
if (_location != _in_method) break; // only allow for methods
+ if (!privileged) break; // only allow in privileged code
return _method_LambdaForm_Compiled;
case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature):
if (_location != _in_method) break; // only allow for methods
+ if (!privileged) break; // only allow in privileged code
return _method_LambdaForm_Hidden;
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature):
+ if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes
+ if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges
+ return _sun_misc_Contended;
default: break;
}
return AnnotationCollector::_unknown;
}
void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
- fatal("no field annotations yet");
+ if (is_contended())
+ f->set_contended_group(contended_group());
}
void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
@@ -1838,7 +1848,7 @@
}
void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
- fatal("no class annotations yet");
+ k->set_is_contended(is_contended());
}
@@ -2148,9 +2158,21 @@
cp, CHECK_(nullHandle));
} else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
method_parameters_length = cfs->get_u1_fast();
+ // Track the actual size (note: this is written for clarity; a
+ // decent compiler will CSE and constant-fold this into a single
+ // expression)
+ u2 actual_size = 1;
method_parameters_data = cfs->get_u1_buffer();
+ actual_size += 2 * method_parameters_length;
cfs->skip_u2_fast(method_parameters_length);
+ actual_size += 4 * method_parameters_length;
cfs->skip_u4_fast(method_parameters_length);
+ // Enforce attribute length
+ if (method_attribute_length != actual_size) {
+ classfile_parse_error(
+ "Invalid MethodParameters method attribute length %u in class file %s",
+ method_attribute_length, CHECK_(nullHandle));
+ }
// ignore this attribute if it cannot be reflected
if (!SystemDictionary::Parameter_klass_loaded())
method_parameters_length = 0;
@@ -2181,7 +2203,8 @@
runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
- parse_annotations(runtime_visible_annotations,
+ parse_annotations(loader_data,
+ runtime_visible_annotations,
runtime_visible_annotations_length, cp, &parsed_annotations,
CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
@@ -2297,7 +2320,10 @@
elem[i].name_cp_index =
Bytes::get_Java_u2(method_parameters_data);
method_parameters_data += 2;
- elem[i].flags = Bytes::get_Java_u4(method_parameters_data);
+ u4 flags = Bytes::get_Java_u4(method_parameters_data);
+ // This caused an alignment fault on Sparc, if flags was a u4
+ elem[i].flags_lo = extract_low_short_from_int(flags);
+ elem[i].flags_hi = extract_high_short_from_int(flags);
method_parameters_data += 4;
}
}
@@ -2475,26 +2501,38 @@
*has_default_methods = true;
}
methods->at_put(index, method());
- if (*methods_annotations == NULL) {
- *methods_annotations =
- MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+
+ if (method_annotations != NULL) {
+ if (*methods_annotations == NULL) {
+ *methods_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+ }
+ (*methods_annotations)->at_put(index, method_annotations);
}
- (*methods_annotations)->at_put(index, method_annotations);
- if (*methods_parameter_annotations == NULL) {
- *methods_parameter_annotations =
- MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+
+ if (method_parameter_annotations != NULL) {
+ if (*methods_parameter_annotations == NULL) {
+ *methods_parameter_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+ }
+ (*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
}
- (*methods_parameter_annotations)->at_put(index, method_parameter_annotations);
- if (*methods_default_annotations == NULL) {
- *methods_default_annotations =
- MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+
+ if (method_default_annotations != NULL) {
+ if (*methods_default_annotations == NULL) {
+ *methods_default_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+ }
+ (*methods_default_annotations)->at_put(index, method_default_annotations);
}
- (*methods_default_annotations)->at_put(index, method_default_annotations);
- if (*methods_type_annotations == NULL) {
- *methods_type_annotations =
- MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+
+ if (method_type_annotations != NULL) {
+ if (*methods_type_annotations == NULL) {
+ *methods_type_annotations =
+ MetadataFactory::new_array<AnnotationArray*>(loader_data, length, NULL, CHECK_NULL);
+ }
+ (*methods_type_annotations)->at_put(index, method_type_annotations);
}
- (*methods_type_annotations)->at_put(index, method_type_annotations);
}
if (_need_verify && length > 1) {
@@ -2886,7 +2924,8 @@
runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
- parse_annotations(runtime_visible_annotations,
+ parse_annotations(loader_data,
+ runtime_visible_annotations,
runtime_visible_annotations_length,
cp,
parsed_annotations,
@@ -3309,8 +3348,7 @@
bool has_final_method = false;
AccessFlags promoted_flags;
promoted_flags.set_flags(0);
- // These need to be oop pointers because they are allocated lazily
- // inside parse_methods inside a nested HandleMark
+
Array<AnnotationArray*>* methods_annotations = NULL;
Array<AnnotationArray*>* methods_parameter_annotations = NULL;
Array<AnnotationArray*>* methods_default_annotations = NULL;
@@ -3405,18 +3443,21 @@
// Size of Java itable (in words)
itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces);
+ // get the padding width from the option
+ // TODO: Ask VM about specific CPU we are running on
+ int pad_size = ContendedPaddingWidth;
+
// Field size and offset computation
int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size();
#ifndef PRODUCT
int orig_nonstatic_field_size = 0;
#endif
- int static_field_size = 0;
int next_static_oop_offset;
int next_static_double_offset;
int next_static_word_offset;
int next_static_short_offset;
int next_static_byte_offset;
- int next_static_type_offset;
+ int next_static_padded_offset;
int next_nonstatic_oop_offset;
int next_nonstatic_double_offset;
int next_nonstatic_word_offset;
@@ -3426,11 +3467,36 @@
int first_nonstatic_oop_offset;
int first_nonstatic_field_offset;
int next_nonstatic_field_offset;
+ int next_nonstatic_padded_offset;
+
+ // Count the contended fields by type.
+ int static_contended_count = 0;
+ int nonstatic_contended_count = 0;
+ FieldAllocationCount fac_contended;
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+ FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
+ if (fs.is_contended()) {
+ fac_contended.count[atype]++;
+ if (fs.access_flags().is_static()) {
+ static_contended_count++;
+ } else {
+ nonstatic_contended_count++;
+ }
+ }
+ }
+ int contended_count = static_contended_count + nonstatic_contended_count;
+
// Calculate the starting byte offsets
next_static_oop_offset = InstanceMirrorKlass::offset_of_static_fields();
+
+ // class is contended, pad before all the fields
+ if (parsed_annotations.is_contended()) {
+ next_static_oop_offset += pad_size;
+ }
+
next_static_double_offset = next_static_oop_offset +
- (fac.count[STATIC_OOP] * heapOopSize);
+ ((fac.count[STATIC_OOP] - fac_contended.count[STATIC_OOP]) * heapOopSize);
if ( fac.count[STATIC_DOUBLE] &&
(Universe::field_type_should_be_aligned(T_DOUBLE) ||
Universe::field_type_should_be_aligned(T_LONG)) ) {
@@ -3438,25 +3504,29 @@
}
next_static_word_offset = next_static_double_offset +
- (fac.count[STATIC_DOUBLE] * BytesPerLong);
+ ((fac.count[STATIC_DOUBLE] - fac_contended.count[STATIC_DOUBLE]) * BytesPerLong);
next_static_short_offset = next_static_word_offset +
- (fac.count[STATIC_WORD] * BytesPerInt);
+ ((fac.count[STATIC_WORD] - fac_contended.count[STATIC_WORD]) * BytesPerInt);
next_static_byte_offset = next_static_short_offset +
- (fac.count[STATIC_SHORT] * BytesPerShort);
- next_static_type_offset = align_size_up((next_static_byte_offset +
- fac.count[STATIC_BYTE] ), wordSize );
- static_field_size = (next_static_type_offset -
- next_static_oop_offset) / wordSize;
+ ((fac.count[STATIC_SHORT] - fac_contended.count[STATIC_SHORT]) * BytesPerShort);
+ next_static_padded_offset = next_static_byte_offset +
+ ((fac.count[STATIC_BYTE] - fac_contended.count[STATIC_BYTE]) * 1);
first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
nonstatic_field_size * heapOopSize;
+
+ // class is contended, pad before all the fields
+ if (parsed_annotations.is_contended()) {
+ first_nonstatic_field_offset += pad_size;
+ }
+
next_nonstatic_field_offset = first_nonstatic_field_offset;
- unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE];
- unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD];
- unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT];
- unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE];
- unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP];
+ unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
+ unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
+ unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
+ unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
+ unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
bool super_has_nonstatic_fields =
(super_klass() != NULL && super_klass->has_nonstatic_fields());
@@ -3529,12 +3599,12 @@
}
if( allocation_style == 0 ) {
- // Fields order: oops, longs/doubles, ints, shorts/chars, bytes
+ // Fields order: oops, longs/doubles, ints, shorts/chars, bytes, padded fields
next_nonstatic_oop_offset = next_nonstatic_field_offset;
next_nonstatic_double_offset = next_nonstatic_oop_offset +
(nonstatic_oop_count * heapOopSize);
} else if( allocation_style == 1 ) {
- // Fields order: longs/doubles, ints, shorts/chars, bytes, oops
+ // Fields order: longs/doubles, ints, shorts/chars, bytes, oops, padded fields
next_nonstatic_double_offset = next_nonstatic_field_offset;
} else if( allocation_style == 2 ) {
// Fields allocation: oops fields in super and sub classes are together.
@@ -3613,27 +3683,33 @@
(nonstatic_word_count * BytesPerInt);
next_nonstatic_byte_offset = next_nonstatic_short_offset +
(nonstatic_short_count * BytesPerShort);
-
- int notaligned_offset;
- if( allocation_style == 0 ) {
- notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
- } else { // allocation_style == 1
- next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
+ next_nonstatic_padded_offset = next_nonstatic_byte_offset +
+ nonstatic_byte_count;
+
+ // let oops jump before padding with this allocation style
+ if( allocation_style == 1 ) {
+ next_nonstatic_oop_offset = next_nonstatic_padded_offset;
if( nonstatic_oop_count > 0 ) {
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
}
- notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
+ next_nonstatic_padded_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
}
- next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
- nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
- - first_nonstatic_field_offset)/heapOopSize);
// Iterate over fields again and compute correct offsets.
// The field allocation type was temporarily stored in the offset slot.
// oop fields are located before non-oop fields (static and non-static).
for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+
+ // skip already laid out fields
+ if (fs.is_offset_set()) continue;
+
+ // contended fields are handled below
+ if (fs.is_contended()) continue;
+
int real_offset;
- FieldAllocationType atype = (FieldAllocationType) fs.offset();
+ FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
+
+ // pack the rest of the fields
switch (atype) {
case STATIC_OOP:
real_offset = next_static_oop_offset;
@@ -3722,13 +3798,225 @@
fs.set_offset(real_offset);
}
+
+ // Handle the contended cases.
+ //
+ // Each contended field should not intersect the cache line with another contended field.
+ // In the absence of alignment information, we end up with pessimistically separating
+ // the fields with full-width padding.
+ //
+ // Additionally, this should not break alignment for the fields, so we round the alignment up
+ // for each field.
+ if (contended_count > 0) {
+
+ // if there is at least one contended field, we need to have pre-padding for them
+ if (nonstatic_contended_count > 0) {
+ next_nonstatic_padded_offset += pad_size;
+ }
+
+ // collect all contended groups
+ BitMap bm(cp->size());
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+ // skip already laid out fields
+ if (fs.is_offset_set()) continue;
+
+ if (fs.is_contended()) {
+ bm.set_bit(fs.contended_group());
+ }
+ }
+
+ int current_group = -1;
+ while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) {
+
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+
+ // skip already laid out fields
+ if (fs.is_offset_set()) continue;
+
+ // skip non-contended fields and fields from different group
+ if (!fs.is_contended() || (fs.contended_group() != current_group)) continue;
+
+ // handle statics below
+ if (fs.access_flags().is_static()) continue;
+
+ int real_offset;
+ FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
+
+ switch (atype) {
+ case NONSTATIC_BYTE:
+ next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, 1);
+ real_offset = next_nonstatic_padded_offset;
+ next_nonstatic_padded_offset += 1;
+ break;
+
+ case NONSTATIC_SHORT:
+ next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerShort);
+ real_offset = next_nonstatic_padded_offset;
+ next_nonstatic_padded_offset += BytesPerShort;
+ break;
+
+ case NONSTATIC_WORD:
+ next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerInt);
+ real_offset = next_nonstatic_padded_offset;
+ next_nonstatic_padded_offset += BytesPerInt;
+ break;
+
+ case NONSTATIC_DOUBLE:
+ next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, BytesPerLong);
+ real_offset = next_nonstatic_padded_offset;
+ next_nonstatic_padded_offset += BytesPerLong;
+ break;
+
+ case NONSTATIC_OOP:
+ next_nonstatic_padded_offset = align_size_up(next_nonstatic_padded_offset, heapOopSize);
+ real_offset = next_nonstatic_padded_offset;
+ next_nonstatic_padded_offset += heapOopSize;
+
+ // Create new oop map
+ nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
+ nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
+ nonstatic_oop_map_count += 1;
+ if( first_nonstatic_oop_offset == 0 ) { // Undefined
+ first_nonstatic_oop_offset = real_offset;
+ }
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ if (fs.contended_group() == 0) {
+ // Contended group defines the equivalence class over the fields:
+ // the fields within the same contended group are not inter-padded.
+ // The only exception is default group, which does not incur the
+ // equivalence, and so requires intra-padding.
+ next_nonstatic_padded_offset += pad_size;
+ }
+
+ fs.set_offset(real_offset);
+ } // for
+
+ // Start laying out the next group.
+ // Note that this will effectively pad the last group in the back;
+ // this is expected to alleviate memory contention effects for
+ // subclass fields and/or adjacent object.
+ // If this was the default group, the padding is already in place.
+ if (current_group != 0) {
+ next_nonstatic_padded_offset += pad_size;
+ }
+ }
+
+ // handle static fields
+
+ // if there is at least one contended field, we need to have pre-padding for them
+ if (static_contended_count > 0) {
+ next_static_padded_offset += pad_size;
+ }
+
+ current_group = -1;
+ while ((current_group = (int)bm.get_next_one_offset(current_group + 1)) != (int)bm.size()) {
+
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+
+ // skip already laid out fields
+ if (fs.is_offset_set()) continue;
+
+ // skip non-contended fields and fields from different group
+ if (!fs.is_contended() || (fs.contended_group() != current_group)) continue;
+
+ // non-statics already handled above
+ if (!fs.access_flags().is_static()) continue;
+
+ int real_offset;
+ FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
+
+ switch (atype) {
+
+ case STATIC_BYTE:
+ next_static_padded_offset = align_size_up(next_static_padded_offset, 1);
+ real_offset = next_static_padded_offset;
+ next_static_padded_offset += 1;
+ break;
+
+ case STATIC_SHORT:
+ next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerShort);
+ real_offset = next_static_padded_offset;
+ next_static_padded_offset += BytesPerShort;
+ break;
+
+ case STATIC_WORD:
+ next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerInt);
+ real_offset = next_static_padded_offset;
+ next_static_padded_offset += BytesPerInt;
+ break;
+
+ case STATIC_DOUBLE:
+ next_static_padded_offset = align_size_up(next_static_padded_offset, BytesPerLong);
+ real_offset = next_static_padded_offset;
+ next_static_padded_offset += BytesPerLong;
+ break;
+
+ case STATIC_OOP:
+ next_static_padded_offset = align_size_up(next_static_padded_offset, heapOopSize);
+ real_offset = next_static_padded_offset;
+ next_static_padded_offset += heapOopSize;
+ break;
+
+ default:
+ ShouldNotReachHere();
+ }
+
+ if (fs.contended_group() == 0) {
+ // Contended group defines the equivalence class over the fields:
+ // the fields within the same contended group are not inter-padded.
+ // The only exception is default group, which does not incur the
+ // equivalence, and so requires intra-padding.
+ next_static_padded_offset += pad_size;
+ }
+
+ fs.set_offset(real_offset);
+ } // for
+
+ // Start laying out the next group.
+ // Note that this will effectively pad the last group in the back;
+ // this is expected to alleviate memory contention effects for
+ // subclass fields and/or adjacent object.
+ // If this was the default group, the padding is already in place.
+ if (current_group != 0) {
+ next_static_padded_offset += pad_size;
+ }
+
+ }
+
+ } // handle contended
+
// Size of instances
int instance_size;
+ int notaligned_offset = next_nonstatic_padded_offset;
+
+ // Entire class is contended, pad in the back.
+ // This helps to alleviate memory contention effects for subclass fields
+ // and/or adjacent object.
+ if (parsed_annotations.is_contended()) {
+ notaligned_offset += pad_size;
+ next_static_padded_offset += pad_size;
+ }
+
+ int next_static_type_offset = align_size_up(next_static_padded_offset, wordSize);
+ int static_field_size = (next_static_type_offset -
+ InstanceMirrorKlass::offset_of_static_fields()) / wordSize;
+
+ next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
+ nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
+ - first_nonstatic_field_offset)/heapOopSize);
+
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
- assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");
+ assert(instance_size == align_object_size(align_size_up(
+ (instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize + ((parsed_annotations.is_contended()) ? pad_size : 0)),
+ wordSize) / wordSize), "consistent layout helper value");
// Number of non-static oop map blocks allocated at end of klass.
const unsigned int total_oop_map_count =
@@ -3912,7 +4200,10 @@
// check that if this class is an interface then it doesn't have static methods
if (this_klass->is_interface()) {
- check_illegal_static_method(this_klass, CHECK_(nullHandle));
+ /* An interface in a JAVA 8 classfile can be static */
+ if (_major_version < JAVA_8_VERSION) {
+ check_illegal_static_method(this_klass, CHECK_(nullHandle));
+ }
}
@@ -4005,6 +4296,18 @@
}
#endif
+#ifndef PRODUCT
+ if (PrintFieldLayout) {
+ print_field_layout(name,
+ fields,
+ cp,
+ instance_size,
+ first_nonstatic_field_offset,
+ next_nonstatic_field_offset,
+ next_static_type_offset);
+ }
+#endif
+
// preserve result across HandleMark
preserve_this_klass = this_klass();
}
@@ -4017,6 +4320,38 @@
return this_klass;
}
+void ClassFileParser::print_field_layout(Symbol* name,
+ Array<u2>* fields,
+ constantPoolHandle cp,
+ int instance_size,
+ int instance_fields_start,
+ int instance_fields_end,
+ int static_fields_end) {
+ tty->print("%s: field layout\n", name->as_klass_external_name());
+ tty->print(" @%3d %s\n", instance_fields_start, "--- instance fields start ---");
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+ if (!fs.access_flags().is_static()) {
+ tty->print(" @%3d \"%s\" %s\n",
+ fs.offset(),
+ fs.name()->as_klass_external_name(),
+ fs.signature()->as_klass_external_name());
+ }
+ }
+ tty->print(" @%3d %s\n", instance_fields_end, "--- instance fields end ---");
+ tty->print(" @%3d %s\n", instance_size * wordSize, "--- instance ends ---");
+ tty->print(" @%3d %s\n", InstanceMirrorKlass::offset_of_static_fields(), "--- static fields start ---");
+ for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) {
+ tty->print(" @%3d \"%s\" %s\n",
+ fs.offset(),
+ fs.name()->as_klass_external_name(),
+ fs.signature()->as_klass_external_name());
+ }
+ }
+ tty->print(" @%3d %s\n", static_fields_end, "--- static fields end ---");
+ tty->print("\n");
+}
+
unsigned int
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
unsigned int nonstatic_oop_map_count,
@@ -4466,6 +4801,7 @@
const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0;
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0;
+ const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
const bool is_initializer = (name == vmSymbols::object_initializer_name());
@@ -4473,11 +4809,33 @@
bool is_illegal = false;
if (is_interface) {
- if (!is_public || is_static || is_final || is_native ||
- ((is_synchronized || is_strict) && major_gte_15 &&
- (!major_gte_8 || is_abstract)) ||
- (!major_gte_8 && !is_abstract)) {
- is_illegal = true;
+ if (major_gte_8) {
+ // Class file version is JAVA_8_VERSION or later Methods of
+ // interfaces may set any of the flags except ACC_PROTECTED,
+ // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must
+ // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set.
+ if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */
+ (is_native || is_protected || is_final || is_synchronized) ||
+ // If a specific method of a class or interface has its
+ // ACC_ABSTRACT flag set, it must not have any of its
+ // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC,
+ // ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to
+ // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as
+ // those flags are illegal irrespective of ACC_ABSTRACT being set or not.
+ (is_abstract && (is_private || is_static || is_strict))) {
+ is_illegal = true;
+ }
+ } else if (major_gte_15) {
+ // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION)
+ if (!is_public || is_static || is_final || is_synchronized ||
+ is_native || !is_abstract || is_strict) {
+ is_illegal = true;
+ }
+ } else {
+ // Class file version is pre-JAVA_1_5_VERSION
+ if (!is_public || is_static || is_final || is_native || !is_abstract) {
+ is_illegal = true;
+ }
}
} else { // not interface
if (is_initializer) {
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -95,17 +95,20 @@
_method_DontInline,
_method_LambdaForm_Compiled,
_method_LambdaForm_Hidden,
+ _sun_misc_Contended,
_annotation_LIMIT
};
const Location _location;
int _annotations_present;
+ u2 _contended_group;
+
AnnotationCollector(Location location)
: _location(location), _annotations_present(0)
{
assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
}
// If this annotation name has an ID, report it (or _none).
- ID annotation_index(Symbol* name);
+ ID annotation_index(ClassLoaderData* loader_data, Symbol* name);
// Set the annotation name:
void set_annotation(ID id) {
assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
@@ -114,6 +117,12 @@
// Report if the annotation is present.
bool has_any_annotations() { return _annotations_present != 0; }
bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; }
+
+ void set_contended_group(u2 group) { _contended_group = group; }
+ u2 contended_group() { return _contended_group; }
+
+ void set_contended(bool contended) { set_annotation(_sun_misc_Contended); }
+ bool is_contended() { return has_annotation(_sun_misc_Contended); }
};
class FieldAnnotationCollector: public AnnotationCollector {
public:
@@ -177,6 +186,14 @@
Array<AnnotationArray*>** fields_type_annotations,
u2* java_fields_count_ptr, TRAPS);
+ void print_field_layout(Symbol* name,
+ Array<u2>* fields,
+ constantPoolHandle cp,
+ int instance_size,
+ int instance_fields_start,
+ int instance_fields_end,
+ int static_fields_end);
+
// Method parsing
methodHandle parse_method(ClassLoaderData* loader_data,
constantPoolHandle cp,
@@ -247,7 +264,8 @@
int runtime_invisible_annotations_length, TRAPS);
int skip_annotation(u1* buffer, int limit, int index);
int skip_annotation_value(u1* buffer, int limit, int index);
- void parse_annotations(u1* buffer, int limit, constantPoolHandle cp,
+ void parse_annotations(ClassLoaderData* loader_data,
+ u1* buffer, int limit, constantPoolHandle cp,
/* Results (currently, only one result is supported): */
AnnotationCollector* result,
TRAPS);
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -318,6 +318,7 @@
}
Metaspace* ClassLoaderData::metaspace_non_null() {
+ assert(!DumpSharedSpaces, "wrong metaspace!");
// If the metaspace has not been allocated, create a new one. Might want
// to create smaller arena for Reflection class loaders also.
// The reason for the delayed allocation is because some class loaders are
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1285,13 +1285,15 @@
enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS };
- Array<AnnotationArray*>* original_annots[NUM_ARRAYS];
+ Array<AnnotationArray*>* original_annots[NUM_ARRAYS] = { NULL };
Array<Method*>* original_methods = klass->methods();
Annotations* annots = klass->annotations();
- original_annots[ANNOTATIONS] = annots->methods_annotations();
- original_annots[PARAMETERS] = annots->methods_parameter_annotations();
- original_annots[DEFAULTS] = annots->methods_default_annotations();
+ if (annots != NULL) {
+ original_annots[ANNOTATIONS] = annots->methods_annotations();
+ original_annots[PARAMETERS] = annots->methods_parameter_annotations();
+ original_annots[DEFAULTS] = annots->methods_default_annotations();
+ }
Array<int>* original_ordering = klass->method_ordering();
Array<int>* merged_ordering = Universe::the_empty_int_array();
@@ -1370,9 +1372,15 @@
// Replace klass methods with new merged lists
klass->set_methods(merged_methods);
- annots->set_methods_annotations(merged_annots[ANNOTATIONS]);
- annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]);
- annots->set_methods_default_annotations(merged_annots[DEFAULTS]);
+ if (annots != NULL) {
+ annots->set_methods_annotations(merged_annots[ANNOTATIONS]);
+ annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]);
+ annots->set_methods_default_annotations(merged_annots[DEFAULTS]);
+ } else {
+ assert(merged_annots[ANNOTATIONS] == NULL, "Must be");
+ assert(merged_annots[PARAMETERS] == NULL, "Must be");
+ assert(merged_annots[DEFAULTS] == NULL, "Must be");
+ }
ClassLoaderData* cld = klass->class_loader_data();
MetadataFactory::free_array(cld, original_methods);
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -687,19 +687,6 @@
}
-Method* java_lang_Class::resolved_constructor(oop java_class) {
- Metadata* constructor = java_class->metadata_field(_resolved_constructor_offset);
- assert(constructor == NULL || constructor->is_method(), "should be method");
- return ((Method*)constructor);
-}
-
-
-void java_lang_Class::set_resolved_constructor(oop java_class, Method* constructor) {
- assert(constructor->is_method(), "should be method");
- java_class->metadata_field_put(_resolved_constructor_offset, constructor);
-}
-
-
bool java_lang_Class::is_primitive(oop java_class) {
// should assert:
//assert(java_lang_Class::is_instance(java_class), "must be a Class object");
@@ -924,7 +911,6 @@
// Write the thread status value to threadStatus field in java.lang.Thread java class.
void java_lang_Thread::set_thread_status(oop java_thread,
java_lang_Thread::ThreadStatus status) {
- assert(JavaThread::current()->thread_state() == _thread_in_vm, "Java Thread is not running in vm");
// The threadStatus is only present starting in 1.5
if (_thread_status_offset > 0) {
java_thread->int_field_put(_thread_status_offset, status);
@@ -1158,179 +1144,43 @@
}
}
-// Print stack trace element to resource allocated buffer
-char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) {
- // Get strings and string lengths
- InstanceKlass* klass = method->method_holder();
- const char* klass_name = klass->external_name();
- int buf_len = (int)strlen(klass_name);
- char* source_file_name;
- if (klass->source_file_name() == NULL) {
- source_file_name = NULL;
+// After this many redefines, the stack trace is unreliable.
+const int MAX_VERSION = USHRT_MAX;
+
+// Helper backtrace functions to store bci|version together.
+static inline int merge_bci_and_version(int bci, int version) {
+ // only store u2 for version, checking for overflow.
+ if (version > USHRT_MAX || version < 0) version = MAX_VERSION;
+ assert((jushort)bci == bci, "bci should be short");
+ return build_int_from_shorts(version, bci);
+}
+
+static inline int bci_at(unsigned int merged) {
+ return extract_high_short_from_int(merged);
+}
+static inline int version_at(unsigned int merged) {
+ return extract_low_short_from_int(merged);
+}
+
+static inline bool version_matches(Method* method, int version) {
+ return (method->constants()->version() == version && version < MAX_VERSION);
+}
+
+static inline int get_line_number(Method* method, int bci) {
+ int line_number = 0;
+ if (method->is_native()) {
+ // Negative value different from -1 below, enabling Java code in
+ // class java.lang.StackTraceElement to distinguish "native" from
+ // "no LineNumberTable". JDK tests for -2.
+ line_number = -2;
} else {
- source_file_name = klass->source_file_name()->as_C_string();
- buf_len += (int)strlen(source_file_name);
- }
- char* method_name = method->name()->as_C_string();
- buf_len += (int)strlen(method_name);
-
- // Allocate temporary buffer with extra space for formatting and line number
- char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64);
-
- // Print stack trace line in buffer
- sprintf(buf, "\tat %s.%s", klass_name, method_name);
- if (method->is_native()) {
- strcat(buf, "(Native Method)");
- } else {
- int line_number = method->line_number_from_bci(bci);
- if (source_file_name != NULL && (line_number != -1)) {
- // Sourcename and linenumber
- sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number);
- } else if (source_file_name != NULL) {
- // Just sourcename
- sprintf(buf + (int)strlen(buf), "(%s)", source_file_name);
- } else {
- // Neither soucename and linenumber
- sprintf(buf + (int)strlen(buf), "(Unknown Source)");
- }
- nmethod* nm = method->code();
- if (WizardMode && nm != NULL) {
- sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
+ // Returns -1 if no LineNumberTable, and otherwise actual line number
+ line_number = method->line_number_from_bci(bci);
+ if (line_number == -1 && ShowHiddenFrames) {
+ line_number = bci + 1000000;
}
}
-
- return buf;
-}
-
-
-void java_lang_Throwable::print_stack_element(Handle stream, Method* method, int bci) {
- ResourceMark rm;
- char* buf = print_stack_element_to_buffer(method, bci);
- print_to_stream(stream, buf);
-}
-
-void java_lang_Throwable::print_stack_element(outputStream *st, Method* method, int bci) {
- ResourceMark rm;
- char* buf = print_stack_element_to_buffer(method, bci);
- st->print_cr("%s", buf);
-}
-
-void java_lang_Throwable::print_to_stream(Handle stream, const char* str) {
- if (stream.is_null()) {
- tty->print_cr("%s", str);
- } else {
- EXCEPTION_MARK;
- JavaValue result(T_VOID);
- Handle arg (THREAD, oopFactory::new_charArray(str, THREAD));
- if (!HAS_PENDING_EXCEPTION) {
- JavaCalls::call_virtual(&result,
- stream,
- KlassHandle(THREAD, stream->klass()),
- vmSymbols::println_name(),
- vmSymbols::char_array_void_signature(),
- arg,
- THREAD);
- }
- // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
- if (HAS_PENDING_EXCEPTION) CLEAR_PENDING_EXCEPTION;
- }
-
-}
-
-
-const char* java_lang_Throwable::no_stack_trace_message() {
- return "\t<<no stack trace available>>";
-}
-
-
-// Currently used only for exceptions occurring during startup
-void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) {
- Thread *THREAD = Thread::current();
- Handle h_throwable(THREAD, throwable);
- while (h_throwable.not_null()) {
- objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable())));
- if (result.is_null()) {
- st->print_cr(no_stack_trace_message());
- return;
- }
-
- while (result.not_null()) {
- typeArrayHandle methods (THREAD,
- typeArrayOop(result->obj_at(trace_methods_offset)));
- typeArrayHandle bcis (THREAD,
- typeArrayOop(result->obj_at(trace_bcis_offset)));
-
- if (methods.is_null() || bcis.is_null()) {
- st->print_cr(no_stack_trace_message());
- return;
- }
-
- int length = methods()->length();
- for (int index = 0; index < length; index++) {
- Method* method = ((Method*)methods()->metadata_at(index));
- if (method == NULL) goto handle_cause;
- int bci = bcis->ushort_at(index);
- print_stack_element(st, method, bci);
- }
- result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
- }
- handle_cause:
- {
- EXCEPTION_MARK;
- JavaValue result(T_OBJECT);
- JavaCalls::call_virtual(&result,
- h_throwable,
- KlassHandle(THREAD, h_throwable->klass()),
- vmSymbols::getCause_name(),
- vmSymbols::void_throwable_signature(),
- THREAD);
- // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
- if (HAS_PENDING_EXCEPTION) {
- CLEAR_PENDING_EXCEPTION;
- h_throwable = Handle();
- } else {
- h_throwable = Handle(THREAD, (oop) result.get_jobject());
- if (h_throwable.not_null()) {
- st->print("Caused by: ");
- print(h_throwable, st);
- st->cr();
- }
- }
- }
- }
-}
-
-
-void java_lang_Throwable::print_stack_trace(oop throwable, oop print_stream) {
- // Note: this is no longer used in Merlin, but we support it for compatibility.
- Thread *thread = Thread::current();
- Handle stream(thread, print_stream);
- objArrayHandle result (thread, objArrayOop(backtrace(throwable)));
- if (result.is_null()) {
- print_to_stream(stream, no_stack_trace_message());
- return;
- }
-
- while (result.not_null()) {
- typeArrayHandle methods(thread,
- typeArrayOop(result->obj_at(trace_methods_offset)));
- typeArrayHandle bcis (thread,
- typeArrayOop(result->obj_at(trace_bcis_offset)));
-
- if (methods.is_null() || bcis.is_null()) {
- print_to_stream(stream, no_stack_trace_message());
- return;
- }
-
- int length = methods()->length();
- for (int index = 0; index < length; index++) {
- Method* method = ((Method*)methods()->metadata_at(index));
- if (method == NULL) return;
- int bci = bcis->ushort_at(index);
- print_stack_element(stream, method, bci);
- }
- result = objArrayHandle(thread, objArrayOop(result->obj_at(trace_next_offset)));
- }
+ return line_number;
}
// This class provides a simple wrapper over the internal structure of
@@ -1350,13 +1200,30 @@
enum {
trace_methods_offset = java_lang_Throwable::trace_methods_offset,
- trace_bcis_offset = java_lang_Throwable::trace_bcis_offset,
+ trace_bcis_offset = java_lang_Throwable::trace_bcis_offset,
trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset,
trace_next_offset = java_lang_Throwable::trace_next_offset,
trace_size = java_lang_Throwable::trace_size,
trace_chunk_size = java_lang_Throwable::trace_chunk_size
};
+ // get info out of chunks
+ static typeArrayOop get_methods(objArrayHandle chunk) {
+ typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
+ assert(methods != NULL, "method array should be initialized in backtrace");
+ return methods;
+ }
+ static typeArrayOop get_bcis(objArrayHandle chunk) {
+ typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset));
+ assert(bcis != NULL, "bci array should be initialized in backtrace");
+ return bcis;
+ }
+ static objArrayOop get_mirrors(objArrayHandle chunk) {
+ objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset));
+ assert(mirrors != NULL, "mirror array should be initialized in backtrace");
+ return mirrors;
+ }
+
// constructor for new backtrace
BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) {
expand(CHECK);
@@ -1364,6 +1231,19 @@
_index = 0;
}
+ BacktraceBuilder(objArrayHandle backtrace) {
+ _methods = get_methods(backtrace);
+ _bcis = get_bcis(backtrace);
+ _mirrors = get_mirrors(backtrace);
+ assert(_methods->length() == _bcis->length() &&
+ _methods->length() == _mirrors->length(),
+ "method and source information arrays should match");
+
+ // head is the preallocated backtrace
+ _backtrace = _head = backtrace();
+ _index = 0;
+ }
+
void expand(TRAPS) {
objArrayHandle old_head(THREAD, _head);
Pause_No_Safepoint_Verifier pnsv(&_nsv);
@@ -1371,10 +1251,10 @@
objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
objArrayHandle new_head(THREAD, head);
- typeArrayOop methods = oopFactory::new_metaDataArray(trace_chunk_size, CHECK);
+ typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK);
typeArrayHandle new_methods(THREAD, methods);
- typeArrayOop bcis = oopFactory::new_shortArray(trace_chunk_size, CHECK);
+ typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK);
typeArrayHandle new_bcis(THREAD, bcis);
objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
@@ -1389,7 +1269,7 @@
_head = new_head();
_methods = new_methods();
- _bcis = new_bcis();
+ _bcis = new_bcis();
_mirrors = new_mirrors();
_index = 0;
}
@@ -1403,7 +1283,6 @@
// shorts. The later line number lookup would just smear the -1
// to a 0 even if it could be recorded.
if (bci == SynchronizationEntryBCI) bci = 0;
- assert(bci == (jushort)bci, "doesn't fit");
if (_index >= trace_chunk_size) {
methodHandle mhandle(THREAD, method);
@@ -1411,26 +1290,148 @@
method = mhandle();
}
- _methods->metadata_at_put(_index, method);
- _bcis->ushort_at_put(_index, bci);
- // we need to save the mirrors in the backtrace to keep the methods from
- // being unloaded if their class loader is unloaded while we still have
- // this stack trace.
+ _methods->short_at_put(_index, method->method_idnum());
+ _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version()));
+
+ // We need to save the mirrors in the backtrace to keep the class
+ // from being unloaded while we still have this stack trace.
+ assert(method->method_holder()->java_mirror() != NULL, "never push null for mirror");
_mirrors->obj_at_put(_index, method->method_holder()->java_mirror());
_index++;
}
- Method* current_method() {
- assert(_index >= 0 && _index < trace_chunk_size, "out of range");
- return ((Method*)_methods->metadata_at(_index));
+};
+
+// Print stack trace element to resource allocated buffer
+char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror,
+ int method_id, int version, int bci) {
+
+ // Get strings and string lengths
+ InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
+ const char* klass_name = holder->external_name();
+ int buf_len = (int)strlen(klass_name);
+
+ // pushing to the stack trace added one.
+ Method* method = holder->method_with_idnum(method_id);
+ char* method_name = method->name()->as_C_string();
+ buf_len += (int)strlen(method_name);
+
+ char* source_file_name = NULL;
+ if (version_matches(method, version)) {
+ Symbol* source = holder->source_file_name();
+ if (source != NULL) {
+ source_file_name = source->as_C_string();
+ buf_len += (int)strlen(source_file_name);
+ }
+ }
+
+ // Allocate temporary buffer with extra space for formatting and line number
+ char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64);
+
+ // Print stack trace line in buffer
+ sprintf(buf, "\tat %s.%s", klass_name, method_name);
+
+ if (!version_matches(method, version)) {
+ strcat(buf, "(Redefined)");
+ } else {
+ int line_number = get_line_number(method, bci);
+ if (line_number == -2) {
+ strcat(buf, "(Native Method)");
+ } else {
+ if (source_file_name != NULL && (line_number != -1)) {
+ // Sourcename and linenumber
+ sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number);
+ } else if (source_file_name != NULL) {
+ // Just sourcename
+ sprintf(buf + (int)strlen(buf), "(%s)", source_file_name);
+ } else {
+ // Neither sourcename nor linenumber
+ sprintf(buf + (int)strlen(buf), "(Unknown Source)");
+ }
+ nmethod* nm = method->code();
+ if (WizardMode && nm != NULL) {
+ sprintf(buf + (int)strlen(buf), "(nmethod " INTPTR_FORMAT ")", (intptr_t)nm);
+ }
+ }
}
- jushort current_bci() {
- assert(_index >= 0 && _index < trace_chunk_size, "out of range");
- return _bcis->ushort_at(_index);
+ return buf;
+}
+
+void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror,
+ int method_id, int version, int bci) {
+ ResourceMark rm;
+ char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci);
+ st->print_cr("%s", buf);
+}
+
+void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) {
+ Handle mirror = method->method_holder()->java_mirror();
+ int method_id = method->method_idnum();
+ int version = method->constants()->version();
+ print_stack_element(st, mirror, method_id, version, bci);
+}
+
+const char* java_lang_Throwable::no_stack_trace_message() {
+ return "\t<<no stack trace available>>";
+}
+
+
+// Currently used only for exceptions occurring during startup
+void java_lang_Throwable::print_stack_trace(oop throwable, outputStream* st) {
+ Thread *THREAD = Thread::current();
+ Handle h_throwable(THREAD, throwable);
+ while (h_throwable.not_null()) {
+ objArrayHandle result (THREAD, objArrayOop(backtrace(h_throwable())));
+ if (result.is_null()) {
+ st->print_cr(no_stack_trace_message());
+ return;
+ }
+
+ while (result.not_null()) {
+
+ // Get method id, bci, version and mirror from chunk
+ typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result));
+ typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result));
+ objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result));
+
+ int length = methods()->length();
+ for (int index = 0; index < length; index++) {
+ Handle mirror(THREAD, mirrors->obj_at(index));
+ // NULL mirror means end of stack trace
+ if (mirror.is_null()) goto handle_cause;
+ int method = methods->short_at(index);
+ int version = version_at(bcis->int_at(index));
+ int bci = bci_at(bcis->int_at(index));
+ print_stack_element(st, mirror, method, version, bci);
+ }
+ result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset)));
+ }
+ handle_cause:
+ {
+ EXCEPTION_MARK;
+ JavaValue cause(T_OBJECT);
+ JavaCalls::call_virtual(&cause,
+ h_throwable,
+ KlassHandle(THREAD, h_throwable->klass()),
+ vmSymbols::getCause_name(),
+ vmSymbols::void_throwable_signature(),
+ THREAD);
+ // Ignore any exceptions. we are in the middle of exception handling. Same as classic VM.
+ if (HAS_PENDING_EXCEPTION) {
+ CLEAR_PENDING_EXCEPTION;
+ h_throwable = Handle();
+ } else {
+ h_throwable = Handle(THREAD, (oop) cause.get_jobject());
+ if (h_throwable.not_null()) {
+ st->print("Caused by: ");
+ print(h_throwable, st);
+ st->cr();
+ }
+ }
+ }
}
-};
-
+}
void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) {
if (!StackTraceInThrowable) return;
@@ -1591,21 +1592,8 @@
// No-op if stack trace is disabled
if (!StackTraceInThrowable) return;
-
- objArrayOop h_oop = oopFactory::new_objectArray(trace_size, CHECK);
- objArrayHandle backtrace (THREAD, h_oop);
- typeArrayOop m_oop = oopFactory::new_metaDataArray(trace_chunk_size, CHECK);
- typeArrayHandle methods (THREAD, m_oop);
- typeArrayOop b = oopFactory::new_shortArray(trace_chunk_size, CHECK);
- typeArrayHandle bcis(THREAD, b);
- objArrayOop mirror_oop = oopFactory::new_objectArray(trace_chunk_size, CHECK);
- objArrayHandle mirrors (THREAD, mirror_oop);
-
- // backtrace has space for one chunk (next is NULL)
- backtrace->obj_at_put(trace_methods_offset, methods());
- backtrace->obj_at_put(trace_bcis_offset, bcis());
- backtrace->obj_at_put(trace_mirrors_offset, mirrors());
- set_backtrace(throwable(), backtrace());
+ BacktraceBuilder bt(CHECK); // creates a backtrace
+ set_backtrace(throwable(), bt.backtrace());
}
@@ -1617,48 +1605,26 @@
assert(throwable->is_a(SystemDictionary::Throwable_klass()), "sanity check");
- objArrayOop backtrace = (objArrayOop)java_lang_Throwable::backtrace(throwable());
- assert(backtrace != NULL, "backtrace not preallocated");
-
- oop m = backtrace->obj_at(trace_methods_offset);
- typeArrayOop methods = typeArrayOop(m);
- assert(methods != NULL && methods->length() > 0, "method array not preallocated");
-
- oop b = backtrace->obj_at(trace_bcis_offset);
- typeArrayOop bcis = typeArrayOop(b);
- assert(bcis != NULL, "bci array not preallocated");
-
- oop mr = backtrace->obj_at(trace_mirrors_offset);
- objArrayOop mirrors = objArrayOop(mr);
- assert(mirrors != NULL, "bci array not preallocated");
-
- assert(methods->length() == bcis->length() &&
- methods->length() == mirrors->length(),
- "method and bci arrays should match");
-
- JavaThread* thread = JavaThread::current();
- ResourceMark rm(thread);
- vframeStream st(thread);
+ JavaThread* THREAD = JavaThread::current();
+
+ objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable()));
+ assert(backtrace.not_null(), "backtrace should have been preallocated");
+
+ ResourceMark rm(THREAD);
+ vframeStream st(THREAD);
+
+ BacktraceBuilder bt(backtrace);
// Unlike fill_in_stack_trace we do not skip fillInStackTrace or throwable init
// methods as preallocated errors aren't created by "java" code.
// fill in as much stack trace as possible
+ typeArrayOop methods = BacktraceBuilder::get_methods(backtrace);
int max_chunks = MIN2(methods->length(), (int)MaxJavaStackTraceDepth);
int chunk_count = 0;
for (;!st.at_end(); st.next()) {
- // Add entry and smear the -1 bci to 0 since the array only holds
- // unsigned shorts. The later line number lookup would just smear
- // the -1 to a 0 even if it could be recorded.
- int bci = st.bci();
- if (bci == SynchronizationEntryBCI) bci = 0;
- assert(bci == (jushort)bci, "doesn't fit");
- bcis->ushort_at_put(chunk_count, bci);
- methods->metadata_at_put(chunk_count, st.method());
- mirrors->obj_at_put(chunk_count,
- st.method()->method_holder()->java_mirror());
-
+ bt.push(st.method(), st.bci(), CHECK);
chunk_count++;
// Bail-out for deep stacks
@@ -1672,7 +1638,6 @@
java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
assert(java_lang_Throwable::unassigned_stacktrace() != NULL, "not initialized");
}
-
}
@@ -1691,12 +1656,12 @@
chunk = next;
}
assert(chunk != NULL && chunk->obj_at(trace_next_offset) == NULL, "sanity check");
- // Count element in remaining partial chunk
- typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
- typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset));
- assert(methods != NULL && bcis != NULL, "sanity check");
- for (int i = 0; i < methods->length(); i++) {
- if (methods->metadata_at(i) == NULL) break;
+ // Count element in remaining partial chunk. NULL value for mirror
+ // marks the end of the stack trace elements that are saved.
+ objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
+ assert(mirrors != NULL, "sanity check");
+ for (int i = 0; i < mirrors->length(); i++) {
+ if (mirrors->obj_at(i) == NULL) break;
depth++;
}
}
@@ -1722,25 +1687,28 @@
if (chunk == NULL) {
THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
}
- // Get method,bci from chunk
- typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
- typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset));
- assert(methods != NULL && bcis != NULL, "sanity check");
- methodHandle method(THREAD, ((Method*)methods->metadata_at(chunk_index)));
- int bci = bcis->ushort_at(chunk_index);
+ // Get method id, bci, version and mirror from chunk
+ typeArrayOop methods = BacktraceBuilder::get_methods(chunk);
+ typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk);
+ objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk);
+
+ assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check");
+
+ int method = methods->short_at(chunk_index);
+ int version = version_at(bcis->int_at(chunk_index));
+ int bci = bci_at(bcis->int_at(chunk_index));
+ Handle mirror(THREAD, mirrors->obj_at(chunk_index));
+
// Chunk can be partial full
- if (method.is_null()) {
+ if (mirror.is_null()) {
THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL);
}
- oop element = java_lang_StackTraceElement::create(method, bci, CHECK_0);
+ oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0);
return element;
}
-oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
- // SystemDictionary::stackTraceElement_klass() will be null for pre-1.4 JDKs
- assert(JDK_Version::is_gte_jdk14x_version(), "should only be called in >= 1.4");
-
+oop java_lang_StackTraceElement::create(Handle mirror, int method_id, int version, int bci, TRAPS) {
// Allocate java.lang.StackTraceElement instance
Klass* k = SystemDictionary::StackTraceElement_klass();
assert(k != NULL, "must be loaded in 1.4+");
@@ -1752,37 +1720,39 @@
Handle element = ik->allocate_instance_handle(CHECK_0);
// Fill in class name
ResourceMark rm(THREAD);
- const char* str = method->method_holder()->external_name();
+ InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
+ const char* str = holder->external_name();
oop classname = StringTable::intern((char*) str, CHECK_0);
java_lang_StackTraceElement::set_declaringClass(element(), classname);
+
// Fill in method name
+ Method* method = holder->method_with_idnum(method_id);
oop methodname = StringTable::intern(method->name(), CHECK_0);
java_lang_StackTraceElement::set_methodName(element(), methodname);
- // Fill in source file name
- Symbol* source = method->method_holder()->source_file_name();
- if (ShowHiddenFrames && source == NULL)
- source = vmSymbols::unknown_class_name();
- oop filename = StringTable::intern(source, CHECK_0);
- java_lang_StackTraceElement::set_fileName(element(), filename);
- // File in source line number
- int line_number;
- if (method->is_native()) {
- // Negative value different from -1 below, enabling Java code in
- // class java.lang.StackTraceElement to distinguish "native" from
- // "no LineNumberTable".
- line_number = -2;
+
+ if (!version_matches(method, version)) {
+ // The method was redefined, accurate line number information isn't available
+ java_lang_StackTraceElement::set_fileName(element(), NULL);
+ java_lang_StackTraceElement::set_lineNumber(element(), -1);
} else {
- // Returns -1 if no LineNumberTable, and otherwise actual line number
- line_number = method->line_number_from_bci(bci);
- if (line_number == -1 && ShowHiddenFrames) {
- line_number = bci + 1000000;
- }
+ // Fill in source file name and line number.
+ Symbol* source = holder->source_file_name();
+ if (ShowHiddenFrames && source == NULL)
+ source = vmSymbols::unknown_class_name();
+ oop filename = StringTable::intern(source, CHECK_0);
+ java_lang_StackTraceElement::set_fileName(element(), filename);
+
+ int line_number = get_line_number(method, bci);
+ java_lang_StackTraceElement::set_lineNumber(element(), line_number);
}
- java_lang_StackTraceElement::set_lineNumber(element(), line_number);
-
return element();
}
+oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) {
+ Handle mirror (THREAD, method->method_holder()->java_mirror());
+ int method_id = method->method_idnum();
+ return create(mirror, method_id, method->constants()->version(), bci, THREAD);
+}
void java_lang_reflect_AccessibleObject::compute_offsets() {
Klass* k = SystemDictionary::reflect_AccessibleObject_klass();
@@ -2949,7 +2919,6 @@
int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
-int java_lang_Class::_resolved_constructor_offset;
int java_lang_Class::_oop_size_offset;
int java_lang_Class::_static_oop_field_count_offset;
GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = NULL;
@@ -3303,7 +3272,6 @@
// Fake fields
// CHECK_OFFSET("java/lang/Class", java_lang_Class, klass); // %%% this needs to be checked
// CHECK_OFFSET("java/lang/Class", java_lang_Class, array_klass); // %%% this needs to be checked
- // CHECK_OFFSET("java/lang/Class", java_lang_Class, resolved_constructor); // %%% this needs to be checked
// java.lang.Throwable
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -206,7 +206,6 @@
#define CLASS_INJECTED_FIELDS(macro) \
macro(java_lang_Class, klass, intptr_signature, false) \
- macro(java_lang_Class, resolved_constructor, intptr_signature, false) \
macro(java_lang_Class, array_klass, intptr_signature, false) \
macro(java_lang_Class, oop_size, int_signature, false) \
macro(java_lang_Class, static_oop_field_count, int_signature, false)
@@ -218,7 +217,6 @@
// The fake offsets are added by the class loader when java.lang.Class is loaded
static int _klass_offset;
- static int _resolved_constructor_offset;
static int _array_klass_offset;
static int _oop_size_offset;
@@ -254,15 +252,11 @@
static bool is_primitive(oop java_class);
static BasicType primitive_type(oop java_class);
static oop primitive_mirror(BasicType t);
- // JVM_NewInstance support
- static Method* resolved_constructor(oop java_class);
- static void set_resolved_constructor(oop java_class, Method* constructor);
// JVM_NewArray support
static Klass* array_klass(oop java_class);
static void set_array_klass(oop java_class, Klass* klass);
// compiler support for class operations
static int klass_offset_in_bytes() { return _klass_offset; }
- static int resolved_constructor_offset_in_bytes() { return _resolved_constructor_offset; }
static int array_klass_offset_in_bytes() { return _array_klass_offset; }
// Support for classRedefinedCount field
static int classRedefinedCount(oop the_class_mirror);
@@ -469,8 +463,7 @@
static int static_unassigned_stacktrace_offset;
// Printing
- static char* print_stack_element_to_buffer(Method* method, int bci);
- static void print_to_stream(Handle stream, const char* str);
+ static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci);
// StackTrace (programmatic access, new since 1.4)
static void clear_stacktrace(oop throwable);
// No stack trace available
@@ -490,12 +483,9 @@
static oop message(oop throwable);
static oop message(Handle throwable);
static void set_message(oop throwable, oop value);
- // Print stack trace stored in exception by call-back to Java
- // Note: this is no longer used in Merlin, but we still suppport
- // it for compatibility.
- static void print_stack_trace(oop throwable, oop print_stream);
- static void print_stack_element(Handle stream, Method* method, int bci);
- static void print_stack_element(outputStream *st, Method* method, int bci);
+ 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);
static void print_stack_usage(Handle stream);
// Allocate space for backtrace (created but stack trace not filled in)
@@ -1263,7 +1253,8 @@
static void set_lineNumber(oop element, int value);
// Create an instance of StackTraceElement
- static oop create(methodHandle m, int bci, TRAPS);
+ static oop create(Handle mirror, int method, int version, int bci, TRAPS);
+ static oop create(methodHandle method, int bci, TRAPS);
// Debugging
friend class JavaClasses;
--- a/hotspot/src/share/vm/classfile/placeholders.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/placeholders.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -142,7 +142,7 @@
}
-// placeholder used to track class loading internal states
+// placeholder is used to track class loading internal states
// placeholder existence now for loading superclass/superinterface
// superthreadQ tracks class circularity, while loading superclass/superinterface
// loadInstanceThreadQ tracks load_instance_class calls
@@ -153,15 +153,17 @@
// All claimants remove SeenThread after completing action
// On removal: if definer and all queues empty, remove entry
// Note: you can be in both placeholders and systemDictionary
-// see parse_stream for redefine classes
// Therefore - must always check SD first
// Ignores the case where entry is not found
void PlaceholderTable::find_and_remove(int index, unsigned int hash,
- Symbol* name, ClassLoaderData* loader_data, Thread* thread) {
+ Symbol* name, ClassLoaderData* loader_data,
+ classloadAction action,
+ Thread* thread) {
assert_locked_or_safepoint(SystemDictionary_lock);
PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
if (probe != NULL) {
- // No other threads using this entry
+ probe->remove_seen_thread(thread, action);
+ // If no other threads using this entry, and this thread is not using this entry for other states
if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
&& (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
remove_entry(index, hash, name, loader_data);
--- a/hotspot/src/share/vm/classfile/placeholders.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/placeholders.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -82,7 +82,7 @@
};
// find_and_add returns probe pointer - old or new
- // If no entry exists, add a placeholder entry and push SeenThread
+ // If no entry exists, add a placeholder entry and push SeenThread for classloadAction
// If entry exists, reuse entry and push SeenThread for classloadAction
PlaceholderEntry* find_and_add(int index, unsigned int hash,
Symbol* name, ClassLoaderData* loader_data,
@@ -92,9 +92,11 @@
void remove_entry(int index, unsigned int hash,
Symbol* name, ClassLoaderData* loader_data);
-// Remove placeholder information
+ // find_and_remove first removes SeenThread for classloadAction
+ // If all queues are empty and definer is null, remove the PlacheholderEntry completely
void find_and_remove(int index, unsigned int hash,
- Symbol* name, ClassLoaderData* loader_data, Thread* thread);
+ Symbol* name, ClassLoaderData* loader_data,
+ classloadAction action, Thread* thread);
// GC support.
void classes_do(KlassClosure* f);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -172,7 +172,7 @@
assert(klass_h() == NULL, "Should not have result with exception pending");
Handle e(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
- THROW_MSG_CAUSE_0(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e);
+ THROW_MSG_CAUSE_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string(), e);
} else {
return NULL;
}
@@ -181,9 +181,9 @@
if (klass_h() == NULL) {
ResourceMark rm(THREAD);
if (throw_error) {
- THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string());
+ THROW_MSG_NULL(vmSymbols::java_lang_NoClassDefFoundError(), class_name->as_C_string());
} else {
- THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
+ THROW_MSG_NULL(vmSymbols::java_lang_ClassNotFoundException(), class_name->as_C_string());
}
}
return (Klass*)klass_h();
@@ -343,29 +343,29 @@
}
if (throw_circularity_error) {
ResourceMark rm(THREAD);
- THROW_MSG_0(vmSymbols::java_lang_ClassCircularityError(), child_name->as_C_string());
+ THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), child_name->as_C_string());
}
// java.lang.Object should have been found above
assert(class_name != NULL, "null super class for resolving");
// Resolve the super class or interface, check results on return
- Klass* superk = NULL;
- superk = SystemDictionary::resolve_or_null(class_name,
+ Klass* superk = SystemDictionary::resolve_or_null(class_name,
class_loader,
protection_domain,
THREAD);
KlassHandle superk_h(THREAD, superk);
- // Note: clean up of placeholders currently in callers of
- // resolve_super_or_fail - either at update_dictionary time
- // or on error
+ // Clean up of placeholders moved so that each classloadAction registrar self-cleans up
+ // It is no longer necessary to keep the placeholder table alive until update_dictionary
+ // or error. GC used to walk the placeholder table as strong roots.
+ // The instanceKlass is kept alive because the class loader is on the stack,
+ // which keeps the loader_data alive, as well as all instanceKlasses in
+ // the loader_data. parseClassFile adds the instanceKlass to loader_data.
{
- MutexLocker mu(SystemDictionary_lock, THREAD);
- PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, child_name, loader_data);
- if (probe != NULL) {
- probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_SUPER);
- }
+ MutexLocker mu(SystemDictionary_lock, THREAD);
+ placeholders()->find_and_remove(p_index, p_hash, child_name, loader_data, PlaceholderTable::LOAD_SUPER, THREAD);
+ SystemDictionary_lock->notify_all();
}
if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
// can null superk
@@ -430,8 +430,8 @@
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
- // SystemDictionary::do_unloading() asserts that classes are only
- // unloaded at a safepoint.
+ // Dictionary::do_unloading() asserts that classes in SD are only
+ // unloaded at a safepoint. Anonymous classes are not in SD.
No_Safepoint_Verifier nosafepoint;
dictionary()->add_protection_domain(d_index, d_hash, klass, loader_data,
protection_domain, THREAD);
@@ -486,7 +486,6 @@
// super class loading here.
// This also is critical in cases where the original thread gets stalled
// even in non-circularity situations.
-// Note: only one thread can define the class, but multiple can resolve
// Note: must call resolve_super_or_fail even if null super -
// to force placeholder entry creation for this class for circularity detection
// Caller must check for pending exception
@@ -518,14 +517,6 @@
protection_domain,
true,
CHECK_(nh));
- // We don't redefine the class, so we just need to clean up if there
- // was not an error (don't want to modify any system dictionary
- // data structures).
- {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
- SystemDictionary_lock->notify_all();
- }
// parallelCapable class loaders do NOT wait for parallel superclass loads to complete
// Serial class loaders and bootstrap classloader do wait for superclass loads
@@ -595,6 +586,10 @@
// Do lookup to see if class already exist and the protection domain
// has the right access
+ // This call uses find which checks protection domain already matches
+ // All subsequent calls use find_class, and set has_loaded_class so that
+ // before we return a result we call out to java to check for valid protection domain
+ // to allow returning the Klass* and add it to the pd_set if it is valid
unsigned int d_hash = dictionary()->compute_hash(name, loader_data);
int d_index = dictionary()->hash_to_index(d_hash);
Klass* probe = dictionary()->find(d_index, d_hash, name, loader_data,
@@ -652,7 +647,7 @@
}
}
- // If the class in is in the placeholder table, class loading is in progress
+ // If the class is in the placeholder table, class loading is in progress
if (super_load_in_progress && havesupername==true) {
k = SystemDictionary::handle_parallel_super_load(name, superclassname,
class_loader, protection_domain, lockObject, THREAD);
@@ -664,7 +659,9 @@
}
}
+ bool throw_circularity_error = false;
if (!class_has_been_loaded) {
+ bool load_instance_added = false;
// add placeholder entry to record loading instance class
// Five cases:
@@ -690,7 +687,7 @@
// No performance benefit and no deadlock issues.
// case 5. parallelCapable user level classloaders - without objectLocker
// Allow parallel classloading of a class/classloader pair
- bool throw_circularity_error = false;
+
{
MutexLocker mu(SystemDictionary_lock, THREAD);
if (class_loader.is_null() || !is_parallelCapable(class_loader)) {
@@ -726,12 +723,13 @@
}
}
}
- // All cases: add LOAD_INSTANCE
+ // All cases: add LOAD_INSTANCE holding SystemDictionary_lock
// case 3: UnsyncloadClass || case 5: parallelCapable: allow competing threads to try
// LOAD_INSTANCE in parallel
- // add placeholder entry even if error - callers will remove on error
+
if (!throw_circularity_error && !class_has_been_loaded) {
PlaceholderEntry* newprobe = placeholders()->find_and_add(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, NULL, THREAD);
+ load_instance_added = true;
// For class loaders that do not acquire the classloader object lock,
// if they did not catch another thread holding LOAD_INSTANCE,
// need a check analogous to the acquire ObjectLocker/find_class
@@ -740,19 +738,18 @@
// class loaders holding the ObjectLock shouldn't find the class here
Klass* check = find_class(d_index, d_hash, name, loader_data);
if (check != NULL) {
- // Klass is already loaded, so just return it
+ // Klass is already loaded, so return it after checking/adding protection domain
k = instanceKlassHandle(THREAD, check);
class_has_been_loaded = true;
- newprobe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE);
- placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
- SystemDictionary_lock->notify_all();
}
}
}
+
// must throw error outside of owning lock
if (throw_circularity_error) {
+ assert(!HAS_PENDING_EXCEPTION && load_instance_added == false,"circularity error cleanup");
ResourceMark rm(THREAD);
- THROW_MSG_0(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string());
+ THROW_MSG_NULL(vmSymbols::java_lang_ClassCircularityError(), name->as_C_string());
}
if (!class_has_been_loaded) {
@@ -782,20 +779,6 @@
}
}
- // clean up placeholder entries for success or error
- // This cleans up LOAD_INSTANCE entries
- // It also cleans up LOAD_SUPER entries on errors from
- // calling load_instance_class
- {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- PlaceholderEntry* probe = placeholders()->get_entry(p_index, p_hash, name, loader_data);
- if (probe != NULL) {
- probe->remove_seen_thread(THREAD, PlaceholderTable::LOAD_INSTANCE);
- placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
- SystemDictionary_lock->notify_all();
- }
- }
-
// If everything was OK (no exceptions, no null return value), and
// class_loader is NOT the defining loader, do a little more bookkeeping.
if (!HAS_PENDING_EXCEPTION && !k.is_null() &&
@@ -819,18 +802,22 @@
}
}
}
- if (HAS_PENDING_EXCEPTION || k.is_null()) {
- // On error, clean up placeholders
- {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
- SystemDictionary_lock->notify_all();
- }
- return NULL;
- }
+ } // load_instance_class loop
+
+ if (load_instance_added == true) {
+ // clean up placeholder entries for LOAD_INSTANCE success or error
+ // This brackets the SystemDictionary updates for both defining
+ // and initiating loaders
+ MutexLocker mu(SystemDictionary_lock, THREAD);
+ placeholders()->find_and_remove(p_index, p_hash, name, loader_data, PlaceholderTable::LOAD_INSTANCE, THREAD);
+ SystemDictionary_lock->notify_all();
}
}
+ if (HAS_PENDING_EXCEPTION || k.is_null()) {
+ return NULL;
+ }
+
#ifdef ASSERT
{
ClassLoaderData* loader_data = k->class_loader_data();
@@ -850,8 +837,8 @@
// so we cannot allow GC to occur while we're holding this entry.
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
- // SystemDictionary::do_unloading() asserts that classes are only
- // unloaded at a safepoint.
+ // Dictionary::do_unloading() asserts that classes in SD are only
+ // unloaded at a safepoint. Anonymous classes are not in SD.
No_Safepoint_Verifier nosafepoint;
if (dictionary()->is_valid_protection_domain(d_index, d_hash, name,
loader_data,
@@ -898,8 +885,8 @@
// so we cannot allow GC to occur while we're holding this entry.
// We're using a No_Safepoint_Verifier to catch any place where we
// might potentially do a GC at all.
- // SystemDictionary::do_unloading() asserts that classes are only
- // unloaded at a safepoint.
+ // Dictionary::do_unloading() asserts that classes in SD are only
+ // unloaded at a safepoint. Anonymous classes are not in SD.
No_Safepoint_Verifier nosafepoint;
return dictionary()->find(d_index, d_hash, class_name, loader_data,
protection_domain, THREAD);
@@ -965,10 +952,6 @@
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
- // Further note: a placeholder will be added for this class when
- // super classes are loaded (resolve_super_or_fail). We expect this
- // to be called for all classes but java.lang.Object; and we preload
- // java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
loader_data,
@@ -979,21 +962,6 @@
true,
THREAD);
- // We don't redefine the class, so we just need to clean up whether there
- // was an error or not (don't want to modify any system dictionary
- // data structures).
- // Parsed name could be null if we threw an error before we got far
- // enough along to parse it -- in that case, there is nothing to clean up.
- if (parsed_name != NULL) {
- unsigned int p_hash = placeholders()->compute_hash(parsed_name,
- loader_data);
- int p_index = placeholders()->hash_to_index(p_hash);
- {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- placeholders()->find_and_remove(p_index, p_hash, parsed_name, loader_data, THREAD);
- SystemDictionary_lock->notify_all();
- }
- }
if (host_klass.not_null() && k.not_null()) {
assert(EnableInvokeDynamic, "");
@@ -1062,10 +1030,6 @@
// throw potential ClassFormatErrors.
//
// Note: "name" is updated.
- // Further note: a placeholder will be added for this class when
- // super classes are loaded (resolve_super_or_fail). We expect this
- // to be called for all classes but java.lang.Object; and we preload
- // java.lang.Object through resolve_or_fail, not this path.
instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
loader_data,
@@ -1114,25 +1078,7 @@
}
}
- // If parsing the class file or define_instance_class failed, we
- // need to remove the placeholder added on our behalf. But we
- // must make sure parsed_name is valid first (it won't be if we had
- // a format error before the class was parsed far enough to
- // find the name).
- if (HAS_PENDING_EXCEPTION && parsed_name != NULL) {
- unsigned int p_hash = placeholders()->compute_hash(parsed_name,
- loader_data);
- int p_index = placeholders()->hash_to_index(p_hash);
- {
- MutexLocker mu(SystemDictionary_lock, THREAD);
- placeholders()->find_and_remove(p_index, p_hash, parsed_name, loader_data, THREAD);
- SystemDictionary_lock->notify_all();
- }
- return NULL;
- }
-
- // Make sure that we didn't leave a place holder in the
- // SystemDictionary; this is only done on success
+ // Make sure we have an entry in the SystemDictionary on success
debug_only( {
if (!HAS_PENDING_EXCEPTION) {
assert(parsed_name != NULL, "parsed_name is still null?");
@@ -1547,8 +1493,7 @@
// Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary
if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instance_klass() != NULL)) {
- probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
- placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
+ placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
#ifdef ASSERT
Klass* check = find_class(d_index, d_hash, name_h, loader_data);
@@ -1578,8 +1523,7 @@
probe->set_instance_klass(k());
}
probe->set_definer(NULL);
- probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
- placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, THREAD);
+ placeholders()->find_and_remove(p_index, p_hash, name_h, loader_data, PlaceholderTable::DEFINE_CLASS, THREAD);
SystemDictionary_lock->notify_all();
}
}
@@ -1736,6 +1680,8 @@
}
return newsize;
}
+// Assumes classes in the SystemDictionary are only unloaded at a safepoint
+// Note: anonymous classes are not in the SD.
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
// First, mark for unload all ClassLoaderData referencing a dead class loader.
bool has_dead_loaders = ClassLoaderDataGraph::do_unloading(is_alive);
@@ -2105,9 +2051,7 @@
// All loaded classes get a unique ID.
TRACE_INIT_ID(k);
- // Check for a placeholder. If there, remove it and make a
- // new system dictionary entry.
- placeholders()->find_and_remove(p_index, p_hash, name, loader_data, THREAD);
+ // Make a new system dictionary entry.
Klass* sd_check = find_class(d_index, d_hash, name, loader_data);
if (sd_check == NULL) {
dictionary()->add_klass(name, loader_data, k);
@@ -2116,12 +2060,8 @@
#ifdef ASSERT
sd_check = find_class(d_index, d_hash, name, loader_data);
assert (sd_check != NULL, "should have entry in system dictionary");
-// Changed to allow PH to remain to complete class circularity checking
-// while only one thread can define a class at one time, multiple
-// classes can resolve the superclass for a class at one time,
-// and the placeholder is used to track that
-// Symbol* ph_check = find_placeholder(name, class_loader);
-// assert (ph_check == NULL, "should not have a placeholder entry");
+ // Note: there may be a placeholder entry: for circularity testing
+ // or for parallel defines
#endif
SystemDictionary_lock->notify_all();
}
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -194,7 +194,10 @@
template(java_lang_VirtualMachineError, "java/lang/VirtualMachineError") \
template(java_lang_StackOverflowError, "java/lang/StackOverflowError") \
template(java_lang_StackTraceElement, "java/lang/StackTraceElement") \
+ \
+ /* Concurrency support */ \
template(java_util_concurrent_locks_AbstractOwnableSynchronizer, "java/util/concurrent/locks/AbstractOwnableSynchronizer") \
+ template(sun_misc_Contended_signature, "Lsun/misc/Contended;") \
\
/* class symbols needed by intrinsics */ \
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, template, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
@@ -284,7 +287,7 @@
NOT_LP64( do_alias(intptr_signature, int_signature) ) \
LP64_ONLY( do_alias(intptr_signature, long_signature) ) \
template(selectAlternative_signature, "(ZLjava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;)Ljava/lang/invoke/MethodHandle;") \
- \
+ \
/* common method and field names */ \
template(object_initializer_name, "<init>") \
template(class_initializer_name, "<clinit>") \
@@ -383,7 +386,6 @@
template(basicType_name, "basicType") \
template(append_name, "append") \
template(klass_name, "klass") \
- template(resolved_constructor_name, "resolved_constructor") \
template(array_klass_name, "array_klass") \
template(oop_size_name, "oop_size") \
template(static_oop_field_count_name, "static_oop_field_count") \
@@ -733,6 +735,11 @@
do_intrinsic(_checkIndex, java_nio_Buffer, checkIndex_name, int_int_signature, F_R) \
do_name( checkIndex_name, "checkIndex") \
\
+ do_class(sun_nio_cs_iso8859_1_Encoder, "sun/nio/cs/ISO_8859_1$Encoder") \
+ do_intrinsic(_encodeISOArray, sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S) \
+ do_name( encodeISOArray_name, "encodeISOArray") \
+ do_signature(encodeISOArray_signature, "([CI[BII)I") \
+ \
/* java/lang/ref/Reference */ \
do_intrinsic(_Reference_get, java_lang_ref_Reference, get_name, void_object_signature, F_R) \
\
--- a/hotspot/src/share/vm/code/codeCache.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/code/codeCache.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -30,6 +30,7 @@
#include "code/icBuffer.hpp"
#include "code/nmethod.hpp"
#include "code/pcDesc.hpp"
+#include "compiler/compileBroker.hpp"
#include "gc_implementation/shared/markSweep.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/gcLocker.hpp"
@@ -39,6 +40,7 @@
#include "oops/objArrayOop.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/handles.inline.hpp"
+#include "runtime/arguments.hpp"
#include "runtime/icache.hpp"
#include "runtime/java.hpp"
#include "runtime/mutexLocker.hpp"
@@ -168,6 +170,8 @@
return (nmethod*)cb;
}
+static size_t maxCodeCacheUsed = 0;
+
CodeBlob* CodeCache::allocate(int size) {
// Do not seize the CodeCache lock here--if the caller has not
// already done so, we are going to lose bigtime, since the code
@@ -192,6 +196,8 @@
(address)_heap->end() - (address)_heap->begin());
}
}
+ maxCodeCacheUsed = MAX2(maxCodeCacheUsed, ((address)_heap->high_boundary() -
+ (address)_heap->low_boundary()) - unallocated_capacity());
verify_if_often();
print_trace("allocation", cb, size);
return cb;
@@ -928,7 +934,14 @@
FREE_C_HEAP_ARRAY(int, buckets, mtCode);
}
+#endif // !PRODUCT
+
void CodeCache::print() {
+ print_summary(tty);
+
+#ifndef PRODUCT
+ if (!Verbose) return;
+
CodeBlob_sizes live;
CodeBlob_sizes dead;
@@ -953,7 +966,7 @@
}
- if (Verbose) {
+ if (WizardMode) {
// print the oop_map usage
int code_size = 0;
int number_of_blobs = 0;
@@ -977,20 +990,30 @@
tty->print_cr(" map size = %d", map_size);
}
+#endif // !PRODUCT
}
-#endif // PRODUCT
+void CodeCache::print_summary(outputStream* st, bool detailed) {
+ size_t total = (_heap->high_boundary() - _heap->low_boundary());
+ st->print_cr("CodeCache: size=" SIZE_FORMAT "Kb used=" SIZE_FORMAT
+ "Kb max_used=" SIZE_FORMAT "Kb free=" SIZE_FORMAT
+ "Kb max_free_chunk=" SIZE_FORMAT "Kb",
+ total/K, (total - unallocated_capacity())/K,
+ maxCodeCacheUsed/K, unallocated_capacity()/K, largest_free_block()/K);
-void CodeCache::print_bounds(outputStream* st) {
- st->print_cr("Code Cache [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
- _heap->low_boundary(),
- _heap->high(),
- _heap->high_boundary());
- st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
- " adapters=" UINT32_FORMAT " free_code_cache=" SIZE_FORMAT "Kb"
- " largest_free_block=" SIZE_FORMAT,
- nof_blobs(), nof_nmethods(), nof_adapters(),
- unallocated_capacity()/K, largest_free_block());
+ if (detailed) {
+ st->print_cr(" bounds [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT "]",
+ _heap->low_boundary(),
+ _heap->high(),
+ _heap->high_boundary());
+ st->print_cr(" total_blobs=" UINT32_FORMAT " nmethods=" UINT32_FORMAT
+ " adapters=" UINT32_FORMAT,
+ nof_blobs(), nof_nmethods(), nof_adapters());
+ st->print_cr(" compilation: %s", CompileBroker::should_compile_new_jobs() ?
+ "enabled" : Arguments::mode() == Arguments::_int ?
+ "disabled (interpreter mode)" :
+ "disabled (not enough contiguous free space left)");
+ }
}
void CodeCache::log_state(outputStream* st) {
--- a/hotspot/src/share/vm/code/codeCache.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/code/codeCache.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -145,11 +145,11 @@
static void prune_scavenge_root_nmethods();
// Printing/debugging
- static void print() PRODUCT_RETURN; // prints summary
+ static void print(); // prints summary
static void print_internals();
static void verify(); // verifies the code cache
static void print_trace(const char* event, CodeBlob* cb, int size = 0) PRODUCT_RETURN;
- static void print_bounds(outputStream* st); // Prints a summary of the bounds of the code cache
+ static void print_summary(outputStream* st, bool detailed = true); // Prints a summary of the code cache usage
static void log_state(outputStream* st);
// The full limits of the codeCache
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -50,6 +50,7 @@
// Missing feature tests
virtual bool supports_native() { return true; }
virtual bool supports_osr () { return true; }
+ virtual bool can_compile_method(methodHandle method) { return true; }
#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK))
virtual bool is_c1 () { return false; }
virtual bool is_c2 () { return false; }
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1218,7 +1218,7 @@
// lock, make sure that the compilation
// isn't prohibited in a straightforward way.
- if (compiler(comp_level) == NULL || compilation_is_prohibited(method, osr_bci, comp_level)) {
+ if (compiler(comp_level) == NULL || !compiler(comp_level)->can_compile_method(method) || compilation_is_prohibited(method, osr_bci, comp_level)) {
return NULL;
}
@@ -1714,6 +1714,20 @@
}
}
+// wrapper for CodeCache::print_summary()
+static void codecache_print(bool detailed)
+{
+ ResourceMark rm;
+ stringStream s;
+ // Dump code cache into a buffer before locking the tty,
+ {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ CodeCache::print_summary(&s, detailed);
+ }
+ ttyLocker ttyl;
+ tty->print_cr(s.as_string());
+}
+
// ------------------------------------------------------------------
// CompileBroker::invoke_compiler_on_method
//
@@ -1841,6 +1855,9 @@
tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes());
}
+ if (PrintCodeCacheOnCompilation)
+ codecache_print(/* detailed= */ false);
+
// Disable compilation, if required.
switch (compilable) {
case ciEnv::MethodCompilable_never:
@@ -1885,6 +1902,7 @@
UseInterpreter = true;
if (UseCompiler || AlwaysCompileLoopMethods ) {
if (xtty != NULL) {
+ ResourceMark rm;
stringStream s;
// Dump code cache state into a buffer before locking the tty,
// because log_state() will use locks causing lock conflicts.
@@ -1898,9 +1916,9 @@
}
warning("CodeCache is full. Compiler has been disabled.");
warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
- CodeCache::print_bounds(tty);
#ifndef PRODUCT
if (CompileTheWorld || ExitOnFullCodeCache) {
+ codecache_print(/* detailed= */ true);
before_exit(JavaThread::current());
exit_globals(); // will delete tty
vm_direct_exit(CompileTheWorld ? 0 : 1);
@@ -1913,6 +1931,7 @@
AlwaysCompileLoopMethods = false;
}
}
+ codecache_print(/* detailed= */ true);
}
// ------------------------------------------------------------------
--- a/hotspot/src/share/vm/compiler/oopMap.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -542,17 +542,17 @@
st->print("Oop");
break;
case OopMapValue::value_value:
- st->print("Value" );
+ st->print("Value");
break;
case OopMapValue::narrowoop_value:
- tty->print("NarrowOop" );
+ st->print("NarrowOop");
break;
case OopMapValue::callee_saved_value:
- st->print("Callers_" );
+ st->print("Callers_");
optional->print_on(st);
break;
case OopMapValue::derived_oop_value:
- st->print("Derived_oop_" );
+ st->print("Derived_oop_");
optional->print_on(st);
break;
default:
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -554,7 +554,7 @@
reportIndexedFreeListStatistics();
size_t total_size = totalSizeInIndexedFreeLists() +
_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
- gclog_or_tty->print(" free=%ld frag=%1.4f\n", total_size, flsFrag());
+ gclog_or_tty->print(" free=" SIZE_FORMAT " frag=%1.4f\n", total_size, flsFrag());
}
}
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -3338,7 +3338,7 @@
if (Verbose && PrintGC) {
size_t new_mem_size = _virtual_space.committed_size();
size_t old_mem_size = new_mem_size - bytes;
- gclog_or_tty->print_cr("Expanding %s from %ldK by %ldK to %ldK",
+ gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
name(), old_mem_size/K, bytes/K, new_mem_size/K);
}
}
@@ -9203,7 +9203,7 @@
if (Verbose && PrintGCDetails) {
size_t new_mem_size = _virtual_space.committed_size();
size_t old_mem_size = new_mem_size + bytes;
- gclog_or_tty->print_cr("Shrinking %s from %ldK by %ldK to %ldK",
+ gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K by " SIZE_FORMAT "K to " SIZE_FORMAT "K",
name(), old_mem_size/K, bytes/K, new_mem_size/K);
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -131,17 +131,23 @@
#ifndef PRODUCT
+template <> const int WorkerDataArray<int>::_uninitialized = -1;
+template <> const double WorkerDataArray<double>::_uninitialized = -1.0;
+template <> const size_t WorkerDataArray<size_t>::_uninitialized = (size_t)-1;
+
template <class T>
void WorkerDataArray<T>::reset() {
for (uint i = 0; i < _length; i++) {
- _data[i] = (T)-1;
+ _data[i] = (T)_uninitialized;
}
}
template <class T>
void WorkerDataArray<T>::verify() {
for (uint i = 0; i < _length; i++) {
- assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i));
+ assert(_data[i] != _uninitialized,
+ err_msg("Invalid data for worker " UINT32_FORMAT ", data: %lf, uninitialized: %lf",
+ i, (double)_data[i], (double)_uninitialized));
}
}
@@ -201,20 +207,20 @@
_last_termination_attempts.verify();
_last_gc_worker_end_times_ms.verify();
- for (uint i = 0; i < _active_gc_threads; i++) {
- double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
- _last_gc_worker_times_ms.set(i, worker_time);
+ for (uint i = 0; i < _active_gc_threads; i++) {
+ double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
+ _last_gc_worker_times_ms.set(i, worker_time);
- double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
- _last_satb_filtering_times_ms.get(i) +
- _last_update_rs_times_ms.get(i) +
- _last_scan_rs_times_ms.get(i) +
- _last_obj_copy_times_ms.get(i) +
- _last_termination_times_ms.get(i);
+ double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
+ _last_satb_filtering_times_ms.get(i) +
+ _last_update_rs_times_ms.get(i) +
+ _last_scan_rs_times_ms.get(i) +
+ _last_obj_copy_times_ms.get(i) +
+ _last_termination_times_ms.get(i);
- double worker_other_time = worker_time - worker_known_time;
- _last_gc_worker_other_times_ms.set(i, worker_other_time);
- }
+ double worker_other_time = worker_time - worker_known_time;
+ _last_gc_worker_other_times_ms.set(i, worker_other_time);
+ }
_last_gc_worker_times_ms.verify();
_last_gc_worker_other_times_ms.verify();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -35,6 +35,8 @@
const char* _print_format;
bool _print_sum;
+ NOT_PRODUCT(static const T _uninitialized;)
+
// We are caching the sum and average to only have to calculate them once.
// This is not done in an MT-safe way. It is intetened to allow single
// threaded code to call sum() and average() multiple times in any order
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -287,24 +287,24 @@
"The number of times we'll force an overflow during " \
"concurrent marking") \
\
- experimental(uintx, G1NewSizePercent, 20, \
+ experimental(uintx, G1NewSizePercent, 5, \
"Percentage (0-100) of the heap size to use as default " \
"minimum young gen size.") \
\
- experimental(uintx, G1MaxNewSizePercent, 80, \
+ experimental(uintx, G1MaxNewSizePercent, 60, \
"Percentage (0-100) of the heap size to use as default " \
" maximum young gen size.") \
\
- experimental(uintx, G1MixedGCLiveThresholdPercent, 90, \
+ experimental(uintx, G1MixedGCLiveThresholdPercent, 65, \
"Threshold for regions to be considered for inclusion in the " \
"collection set of mixed GCs. " \
"Regions with live bytes exceeding this will not be collected.") \
\
- product(uintx, G1HeapWastePercent, 5, \
+ product(uintx, G1HeapWastePercent, 10, \
"Amount of space, expressed as a percentage of the heap size, " \
"that G1 is willing not to collect to avoid expensive GCs.") \
\
- product(uintx, G1MixedGCCountTarget, 4, \
+ product(uintx, G1MixedGCCountTarget, 8, \
"The target number of mixed GCs after a marking cycle.") \
\
experimental(uintx, G1OldCSetRegionThresholdPercent, 10, \
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -878,12 +878,6 @@
bool ParNewGeneration::_avoid_promotion_undo = false;
-void ParNewGeneration::adjust_desired_tenuring_threshold() {
- // Set the desired survivor size to half the real survivor space
- _tenuring_threshold =
- age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
-}
-
// A Generation that does parallel young-gen collection.
void ParNewGeneration::collect(bool full,
@@ -1013,6 +1007,8 @@
size_policy->reset_gc_overhead_limit_count();
assert(to()->is_empty(), "to space should be empty now");
+
+ adjust_desired_tenuring_threshold();
} else {
assert(_promo_failure_scan_stack.is_empty(), "post condition");
_promo_failure_scan_stack.clear(true); // Clear cached segments.
@@ -1035,7 +1031,6 @@
from()->set_concurrent_iteration_safe_limit(from()->top());
to()->set_concurrent_iteration_safe_limit(to()->top());
- adjust_desired_tenuring_threshold();
if (ResizePLAB) {
plab_stats()->adjust_desired_plab_sz(n_workers);
}
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -347,10 +347,6 @@
bool survivor_overflow() { return _survivor_overflow; }
void set_survivor_overflow(bool v) { _survivor_overflow = v; }
- // Adjust the tenuring threshold. See the implementation for
- // the details of the policy.
- virtual void adjust_desired_tenuring_threshold();
-
public:
ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level);
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -529,7 +529,7 @@
if (PrintTenuringDistribution) {
gclog_or_tty->cr();
- gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)",
+ gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max %u)",
size_policy->calculated_survivor_size_in_bytes(),
_tenuring_threshold, MaxTenuringThreshold);
}
--- a/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -96,7 +96,7 @@
if (PrintTenuringDistribution) {
gclog_or_tty->cr();
- gclog_or_tty->print_cr("Desired survivor size %ld bytes, new threshold %u (max %u)",
+ gclog_or_tty->print_cr("Desired survivor size " SIZE_FORMAT " bytes, new threshold %u (max %u)",
desired_survivor_size*oopSize, result, MaxTenuringThreshold);
}
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -550,6 +550,11 @@
return allocate(size, is_tlab);
}
+void DefNewGeneration::adjust_desired_tenuring_threshold() {
+ // Set the desired survivor size to half the real survivor space
+ _tenuring_threshold =
+ age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
+}
void DefNewGeneration::collect(bool full,
bool clear_all_soft_refs,
@@ -649,9 +654,7 @@
assert(to()->is_empty(), "to space should be empty now");
- // Set the desired survivor size to half the real survivor space
- _tenuring_threshold =
- age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
+ adjust_desired_tenuring_threshold();
// A successful scavenge should restart the GC time limit count which is
// for full GC's.
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -124,7 +124,9 @@
_should_allocate_from_space = true;
}
- protected:
+ // Tenuring
+ void adjust_desired_tenuring_threshold();
+
// Spaces
EdenSpace* _eden_space;
ContiguousSpace* _from_space;
--- a/hotspot/src/share/vm/memory/metadataFactory.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/memory/metadataFactory.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -66,7 +66,11 @@
if (data != NULL) {
assert(loader_data != NULL, "shouldn't pass null");
int size = data->size();
- loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false);
+ if (DumpSharedSpaces) {
+ loader_data->ro_metaspace()->deallocate((MetaWord*)data, size, false);
+ } else {
+ loader_data->metaspace_non_null()->deallocate((MetaWord*)data, size, false);
+ }
}
}
@@ -77,6 +81,7 @@
assert(loader_data != NULL, "shouldn't pass null");
int size = md->size();
// Call metadata's deallocate function which will call deallocate fields
+ assert(!DumpSharedSpaces, "cannot deallocate metadata when dumping CDS archive");
assert(!md->on_stack(), "can't deallocate things on stack");
md->deallocate_contents(loader_data);
loader_data->metaspace_non_null()->deallocate((MetaWord*)md, size, md->is_klass());
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -373,17 +373,44 @@
md_top = wc.get_top();
// Print shared spaces all the time
- const char* fmt = "%s space: " PTR_FORMAT " out of " PTR_FORMAT " words allocated at " PTR_FORMAT ".";
+ const char* fmt = "%s space: %9d [ %4.1f%% of total] out of %9d bytes [%4.1f%% used] at " PTR_FORMAT;
Metaspace* ro_space = _loader_data->ro_metaspace();
Metaspace* rw_space = _loader_data->rw_metaspace();
- tty->print_cr(fmt, "ro", ro_space->used_words(Metaspace::NonClassType),
- ro_space->capacity_words(Metaspace::NonClassType),
- ro_space->bottom());
- tty->print_cr(fmt, "rw", rw_space->used_words(Metaspace::NonClassType),
- rw_space->capacity_words(Metaspace::NonClassType),
- rw_space->bottom());
- tty->print_cr(fmt, "md", md_top - md_low, md_end-md_low, md_low);
- tty->print_cr(fmt, "mc", mc_top - mc_low, mc_end-mc_low, mc_low);
+ const size_t BPW = BytesPerWord;
+
+ // Allocated size of each space (may not be all occupied)
+ const size_t ro_alloced = ro_space->capacity_words(Metaspace::NonClassType) * BPW;
+ const size_t rw_alloced = rw_space->capacity_words(Metaspace::NonClassType) * BPW;
+ const size_t md_alloced = md_end-md_low;
+ const size_t mc_alloced = mc_end-mc_low;
+ const size_t total_alloced = ro_alloced + rw_alloced + md_alloced + mc_alloced;
+
+ // Occupied size of each space.
+ const size_t ro_bytes = ro_space->used_words(Metaspace::NonClassType) * BPW;
+ const size_t rw_bytes = rw_space->used_words(Metaspace::NonClassType) * BPW;
+ const size_t md_bytes = size_t(md_top - md_low);
+ const size_t mc_bytes = size_t(mc_top - mc_low);
+
+ // Percent of total size
+ const size_t total_bytes = ro_bytes + rw_bytes + md_bytes + mc_bytes;
+ const double ro_t_perc = ro_bytes / double(total_bytes) * 100.0;
+ const double rw_t_perc = rw_bytes / double(total_bytes) * 100.0;
+ const double md_t_perc = md_bytes / double(total_bytes) * 100.0;
+ const double mc_t_perc = mc_bytes / double(total_bytes) * 100.0;
+
+ // Percent of fullness of each space
+ const double ro_u_perc = ro_bytes / double(ro_alloced) * 100.0;
+ const double rw_u_perc = rw_bytes / double(rw_alloced) * 100.0;
+ const double md_u_perc = md_bytes / double(md_alloced) * 100.0;
+ const double mc_u_perc = mc_bytes / double(mc_alloced) * 100.0;
+ const double total_u_perc = total_bytes / double(total_alloced) * 100.0;
+
+ tty->print_cr(fmt, "ro", ro_bytes, ro_t_perc, ro_alloced, ro_u_perc, ro_space->bottom());
+ tty->print_cr(fmt, "rw", rw_bytes, rw_t_perc, rw_alloced, rw_u_perc, rw_space->bottom());
+ tty->print_cr(fmt, "md", md_bytes, md_t_perc, md_alloced, md_u_perc, md_low);
+ tty->print_cr(fmt, "mc", mc_bytes, mc_t_perc, mc_alloced, mc_u_perc, mc_low);
+ tty->print_cr("total : %9d [100.0%% of total] out of %9d bytes [%4.1f%% used]",
+ total_bytes, total_alloced, total_u_perc);
// Update the vtable pointers in all of the Klass objects in the
// heap. They should point to newly generated vtable.
--- a/hotspot/src/share/vm/memory/universe.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/memory/universe.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -228,7 +228,7 @@
if (size < alignment || size % alignment != 0) {
ResourceMark rm;
stringStream st;
- st.print("Size of %s (%ld bytes) must be aligned to %ld bytes", name, size, alignment);
+ st.print("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment);
char* error = st.as_string();
vm_exit_during_initialization(error);
}
--- a/hotspot/src/share/vm/oops/constMethod.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/constMethod.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -122,7 +122,12 @@
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
public:
u2 name_cp_index;
- u4 flags;
+ // This has to happen, otherwise it will cause SIGBUS from a
+ // misaligned u4 on some architectures (ie SPARC)
+ // because MethodParametersElements are only aligned mod 2
+ // within the ConstMethod container u2 flags_hi;
+ u2 flags_hi;
+ u2 flags_lo;
};
--- a/hotspot/src/share/vm/oops/constantPool.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,7 @@
set_pool_holder(NULL);
set_flags(0);
// only set to non-zero if constant pool is merged by RedefineClasses
- set_orig_length(0);
+ set_version(0);
set_lock(new Monitor(Monitor::nonleaf + 2, "A constant pool lock"));
// all fields are initialized; needed for GC
set_on_stack(false);
--- a/hotspot/src/share/vm/oops/constantPool.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,8 +103,8 @@
union {
// set for CDS to restore resolved references
int _resolved_reference_length;
- // only set to non-zero if constant pool is merged by RedefineClasses
- int _orig_length;
+ // keeps version number for redefined classes (used in backtrace)
+ int _version;
} _saved;
Monitor* _lock;
@@ -784,8 +784,11 @@
static void copy_cp_to_impl(constantPoolHandle from_cp, int start_i, int end_i, constantPoolHandle to_cp, int to_i, TRAPS);
static void copy_entry_to(constantPoolHandle from_cp, int from_i, constantPoolHandle to_cp, int to_i, TRAPS);
int find_matching_entry(int pattern_i, constantPoolHandle search_cp, TRAPS);
- int orig_length() const { return _saved._orig_length; }
- void set_orig_length(int orig_length) { _saved._orig_length = orig_length; }
+ int version() const { return _saved._version; }
+ void set_version(int version) { _saved._version = version; }
+ void increment_and_save_version(int version) {
+ _saved._version = version >= 0 ? (version + 1) : version; // keep overflow
+ }
void set_resolved_reference_length(int length) { _saved._resolved_reference_length = length; }
int resolved_reference_length() const { return _saved._resolved_reference_length; }
--- a/hotspot/src/share/vm/oops/fieldInfo.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/fieldInfo.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -43,14 +43,29 @@
public:
// fields
// Field info extracted from the class file and stored
- // as an array of 7 shorts
+ // as an array of 6 shorts.
+
+#define FIELDINFO_TAG_SIZE 2
+#define FIELDINFO_TAG_BLANK 0
+#define FIELDINFO_TAG_OFFSET 1
+#define FIELDINFO_TAG_TYPE_PLAIN 2
+#define FIELDINFO_TAG_TYPE_CONTENDED 3
+#define FIELDINFO_TAG_MASK 3
+
+ // Packed field has the tag, and can be either of:
+ // hi bits <--------------------------- lo bits
+ // |---------high---------|---------low---------|
+ // ..........................................00 - blank
+ // [------------------offset----------------]01 - real field offset
+ // ......................[-------type-------]10 - plain field with type
+ // [--contention_group--][-------type-------]11 - contended field with type and contention group
enum FieldOffset {
access_flags_offset = 0,
name_index_offset = 1,
signature_index_offset = 2,
initval_index_offset = 3,
- low_offset = 4,
- high_offset = 5,
+ low_packed_offset = 4,
+ high_packed_offset = 5,
field_slots = 6
};
@@ -76,17 +91,90 @@
void initialize(u2 access_flags,
u2 name_index,
u2 signature_index,
- u2 initval_index,
- u4 offset) {
+ u2 initval_index) {
_shorts[access_flags_offset] = access_flags;
_shorts[name_index_offset] = name_index;
_shorts[signature_index_offset] = signature_index;
_shorts[initval_index_offset] = initval_index;
- set_offset(offset);
+ _shorts[low_packed_offset] = 0;
+ _shorts[high_packed_offset] = 0;
}
u2 access_flags() const { return _shorts[access_flags_offset]; }
- u4 offset() const { return build_int_from_shorts(_shorts[low_offset], _shorts[high_offset]); }
+ u4 offset() const {
+ u2 lo = _shorts[low_packed_offset];
+ switch(lo & FIELDINFO_TAG_MASK) {
+ case FIELDINFO_TAG_OFFSET:
+ return build_int_from_shorts(_shorts[low_packed_offset], _shorts[high_packed_offset]) >> FIELDINFO_TAG_SIZE;
+#ifndef PRODUCT
+ case FIELDINFO_TAG_TYPE_PLAIN:
+ ShouldNotReachHere2("Asking offset for the plain type field");
+ case FIELDINFO_TAG_TYPE_CONTENDED:
+ ShouldNotReachHere2("Asking offset for the contended type field");
+ case FIELDINFO_TAG_BLANK:
+ ShouldNotReachHere2("Asking offset for the blank field");
+#endif
+ }
+ ShouldNotReachHere();
+ return 0;
+ }
+
+ bool is_contended() const {
+ u2 lo = _shorts[low_packed_offset];
+ switch(lo & FIELDINFO_TAG_MASK) {
+ case FIELDINFO_TAG_TYPE_PLAIN:
+ return false;
+ case FIELDINFO_TAG_TYPE_CONTENDED:
+ return true;
+#ifndef PRODUCT
+ case FIELDINFO_TAG_OFFSET:
+ ShouldNotReachHere2("Asking contended flag for the field with offset");
+ case FIELDINFO_TAG_BLANK:
+ ShouldNotReachHere2("Asking contended flag for the blank field");
+#endif
+ }
+ ShouldNotReachHere();
+ return false;
+ }
+
+ u2 contended_group() const {
+ u2 lo = _shorts[low_packed_offset];
+ switch(lo & FIELDINFO_TAG_MASK) {
+ case FIELDINFO_TAG_TYPE_PLAIN:
+ return 0;
+ case FIELDINFO_TAG_TYPE_CONTENDED:
+ return _shorts[high_packed_offset];
+#ifndef PRODUCT
+ case FIELDINFO_TAG_OFFSET:
+ ShouldNotReachHere2("Asking the contended group for the field with offset");
+ case FIELDINFO_TAG_BLANK:
+ ShouldNotReachHere2("Asking the contended group for the blank field");
+#endif
+ }
+ ShouldNotReachHere();
+ return 0;
+ }
+
+ u2 allocation_type() const {
+ u2 lo = _shorts[low_packed_offset];
+ switch(lo & FIELDINFO_TAG_MASK) {
+ case FIELDINFO_TAG_TYPE_PLAIN:
+ case FIELDINFO_TAG_TYPE_CONTENDED:
+ return (lo >> FIELDINFO_TAG_SIZE);
+#ifndef PRODUCT
+ case FIELDINFO_TAG_OFFSET:
+ ShouldNotReachHere2("Asking the field type for field with offset");
+ case FIELDINFO_TAG_BLANK:
+ ShouldNotReachHere2("Asking the field type for the blank field");
+#endif
+ }
+ ShouldNotReachHere();
+ return 0;
+ }
+
+ bool is_offset_set() const {
+ return (_shorts[low_packed_offset] & FIELDINFO_TAG_MASK) == FIELDINFO_TAG_OFFSET;
+ }
Symbol* name(constantPoolHandle cp) const {
int index = name_index();
@@ -106,8 +194,46 @@
void set_access_flags(u2 val) { _shorts[access_flags_offset] = val; }
void set_offset(u4 val) {
- _shorts[low_offset] = extract_low_short_from_int(val);
- _shorts[high_offset] = extract_high_short_from_int(val);
+ val = val << FIELDINFO_TAG_SIZE; // make room for tag
+ _shorts[low_packed_offset] = extract_low_short_from_int(val) | FIELDINFO_TAG_OFFSET;
+ _shorts[high_packed_offset] = extract_high_short_from_int(val);
+ }
+
+ void set_allocation_type(int type) {
+ u2 lo = _shorts[low_packed_offset];
+ switch(lo & FIELDINFO_TAG_MASK) {
+ case FIELDINFO_TAG_BLANK:
+ _shorts[low_packed_offset] = ((type << FIELDINFO_TAG_SIZE)) & 0xFFFF;
+ _shorts[low_packed_offset] &= ~FIELDINFO_TAG_MASK;
+ _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_PLAIN;
+ return;
+#ifndef PRODUCT
+ case FIELDINFO_TAG_TYPE_PLAIN:
+ case FIELDINFO_TAG_TYPE_CONTENDED:
+ case FIELDINFO_TAG_OFFSET:
+ ShouldNotReachHere2("Setting the field type with overwriting");
+#endif
+ }
+ ShouldNotReachHere();
+ }
+
+ void set_contended_group(u2 val) {
+ u2 lo = _shorts[low_packed_offset];
+ switch(lo & FIELDINFO_TAG_MASK) {
+ case FIELDINFO_TAG_TYPE_PLAIN:
+ _shorts[low_packed_offset] |= FIELDINFO_TAG_TYPE_CONTENDED;
+ _shorts[high_packed_offset] = val;
+ return;
+#ifndef PRODUCT
+ case FIELDINFO_TAG_TYPE_CONTENDED:
+ ShouldNotReachHere2("Overwriting contended group");
+ case FIELDINFO_TAG_BLANK:
+ ShouldNotReachHere2("Setting contended group for the blank field");
+ case FIELDINFO_TAG_OFFSET:
+ ShouldNotReachHere2("Setting contended group for field with offset");
+#endif
+ }
+ ShouldNotReachHere();
}
bool is_internal() const {
--- a/hotspot/src/share/vm/oops/fieldStreams.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/fieldStreams.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -160,9 +160,26 @@
return field()->offset();
}
+ int allocation_type() const {
+ return field()->allocation_type();
+ }
+
void set_offset(int offset) {
field()->set_offset(offset);
}
+
+ bool is_offset_set() const {
+ return field()->is_offset_set();
+ }
+
+ bool is_contended() const {
+ return field()->is_contended();
+ }
+
+ int contended_group() const {
+ return field()->contended_group();
+ }
+
};
// Iterate over only the internal fields
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -2890,11 +2890,7 @@
st->print(BULLET"fake entry for mirror: ");
mirrored_klass->print_value_on_maybe_null(st);
st->cr();
- st->print(BULLET"fake entry resolved_constructor: ");
- Method* ctor = java_lang_Class::resolved_constructor(obj);
- ctor->print_value_on_maybe_null(st);
Klass* array_klass = java_lang_Class::array_klass(obj);
- st->cr();
st->print(BULLET"fake entry for array: ");
array_klass->print_value_on_maybe_null(st);
st->cr();
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -225,12 +225,17 @@
u2 _java_fields_count; // The number of declared Java fields
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
+ // _is_marked_dependent can be set concurrently, thus cannot be part of the
+ // _misc_flags.
bool _is_marked_dependent; // used for marking during flushing and deoptimization
+
enum {
_misc_rewritten = 1 << 0, // methods rewritten.
_misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
_misc_should_verify_class = 1 << 2, // allow caching of preverification
- _misc_is_anonymous = 1 << 3 // has embedded _inner_classes field
+ _misc_is_anonymous = 1 << 3, // has embedded _inner_classes field
+ _misc_is_contended = 1 << 4, // marked with contended annotation
+ _misc_has_default_methods = 1 << 5 // class/superclass/implemented interfaces has default methods
};
u2 _misc_flags;
u2 _minor_version; // minor version number of class file
@@ -253,10 +258,6 @@
jint _cached_class_file_len; // JVMTI: length of above
JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
- // true if class, superclass, or implemented interfaces have default methods
- bool _has_default_methods;
-
- volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
// Method array.
Array<Method*>* _methods;
// Interface (Klass*s) this class declares locally to implement.
@@ -280,6 +281,8 @@
// ...
Array<u2>* _fields;
+ volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
+
// Class states are defined as ClassState (see above).
// Place the _init_state here to utilize the unused 2-byte after
// _idnum_allocated_count.
@@ -550,6 +553,17 @@
return is_anonymous() ? java_mirror() : class_loader();
}
+ bool is_contended() const {
+ return (_misc_flags & _misc_is_contended) != 0;
+ }
+ void set_is_contended(bool value) {
+ if (value) {
+ _misc_flags |= _misc_is_contended;
+ } else {
+ _misc_flags &= ~_misc_is_contended;
+ }
+ }
+
// signers
objArrayOop signers() const { return _signers; }
void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
@@ -616,8 +630,16 @@
return _jvmti_cached_class_field_map;
}
- bool has_default_methods() const { return _has_default_methods; }
- void set_has_default_methods(bool b) { _has_default_methods = b; }
+ bool has_default_methods() const {
+ return (_misc_flags & _misc_has_default_methods) != 0;
+ }
+ void set_has_default_methods(bool b) {
+ if (b) {
+ _misc_flags |= _misc_has_default_methods;
+ } else {
+ _misc_flags &= ~_misc_has_default_methods;
+ }
+ }
// for adding methods, ConstMethod::UNSET_IDNUM means no more ids available
inline u2 next_method_idnum();
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -516,6 +516,9 @@
develop(bool, SpecialArraysEquals, true, \
"special version of Arrays.equals(char[],char[])") \
\
+ product(bool, SpecialEncodeISOArray, true, \
+ "special version of ISO_8859_1$Encoder.encodeISOArray") \
+ \
develop(bool, BailoutToInterpreterForThrows, false, \
"Compiled methods which throws/catches exceptions will be " \
"deopt and intp.") \
--- a/hotspot/src/share/vm/opto/callnode.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -165,13 +165,13 @@
#ifndef PRODUCT
-void ReturnNode::dump_req() const {
+void ReturnNode::dump_req(outputStream *st) const {
// Dump the required inputs, enclosed in '(' and ')'
uint i; // Exit value of loop
- for( i=0; i<req(); i++ ) { // For all required inputs
- if( i == TypeFunc::Parms ) tty->print("returns");
- if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
- else tty->print("_ ");
+ for (i = 0; i < req(); i++) { // For all required inputs
+ if (i == TypeFunc::Parms) st->print("returns");
+ if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
+ else st->print("_ ");
}
}
#endif
@@ -208,13 +208,13 @@
}
#ifndef PRODUCT
-void RethrowNode::dump_req() const {
+void RethrowNode::dump_req(outputStream *st) const {
// Dump the required inputs, enclosed in '(' and ')'
uint i; // Exit value of loop
- for( i=0; i<req(); i++ ) { // For all required inputs
- if( i == TypeFunc::Parms ) tty->print("exception");
- if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
- else tty->print("_ ");
+ for (i = 0; i < req(); i++) { // For all required inputs
+ if (i == TypeFunc::Parms) st->print("exception");
+ if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
+ else st->print("_ ");
}
}
#endif
@@ -330,7 +330,8 @@
st->print(" %s%d]=#ScObj" INT32_FORMAT, msg, i, sco_n);
return;
}
- if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined
+ if (regalloc->node_regs_max_index() > 0 &&
+ OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined
char buf[50];
regalloc->dump_register(n,buf);
st->print(" %s%d]=%s",msg,i,buf);
@@ -381,7 +382,7 @@
//------------------------------format-----------------------------------------
void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const {
st->print(" #");
- if( _method ) {
+ if (_method) {
_method->print_short_name(st);
st->print(" @ bci:%d ",_bci);
} else {
@@ -393,21 +394,22 @@
MachSafePointNode *mcall = n->as_MachSafePoint();
uint i;
// Print locals
- for( i = 0; i < (uint)loc_size(); i++ )
- format_helper( regalloc, st, mcall->local(this, i), "L[", i, &scobjs );
+ for (i = 0; i < (uint)loc_size(); i++)
+ format_helper(regalloc, st, mcall->local(this, i), "L[", i, &scobjs);
// Print stack
for (i = 0; i < (uint)stk_size(); i++) {
if ((uint)(_stkoff + i) >= mcall->len())
st->print(" oob ");
else
- format_helper( regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs );
+ format_helper(regalloc, st, mcall->stack(this, i), "STK[", i, &scobjs);
}
for (i = 0; (int)i < nof_monitors(); i++) {
Node *box = mcall->monitor_box(this, i);
Node *obj = mcall->monitor_obj(this, i);
- if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) {
+ if (regalloc->node_regs_max_index() > 0 &&
+ OptoReg::is_valid(regalloc->get_reg_first(box))) {
box = BoxLockNode::box_node(box);
- format_helper( regalloc, st, box, "MON-BOX[", i, &scobjs );
+ format_helper(regalloc, st, box, "MON-BOX[", i, &scobjs);
} else {
OptoReg::Name box_reg = BoxLockNode::reg(box);
st->print(" MON-BOX%d=%s+%d",
@@ -420,7 +422,7 @@
if (BoxLockNode::box_node(box)->is_eliminated())
obj_msg = "MON-OBJ(LOCK ELIMINATED)[";
}
- format_helper( regalloc, st, obj, obj_msg, i, &scobjs );
+ format_helper(regalloc, st, obj, obj_msg, i, &scobjs);
}
for (i = 0; i < (uint)scobjs.length(); i++) {
@@ -463,9 +465,9 @@
st->print(" [");
cifield = iklass->nonstatic_field_at(0);
cifield->print_name_on(st);
- format_helper( regalloc, st, fld_node, ":", 0, &scobjs );
+ format_helper(regalloc, st, fld_node, ":", 0, &scobjs);
} else {
- format_helper( regalloc, st, fld_node, "[", 0, &scobjs );
+ format_helper(regalloc, st, fld_node, "[", 0, &scobjs);
}
for (uint j = 1; j < nf; j++) {
fld_node = mcall->in(first_ind+j);
@@ -473,9 +475,9 @@
st->print(", [");
cifield = iklass->nonstatic_field_at(j);
cifield->print_name_on(st);
- format_helper( regalloc, st, fld_node, ":", j, &scobjs );
+ format_helper(regalloc, st, fld_node, ":", j, &scobjs);
} else {
- format_helper( regalloc, st, fld_node, ", [", j, &scobjs );
+ format_helper(regalloc, st, fld_node, ", [", j, &scobjs);
}
}
}
@@ -483,7 +485,7 @@
}
}
st->print_cr("");
- if (caller() != NULL) caller()->format(regalloc, n, st);
+ if (caller() != NULL) caller()->format(regalloc, n, st);
}
@@ -586,15 +588,15 @@
uint CallNode::cmp( const Node &n ) const
{ return _tf == ((CallNode&)n)._tf && _jvms == ((CallNode&)n)._jvms; }
#ifndef PRODUCT
-void CallNode::dump_req() const {
+void CallNode::dump_req(outputStream *st) const {
// Dump the required inputs, enclosed in '(' and ')'
uint i; // Exit value of loop
- for( i=0; i<req(); i++ ) { // For all required inputs
- if( i == TypeFunc::Parms ) tty->print("(");
- if( in(i) ) tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
- else tty->print("_ ");
+ for (i = 0; i < req(); i++) { // For all required inputs
+ if (i == TypeFunc::Parms) st->print("(");
+ if (in(i)) st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
+ else st->print("_ ");
}
- tty->print(")");
+ st->print(")");
}
void CallNode::dump_spec(outputStream *st) const {
--- a/hotspot/src/share/vm/opto/callnode.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -126,7 +126,7 @@
virtual uint ideal_reg() const { return NotAMachineReg; }
virtual uint match_edge(uint idx) const;
#ifndef PRODUCT
- virtual void dump_req() const;
+ virtual void dump_req(outputStream *st = tty) const;
#endif
};
@@ -147,7 +147,7 @@
virtual uint match_edge(uint idx) const;
virtual uint ideal_reg() const { return NotAMachineReg; }
#ifndef PRODUCT
- virtual void dump_req() const;
+ virtual void dump_req(outputStream *st = tty) const;
#endif
};
@@ -579,7 +579,7 @@
virtual uint match_edge(uint idx) const;
#ifndef PRODUCT
- virtual void dump_req() const;
+ virtual void dump_req(outputStream *st = tty) const;
virtual void dump_spec(outputStream *st) const;
#endif
};
--- a/hotspot/src/share/vm/opto/classes.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/classes.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -127,6 +127,7 @@
macro(DivMod)
macro(DivModI)
macro(DivModL)
+macro(EncodeISOArray)
macro(EncodeP)
macro(EncodePKlass)
macro(ExpD)
--- a/hotspot/src/share/vm/opto/compile.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -692,7 +692,7 @@
PhaseGVN gvn(node_arena(), estimated_size);
set_initial_gvn(&gvn);
- if (PrintInlining) {
+ if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) {
_print_inlining_list = new (comp_arena())GrowableArray<PrintInliningBuffer>(comp_arena(), 1, 1, PrintInliningBuffer());
}
{ // Scope for timing the parser
@@ -2049,7 +2049,7 @@
} // (End scope of igvn; run destructor if necessary for asserts.)
- dump_inlining();
+ dump_inlining();
// A method with only infinite loops has no edges entering loops from root
{
NOT_PRODUCT( TracePhase t2("graphReshape", &_t_graphReshaping, TimeCompiler); )
@@ -3497,7 +3497,7 @@
}
void Compile::dump_inlining() {
- if (PrintInlining) {
+ if (PrintInlining || PrintIntrinsics NOT_PRODUCT( || PrintOptoInlining)) {
// Print inlining message for candidates that we couldn't inline
// for lack of space or non constant receiver
for (int i = 0; i < _late_inlines.length(); i++) {
--- a/hotspot/src/share/vm/opto/doCall.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/doCall.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -553,7 +553,13 @@
rtype = ctype;
}
} else {
- assert(rtype == ctype, "mismatched return types"); // symbolic resolution enforces this
+ // Symbolic resolution enforces the types to be the same.
+ // NOTE: We must relax the assert for unloaded types because two
+ // different ciType instances of the same unloaded class type
+ // can appear to be "loaded" by different loaders (depending on
+ // the accessing class).
+ assert(!rtype->is_loaded() || !ctype->is_loaded() || rtype == ctype,
+ err_msg_res("mismatched return types: rtype=%s, ctype=%s", rtype->name(), ctype->name()));
}
// If the return type of the method is not loaded, assert that the
--- a/hotspot/src/share/vm/opto/escape.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/escape.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -523,7 +523,8 @@
case Op_AryEq:
case Op_StrComp:
case Op_StrEquals:
- case Op_StrIndexOf: {
+ case Op_StrIndexOf:
+ case Op_EncodeISOArray: {
add_local_var(n, PointsToNode::ArgEscape);
delayed_worklist->push(n); // Process it later.
break;
@@ -701,7 +702,8 @@
case Op_AryEq:
case Op_StrComp:
case Op_StrEquals:
- case Op_StrIndexOf: {
+ case Op_StrIndexOf:
+ case Op_EncodeISOArray: {
// char[] arrays passed to string intrinsic do not escape but
// they are not scalar replaceable. Adjust escape state for them.
// Start from in(2) edge since in(1) is memory edge.
@@ -2581,15 +2583,22 @@
}
// Otherwise skip it (the call updated 'result' value).
} else if (result->Opcode() == Op_SCMemProj) {
- assert(result->in(0)->is_LoadStore(), "sanity");
- const Type *at = igvn->type(result->in(0)->in(MemNode::Address));
+ Node* mem = result->in(0);
+ Node* adr = NULL;
+ if (mem->is_LoadStore()) {
+ adr = mem->in(MemNode::Address);
+ } else {
+ assert(mem->Opcode() == Op_EncodeISOArray, "sanity");
+ adr = mem->in(3); // Memory edge corresponds to destination array
+ }
+ const Type *at = igvn->type(adr);
if (at != Type::TOP) {
assert (at->isa_ptr() != NULL, "pointer type required.");
int idx = C->get_alias_index(at->is_ptr());
assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field");
break;
}
- result = result->in(0)->in(MemNode::Memory);
+ result = mem->in(MemNode::Memory);
}
}
if (result->is_Phi()) {
@@ -2927,6 +2936,11 @@
if (m->is_MergeMem()) {
assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist");
}
+ } else if (use->Opcode() == Op_EncodeISOArray) {
+ if (use->in(MemNode::Memory) == n || use->in(3) == n) {
+ // EncodeISOArray overwrites destination array
+ memnode_worklist.append_if_missing(use);
+ }
} else {
uint op = use->Opcode();
if (!(op == Op_CmpP || op == Op_Conv2B ||
@@ -2962,6 +2976,16 @@
n = n->as_MemBar()->proj_out(TypeFunc::Memory);
if (n == NULL)
continue;
+ } else if (n->Opcode() == Op_EncodeISOArray) {
+ // get the memory projection
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ Node *use = n->fast_out(i);
+ if (use->Opcode() == Op_SCMemProj) {
+ n = use;
+ break;
+ }
+ }
+ assert(n->Opcode() == Op_SCMemProj, "memory projection required");
} else {
assert(n->is_Mem(), "memory node required.");
Node *addr = n->in(MemNode::Address);
@@ -2999,7 +3023,7 @@
Node *use = n->fast_out(i);
if (use->is_Phi() || use->is_ClearArray()) {
memnode_worklist.append_if_missing(use);
- } else if(use->is_Mem() && use->in(MemNode::Memory) == n) {
+ } else if (use->is_Mem() && use->in(MemNode::Memory) == n) {
if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores
continue;
memnode_worklist.append_if_missing(use);
@@ -3010,6 +3034,11 @@
assert(use->in(MemNode::Memory) != n, "EA: missing memory path");
} else if (use->is_MergeMem()) {
assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist");
+ } else if (use->Opcode() == Op_EncodeISOArray) {
+ if (use->in(MemNode::Memory) == n || use->in(3) == n) {
+ // EncodeISOArray overwrites destination array
+ memnode_worklist.append_if_missing(use);
+ }
} else {
uint op = use->Opcode();
if (!(op == Op_StoreCM ||
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -547,7 +547,7 @@
// max. 2 chars allowed
if (value >= -9 && value <= 99) {
- sprintf(buffer, INT64_FORMAT, value);
+ sprintf(buffer, JLONG_FORMAT, value);
print_prop(short_name, buffer);
} else {
print_prop(short_name, "L");
--- a/hotspot/src/share/vm/opto/lcm.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -175,6 +175,7 @@
case Op_StrEquals:
case Op_StrIndexOf:
case Op_AryEq:
+ case Op_EncodeISOArray:
// Not a legit memory op for implicit null check regardless of
// embedded loads
continue;
--- a/hotspot/src/share/vm/opto/library_call.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/library_call.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -290,6 +290,7 @@
bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
+ bool inline_encodeISOArray();
};
@@ -381,6 +382,10 @@
// These also use the arraycopy intrinsic mechanism:
if (!InlineArrayCopy) return NULL;
break;
+ case vmIntrinsics::_encodeISOArray:
+ if (!SpecialEncodeISOArray) return NULL;
+ if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return NULL;
+ break;
case vmIntrinsics::_checkIndex:
// We do not intrinsify this. The optimizer does fine with it.
return NULL;
@@ -799,6 +804,9 @@
case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
+ case vmIntrinsics::_encodeISOArray:
+ return inline_encodeISOArray();
+
default:
// If you get here, it may be that someone has added a new intrinsic
// to the list in vmSymbols.hpp without implementing it here.
@@ -3559,7 +3567,6 @@
// public static <T,U> T[] java.util.Arrays.copyOf( U[] original, int newLength, Class<? extends T[]> newType);
// public static <T,U> T[] java.util.Arrays.copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType);
bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
- return false;
if (too_many_traps(Deoptimization::Reason_intrinsic)) return false;
// Get the arguments.
@@ -5369,6 +5376,47 @@
src_start, dest_start, copy_length XTOP);
}
+//-------------inline_encodeISOArray-----------------------------------
+// encode char[] to byte[] in ISO_8859_1
+bool LibraryCallKit::inline_encodeISOArray() {
+ assert(callee()->signature()->size() == 5, "encodeISOArray has 5 parameters");
+ // no receiver since it is static method
+ Node *src = argument(0);
+ Node *src_offset = argument(1);
+ Node *dst = argument(2);
+ Node *dst_offset = argument(3);
+ Node *length = argument(4);
+
+ const Type* src_type = src->Value(&_gvn);
+ const Type* dst_type = dst->Value(&_gvn);
+ const TypeAryPtr* top_src = src_type->isa_aryptr();
+ const TypeAryPtr* top_dest = dst_type->isa_aryptr();
+ if (top_src == NULL || top_src->klass() == NULL ||
+ top_dest == NULL || top_dest->klass() == NULL) {
+ // failed array check
+ return false;
+ }
+
+ // Figure out the size and type of the elements we will be copying.
+ BasicType src_elem = src_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ BasicType dst_elem = dst_type->isa_aryptr()->klass()->as_array_klass()->element_type()->basic_type();
+ if (src_elem != T_CHAR || dst_elem != T_BYTE) {
+ return false;
+ }
+ Node* src_start = array_element_address(src, src_offset, src_elem);
+ Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
+ // 'src_start' points to src array + scaled offset
+ // 'dst_start' points to dst array + scaled offset
+
+ const TypeAryPtr* mtype = TypeAryPtr::BYTES;
+ Node* enc = new (C) EncodeISOArrayNode(control(), memory(mtype), src_start, dst_start, length);
+ enc = _gvn.transform(enc);
+ Node* res_mem = _gvn.transform(new (C) SCMemProjNode(enc));
+ set_memory(res_mem, mtype);
+ set_result(enc);
+ return true;
+}
+
//----------------------------inline_reference_get----------------------------
// public T java.lang.ref.Reference.get();
bool LibraryCallKit::inline_reference_get() {
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -613,6 +613,7 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_EncodeISOArray:
case Op_AryEq: {
return false;
}
@@ -717,6 +718,7 @@
case Op_StrComp:
case Op_StrEquals:
case Op_StrIndexOf:
+ case Op_EncodeISOArray:
case Op_AryEq: {
// Do not unroll a loop with String intrinsics code.
// String intrinsics are large and have loops.
--- a/hotspot/src/share/vm/opto/machnode.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/machnode.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -506,7 +506,7 @@
#ifndef PRODUCT
void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
int reg = ra_->get_reg_first(in(1)->in(_vidx));
- tty->print("%s %s", Name(), Matcher::regName[reg]);
+ st->print("%s %s", Name(), Matcher::regName[reg]);
}
#endif
--- a/hotspot/src/share/vm/opto/macro.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -361,14 +361,21 @@
}
// Otherwise skip it (the call updated 'mem' value).
} else if (mem->Opcode() == Op_SCMemProj) {
- assert(mem->in(0)->is_LoadStore(), "sanity");
- const TypePtr* atype = mem->in(0)->in(MemNode::Address)->bottom_type()->is_ptr();
+ mem = mem->in(0);
+ Node* adr = NULL;
+ if (mem->is_LoadStore()) {
+ adr = mem->in(MemNode::Address);
+ } else {
+ assert(mem->Opcode() == Op_EncodeISOArray, "sanity");
+ adr = mem->in(3); // Destination array
+ }
+ const TypePtr* atype = adr->bottom_type()->is_ptr();
int adr_idx = Compile::current()->get_alias_index(atype);
if (adr_idx == alias_idx) {
assert(false, "Object is not scalar replaceable if a LoadStore node access its field");
return NULL;
}
- mem = mem->in(0)->in(MemNode::Memory);
+ mem = mem->in(MemNode::Memory);
} else {
return mem;
}
@@ -445,7 +452,7 @@
}
values.at_put(j, val);
} else if (val->Opcode() == Op_SCMemProj) {
- assert(val->in(0)->is_LoadStore(), "sanity");
+ assert(val->in(0)->is_LoadStore() || val->in(0)->Opcode() == Op_EncodeISOArray, "sanity");
assert(false, "Object is not scalar replaceable if a LoadStore node access its field");
return NULL;
} else {
--- a/hotspot/src/share/vm/opto/matcher.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/matcher.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -919,6 +919,7 @@
case Op_AryEq:
case Op_MemBarVolatile:
case Op_MemBarCPUOrder: // %%% these ideals should have narrower adr_type?
+ case Op_EncodeISOArray:
nidx = Compile::AliasIdxTop;
nat = NULL;
break;
@@ -1982,6 +1983,7 @@
case Op_StrEquals:
case Op_StrIndexOf:
case Op_AryEq:
+ case Op_EncodeISOArray:
set_shared(n); // Force result into register (it will be anyways)
break;
case Op_ConP: { // Convert pointers above the centerline to NUL
@@ -2183,6 +2185,13 @@
n->del_req(4);
break;
}
+ case Op_EncodeISOArray: {
+ // Restructure into a binary tree for Matching.
+ Node* pair = new (C) BinaryNode(n->in(3), n->in(4));
+ n->set_req(3, pair);
+ n->del_req(4);
+ break;
+ }
default:
break;
}
--- a/hotspot/src/share/vm/opto/memnode.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/memnode.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -2797,6 +2797,26 @@
}
//=============================================================================
+//------------------------------match_edge-------------------------------------
+// Do not match memory edge
+uint EncodeISOArrayNode::match_edge(uint idx) const {
+ return idx == 2 || idx == 3; // EncodeISOArray src (Binary dst len)
+}
+
+//------------------------------Ideal------------------------------------------
+// Return a node which is more "ideal" than the current node. Strip out
+// control copies
+Node *EncodeISOArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+ return remove_dead_region(phase, can_reshape) ? this : NULL;
+}
+
+//------------------------------Value------------------------------------------
+const Type *EncodeISOArrayNode::Value(PhaseTransform *phase) const {
+ if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP;
+ return bottom_type();
+}
+
+//=============================================================================
MemBarNode::MemBarNode(Compile* C, int alias_idx, Node* precedent)
: MultiNode(TypeFunc::Parms + (precedent == NULL? 0: 1)),
_adr_type(C->get_adr_type(alias_idx))
--- a/hotspot/src/share/vm/opto/memnode.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/memnode.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -888,6 +888,22 @@
virtual const Type* bottom_type() const { return TypeInt::BOOL; }
};
+
+//------------------------------EncodeISOArray--------------------------------
+// encode char[] to byte[] in ISO_8859_1
+class EncodeISOArrayNode: public Node {
+public:
+ EncodeISOArrayNode(Node *control, Node* arymem, Node* s1, Node* s2, Node* c): Node(control, arymem, s1, s2, c) {};
+ virtual int Opcode() const;
+ virtual bool depends_only_on_test() const { return false; }
+ virtual const Type* bottom_type() const { return TypeInt::INT; }
+ virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
+ virtual uint match_edge(uint idx) const;
+ virtual uint ideal_reg() const { return Op_RegI; }
+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
+ virtual const Type *Value(PhaseTransform *phase) const;
+};
+
//------------------------------MemBar-----------------------------------------
// There are different flavors of Memory Barriers to match the Java Memory
// Model. Monitor-enter and volatile-load act as Aquires: no following ref
--- a/hotspot/src/share/vm/opto/node.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/node.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1476,35 +1476,35 @@
}
#ifdef ASSERT
-static void dump_orig(Node* orig) {
+static void dump_orig(Node* orig, outputStream *st) {
Compile* C = Compile::current();
- if (NotANode(orig)) orig = NULL;
- if (orig != NULL && !C->node_arena()->contains(orig)) orig = NULL;
- if (orig == NULL) return;
- tty->print(" !orig=");
+ if (NotANode(orig)) orig = NULL;
+ if (orig != NULL && !C->node_arena()->contains(orig)) orig = NULL;
+ if (orig == NULL) return;
+ st->print(" !orig=");
Node* fast = orig->debug_orig(); // tortoise & hare algorithm to detect loops
- if (NotANode(fast)) fast = NULL;
+ if (NotANode(fast)) fast = NULL;
while (orig != NULL) {
bool discon = is_disconnected(orig); // if discon, print [123] else 123
- if (discon) tty->print("[");
+ if (discon) st->print("[");
if (!Compile::current()->node_arena()->contains(orig))
- tty->print("o");
- tty->print("%d", orig->_idx);
- if (discon) tty->print("]");
+ st->print("o");
+ st->print("%d", orig->_idx);
+ if (discon) st->print("]");
orig = orig->debug_orig();
- if (NotANode(orig)) orig = NULL;
- if (orig != NULL && !C->node_arena()->contains(orig)) orig = NULL;
- if (orig != NULL) tty->print(",");
+ if (NotANode(orig)) orig = NULL;
+ if (orig != NULL && !C->node_arena()->contains(orig)) orig = NULL;
+ if (orig != NULL) st->print(",");
if (fast != NULL) {
// Step fast twice for each single step of orig:
fast = fast->debug_orig();
- if (NotANode(fast)) fast = NULL;
+ if (NotANode(fast)) fast = NULL;
if (fast != NULL && fast != orig) {
fast = fast->debug_orig();
- if (NotANode(fast)) fast = NULL;
+ if (NotANode(fast)) fast = NULL;
}
if (fast == orig) {
- tty->print("...");
+ st->print("...");
break;
}
}
@@ -1531,35 +1531,34 @@
//------------------------------dump------------------------------------------
// Dump a Node
-void Node::dump() const {
+void Node::dump(const char* suffix, outputStream *st) const {
Compile* C = Compile::current();
bool is_new = C->node_arena()->contains(this);
_in_dump_cnt++;
- tty->print("%c%d\t%s\t=== ",
- is_new ? ' ' : 'o', _idx, Name());
+ st->print("%c%d\t%s\t=== ", is_new ? ' ' : 'o', _idx, Name());
// Dump the required and precedence inputs
- dump_req();
- dump_prec();
+ dump_req(st);
+ dump_prec(st);
// Dump the outputs
- dump_out();
+ dump_out(st);
if (is_disconnected(this)) {
#ifdef ASSERT
- tty->print(" [%d]",debug_idx());
- dump_orig(debug_orig());
+ st->print(" [%d]",debug_idx());
+ dump_orig(debug_orig(), st);
#endif
- tty->cr();
+ st->cr();
_in_dump_cnt--;
return; // don't process dead nodes
}
// Dump node-specific info
- dump_spec(tty);
+ dump_spec(st);
#ifdef ASSERT
// Dump the non-reset _debug_idx
- if( Verbose && WizardMode ) {
- tty->print(" [%d]",debug_idx());
+ if (Verbose && WizardMode) {
+ st->print(" [%d]",debug_idx());
}
#endif
@@ -1569,88 +1568,88 @@
const TypeInstPtr *toop = t->isa_instptr();
const TypeKlassPtr *tkls = t->isa_klassptr();
ciKlass* klass = toop ? toop->klass() : (tkls ? tkls->klass() : NULL );
- if( klass && klass->is_loaded() && klass->is_interface() ) {
- tty->print(" Interface:");
- } else if( toop ) {
- tty->print(" Oop:");
- } else if( tkls ) {
- tty->print(" Klass:");
+ if (klass && klass->is_loaded() && klass->is_interface()) {
+ st->print(" Interface:");
+ } else if (toop) {
+ st->print(" Oop:");
+ } else if (tkls) {
+ st->print(" Klass:");
}
- t->dump();
- } else if( t == Type::MEMORY ) {
- tty->print(" Memory:");
- MemNode::dump_adr_type(this, adr_type(), tty);
- } else if( Verbose || WizardMode ) {
- tty->print(" Type:");
- if( t ) {
- t->dump();
+ t->dump_on(st);
+ } else if (t == Type::MEMORY) {
+ st->print(" Memory:");
+ MemNode::dump_adr_type(this, adr_type(), st);
+ } else if (Verbose || WizardMode) {
+ st->print(" Type:");
+ if (t) {
+ t->dump_on(st);
} else {
- tty->print("no type");
+ st->print("no type");
}
} else if (t->isa_vect() && this->is_MachSpillCopy()) {
// Dump MachSpillcopy vector type.
- t->dump();
+ t->dump_on(st);
}
if (is_new) {
- debug_only(dump_orig(debug_orig()));
+ debug_only(dump_orig(debug_orig(), st));
Node_Notes* nn = C->node_notes_at(_idx);
if (nn != NULL && !nn->is_clear()) {
if (nn->jvms() != NULL) {
- tty->print(" !jvms:");
- nn->jvms()->dump_spec(tty);
+ st->print(" !jvms:");
+ nn->jvms()->dump_spec(st);
}
}
}
- tty->cr();
+ if (suffix) st->print(suffix);
_in_dump_cnt--;
}
//------------------------------dump_req--------------------------------------
-void Node::dump_req() const {
+void Node::dump_req(outputStream *st) const {
// Dump the required input edges
for (uint i = 0; i < req(); i++) { // For all required inputs
Node* d = in(i);
if (d == NULL) {
- tty->print("_ ");
+ st->print("_ ");
} else if (NotANode(d)) {
- tty->print("NotANode "); // uninitialized, sentinel, garbage, etc.
+ st->print("NotANode "); // uninitialized, sentinel, garbage, etc.
} else {
- tty->print("%c%d ", Compile::current()->node_arena()->contains(d) ? ' ' : 'o', d->_idx);
+ st->print("%c%d ", Compile::current()->node_arena()->contains(d) ? ' ' : 'o', d->_idx);
}
}
}
//------------------------------dump_prec-------------------------------------
-void Node::dump_prec() const {
+void Node::dump_prec(outputStream *st) const {
// Dump the precedence edges
int any_prec = 0;
for (uint i = req(); i < len(); i++) { // For all precedence inputs
Node* p = in(i);
if (p != NULL) {
- if( !any_prec++ ) tty->print(" |");
- if (NotANode(p)) { tty->print("NotANode "); continue; }
- tty->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
+ if (!any_prec++) st->print(" |");
+ if (NotANode(p)) { st->print("NotANode "); continue; }
+ st->print("%c%d ", Compile::current()->node_arena()->contains(in(i)) ? ' ' : 'o', in(i)->_idx);
}
}
}
//------------------------------dump_out--------------------------------------
-void Node::dump_out() const {
+void Node::dump_out(outputStream *st) const {
// Delimit the output edges
- tty->print(" [[");
+ st->print(" [[");
// Dump the output edges
for (uint i = 0; i < _outcnt; i++) { // For all outputs
Node* u = _out[i];
if (u == NULL) {
- tty->print("_ ");
+ st->print("_ ");
} else if (NotANode(u)) {
- tty->print("NotANode ");
+ st->print("NotANode ");
} else {
- tty->print("%c%d ", Compile::current()->node_arena()->contains(u) ? ' ' : 'o', u->_idx);
+ st->print("%c%d ", Compile::current()->node_arena()->contains(u) ? ' ' : 'o', u->_idx);
}
}
- tty->print("]] ");
+ st->print("]] ");
}
//------------------------------dump_nodes-------------------------------------
--- a/hotspot/src/share/vm/opto/node.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/node.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -994,12 +994,13 @@
#ifndef PRODUCT
Node* find(int idx) const; // Search the graph for the given idx.
Node* find_ctrl(int idx) const; // Search control ancestors for the given idx.
- void dump() const; // Print this node,
+ void dump() const { dump("\n"); } // Print this node.
+ void dump(const char* suffix, outputStream *st = tty) const;// Print this node.
void dump(int depth) const; // Print this node, recursively to depth d
void dump_ctrl(int depth) const; // Print control nodes, to depth d
- virtual void dump_req() const; // Print required-edge info
- virtual void dump_prec() const; // Print precedence-edge info
- virtual void dump_out() const; // Print the output edge info
+ virtual void dump_req(outputStream *st = tty) const; // Print required-edge info
+ virtual void dump_prec(outputStream *st = tty) const; // Print precedence-edge info
+ virtual void dump_out(outputStream *st = tty) const; // Print the output edge info
virtual void dump_spec(outputStream *st) const {}; // Print per-node info
void verify_edges(Unique_Node_List &visited); // Verify bi-directional edges
void verify() const; // Check Def-Use info for my subgraph
--- a/hotspot/src/share/vm/opto/optoreg.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/optoreg.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -77,7 +77,7 @@
// (We would like to have an operator+ for RegName, but it is not
// a class, so this would be illegal in C++.)
- static void dump( int );
+ static void dump(int, outputStream *st = tty);
// Get the stack slot number of an OptoReg::Name
static unsigned int reg2stack( OptoReg::Name r) {
--- a/hotspot/src/share/vm/opto/regalloc.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/regalloc.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -40,6 +40,7 @@
Phase(Register_Allocation), _cfg(cfg), _matcher(matcher),
_node_oops(Thread::current()->resource_area()),
_node_regs(0),
+ _node_regs_max_index(0),
_framesize(0xdeadbeef)
{
int i;
--- a/hotspot/src/share/vm/opto/regmask.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/regmask.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -108,13 +108,13 @@
//------------------------------dump-------------------------------------------
#ifndef PRODUCT
-void OptoReg::dump( int r ) {
- switch( r ) {
- case Special: tty->print("r---"); break;
- case Bad: tty->print("rBAD"); break;
+void OptoReg::dump(int r, outputStream *st) {
+ switch (r) {
+ case Special: st->print("r---"); break;
+ case Bad: st->print("rBAD"); break;
default:
- if( r < _last_Mach_Reg ) tty->print(Matcher::regName[r]);
- else tty->print("rS%d",r);
+ if (r < _last_Mach_Reg) st->print(Matcher::regName[r]);
+ else st->print("rS%d",r);
break;
}
}
@@ -404,53 +404,53 @@
#ifndef PRODUCT
//------------------------------print------------------------------------------
-void RegMask::dump( ) const {
- tty->print("[");
+void RegMask::dump(outputStream *st) const {
+ st->print("[");
RegMask rm = *this; // Structure copy into local temp
OptoReg::Name start = rm.find_first_elem(); // Get a register
- if( OptoReg::is_valid(start) ) { // Check for empty mask
+ if (OptoReg::is_valid(start)) { // Check for empty mask
rm.Remove(start); // Yank from mask
- OptoReg::dump(start); // Print register
+ OptoReg::dump(start, st); // Print register
OptoReg::Name last = start;
// Now I have printed an initial register.
// Print adjacent registers as "rX-rZ" instead of "rX,rY,rZ".
// Begin looping over the remaining registers.
- while( 1 ) { //
+ while (1) { //
OptoReg::Name reg = rm.find_first_elem(); // Get a register
- if( !OptoReg::is_valid(reg) )
+ if (!OptoReg::is_valid(reg))
break; // Empty mask, end loop
rm.Remove(reg); // Yank from mask
- if( last+1 == reg ) { // See if they are adjacent
+ if (last+1 == reg) { // See if they are adjacent
// Adjacent registers just collect into long runs, no printing.
last = reg;
} else { // Ending some kind of run
- if( start == last ) { // 1-register run; no special printing
- } else if( start+1 == last ) {
- tty->print(","); // 2-register run; print as "rX,rY"
- OptoReg::dump(last);
+ if (start == last) { // 1-register run; no special printing
+ } else if (start+1 == last) {
+ st->print(","); // 2-register run; print as "rX,rY"
+ OptoReg::dump(last, st);
} else { // Multi-register run; print as "rX-rZ"
- tty->print("-");
- OptoReg::dump(last);
+ st->print("-");
+ OptoReg::dump(last, st);
}
- tty->print(","); // Seperate start of new run
+ st->print(","); // Seperate start of new run
start = last = reg; // Start a new register run
- OptoReg::dump(start); // Print register
+ OptoReg::dump(start, st); // Print register
} // End of if ending a register run or not
} // End of while regmask not empty
- if( start == last ) { // 1-register run; no special printing
- } else if( start+1 == last ) {
- tty->print(","); // 2-register run; print as "rX,rY"
- OptoReg::dump(last);
+ if (start == last) { // 1-register run; no special printing
+ } else if (start+1 == last) {
+ st->print(","); // 2-register run; print as "rX,rY"
+ OptoReg::dump(last, st);
} else { // Multi-register run; print as "rX-rZ"
- tty->print("-");
- OptoReg::dump(last);
+ st->print("-");
+ OptoReg::dump(last, st);
}
- if( rm.is_AllStack() ) tty->print("...");
+ if (rm.is_AllStack()) st->print("...");
}
- tty->print("]");
+ st->print("]");
}
#endif
--- a/hotspot/src/share/vm/opto/regmask.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/regmask.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -310,7 +310,7 @@
#ifndef PRODUCT
void print() const { dump(); }
- void dump() const; // Print a mask
+ void dump(outputStream *st = tty) const; // Print a mask
#endif
static const RegMask Empty; // Common empty mask
--- a/hotspot/src/share/vm/opto/type.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/opto/type.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1542,10 +1542,10 @@
static const char* longnamenear(jlong x, const char* xname, char* buf, jlong n) {
if (n > x) {
if (n >= x + 10000) return NULL;
- sprintf(buf, "%s+" INT64_FORMAT, xname, n - x);
+ sprintf(buf, "%s+" JLONG_FORMAT, xname, n - x);
} else if (n < x) {
if (n <= x - 10000) return NULL;
- sprintf(buf, "%s-" INT64_FORMAT, xname, x - n);
+ sprintf(buf, "%s-" JLONG_FORMAT, xname, x - n);
} else {
return xname;
}
@@ -1557,11 +1557,11 @@
if (n == min_jlong)
return "min";
else if (n < min_jlong + 10000)
- sprintf(buf, "min+" INT64_FORMAT, n - min_jlong);
+ sprintf(buf, "min+" JLONG_FORMAT, n - min_jlong);
else if (n == max_jlong)
return "max";
else if (n > max_jlong - 10000)
- sprintf(buf, "max-" INT64_FORMAT, max_jlong - n);
+ sprintf(buf, "max-" JLONG_FORMAT, max_jlong - n);
else if ((str = longnamenear(max_juint, "maxuint", buf, n)) != NULL)
return str;
else if ((str = longnamenear(max_jint, "maxint", buf, n)) != NULL)
@@ -1569,7 +1569,7 @@
else if ((str = longnamenear(min_jint, "minint", buf, n)) != NULL)
return str;
else
- sprintf(buf, INT64_FORMAT, n);
+ sprintf(buf, JLONG_FORMAT, n);
return buf;
}
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -484,15 +484,6 @@
JVM_END
-JVM_ENTRY(void, JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable))
- JVMWrapper("JVM_PrintStackTrace");
- // Note: This is no longer used in Merlin, but we still support it for compatibility.
- oop exception = JNIHandles::resolve_non_null(receiver);
- oop stream = JNIHandles::resolve_non_null(printable);
- java_lang_Throwable::print_stack_trace(exception, stream);
-JVM_END
-
-
JVM_ENTRY(jint, JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable))
JVMWrapper("JVM_GetStackTraceDepth");
oop exception = JNIHandles::resolve(throwable);
@@ -1582,13 +1573,22 @@
if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) {
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
if (k->oop_is_instance()) {
- typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL);
- return (jbyteArray) JNIHandles::make_local(env, a);
+ Annotations* type_annotations = InstanceKlass::cast(k)->type_annotations();
+ if (type_annotations != NULL) {
+ typeArrayOop a = Annotations::make_java_array(type_annotations->class_annotations(), CHECK_NULL);
+ return (jbyteArray) JNIHandles::make_local(env, a);
+ }
}
}
return NULL;
JVM_END
+static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {
+ if (!cp->is_within_bounds(index)) {
+ THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");
+ }
+}
+
JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method))
{
JVMWrapper("JVM_GetMethodParameters");
@@ -1598,15 +1598,31 @@
Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method));
const int num_params = mh->method_parameters_length();
- if(0 != num_params) {
+ if (0 != num_params) {
+ // make sure all the symbols are properly formatted
+ for (int i = 0; i < num_params; i++) {
+ MethodParametersElement* params = mh->method_parameters_start();
+ int index = params[i].name_cp_index;
+ bounds_check(mh->constants(), index, CHECK_NULL);
+
+ if (0 != index && !mh->constants()->tag_at(index).is_utf8()) {
+ THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
+ "Wrong type at constant pool index");
+ }
+
+ }
+
objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL);
objArrayHandle result (THREAD, result_oop);
- for(int i = 0; i < num_params; i++) {
+ for (int i = 0; i < num_params; i++) {
MethodParametersElement* params = mh->method_parameters_start();
- Symbol* const sym = mh->constants()->symbol_at(params[i].name_cp_index);
+ // For a 0 index, give a NULL symbol
+ Symbol* const sym = 0 != params[i].name_cp_index ?
+ mh->constants()->symbol_at(params[i].name_cp_index) : NULL;
+ int flags = build_int_from_shorts(params[i].flags_lo, params[i].flags_hi);
oop param = Reflection::new_parameter(reflected_method, i, sym,
- params[i].flags, CHECK_NULL);
+ flags, CHECK_NULL);
result->obj_at_put(i, param);
}
return (jobjectArray)JNIHandles::make_local(env, result());
@@ -1830,13 +1846,6 @@
JVM_END
-static void bounds_check(constantPoolHandle cp, jint index, TRAPS) {
- if (!cp->is_within_bounds(index)) {
- THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool index out of bounds");
- }
-}
-
-
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetClassAt");
@@ -1851,7 +1860,6 @@
}
JVM_END
-
JVM_ENTRY(jclass, JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject obj, jobject unused, jint index))
{
JVMWrapper("JVM_ConstantPoolGetClassAtIfLoaded");
--- a/hotspot/src/share/vm/prims/jvm.h Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/prims/jvm.h Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -212,9 +212,6 @@
JNIEXPORT void JNICALL
JVM_FillInStackTrace(JNIEnv *env, jobject throwable);
-JNIEXPORT void JNICALL
-JVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable);
-
JNIEXPORT jint JNICALL
JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable);
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1334,20 +1334,8 @@
return JVMTI_ERROR_INTERNAL;
}
- int orig_length = old_cp->orig_length();
- if (orig_length == 0) {
- // This old_cp is an actual original constant pool. We save
- // the original length in the merged constant pool so that
- // merge_constant_pools() can be more efficient. If a constant
- // pool has a non-zero orig_length() value, then that constant
- // pool was created by a merge operation in RedefineClasses.
- merge_cp->set_orig_length(old_cp->length());
- } else {
- // This old_cp is a merged constant pool from a previous
- // RedefineClasses() calls so just copy the orig_length()
- // value.
- merge_cp->set_orig_length(old_cp->orig_length());
- }
+ // Update the version number of the constant pool
+ merge_cp->increment_and_save_version(old_cp->version());
ResourceMark rm(THREAD);
_index_map_count = 0;
@@ -2417,18 +2405,19 @@
int scratch_cp_length, TRAPS) {
assert(scratch_cp->length() >= scratch_cp_length, "sanity check");
- // scratch_cp is a merged constant pool and has enough space for a
- // worst case merge situation. We want to associate the minimum
- // sized constant pool with the klass to save space.
- constantPoolHandle smaller_cp(THREAD,
- ConstantPool::allocate(loader_data, scratch_cp_length,
- THREAD));
- // preserve orig_length() value in the smaller copy
- int orig_length = scratch_cp->orig_length();
- assert(orig_length != 0, "sanity check");
- smaller_cp->set_orig_length(orig_length);
- scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
- scratch_cp = smaller_cp;
+ // scratch_cp is a merged constant pool and has enough space for a
+ // worst case merge situation. We want to associate the minimum
+ // sized constant pool with the klass to save space.
+ constantPoolHandle smaller_cp(THREAD,
+ ConstantPool::allocate(loader_data, scratch_cp_length, THREAD));
+
+ // preserve version() value in the smaller copy
+ int version = scratch_cp->version();
+ assert(version != 0, "sanity check");
+ smaller_cp->set_version(version);
+
+ scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
+ scratch_cp = smaller_cp;
// attach new constant pool to klass
scratch_cp->set_pool_holder(scratch_class());
--- a/hotspot/src/share/vm/runtime/aprofiler.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/aprofiler.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -129,7 +129,7 @@
assert(!is_active(), "AllocationProfiler cannot be active while printing profile");
tty->cr();
- tty->print_cr("Allocation profile (sizes in bytes, cutoff = %ld bytes):", cutoff * BytesPerWord);
+ tty->print_cr("Allocation profile (sizes in bytes, cutoff = " SIZE_FORMAT " bytes):", cutoff * BytesPerWord);
tty->cr();
// Print regular instance klasses and basic type array klasses
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -532,7 +532,7 @@
// Parses a memory size specification string.
static bool atomull(const char *s, julong* result) {
julong n = 0;
- int args_read = sscanf(s, os::julong_format_specifier(), &n);
+ int args_read = sscanf(s, JULONG_FORMAT, &n);
if (args_read != 1) {
return false;
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -929,11 +929,14 @@
"Starts debugger when an implicit OS (e.g., NULL) " \
"exception happens") \
\
- notproduct(bool, PrintCodeCache, false, \
- "Print the compiled_code cache when exiting") \
+ product(bool, PrintCodeCache, false, \
+ "Print the code cache memory usage when exiting") \
\
develop(bool, PrintCodeCache2, false, \
- "Print detailed info on the compiled_code cache when exiting") \
+ "Print detailed usage info on the code cache when exiting") \
+ \
+ product(bool, PrintCodeCacheOnCompilation, false, \
+ "Print the code cache memory usage each time a method is compiled") \
\
diagnostic(bool, PrintStubCode, false, \
"Print generated stub code") \
@@ -969,18 +972,6 @@
notproduct(uintx, WarnOnStalledSpinLock, 0, \
"Prints warnings for stalled SpinLocks") \
\
- develop(bool, InitializeJavaLangSystem, true, \
- "Initialize java.lang.System - turn off for individual " \
- "method debugging") \
- \
- develop(bool, InitializeJavaLangString, true, \
- "Initialize java.lang.String - turn off for individual " \
- "method debugging") \
- \
- develop(bool, InitializeJavaLangExceptionsErrors, true, \
- "Initialize various error and exception classes - turn off for " \
- "individual method debugging") \
- \
product(bool, RegisterFinalizersAtInit, true, \
"Register finalizable objects at end of Object.<init> or " \
"after allocation") \
@@ -1075,7 +1066,7 @@
\
product(intx, ClearFPUAtPark, 0, "(Unsafe,Unstable)" ) \
\
- product(intx, hashCode, 0, \
+ product(intx, hashCode, 5, \
"(Unstable) select hashCode generation algorithm" ) \
\
product(intx, WorkAroundNPTLTimedWaitHang, 1, \
@@ -1166,6 +1157,18 @@
notproduct(bool, PrintCompactFieldsSavings, false, \
"Print how many words were saved with CompactFields") \
\
+ notproduct(bool, PrintFieldLayout, false, \
+ "Print field layout for each class") \
+ \
+ product(intx, ContendedPaddingWidth, 128, \
+ "How many bytes to pad the fields/classes marked @Contended with")\
+ \
+ product(bool, EnableContended, true, \
+ "Enable @Contended annotation support") \
+ \
+ product(bool, RestrictContended, true, \
+ "Restrict @Contended to trusted classes") \
+ \
product(bool, UseBiasedLocking, true, \
"Enable biased locking in JVM") \
\
--- a/hotspot/src/share/vm/runtime/java.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -368,6 +368,12 @@
if (CITime) {
CompileBroker::print_times();
}
+
+ if (PrintCodeCache) {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ CodeCache::print();
+ }
+
#ifdef COMPILER2
if (PrintPreciseBiasedLockingStatistics) {
OptoRuntime::print_named_counters();
@@ -542,6 +548,10 @@
BeforeExit_lock->notify_all();
}
+ // Shutdown NMT before exit. Otherwise,
+ // it will run into trouble when system destroys static variables.
+ MemTracker::shutdown(MemTracker::NMT_normal);
+
#undef BEFORE_EXIT_NOT_RUN
#undef BEFORE_EXIT_RUNNING
#undef BEFORE_EXIT_DONE
--- a/hotspot/src/share/vm/runtime/objectMonitor.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/objectMonitor.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -653,8 +653,7 @@
assert (_succ != Self, "invariant") ;
if (_Responsible == Self) {
_Responsible = NULL ;
- // Dekker pivot-point.
- // Consider OrderAccess::storeload() here
+ OrderAccess::fence(); // Dekker pivot-point
// We may leave threads on cxq|EntryList without a designated
// "Responsible" thread. This is benign. When this thread subsequently
@@ -674,10 +673,6 @@
//
// The MEMBAR, above, prevents the LD of cxq|EntryList in the subsequent
// exit operation from floating above the ST Responsible=null.
- //
- // In *practice* however, EnterI() is always followed by some atomic
- // operation such as the decrement of _count in ::enter(). Those atomics
- // obviate the need for the explicit MEMBAR, above.
}
// We've acquired ownership with CAS().
--- a/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -101,10 +101,12 @@
return _count;
}
+// Do NOT set _count = 0. There is a race such that _count could
+// be set while inflating prior to setting _owner
+// Just use Atomic::inc/dec and assert 0 when monitor put on free list
inline void ObjectMonitor::set_owner(void* owner) {
_owner = owner;
_recursions = 0;
- _count = 0;
}
--- a/hotspot/src/share/vm/runtime/os.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -641,10 +641,6 @@
static struct hostent* get_host_by_name(char* name);
- // Printing 64 bit integers
- static const char* jlong_format_specifier();
- static const char* julong_format_specifier();
-
// Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal)
static void signal_init();
static void signal_init_pd();
--- a/hotspot/src/share/vm/runtime/perfData.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/perfData.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -192,7 +192,7 @@
}
int PerfLong::format(char* buffer, int length) {
- return jio_snprintf(buffer, length,"%lld", *(jlong*)_valuep);
+ return jio_snprintf(buffer, length, JLONG_FORMAT, *(jlong*)_valuep);
}
PerfLongVariant::PerfLongVariant(CounterNS ns, const char* namep, Units u,
--- a/hotspot/src/share/vm/runtime/reflection.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -862,7 +862,15 @@
oop Reflection::new_parameter(Handle method, int index, Symbol* sym,
int flags, TRAPS) {
- Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
+ Handle name;
+
+ // A null symbol here translates to the empty string
+ if(NULL != sym) {
+ name = java_lang_String::create_from_symbol(sym, CHECK_NULL);
+ } else {
+ name = java_lang_String::create_from_str("", CHECK_NULL);
+ }
+
Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL);
java_lang_reflect_Parameter::set_name(rh(), name());
java_lang_reflect_Parameter::set_modifiers(rh(), flags);
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -333,7 +333,9 @@
void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
TEVENT (jni_exit) ;
if (UseBiasedLocking) {
- BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+ Handle h_obj(THREAD, obj);
+ BiasedLocking::revoke_and_rebias(h_obj, false, THREAD);
+ obj = h_obj();
}
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
--- a/hotspot/src/share/vm/runtime/thread.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1716,7 +1716,6 @@
// cleanup_failed_attach_current_thread as well.
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
assert(this == JavaThread::current(), "thread consistency check");
- if (!InitializeJavaLangSystem) return;
HandleMark hm(this);
Handle uncaught_exception(this, this->pending_exception());
@@ -3469,11 +3468,7 @@
create_vm_init_libraries();
}
- if (InitializeJavaLangString) {
- initialize_class(vmSymbols::java_lang_String(), CHECK_0);
- } else {
- warning("java.lang.String not initialized");
- }
+ initialize_class(vmSymbols::java_lang_String(), CHECK_0);
if (AggressiveOpts) {
{
@@ -3514,53 +3509,39 @@
}
// Initialize java_lang.System (needed before creating the thread)
- if (InitializeJavaLangSystem) {
- initialize_class(vmSymbols::java_lang_System(), CHECK_0);
- initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
- Handle thread_group = create_initial_thread_group(CHECK_0);
- Universe::set_main_thread_group(thread_group());
- initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
- oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
- main_thread->set_threadObj(thread_object);
- // Set thread status to running since main thread has
- // been started and running.
- java_lang_Thread::set_thread_status(thread_object,
- java_lang_Thread::RUNNABLE);
-
- // The VM creates & returns objects of this class. Make sure it's initialized.
- initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
-
- // The VM preresolves methods to these classes. Make sure that they get initialized
- initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
- initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0);
- call_initializeSystemClass(CHECK_0);
-
- // get the Java runtime name after java.lang.System is initialized
- JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
- JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
- } else {
- warning("java.lang.System not initialized");
- }
+ initialize_class(vmSymbols::java_lang_System(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0);
+ Handle thread_group = create_initial_thread_group(CHECK_0);
+ Universe::set_main_thread_group(thread_group());
+ initialize_class(vmSymbols::java_lang_Thread(), CHECK_0);
+ oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0);
+ main_thread->set_threadObj(thread_object);
+ // Set thread status to running since main thread has
+ // been started and running.
+ java_lang_Thread::set_thread_status(thread_object,
+ java_lang_Thread::RUNNABLE);
+
+ // The VM creates & returns objects of this class. Make sure it's initialized.
+ initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
+
+ // The VM preresolves methods to these classes. Make sure that they get initialized
+ initialize_class(vmSymbols::java_lang_reflect_Method(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_ref_Finalizer(), CHECK_0);
+ call_initializeSystemClass(CHECK_0);
+
+ // get the Java runtime name after java.lang.System is initialized
+ JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
+ JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
// an instance of OutOfMemory exception has been allocated earlier
- if (InitializeJavaLangExceptionsErrors) {
- initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
- initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
- initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
- initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
- initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
- initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
- initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
- initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
- } else {
- warning("java.lang.OutOfMemoryError has not been initialized");
- warning("java.lang.NullPointerException has not been initialized");
- warning("java.lang.ClassCastException has not been initialized");
- warning("java.lang.ArrayStoreException has not been initialized");
- warning("java.lang.ArithmeticException has not been initialized");
- warning("java.lang.StackOverflowError has not been initialized");
- warning("java.lang.IllegalArgumentException has not been initialized");
- }
+ initialize_class(vmSymbols::java_lang_OutOfMemoryError(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_NullPointerException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_ClassCastException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_ArrayStoreException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_ArithmeticException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK_0);
+ initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK_0);
}
// See : bugid 4211085.
@@ -4011,10 +3992,6 @@
Mutex::_as_suspend_equivalent_flag);
}
- // Shutdown NMT before exit. Otherwise,
- // it will run into trouble when system destroys static variables.
- MemTracker::shutdown(MemTracker::NMT_normal);
-
// Hang forever on exit if we are reporting an error.
if (ShowMessageBoxOnError && is_error_reported()) {
os::infinite_sleep();
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -868,8 +868,8 @@
tty->print ("Virtual space:");
if (special()) tty->print(" (pinned in memory)");
tty->cr();
- tty->print_cr(" - committed: %ld", committed_size());
- tty->print_cr(" - reserved: %ld", reserved_size());
+ tty->print_cr(" - committed: " SIZE_FORMAT, committed_size());
+ tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high());
tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary());
}
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -257,8 +257,7 @@
c1_nonstatic_field, \
c2_nonstatic_field, \
unchecked_c1_static_field, \
- unchecked_c2_static_field, \
- last_entry) \
+ unchecked_c2_static_field) \
\
/******************************************************************/ \
/* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */ \
@@ -718,7 +717,6 @@
nonstatic_field(ClassLoaderData, _next, ClassLoaderData*) \
\
static_field(ClassLoaderDataGraph, _head, ClassLoaderData*) \
- nonstatic_field(ClassLoaderDataGraph, _unloading, ClassLoaderData*) \
\
/*******************/ \
/* GrowableArrays */ \
@@ -1200,7 +1198,6 @@
/*********************************/ \
\
static_field(java_lang_Class, _klass_offset, int) \
- static_field(java_lang_Class, _resolved_constructor_offset, int) \
static_field(java_lang_Class, _array_klass_offset, int) \
static_field(java_lang_Class, _oop_size_offset, int) \
static_field(java_lang_Class, _static_oop_field_count_offset, int) \
@@ -1238,9 +1235,6 @@
nonstatic_field(FreeList<Metablock>, _count, ssize_t) \
nonstatic_field(MetablockTreeDictionary, _total_size, size_t)
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_STRUCTS_OS_CPU macro (and must */
- /* be present there) */
//--------------------------------------------------------------------------------
// VM_TYPES
@@ -1280,8 +1274,7 @@
declare_unsigned_integer_type, \
declare_c1_toplevel_type, \
declare_c2_type, \
- declare_c2_toplevel_type, \
- last_entry) \
+ declare_c2_toplevel_type) \
\
/*************************************************************/ \
/* Java primitive types -- required by the SA implementation */ \
@@ -2098,10 +2091,6 @@
declare_type(MetablockTreeDictionary, FreeBlockDictionary<Metablock>)
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_TYPES_OS_CPU macro (and must be */
- /* present there) */
-
//--------------------------------------------------------------------------------
// VM_INT_CONSTANTS
//
@@ -2114,8 +2103,7 @@
declare_preprocessor_constant, \
declare_c1_constant, \
declare_c2_constant, \
- declare_c2_preprocessor_constant, \
- last_entry) \
+ declare_c2_preprocessor_constant) \
\
/******************/ \
/* Useful globals */ \
@@ -2294,10 +2282,18 @@
declare_constant(FieldInfo::name_index_offset) \
declare_constant(FieldInfo::signature_index_offset) \
declare_constant(FieldInfo::initval_index_offset) \
- declare_constant(FieldInfo::low_offset) \
- declare_constant(FieldInfo::high_offset) \
+ declare_constant(FieldInfo::low_packed_offset) \
+ declare_constant(FieldInfo::high_packed_offset) \
declare_constant(FieldInfo::field_slots) \
\
+ /*************************************/ \
+ /* FieldInfo tag constants */ \
+ /*************************************/ \
+ \
+ declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \
+ declare_preprocessor_constant("FIELDINFO_TAG_MASK", FIELDINFO_TAG_MASK) \
+ declare_preprocessor_constant("FIELDINFO_TAG_OFFSET", FIELDINFO_TAG_OFFSET) \
+ \
/************************************************/ \
/* InstanceKlass InnerClassAttributeOffset enum */ \
/************************************************/ \
@@ -2483,9 +2479,6 @@
declare_c2_preprocessor_constant("SAVED_ON_ENTRY_REG_COUNT", SAVED_ON_ENTRY_REG_COUNT) \
declare_c2_preprocessor_constant("C_SAVED_ON_ENTRY_REG_COUNT", C_SAVED_ON_ENTRY_REG_COUNT)
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_INT_CONSTANTS_OS_CPU macro (and */
- /* must be present there) */
//--------------------------------------------------------------------------------
// VM_LONG_CONSTANTS
@@ -2495,7 +2488,7 @@
// enums, etc., while "declare_preprocessor_constant" must be used for
// all #defined constants.
-#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant, last_entry) \
+#define VM_LONG_CONSTANTS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
\
/*********************/ \
/* MarkOop constants */ \
@@ -2541,11 +2534,7 @@
/* Constants in markOop used by CMS. */ \
declare_constant(markOopDesc::cms_shift) \
declare_constant(markOopDesc::cms_mask) \
- declare_constant(markOopDesc::size_shift) \
-
- /* NOTE that we do not use the last_entry() macro here; it is used */
- /* in vmStructs_<os>_<cpu>.hpp's VM_LONG_CONSTANTS_OS_CPU macro (and */
- /* must be present there) */
+ declare_constant(markOopDesc::size_shift)
//--------------------------------------------------------------------------------
@@ -2585,7 +2574,8 @@
// This macro checks the type of a VMStructEntry by comparing pointer types
#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
- {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; }
+ {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \
+ assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
// This macro checks the type of a volatile VMStructEntry by comparing pointer types
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
@@ -2608,9 +2598,6 @@
// This is a no-op macro for unchecked fields
#define CHECK_NO_OP(a, b, c)
-// This is a no-op macro for the sentinel value
-#define CHECK_SENTINEL()
-
//
// Build-specific macros:
//
@@ -2789,48 +2776,47 @@
// as long as class VMStructs is a friend
VMStructEntry VMStructs::localHotSpotVMStructs[] = {
- VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_VM_STRUCT_LAST_ENTRY)
+ VM_STRUCTS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C1_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
#ifndef SERIALGC
- VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
+ VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
- VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
+ VM_STRUCTS_CMS(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
- VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
+ VM_STRUCTS_G1(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
#endif // SERIALGC
- VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_VM_STRUCT_LAST_ENTRY)
+ VM_STRUCTS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
- VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY, \
- GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY, \
- GENERATE_VM_STRUCT_LAST_ENTRY)
+ VM_STRUCTS_OS_CPU(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C2_NONSTATIC_VM_STRUCT_ENTRY,
+ GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
+ GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
+
+ GENERATE_VM_STRUCT_LAST_ENTRY()
};
VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
@@ -2842,8 +2828,7 @@
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_C2_VM_TYPE_ENTRY,
- GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
- GENERATE_VM_TYPE_LAST_ENTRY)
+ GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
#ifndef SERIALGC
VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
@@ -2865,8 +2850,7 @@
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_C2_VM_TYPE_ENTRY,
- GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
- GENERATE_VM_TYPE_LAST_ENTRY)
+ GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
VM_TYPES_OS_CPU(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY,
@@ -2875,8 +2859,9 @@
GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY,
GENERATE_C1_TOPLEVEL_VM_TYPE_ENTRY,
GENERATE_C2_VM_TYPE_ENTRY,
- GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY,
- GENERATE_VM_TYPE_LAST_ENTRY)
+ GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
+
+ GENERATE_VM_TYPE_LAST_ENTRY()
};
VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
@@ -2885,8 +2870,7 @@
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
- GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
- GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
+ GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
#ifndef SERIALGC
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
@@ -2898,15 +2882,15 @@
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
- GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
- GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
+ GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
VM_INT_CONSTANTS_OS_CPU(GENERATE_VM_INT_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
GENERATE_C1_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
- GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY,
- GENERATE_VM_INT_CONSTANT_LAST_ENTRY)
+ GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
+
+ GENERATE_VM_INT_CONSTANT_LAST_ENTRY()
};
VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
@@ -2915,22 +2899,21 @@
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
- GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
- GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
+ GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
VM_LONG_CONSTANTS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
- GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
- GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
+ GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
VM_LONG_CONSTANTS_OS_CPU(GENERATE_VM_LONG_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
GENERATE_C1_VM_LONG_CONSTANT_ENTRY,
GENERATE_C2_VM_LONG_CONSTANT_ENTRY,
- GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY,
- GENERATE_VM_LONG_CONSTANT_LAST_ENTRY)
+ GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY)
+
+ GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
};
// This is used both to check the types of referenced fields and, in
@@ -2945,8 +2928,7 @@
CHECK_C1_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
- CHECK_NO_OP,
- CHECK_SENTINEL);
+ CHECK_NO_OP);
#ifndef SERIALGC
VM_STRUCTS_PARALLELGC(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
@@ -2967,8 +2949,7 @@
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
- CHECK_NO_OP,
- CHECK_SENTINEL);
+ CHECK_NO_OP);
VM_STRUCTS_OS_CPU(CHECK_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_STATIC_VM_STRUCT_ENTRY,
@@ -2977,8 +2958,7 @@
CHECK_NONPRODUCT_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_C2_NONSTATIC_VM_STRUCT_ENTRY,
CHECK_NO_OP,
- CHECK_NO_OP,
- CHECK_SENTINEL);
+ CHECK_NO_OP);
VM_TYPES(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@@ -2987,8 +2967,7 @@
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_C2_VM_TYPE_ENTRY,
- CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
- CHECK_SENTINEL);
+ CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
#ifndef SERIALGC
VM_TYPES_PARALLELGC(CHECK_VM_TYPE_ENTRY,
@@ -3010,8 +2989,7 @@
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_C2_VM_TYPE_ENTRY,
- CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
- CHECK_SENTINEL);
+ CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
VM_TYPES_OS_CPU(CHECK_VM_TYPE_ENTRY,
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
@@ -3020,8 +2998,7 @@
CHECK_SINGLE_ARG_VM_TYPE_NO_OP,
CHECK_C1_TOPLEVEL_VM_TYPE_ENTRY,
CHECK_C2_VM_TYPE_ENTRY,
- CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY,
- CHECK_SENTINEL);
+ CHECK_C2_TOPLEVEL_VM_TYPE_ENTRY);
//
// Split VM_STRUCTS() invocation into two parts to allow MS VC++ 6.0
@@ -3040,53 +3017,49 @@
// Solstice NFS setup. If everyone switches to local workspaces on
// Win32, we can put this back in.
#ifndef _WINDOWS
- debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_SENTINEL));
- debug_only(VM_STRUCTS(CHECK_NO_OP, \
- ENSURE_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- ENSURE_FIELD_TYPE_PRESENT, \
- ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
- ENSURE_C1_FIELD_TYPE_PRESENT, \
- ENSURE_C2_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_SENTINEL));
+ debug_only(VM_STRUCTS(ENSURE_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ CHECK_NO_OP,
+ CHECK_NO_OP,
+ CHECK_NO_OP,
+ CHECK_NO_OP,
+ CHECK_NO_OP,
+ CHECK_NO_OP,
+ CHECK_NO_OP));
+ debug_only(VM_STRUCTS(CHECK_NO_OP,
+ ENSURE_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
+ ENSURE_C1_FIELD_TYPE_PRESENT,
+ ENSURE_C2_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ CHECK_NO_OP));
#ifndef SERIALGC
- debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT, \
+ debug_only(VM_STRUCTS_PARALLELGC(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
- debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT, \
- ENSURE_FIELD_TYPE_PRESENT, \
+ debug_only(VM_STRUCTS_CMS(ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
- debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT, \
+ debug_only(VM_STRUCTS_G1(ENSURE_FIELD_TYPE_PRESENT,
ENSURE_FIELD_TYPE_PRESENT));
#endif // SERIALGC
- debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
- ENSURE_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- ENSURE_FIELD_TYPE_PRESENT, \
- ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
- ENSURE_C2_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_SENTINEL));
- debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT, \
- ENSURE_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- ENSURE_FIELD_TYPE_PRESENT, \
- ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT, \
- ENSURE_C2_FIELD_TYPE_PRESENT, \
- CHECK_NO_OP, \
- CHECK_NO_OP, \
- CHECK_SENTINEL));
+ debug_only(VM_STRUCTS_CPU(ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
+ ENSURE_C2_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ CHECK_NO_OP));
+ debug_only(VM_STRUCTS_OS_CPU(ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ ENSURE_FIELD_TYPE_PRESENT,
+ ENSURE_NONPRODUCT_FIELD_TYPE_PRESENT,
+ ENSURE_C2_FIELD_TYPE_PRESENT,
+ CHECK_NO_OP,
+ CHECK_NO_OP));
#endif
}
@@ -3146,10 +3119,10 @@
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
- delete s;
+ delete [] s;
return 1;
}
- delete s;
+ delete [] s;
}
const char* start = NULL;
if (strstr(typeName, "GrowableArray<") == typeName) {
@@ -3165,10 +3138,10 @@
s[len-1] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
- delete s;
+ delete [] s;
return 1;
}
- delete s;
+ delete [] s;
}
if (strstr(typeName, "const ") == typeName) {
const char * s = typeName + strlen("const ");
@@ -3182,8 +3155,10 @@
s[len - 6] = '\0';
// tty->print_cr("checking \"%s\" for \"%s\"", s, typeName);
if (recursiveFindType(origtypes, s, true) == 1) {
+ free(s);
return 1;
}
+ free(s);
}
if (!isRecurse) {
tty->print_cr("type \"%s\" not found", typeName);
@@ -3206,6 +3181,30 @@
#ifndef PRODUCT
void VMStructs::test() {
+ // Make sure last entry in the each array is indeed the correct end marker.
+ // The reason why these are static is to make sure they are zero initialized.
+ // Putting them on the stack will leave some garbage in the padding of some fields.
+ static VMStructEntry struct_last_entry = GENERATE_VM_STRUCT_LAST_ENTRY();
+ assert(memcmp(&localHotSpotVMStructs[(sizeof(localHotSpotVMStructs) / sizeof(VMStructEntry)) - 1],
+ &struct_last_entry,
+ sizeof(VMStructEntry)) == 0, "Incorrect last entry in localHotSpotVMStructs");
+
+ static VMTypeEntry type_last_entry = GENERATE_VM_TYPE_LAST_ENTRY();
+ assert(memcmp(&localHotSpotVMTypes[sizeof(localHotSpotVMTypes) / sizeof(VMTypeEntry) - 1],
+ &type_last_entry,
+ sizeof(VMTypeEntry)) == 0, "Incorrect last entry in localHotSpotVMTypes");
+
+ static VMIntConstantEntry int_last_entry = GENERATE_VM_INT_CONSTANT_LAST_ENTRY();
+ assert(memcmp(&localHotSpotVMIntConstants[sizeof(localHotSpotVMIntConstants) / sizeof(VMIntConstantEntry) - 1],
+ &int_last_entry,
+ sizeof(VMIntConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMIntConstants");
+
+ static VMLongConstantEntry long_last_entry = GENERATE_VM_LONG_CONSTANT_LAST_ENTRY();
+ assert(memcmp(&localHotSpotVMLongConstants[sizeof(localHotSpotVMLongConstants) / sizeof(VMLongConstantEntry) - 1],
+ &long_last_entry,
+ sizeof(VMLongConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMLongConstants");
+
+
// Check for duplicate entries in type array
for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {
for (int j = i + 1; localHotSpotVMTypes[j].typeName != NULL; j++) {
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -570,7 +570,11 @@
if (!t->is_VM_thread()) {
SkipGCALot sgcalot(t); // avoid re-entrant attempts to gc-a-lot
// JavaThread or WatcherThread
- t->check_for_valid_safepoint_state(true);
+ bool concurrent = op->evaluate_concurrently();
+ // only blocking VM operations need to verify the caller's safepoint state:
+ if (!concurrent) {
+ t->check_for_valid_safepoint_state(true);
+ }
// New request from Java thread, evaluate prologue
if (!op->doit_prologue()) {
@@ -582,7 +586,6 @@
// It does not make sense to execute the epilogue, if the VM operation object is getting
// deallocated by the VM thread.
- bool concurrent = op->evaluate_concurrently();
bool execute_epilog = !op->is_cheap_allocated();
assert(!concurrent || op->is_cheap_allocated(), "concurrent => cheap_allocated");
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@
template <> void DCmdArgument<jlong>::parse_value(const char* str,
size_t len, TRAPS) {
- if (str == NULL || sscanf(str, INT64_FORMAT, &_value) != 1) {
+ if (str == NULL || sscanf(str, JLONG_FORMAT, &_value) != 1) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Integer parsing error in diagnostic command arguments\n");
}
@@ -171,7 +171,7 @@
"Integer parsing error nanotime value: syntax error");
}
- int argc = sscanf(str, INT64_FORMAT , &_value._time);
+ int argc = sscanf(str, JLONG_FORMAT, &_value._time);
if (argc != 1) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Integer parsing error nanotime value: syntax error");
--- a/hotspot/src/share/vm/services/heapDumper.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/services/heapDumper.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1866,7 +1866,7 @@
if (error() == NULL) {
char msg[256];
sprintf(msg, "Heap dump file created [%s bytes in %3.3f secs]",
- os::jlong_format_specifier(), timer()->seconds());
+ JLONG_FORMAT, timer()->seconds());
tty->print_cr(msg, writer.bytes_written());
} else {
tty->print_cr("Dump file is incomplete: %s", writer.error());
--- a/hotspot/src/share/vm/services/lowMemoryDetector.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/services/lowMemoryDetector.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -353,7 +353,7 @@
#ifndef PRODUCT
void SensorInfo::print() {
- tty->print_cr("%s count = %ld pending_triggers = %ld pending_clears = %ld",
+ tty->print_cr("%s count = " SIZE_FORMAT " pending_triggers = %ld pending_clears = %ld",
(_sensor_on ? "on" : "off"),
_sensor_count, _pending_trigger_count, _pending_clear_count);
}
--- a/hotspot/src/share/vm/shark/sharkBlock.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkBlock.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1032,7 +1032,7 @@
check_null(value);
object = value->generic_value();
}
- if (is_get && field->is_constant()) {
+ if (is_get && field->is_constant() && field->is_static()) {
SharkConstant *constant = SharkConstant::for_field(iter());
if (constant->is_loaded())
value = constant->value(builder());
@@ -1044,10 +1044,17 @@
BasicType basic_type = field->type()->basic_type();
Type *stack_type = SharkType::to_stackType(basic_type);
Type *field_type = SharkType::to_arrayType(basic_type);
-
+ Type *type = field_type;
+ if (field->is_volatile()) {
+ if (field_type == SharkType::jfloat_type()) {
+ type = SharkType::jint_type();
+ } else if (field_type == SharkType::jdouble_type()) {
+ type = SharkType::jlong_type();
+ }
+ }
Value *addr = builder()->CreateAddressOfStructEntry(
object, in_ByteSize(field->offset_in_bytes()),
- PointerType::getUnqual(field_type),
+ PointerType::getUnqual(type),
"addr");
// Do the access
@@ -1055,6 +1062,7 @@
Value* field_value;
if (field->is_volatile()) {
field_value = builder()->CreateAtomicLoad(addr);
+ field_value = builder()->CreateBitCast(field_value, field_type);
} else {
field_value = builder()->CreateLoad(addr);
}
@@ -1074,6 +1082,7 @@
}
if (field->is_volatile()) {
+ field_value = builder()->CreateBitCast(field_value, type);
builder()->CreateAtomicStore(field_value, addr);
} else {
builder()->CreateStore(field_value, addr);
--- a/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -185,6 +185,9 @@
// Build the LLVM IR for the method
Function *function = SharkFunction::build(env, &builder, flow, name);
+ if (env->failing()) {
+ return;
+ }
// Generate native code. It's unpleasant that we have to drop into
// the VM to do this -- it blocks safepoints -- but I can't see any
--- a/hotspot/src/share/vm/shark/sharkCompiler.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -46,6 +46,9 @@
// Missing feature tests
bool supports_native() { return true; }
bool supports_osr() { return true; }
+ bool can_compile_method(methodHandle method) {
+ return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form());
+ }
// Customization
bool needs_adapters() { return false; }
--- a/hotspot/src/share/vm/shark/sharkConstant.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkConstant.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -37,7 +37,12 @@
ciType *type = NULL;
if (constant.basic_type() == T_OBJECT) {
ciEnv *env = ciEnv::current();
- assert(constant.as_object()->klass() == env->String_klass() || constant.as_object()->klass() == env->Class_klass(), "should be");
+
+ assert(constant.as_object()->klass() == env->String_klass()
+ || constant.as_object()->klass() == env->Class_klass()
+ || constant.as_object()->klass()->is_subtype_of(env->MethodType_klass())
+ || constant.as_object()->klass()->is_subtype_of(env->MethodHandle_klass()), "should be");
+
type = constant.as_object()->klass();
}
return new SharkConstant(constant, type);
--- a/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -77,6 +77,10 @@
// Walk the tree from the start block to determine which
// blocks are entered and which blocks require phis
SharkTopLevelBlock *start_block = block(flow()->start_block_num());
+ if (is_osr() && start_block->stack_depth_at_entry() != 0) {
+ env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0");
+ return;
+ }
assert(start_block->start() == flow()->start_bci(), "blocks out of order");
start_block->enter();
--- a/hotspot/src/share/vm/shark/sharkInliner.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkInliner.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -725,7 +725,7 @@
// Push the result if necessary
if (is_get) {
bool result_pushed = false;
- if (field->is_constant()) {
+ if (field->is_constant() && field->is_static()) {
SharkConstant *sc = SharkConstant::for_field(iter());
if (sc->is_loaded()) {
push(sc->is_nonzero());
--- a/hotspot/src/share/vm/shark/sharkInvariants.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -68,7 +68,7 @@
//
// Accessing this directly is kind of ugly, so it's private. Add
// new accessors below if you need something from it.
- private:
+ protected:
ciEnv* env() const {
assert(_env != NULL, "env not available");
return _env;
@@ -99,12 +99,14 @@
DebugInformationRecorder* debug_info() const {
return env()->debug_info();
}
+ SharkCodeBuffer* code_buffer() const {
+ return builder()->code_buffer();
+ }
+
+ public:
Dependencies* dependencies() const {
return env()->dependencies();
}
- SharkCodeBuffer* code_buffer() const {
- return builder()->code_buffer();
- }
// Commonly used classes
protected:
--- a/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -113,7 +113,19 @@
ciSignature* sig;
method = iter()->get_method(will_link, &sig);
assert(will_link, "typeflow responsibility");
-
+ // We can't compile calls to method handle intrinsics, because we use
+ // the interpreter entry points and they expect the top frame to be an
+ // interpreter frame. We need to implement the intrinsics for Shark.
+ if (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()) {
+ if (SharkPerformanceWarnings) {
+ warning("JSR292 optimization not yet implemented in Shark");
+ }
+ set_trap(
+ Deoptimization::make_trap_request(
+ Deoptimization::Reason_unhandled,
+ Deoptimization::Action_make_not_compilable), bci());
+ return;
+ }
if (!method->holder()->is_linked()) {
set_trap(
Deoptimization::make_trap_request(
@@ -158,6 +170,16 @@
return;
}
break;
+ case Bytecodes::_invokedynamic:
+ case Bytecodes::_invokehandle:
+ if (SharkPerformanceWarnings) {
+ warning("JSR292 optimization not yet implemented in Shark");
+ }
+ set_trap(
+ Deoptimization::make_trap_request(
+ Deoptimization::Reason_unhandled,
+ Deoptimization::Action_make_not_compilable), bci());
+ return;
}
}
@@ -1030,7 +1052,6 @@
dest_method->holder() == java_lang_Object_klass())
return dest_method;
-#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
// This code can replace a virtual call with a direct call if this
// class is the only one in the entire set of loaded classes that
// implements this method. This makes the compiled code dependent
@@ -1064,6 +1085,8 @@
if (monomorphic_target != NULL) {
assert(!monomorphic_target->is_abstract(), "shouldn't be");
+ function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target);
+
// Opto has a bunch of type checking here that I don't
// understand. It's to inhibit casting in one direction,
// possibly because objects in Opto can have inexact
@@ -1097,7 +1120,6 @@
// with non-monomorphic targets if the receiver has an exact
// type. We don't mark types this way, so we can't do this.
-#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
return NULL;
}
@@ -1298,8 +1320,9 @@
// Try to inline the call
if (!call_is_virtual) {
- if (SharkInliner::attempt_inline(call_method, current_state()))
+ if (SharkInliner::attempt_inline(call_method, current_state())) {
return;
+ }
}
// Find the method we are calling
--- a/hotspot/src/share/vm/utilities/exceptions.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -267,6 +267,7 @@
#define THROW_WRAPPED_0(name, oop_to_wrap) THROW_WRAPPED_(name, oop_to_wrap, 0)
#define THROW_ARG_0(name, signature, arg) THROW_ARG_(name, signature, arg, 0)
#define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
+#define THROW_MSG_CAUSE_NULL(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, NULL)
#define THROW_NULL(name) THROW_(name, NULL)
#define THROW_MSG_NULL(name, message) THROW_MSG_(name, message, NULL)
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1250,6 +1250,14 @@
#define PTR64_FORMAT "0x%016" PRIx64
+// Format jlong, if necessary
+#ifndef JLONG_FORMAT
+#define JLONG_FORMAT INT64_FORMAT
+#endif
+#ifndef JULONG_FORMAT
+#define JULONG_FORMAT UINT64_FORMAT
+#endif
+
// Format pointers which change size between 32- and 64-bit.
#ifdef _LP64
#define INTPTR_FORMAT "0x%016" PRIxPTR
--- a/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -306,4 +306,8 @@
#endif
#define offsetof(klass,field) offset_of(klass,field)
+#if defined(_LP64) && defined(__APPLE__)
+#define JLONG_FORMAT "%ld"
+#endif // _LP64 && __APPLE__
+
#endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_GCC_HPP
--- a/hotspot/src/share/vm/utilities/ostream.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/utilities/ostream.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -243,13 +243,11 @@
}
void outputStream::print_jlong(jlong value) {
- // N.B. Same as INT64_FORMAT
- print(os::jlong_format_specifier(), value);
+ print(JLONG_FORMAT, value);
}
void outputStream::print_julong(julong value) {
- // N.B. Same as UINT64_FORMAT
- print(os::julong_format_specifier(), value);
+ print(JULONG_FORMAT, value);
}
/**
--- a/hotspot/src/share/vm/utilities/taskqueue.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/utilities/taskqueue.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -239,8 +239,8 @@
#ifdef TRACESPINNING
void ParallelTaskTerminator::print_termination_counts() {
- gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: %lld "
- "Total spins: %lld Total peeks: %lld",
+ gclog_or_tty->print_cr("ParallelTaskTerminator Total yields: " UINT32_FORMAT
+ " Total spins: " UINT32_FORMAT " Total peeks: " UINT32_FORMAT,
total_yields(),
total_spins(),
total_peeks());
--- a/hotspot/src/share/vm/utilities/vmError.cpp Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/src/share/vm/utilities/vmError.cpp Wed Jul 05 18:38:03 2017 +0200
@@ -702,7 +702,7 @@
if (_verbose && Universe::is_fully_initialized()) {
// print code cache information before vm abort
- CodeCache::print_bounds(st);
+ CodeCache::print_summary(st);
st->cr();
}
--- a/hotspot/test/Makefile Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/test/Makefile Wed Jul 05 18:38:03 2017 +0200
@@ -189,9 +189,9 @@
$(JTREG) -a -v:fail,error \
$(JTREG_KEY_OPTION) \
$(EXTRA_JTREG_OPTIONS) \
- -r:$(ABS_TEST_OUTPUT_DIR)/JTreport \
- -w:$(ABS_TEST_OUTPUT_DIR)/JTwork \
- -jdk:$(PRODUCT_HOME) \
+ -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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6896617/Test6896617.java Wed Jul 05 18:38:03 2017 +0200
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6896617
+ * @summary Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() with SSE instructions on x86
+ * @run main/othervm/timeout=1200 -Xbatch -Xmx256m Test6896617
+ *
+ */
+
+import java.util.*;
+import java.nio.*;
+import java.nio.charset.*;
+
+public class Test6896617 {
+ final static int SIZE = 256;
+
+ public static void main(String[] args) {
+ String csn = "ISO-8859-1";
+ Charset cs = Charset.forName(csn);
+ CharsetEncoder enc = cs.newEncoder();
+ enc.onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
+ CharsetDecoder dec = cs.newDecoder();
+ dec.onMalformedInput(CodingErrorAction.REPLACE)
+ .onUnmappableCharacter(CodingErrorAction.REPLACE);
+
+ byte repl = (byte)'?';
+ enc.replaceWith(new byte[] { repl });
+
+ // Use internal API for tests.
+ sun.nio.cs.ArrayEncoder arrenc = (sun.nio.cs.ArrayEncoder)enc;
+ sun.nio.cs.ArrayDecoder arrdec = (sun.nio.cs.ArrayDecoder)dec;
+
+ // Populate char[] with chars which can be encoded by ISO_8859_1 (<= 0xFF)
+ Random rnd = new Random(0);
+ int maxchar = 0xFF;
+ char[] a = new char[SIZE];
+ byte[] b = new byte[SIZE];
+ char[] at = new char[SIZE];
+ byte[] bt = new byte[SIZE];
+ for (int i = 0; i < SIZE; i++) {
+ char c = (char) rnd.nextInt(maxchar);
+ if (!enc.canEncode(c)) {
+ System.out.printf("Something wrong: can't encode c=%03x\n", (int)c);
+ System.exit(97);
+ }
+ a[i] = c;
+ b[i] = (byte)c;
+ at[i] = (char)-1;
+ bt[i] = (byte)-1;
+ }
+ if (arrenc.encode(a, 0, SIZE, bt) != SIZE || !Arrays.equals(b, bt)) {
+ System.out.println("Something wrong: ArrayEncoder.encode failed");
+ System.exit(97);
+ }
+ if (arrdec.decode(b, 0, SIZE, at) != SIZE || !Arrays.equals(a, at)) {
+ System.out.println("Something wrong: ArrayDecoder.decode failed");
+ System.exit(97);
+ }
+ for (int i = 0; i < SIZE; i++) {
+ at[i] = (char)-1;
+ bt[i] = (byte)-1;
+ }
+
+ ByteBuffer bb = ByteBuffer.wrap(b);
+ CharBuffer ba = CharBuffer.wrap(a);
+ ByteBuffer bbt = ByteBuffer.wrap(bt);
+ CharBuffer bat = CharBuffer.wrap(at);
+ if (!enc.encode(ba, bbt, true).isUnderflow() || !Arrays.equals(b, bt)) {
+ System.out.println("Something wrong: Encoder.encode failed");
+ System.exit(97);
+ }
+ if (!dec.decode(bb, bat, true).isUnderflow() || !Arrays.equals(a, at)) {
+ System.out.println("Something wrong: Decoder.decode failed");
+ System.exit(97);
+ }
+ for (int i = 0; i < SIZE; i++) {
+ at[i] = (char)-1;
+ bt[i] = (byte)-1;
+ }
+
+ // Warm up
+ boolean failed = false;
+ int result = 0;
+ for (int i = 0; i < 10000; i++) {
+ result += arrenc.encode(a, 0, SIZE, bt);
+ result -= arrdec.decode(b, 0, SIZE, at);
+ }
+ for (int i = 0; i < 10000; i++) {
+ result += arrenc.encode(a, 0, SIZE, bt);
+ result -= arrdec.decode(b, 0, SIZE, at);
+ }
+ for (int i = 0; i < 10000; i++) {
+ result += arrenc.encode(a, 0, SIZE, bt);
+ result -= arrdec.decode(b, 0, SIZE, at);
+ }
+ if (result != 0 || !Arrays.equals(b, bt) || !Arrays.equals(a, at)) {
+ failed = true;
+ System.out.println("Failed: ArrayEncoder.encode char[" + SIZE + "] and ArrayDecoder.decode byte[" + SIZE + "]");
+ }
+ for (int i = 0; i < SIZE; i++) {
+ at[i] = (char)-1;
+ bt[i] = (byte)-1;
+ }
+
+ boolean is_underflow = true;
+ for (int i = 0; i < 10000; i++) {
+ ba.clear(); bb.clear(); bat.clear(); bbt.clear();
+ boolean enc_res = enc.encode(ba, bbt, true).isUnderflow();
+ boolean dec_res = dec.decode(bb, bat, true).isUnderflow();
+ is_underflow = is_underflow && enc_res && dec_res;
+ }
+ for (int i = 0; i < SIZE; i++) {
+ at[i] = (char)-1;
+ bt[i] = (byte)-1;
+ }
+ for (int i = 0; i < 10000; i++) {
+ ba.clear(); bb.clear(); bat.clear(); bbt.clear();
+ boolean enc_res = enc.encode(ba, bbt, true).isUnderflow();
+ boolean dec_res = dec.decode(bb, bat, true).isUnderflow();
+ is_underflow = is_underflow && enc_res && dec_res;
+ }
+ for (int i = 0; i < SIZE; i++) {
+ at[i] = (char)-1;
+ bt[i] = (byte)-1;
+ }
+ for (int i = 0; i < 10000; i++) {
+ ba.clear(); bb.clear(); bat.clear(); bbt.clear();
+ boolean enc_res = enc.encode(ba, bbt, true).isUnderflow();
+ boolean dec_res = dec.decode(bb, bat, true).isUnderflow();
+ is_underflow = is_underflow && enc_res && dec_res;
+ }
+ if (!is_underflow || !Arrays.equals(b, bt) || !Arrays.equals(a, at)) {
+ failed = true;
+ System.out.println("Failed: Encoder.encode char[" + SIZE + "] and Decoder.decode byte[" + SIZE + "]");
+ }
+
+ // Test encoder with different source and destination sizes
+ System.out.println("Testing different source and destination sizes");
+ for (int i = 1; i <= SIZE; i++) {
+ for (int j = 1; j <= SIZE; j++) {
+ bt = new byte[j];
+ // very source's SIZE
+ result = arrenc.encode(a, 0, i, bt);
+ int l = Math.min(i, j);
+ if (result != l) {
+ failed = true;
+ System.out.println("Failed: encode char[" + i + "] to byte[" + j + "]: result = " + result + ", expected " + l);
+ }
+ for (int k = 0; k < l; k++) {
+ if (bt[k] != b[k]) {
+ failed = true;
+ System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[k]);
+ }
+ }
+ // very source's offset
+ int sz = SIZE - i + 1;
+ result = arrenc.encode(a, i-1, sz, bt);
+ l = Math.min(sz, j);
+ if (result != l) {
+ failed = true;
+ System.out.println("Failed: encode char[" + sz + "] to byte[" + j + "]: result = " + result + ", expected " + l);
+ }
+ for (int k = 0; k < l; k++) {
+ if (bt[k] != b[i+k-1]) {
+ failed = true;
+ System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[i+k-1]);
+ }
+ }
+ }
+ }
+
+ // Test encoder with char > 0xFF
+ System.out.println("Testing big char");
+
+ byte orig = (byte)'A';
+ bt = new byte[SIZE];
+ for (int i = 1; i <= SIZE; i++) {
+ for (int j = 0; j < i; j++) {
+ a[j] += 0x100;
+ // make sure to replace a different byte
+ bt[j] = orig;
+ result = arrenc.encode(a, 0, i, bt);
+ if (result != i) {
+ failed = true;
+ System.out.println("Failed: encode char[" + i + "] to byte[" + i + "]: result = " + result + ", expected " + i);
+ }
+ if (bt[j] != repl) {
+ failed = true;
+ System.out.println("Failed: encoded replace byte[" + j + "] (" + bt[j] + ") != " + repl);
+ }
+ bt[j] = b[j]; // Restore to compare whole array
+ for (int k = 0; k < i; k++) {
+ if (bt[k] != b[k]) {
+ failed = true;
+ System.out.println("Failed: encoded byte[" + k + "] (" + bt[k] + ") != " + b[k]);
+ }
+ }
+ a[j] -= 0x100; // Restore
+ }
+ }
+
+ // Test sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() performance.
+
+ int itrs = Integer.getInteger("iterations", 1000000);
+ int size = Integer.getInteger("size", 256);
+ a = new char[size];
+ b = new byte[size];
+ bt = new byte[size];
+ for (int i = 0; i < size; i++) {
+ char c = (char) rnd.nextInt(maxchar);
+ if (!enc.canEncode(c)) {
+ System.out.printf("Something wrong: can't encode c=%03x\n", (int)c);
+ System.exit(97);
+ }
+ a[i] = c;
+ b[i] = (byte)-1;
+ bt[i] = (byte)c;
+ }
+ ba = CharBuffer.wrap(a);
+ bb = ByteBuffer.wrap(b);
+ boolean enc_res = enc.encode(ba, bb, true).isUnderflow();
+ if (!enc_res || !Arrays.equals(b, bt)) {
+ failed = true;
+ System.out.println("Failed 1: Encoder.encode char[" + size + "]");
+ }
+ for (int i = 0; i < size; i++) {
+ b[i] = (byte)-1;
+ }
+
+ // Make sure to recompile method if needed before performance run.
+ for (int i = 0; i < 10000; i++) {
+ ba.clear(); bb.clear();
+ enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow();
+ }
+ for (int i = 0; i < size; i++) {
+ b[i] = (byte)-1;
+ }
+ for (int i = 0; i < 10000; i++) {
+ ba.clear(); bb.clear();
+ enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow();
+ }
+ if (!enc_res || !Arrays.equals(b, bt)) {
+ failed = true;
+ System.out.println("Failed 2: Encoder.encode char[" + size + "]");
+ }
+ for (int i = 0; i < size; i++) {
+ b[i] = (byte)-1;
+ }
+
+ System.out.println("Testing ISO_8859_1$Encode.encodeArrayLoop() performance");
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < itrs; i++) {
+ ba.clear(); bb.clear();
+ enc_res = enc_res && enc.encode(ba, bb, true).isUnderflow();
+ }
+ long end = System.currentTimeMillis();
+ if (!enc_res || !Arrays.equals(b, bt)) {
+ failed = true;
+ System.out.println("Failed 3: Encoder.encode char[" + size + "]");
+ } else {
+ System.out.println("size: " + size + " time: " + (end - start));
+ }
+
+ // Test sun.nio.cs.ISO_8859_1$Encode.encode() performance.
+
+ // Make sure to recompile method if needed before performance run.
+ result = 0;
+ for (int i = 0; i < size; i++) {
+ b[i] = (byte)-1;
+ }
+ for (int i = 0; i < 10000; i++) {
+ result += arrenc.encode(a, 0, size, b);
+ }
+ for (int i = 0; i < size; i++) {
+ b[i] = (byte)-1;
+ }
+ for (int i = 0; i < 10000; i++) {
+ result += arrenc.encode(a, 0, size, b);
+ }
+ if (result != size*20000 || !Arrays.equals(b, bt)) {
+ failed = true;
+ System.out.println("Failed 1: ArrayEncoder.encode char[" + SIZE + "]");
+ }
+ for (int i = 0; i < size; i++) {
+ b[i] = (byte)-1;
+ }
+
+ System.out.println("Testing ISO_8859_1$Encode.encode() performance");
+ result = 0;
+ start = System.currentTimeMillis();
+ for (int i = 0; i < itrs; i++) {
+ result += arrenc.encode(a, 0, size, b);
+ }
+ end = System.currentTimeMillis();
+ if (!Arrays.equals(b, bt)) {
+ failed = true;
+ System.out.println("Failed 2: ArrayEncoder.encode char[" + size + "]");
+ } else {
+ System.out.println("size: " + size + " time: " + (end - start));
+ }
+
+ if (failed) {
+ System.out.println("FAILED");
+ System.exit(97);
+ }
+ System.out.println("PASSED");
+ }
+}
--- a/hotspot/test/compiler/7190310/Test7190310.java Wed Jan 30 13:04:22 2013 -0800
+++ b/hotspot/test/compiler/7190310/Test7190310.java Wed Jul 05 18:38:03 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,16 @@
*/
/*
- * Manual test
+ * @test
+ * @bug 7190310
+ * @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
+ * @run main/othervm/timeout=600 -Xbatch Test7190310
+ */
+
+/*
+ * Note bug exhibits as infinite loop, timeout is helpful.
+ * It should normally finish pretty quickly, but on some especially slow machines
+ * it may not. The companion _unsafe test lacks a timeout, but that is okay.
*/
import java.lang.ref.*;
--- a/make/jprt.properties Wed Jan 30 13:04:22 2013 -0800
+++ b/make/jprt.properties Wed Jul 05 18:38:03 2017 +0200
@@ -92,6 +92,7 @@
${jprt.my.test.target.set:TESTNAME=jdk_text}, \
${jprt.my.test.target.set:TESTNAME=jdk_tools}, \
${jprt.my.test.target.set:TESTNAME=jdk_jfr}, \
+ ${jprt.my.test.target.set:TESTNAME=jdk_time}, \
${jprt.my.test.target.set:TESTNAME=jdk_other}
# All vm test targets (testset=all)
--- a/test/Makefile Wed Jan 30 13:04:22 2013 -0800
+++ b/test/Makefile Wed Jul 05 18:38:03 2017 +0200
@@ -63,7 +63,8 @@
jdk_nio \
jdk_security1 \
jdk_text \
- jdk_util
+ jdk_util \
+ jdk_time
# These tests are not part of the default testing list
JDK_NONDEFAULT_TEST_LIST = \