--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad Tue Aug 29 17:17:58 2017 +0200
@@ -12658,6 +12658,64 @@
ins_pipe(ialu_reg_shift);
%}
+// We can use ubfiz when masking by a positive number and then left shifting the result.
+// We know that the mask is positive because immI_bitmask guarantees it.
+instruct ubfizwI(iRegINoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
+%{
+ match(Set dst (LShiftI (AndI src mask) lshift));
+ predicate((unsigned int)n->in(2)->get_int() <= 31 &&
+ (exact_log2(n->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= (31+1));
+
+ ins_cost(INSN_COST);
+ format %{ "ubfizw $dst, $src, $lshift, $mask" %}
+ ins_encode %{
+ int lshift = $lshift$$constant;
+ long mask = $mask$$constant;
+ int width = exact_log2(mask+1);
+ __ ubfizw(as_Register($dst$$reg),
+ as_Register($src$$reg), lshift, width);
+ %}
+ ins_pipe(ialu_reg_shift);
+%}
+// We can use ubfiz when masking by a positive number and then left shifting the result.
+// We know that the mask is positive because immL_bitmask guarantees it.
+instruct ubfizL(iRegLNoSp dst, iRegL src, immI lshift, immL_bitmask mask)
+%{
+ match(Set dst (LShiftL (AndL src mask) lshift));
+ predicate((unsigned int)n->in(2)->get_int() <= 63 &&
+ (exact_log2_long(n->in(1)->in(2)->get_long()+1) + (unsigned int)n->in(2)->get_int()) <= (63+1));
+
+ ins_cost(INSN_COST);
+ format %{ "ubfiz $dst, $src, $lshift, $mask" %}
+ ins_encode %{
+ int lshift = $lshift$$constant;
+ long mask = $mask$$constant;
+ int width = exact_log2(mask+1);
+ __ ubfiz(as_Register($dst$$reg),
+ as_Register($src$$reg), lshift, width);
+ %}
+ ins_pipe(ialu_reg_shift);
+%}
+
+// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
+instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
+%{
+ match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
+ predicate((unsigned int)n->in(2)->get_int() <= 31 &&
+ (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
+
+ ins_cost(INSN_COST);
+ format %{ "ubfiz $dst, $src, $lshift, $mask" %}
+ ins_encode %{
+ int lshift = $lshift$$constant;
+ long mask = $mask$$constant;
+ int width = exact_log2(mask+1);
+ __ ubfiz(as_Register($dst$$reg),
+ as_Register($src$$reg), lshift, width);
+ %}
+ ins_pipe(ialu_reg_shift);
+%}
+
// Rotations
instruct extrOrL(iRegLNoSp dst, iRegL src1, iRegL src2, immI lshift, immI rshift, rFlagsReg cr)
--- a/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4 Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/cpu/aarch64/vm/aarch64_ad.m4 Tue Aug 29 17:17:58 2017 +0200
@@ -214,6 +214,48 @@
ins_pipe(ialu_reg_shift);
%}
+define(`UBFIZ_INSN',
+// We can use ubfiz when masking by a positive number and then left shifting the result.
+// We know that the mask is positive because imm$1_bitmask guarantees it.
+`instruct $2$1(iReg$1NoSp dst, iReg$1`'ORL2I($1) src, immI lshift, imm$1_bitmask mask)
+%{
+ match(Set dst (LShift$1 (And$1 src mask) lshift));
+ predicate((unsigned int)n->in(2)->get_int() <= $3 &&
+ (exact_log2$5(n->in(1)->in(2)->get_$4()+1) + (unsigned int)n->in(2)->get_int()) <= ($3+1));
+
+ ins_cost(INSN_COST);
+ format %{ "$2 $dst, $src, $lshift, $mask" %}
+ ins_encode %{
+ int lshift = $lshift$$constant;
+ long mask = $mask$$constant;
+ int width = exact_log2(mask+1);
+ __ $2(as_Register($dst$$reg),
+ as_Register($src$$reg), lshift, width);
+ %}
+ ins_pipe(ialu_reg_shift);
+%}')
+UBFIZ_INSN(I, ubfizw, 31, int)
+UBFIZ_INSN(L, ubfiz, 63, long, _long)
+
+// If there is a convert I to L block between and AndI and a LShiftL, we can also match ubfiz
+instruct ubfizIConvI2L(iRegLNoSp dst, iRegIorL2I src, immI lshift, immI_bitmask mask)
+%{
+ match(Set dst (LShiftL (ConvI2L(AndI src mask)) lshift));
+ predicate((unsigned int)n->in(2)->get_int() <= 31 &&
+ (exact_log2((unsigned int)n->in(1)->in(1)->in(2)->get_int()+1) + (unsigned int)n->in(2)->get_int()) <= 32);
+
+ ins_cost(INSN_COST);
+ format %{ "ubfiz $dst, $src, $lshift, $mask" %}
+ ins_encode %{
+ int lshift = $lshift$$constant;
+ long mask = $mask$$constant;
+ int width = exact_log2(mask+1);
+ __ ubfiz(as_Register($dst$$reg),
+ as_Register($src$$reg), lshift, width);
+ %}
+ ins_pipe(ialu_reg_shift);
+%}
+
// Rotations
define(`EXTRACT_INSN',
--- a/hotspot/src/os/linux/vm/os_linux.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1748,8 +1748,10 @@
{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
#if defined(VM_LITTLE_ENDIAN)
{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2LSB, (char*)"Power PC 64 LE"},
+ {EM_SH, EM_SH, ELFCLASS32, ELFDATA2LSB, (char*)"SuperH"},
#else
{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
+ {EM_SH, EM_SH, ELFCLASS32, ELFDATA2MSB, (char*)"SuperH BE"},
#endif
{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
{EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
@@ -1791,9 +1793,11 @@
static Elf32_Half running_arch_code=EM_MIPS;
#elif (defined M68K)
static Elf32_Half running_arch_code=EM_68K;
+#elif (defined SH)
+ static Elf32_Half running_arch_code=EM_SH;
#else
#error Method os::dll_load requires that one of following is defined:\
- AARCH64, ALPHA, ARM, AMD64, IA32, IA64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, S390, __sparc
+ AARCH64, ALPHA, ARM, AMD64, IA32, IA64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, S390, SH, __sparc
#endif
// Identify compatability class for VM's architecture and library's architecture
--- a/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/aix_ppc/vm/atomic_aix_ppc.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -95,9 +95,21 @@
#define strasm_nobarrier ""
#define strasm_nobarrier_clobber_memory ""
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
- unsigned int result;
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(4 == sizeof(I));
+ STATIC_CAST(4 == sizeof(D));
+
+ D result;
__asm__ __volatile__ (
strasm_lwsync
@@ -110,13 +122,17 @@
: /*%1*/"r" (add_value), /*%2*/"r" (dest)
: "cc", "memory" );
- return (jint) result;
+ return result;
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(8 == sizeof(I));
+ STATIC_CAST(8 == sizeof(D));
- long result;
+ D result;
__asm__ __volatile__ (
strasm_lwsync
@@ -129,11 +145,7 @@
: /*%1*/"r" (add_value), /*%2*/"r" (dest)
: "cc", "memory" );
- return (intptr_t) result;
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
+ return result;
}
--- a/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -40,13 +40,25 @@
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
- jint addend = add_value;
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::FetchAndAdd<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D fetch_and_add(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::fetch_and_add(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(4 == sizeof(I));
+ STATIC_ASSERT(4 == sizeof(D));
+ D old_value;
__asm__ volatile ( "lock xaddl %0,(%2)"
- : "=r" (addend)
- : "0" (addend), "r" (dest)
+ : "=r" (old_value)
+ : "0" (add_value), "r" (dest)
: "cc", "memory");
- return addend + add_value;
+ return old_value;
}
inline void Atomic::inc (volatile jint* dest) {
@@ -111,17 +123,17 @@
inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- intptr_t addend = add_value;
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::fetch_and_add(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(8 == sizeof(I));
+ STATIC_ASSERT(8 == sizeof(D));
+ D old_value;
__asm__ __volatile__ ( "lock xaddq %0,(%2)"
- : "=r" (addend)
- : "0" (addend), "r" (dest)
+ : "=r" (old_value)
+ : "0" (add_value), "r" (dest)
: "cc", "memory");
- return addend + add_value;
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
+ return old_value;
}
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
@@ -164,15 +176,6 @@
#else // !AMD64
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)Atomic::add((jint)add_value, (volatile jint*)dest);
-}
-
-
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
inc((volatile jint*)dest);
}
--- a/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/bsd_zero/vm/atomic_bsd_zero.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -74,7 +74,7 @@
}
/* Atomically add an int to memory. */
-static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) {
+static inline int m68k_add_and_fetch(int add_value, volatile int *ptr) {
for (;;) {
// Loop until success.
@@ -135,7 +135,7 @@
}
/* Atomically add an int to memory. */
-static inline int arm_add_and_fetch(volatile int *ptr, int add_value) {
+static inline int arm_add_and_fetch(int add_value, volatile int *ptr) {
for (;;) {
// Loop until a __kernel_cmpxchg succeeds.
@@ -173,32 +173,38 @@
*dest = store_value;
}
-inline jint Atomic::add(jint add_value, volatile jint* dest) {
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(4 == sizeof(I));
+ STATIC_CAST(4 == sizeof(D));
+
#ifdef ARM
- return arm_add_and_fetch(dest, add_value);
+ return add_using_helper<int>(arm_add_and_fetch, add_value, dest);
#else
#ifdef M68K
- return m68k_add_and_fetch(dest, add_value);
+ return add_using_helper<int>(m68k_add_and_fetch, add_value, dest);
#else
return __sync_add_and_fetch(dest, add_value);
#endif // M68K
#endif // ARM
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
-#ifdef ARM
- return arm_add_and_fetch(dest, add_value);
-#else
-#ifdef M68K
- return m68k_add_and_fetch(dest, add_value);
-#else
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(8 == sizeof(I));
+ STATIC_CAST(8 == sizeof(D));
+
return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
-#endif // ARM
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
}
inline void Atomic::inc(volatile jint* dest) {
--- a/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_aarch64/vm/atomic_linux_aarch64.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -47,10 +47,15 @@
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
-inline jint Atomic::add(jint add_value, volatile jint* dest)
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
{
- return __sync_add_and_fetch(dest, add_value);
-}
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const {
+ return __sync_add_and_fetch(dest, add_value);
+ }
+};
inline void Atomic::inc(volatile jint* dest)
{
@@ -105,16 +110,6 @@
inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
-{
- return __sync_add_and_fetch(dest, add_value);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest)
-{
- return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
-}
-
inline void Atomic::inc_ptr(volatile intptr_t* dest)
{
add_ptr(1, dest);
--- a/hotspot/src/os_cpu/linux_arm/vm/atomic_linux_arm.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_arm/vm/atomic_linux_arm.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -91,9 +91,21 @@
//
// For ARMv7 we add explicit barriers in the stubs.
-inline jint Atomic::add(jint add_value, volatile jint* dest) {
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(4 == sizeof(I));
+ STATIC_ASSERT(4 == sizeof(D));
#ifdef AARCH64
- jint val;
+ D val;
int tmp;
__asm__ volatile(
"1:\n\t"
@@ -106,7 +118,7 @@
: "memory");
return val;
#else
- return (*os::atomic_add_func)(add_value, dest);
+ return add_using_helper<jint>(os::atomic_add_func, add_value, dest);
#endif
}
@@ -118,9 +130,13 @@
Atomic::add(-1, (volatile jint *)dest);
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
#ifdef AARCH64
- intptr_t val;
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(8 == sizeof(I));
+ STATIC_ASSERT(8 == sizeof(D));
+ D val;
int tmp;
__asm__ volatile(
"1:\n\t"
@@ -132,14 +148,8 @@
: [add_val] "r" (add_value), [dest] "r" (dest)
: "memory");
return val;
-#else
- return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest);
-#endif
}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
-}
+#endif // AARCH64
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
Atomic::add_ptr(1, dest);
--- a/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -93,9 +93,21 @@
#define strasm_nobarrier ""
#define strasm_nobarrier_clobber_memory ""
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
- unsigned int result;
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(4 == sizeof(I));
+ STATIC_CAST(4 == sizeof(D));
+
+ D result;
__asm__ __volatile__ (
strasm_lwsync
@@ -108,13 +120,17 @@
: /*%1*/"r" (add_value), /*%2*/"r" (dest)
: "cc", "memory" );
- return (jint) result;
+ return result;
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(8 == sizeof(I));
+ STATIC_CAST(8 == sizeof(D));
- long result;
+ D result;
__asm__ __volatile__ (
strasm_lwsync
@@ -127,11 +143,7 @@
: /*%1*/"r" (add_value), /*%2*/"r" (dest)
: "cc", "memory" );
- return (intptr_t) result;
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
+ return result;
}
--- a/hotspot/src/os_cpu/linux_s390/vm/atomic_linux_s390.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_s390/vm/atomic_linux_s390.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -82,8 +82,21 @@
// The return value of the method is the value that was successfully stored. At the
// time the caller receives back control, the value in memory may have changed already.
-inline jint Atomic::add(jint inc, volatile jint*dest) {
- unsigned int old, upd;
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(4 == sizeof(I));
+ STATIC_CAST(4 == sizeof(D));
+
+ D old, upd;
if (VM_Version::has_LoadAndALUAtomicV1()) {
__asm__ __volatile__ (
@@ -124,12 +137,17 @@
);
}
- return (jint)upd;
+ return upd;
}
-inline intptr_t Atomic::add_ptr(intptr_t inc, volatile intptr_t* dest) {
- unsigned long old, upd;
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(8 == sizeof(I));
+ STATIC_CAST(8 == sizeof(D));
+
+ D old, upd;
if (VM_Version::has_LoadAndALUAtomicV1()) {
__asm__ __volatile__ (
@@ -170,11 +188,7 @@
);
}
- return (intptr_t)upd;
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
+ return upd;
}
--- a/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_sparc/vm/atomic_linux_sparc.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -51,8 +51,21 @@
inline jlong Atomic::load(const volatile jlong* src) { return *src; }
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
- intptr_t rv;
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(4 == sizeof(I));
+ STATIC_CAST(4 == sizeof(D));
+
+ D rv;
__asm__ volatile(
"1: \n\t"
" ld [%2], %%o2\n\t"
@@ -68,8 +81,12 @@
return rv;
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- intptr_t rv;
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(8 == sizeof(I));
+ STATIC_CAST(8 == sizeof(D));
+
+ D rv;
__asm__ volatile(
"1: \n\t"
" ldx [%2], %%o2\n\t"
@@ -85,10 +102,6 @@
return rv;
}
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest);
-}
-
inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
intptr_t rv = exchange_value;
--- a/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -40,13 +40,25 @@
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
- jint addend = add_value;
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::FetchAndAdd<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D fetch_and_add(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::fetch_and_add(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(4 == sizeof(I));
+ STATIC_ASSERT(4 == sizeof(D));
+ D old_value;
__asm__ volatile ( "lock xaddl %0,(%2)"
- : "=r" (addend)
- : "0" (addend), "r" (dest)
+ : "=r" (old_value)
+ : "0" (add_value), "r" (dest)
: "cc", "memory");
- return addend + add_value;
+ return old_value;
}
inline void Atomic::inc (volatile jint* dest) {
@@ -111,17 +123,17 @@
inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- intptr_t addend = add_value;
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::fetch_and_add(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(8 == sizeof(I));
+ STATIC_ASSERT(8 == sizeof(D));
+ D old_value;
__asm__ __volatile__ ("lock xaddq %0,(%2)"
- : "=r" (addend)
- : "0" (addend), "r" (dest)
+ : "=r" (old_value)
+ : "0" (add_value), "r" (dest)
: "cc", "memory");
- return addend + add_value;
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr(add_value, (volatile intptr_t*)dest);
+ return old_value;
}
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
@@ -164,15 +176,6 @@
#else // !AMD64
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- return (intptr_t)Atomic::add((jint)add_value, (volatile jint*)dest);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)Atomic::add((jint)add_value, (volatile jint*)dest);
-}
-
-
inline void Atomic::inc_ptr(volatile intptr_t* dest) {
inc((volatile jint*)dest);
}
--- a/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/linux_zero/vm/atomic_linux_zero.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -74,7 +74,7 @@
}
/* Atomically add an int to memory. */
-static inline int m68k_add_and_fetch(volatile int *ptr, int add_value) {
+static inline int m68k_add_and_fetch(int add_value, volatile int *ptr) {
for (;;) {
// Loop until success.
@@ -135,7 +135,7 @@
}
/* Atomically add an int to memory. */
-static inline int arm_add_and_fetch(volatile int *ptr, int add_value) {
+static inline int arm_add_and_fetch(int add_value, volatile int *ptr) {
for (;;) {
// Loop until a __kernel_cmpxchg succeeds.
@@ -167,32 +167,38 @@
*dest = store_value;
}
-inline jint Atomic::add(jint add_value, volatile jint* dest) {
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(4 == sizeof(I));
+ STATIC_CAST(4 == sizeof(D));
+
#ifdef ARM
- return arm_add_and_fetch(dest, add_value);
+ return add_using_helper<int>(arm_add_and_fetch, add_value, dest);
#else
#ifdef M68K
- return m68k_add_and_fetch(dest, add_value);
+ return add_using_helper<int>(m68k_add_and_fetch, add_value, dest);
#else
return __sync_add_and_fetch(dest, add_value);
#endif // M68K
#endif // ARM
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
-#ifdef ARM
- return arm_add_and_fetch(dest, add_value);
-#else
-#ifdef M68K
- return m68k_add_and_fetch(dest, add_value);
-#else
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_CAST(8 == sizeof(I));
+ STATIC_CAST(8 == sizeof(D));
+
return __sync_add_and_fetch(dest, add_value);
-#endif // M68K
-#endif // ARM
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void *) add_ptr(add_value, (volatile intptr_t *) dest);
}
inline void Atomic::inc(volatile jint* dest) {
--- a/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -62,22 +62,21 @@
extern "C" jint _Atomic_swap32(jint exchange_value, volatile jint* dest);
extern "C" intptr_t _Atomic_swap64(intptr_t exchange_value, volatile intptr_t* dest);
-extern "C" jint _Atomic_add32(jint inc, volatile jint* dest);
-extern "C" intptr_t _Atomic_add64(intptr_t add_value, volatile intptr_t* dest);
-
-
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
- return _Atomic_add32(add_value, dest);
-}
-
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- return _Atomic_add64(add_value, dest);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest);
-}
-
+// Implement ADD using a CAS loop.
+template<size_t byte_size>
+struct Atomic::PlatformAdd VALUE_OBJ_CLASS_SPEC {
+ template<typename I, typename D>
+ inline D operator()(I add_value, D volatile* dest) const {
+ D old_value = *dest;
+ while (true) {
+ D new_value = old_value + add_value;
+ D result = cmpxchg(new_value, dest, old_value);
+ if (result == old_value) break;
+ old_value = result;
+ }
+ return old_value + add_value;
+ }
+};
inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
return _Atomic_swap32(exchange_value, dest);
--- a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.il Tue Aug 29 17:17:58 2017 +0200
@@ -90,58 +90,6 @@
.nonvolatile
.end
- // Support for jint Atomic::add(jint add_value, volatile jint* dest).
- //
- // Arguments:
- // add_value: O0 (e.g., +1 or -1)
- // dest: O1
- //
- // Results:
- // O0: the new value stored in dest
- //
- // Overwrites O3
-
- .inline _Atomic_add32, 2
- .volatile
- 2:
- ld [%o1], %o2
- add %o0, %o2, %o3
- cas [%o1], %o2, %o3
- cmp %o2, %o3
- bne 2b
- nop
- add %o0, %o2, %o0
- .nonvolatile
- .end
-
-
- // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
- //
- // 64-bit
- //
- // Arguments:
- // add_value: O0 (e.g., +1 or -1)
- // dest: O1
- //
- // Results:
- // O0: the new value stored in dest
- //
- // Overwrites O3
-
- .inline _Atomic_add64, 2
- .volatile
- 3:
- ldx [%o1], %o2
- add %o0, %o2, %o3
- casx [%o1], %o2, %o3
- cmp %o2, %o3
- bne %xcc, 3b
- nop
- add %o0, %o2, %o0
- .nonvolatile
- .end
-
-
// Support for void Prefetch::read(void *loc, intx interval)
//
// Prefetch for several reads.
--- a/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -51,6 +51,8 @@
extern "C" {
jint _Atomic_add(jint add_value, volatile jint* dest);
+ jlong _Atomic_add_long(jlong add_value, volatile jlong* dest);
+
jint _Atomic_xchg(jint exchange_value, volatile jint* dest);
jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest,
jbyte compare_value);
@@ -60,8 +62,34 @@
jlong compare_value);
}
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
- return _Atomic_add(add_value, dest);
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
+// Not using add_using_helper; see comment for cmpxchg.
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(4 == sizeof(I));
+ STATIC_ASSERT(4 == sizeof(D));
+ return PrimitiveConversions::cast<D>(
+ _Atomic_add(PrimitiveConversions::cast<jint>(add_value),
+ reinterpret_cast<jint volatile*>(dest)));
+}
+
+// Not using add_using_helper; see comment for cmpxchg.
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(8 == sizeof(I));
+ STATIC_ASSERT(8 == sizeof(D));
+ return PrimitiveConversions::cast<D>(
+ _Atomic_add_long(PrimitiveConversions::cast<jlong>(add_value),
+ reinterpret_cast<jlong volatile*>(dest)));
}
inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
@@ -115,17 +143,8 @@
inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
-extern "C" jlong _Atomic_add_long(jlong add_value, volatile jlong* dest);
extern "C" jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest);
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- return (intptr_t)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest);
-}
-
inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
return (intptr_t)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest);
}
--- a/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -57,20 +57,28 @@
inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
+template<size_t byte_size>
+struct Atomic::PlatformAdd
+ : Atomic::AddAndFetch<Atomic::PlatformAdd<byte_size> >
+{
+ template<typename I, typename D>
+ D add_and_fetch(I add_value, D volatile* dest) const;
+};
+
#ifdef AMD64
inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
- return (jint)(*os::atomic_add_func)(add_value, dest);
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ return add_using_helper<jint>(os::atomic_add_func, add_value, dest);
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- return (intptr_t)(*os::atomic_add_ptr_func)(add_value, dest);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)(*os::atomic_add_ptr_func)(add_value, (volatile intptr_t*)dest);
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<8>::add_and_fetch(I add_value, D volatile* dest) const {
+ return add_using_helper<intptr_t>(os::atomic_add_ptr_func, add_value, dest);
}
inline void Atomic::inc (volatile jint* dest) {
@@ -130,7 +138,11 @@
#else // !AMD64
-inline jint Atomic::add (jint add_value, volatile jint* dest) {
+template<>
+template<typename I, typename D>
+inline D Atomic::PlatformAdd<4>::add_and_fetch(I add_value, D volatile* dest) const {
+ STATIC_ASSERT(4 == sizeof(I));
+ STATIC_ASSERT(4 == sizeof(D));
__asm {
mov edx, dest;
mov eax, add_value;
@@ -140,14 +152,6 @@
}
}
-inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
- return (intptr_t)add((jint)add_value, (volatile jint*)dest);
-}
-
-inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
- return (void*)add((jint)add_value, (volatile jint*)dest);
-}
-
inline void Atomic::inc (volatile jint* dest) {
// alternative for InterlockedIncrement
__asm {
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -77,9 +77,8 @@
#include "services/classLoadingService.hpp"
#include "services/diagnosticCommand.hpp"
#include "services/threadService.hpp"
-#include "trace/traceMacros.hpp"
+#include "trace/tracing.hpp"
#include "utilities/macros.hpp"
-#include "utilities/ticks.hpp"
#if INCLUDE_CDS
#include "classfile/sharedClassUtil.hpp"
#include "classfile/systemDictionaryShared.hpp"
@@ -87,9 +86,6 @@
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
#endif
-#if INCLUDE_TRACE
-#include "trace/tracing.hpp"
-#endif
PlaceholderTable* SystemDictionary::_placeholders = NULL;
Dictionary* SystemDictionary::_shared_dictionary = NULL;
@@ -615,17 +611,17 @@
return NULL;
}
-static void post_class_load_event(const Ticks& start_time,
- InstanceKlass* k,
+static void post_class_load_event(EventClassLoad* event,
+ const InstanceKlass* k,
const ClassLoaderData* init_cld) {
#if INCLUDE_TRACE
- EventClassLoad event(UNTIMED);
- if (event.should_commit()) {
- event.set_starttime(start_time);
- event.set_loadedClass(k);
- event.set_definingClassLoader(k->class_loader_data());
- event.set_initiatingClassLoader(init_cld);
- event.commit();
+ assert(event != NULL, "invariant");
+ assert(k != NULL, "invariant");
+ if (event->should_commit()) {
+ event->set_loadedClass(k);
+ event->set_definingClassLoader(k->class_loader_data());
+ event->set_initiatingClassLoader(init_cld);
+ event->commit();
}
#endif // INCLUDE_TRACE
}
@@ -653,7 +649,7 @@
assert(name != NULL && !FieldType::is_array(name) &&
!FieldType::is_obj(name), "invalid class name");
- Ticks class_load_start_time = Ticks::now();
+ EventClassLoad class_load_start_event;
HandleMark hm(THREAD);
@@ -899,7 +895,7 @@
return NULL;
}
- post_class_load_event(class_load_start_time, k, loader_data);
+ post_class_load_event(&class_load_start_event, k, loader_data);
#ifdef ASSERT
{
@@ -1006,7 +1002,7 @@
GrowableArray<Handle>* cp_patches,
TRAPS) {
- Ticks class_load_start_time = Ticks::now();
+ EventClassLoad class_load_start_event;
ClassLoaderData* loader_data;
if (host_klass != NULL) {
@@ -1064,7 +1060,7 @@
JvmtiExport::post_class_load((JavaThread *) THREAD, k);
}
- post_class_load_event(class_load_start_time, k, loader_data);
+ post_class_load_event(&class_load_start_event, k, loader_data);
}
assert(host_klass != NULL || NULL == cp_patches,
"cp_patches only found with host_klass");
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -720,44 +720,49 @@
// At this point it may be possible that no osthread was created for the
// JavaThread due to lack of memory. We would have to throw an exception
// in that case. However, since this must work and we do not allow
- // exceptions anyway, check and abort if this fails.
+ // exceptions anyway, check and abort if this fails. But first release the
+ // lock.
- if (thread == NULL || thread->osthread() == NULL) {
- vm_exit_during_initialization("java.lang.OutOfMemoryError",
- os::native_thread_creation_failed_msg());
- }
+ if (thread != NULL && thread->osthread() != NULL) {
+
+ java_lang_Thread::set_thread(thread_oop(), thread);
- java_lang_Thread::set_thread(thread_oop(), thread);
+ // Note that this only sets the JavaThread _priority field, which by
+ // definition is limited to Java priorities and not OS priorities.
+ // The os-priority is set in the CompilerThread startup code itself
- // Note that this only sets the JavaThread _priority field, which by
- // definition is limited to Java priorities and not OS priorities.
- // The os-priority is set in the CompilerThread startup code itself
+ java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
- java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
+ // Note that we cannot call os::set_priority because it expects Java
+ // priorities and we are *explicitly* using OS priorities so that it's
+ // possible to set the compiler thread priority higher than any Java
+ // thread.
- // Note that we cannot call os::set_priority because it expects Java
- // priorities and we are *explicitly* using OS priorities so that it's
- // possible to set the compiler thread priority higher than any Java
- // thread.
-
- int native_prio = CompilerThreadPriority;
- if (native_prio == -1) {
- if (UseCriticalCompilerThreadPriority) {
- native_prio = os::java_to_os_priority[CriticalPriority];
- } else {
- native_prio = os::java_to_os_priority[NearMaxPriority];
+ int native_prio = CompilerThreadPriority;
+ if (native_prio == -1) {
+ if (UseCriticalCompilerThreadPriority) {
+ native_prio = os::java_to_os_priority[CriticalPriority];
+ } else {
+ native_prio = os::java_to_os_priority[NearMaxPriority];
+ }
}
- }
- os::set_native_priority(thread, native_prio);
+ os::set_native_priority(thread, native_prio);
- java_lang_Thread::set_daemon(thread_oop());
+ java_lang_Thread::set_daemon(thread_oop());
- thread->set_threadObj(thread_oop());
- if (compiler_thread) {
- thread->as_CompilerThread()->set_compiler(comp);
+ thread->set_threadObj(thread_oop());
+ if (compiler_thread) {
+ thread->as_CompilerThread()->set_compiler(comp);
+ }
+ Threads::add(thread);
+ Thread::start(thread);
}
- Threads::add(thread);
- Thread::start(thread);
+ }
+
+ // First release lock before aborting VM.
+ if (thread == NULL || thread->osthread() == NULL) {
+ vm_exit_during_initialization("java.lang.OutOfMemoryError",
+ os::native_thread_creation_failed_msg());
}
// Let go of Threads_lock before yielding
--- a/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CardLiveData.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -409,7 +409,7 @@
virtual void work(uint worker_id) {
while (true) {
- size_t to_process = Atomic::add(1, &_cur_chunk) - 1;
+ size_t to_process = Atomic::add(1u, &_cur_chunk) - 1;
if (to_process >= _num_chunks) {
break;
}
--- a/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1ConcurrentMark.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -200,7 +200,7 @@
return NULL;
}
- size_t cur_idx = Atomic::add(1, &_hwm) - 1;
+ size_t cur_idx = Atomic::add(1u, &_hwm) - 1;
if (cur_idx >= _chunk_capacity) {
return NULL;
}
--- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 +64,7 @@
return card_ptr;
}
// Otherwise, the card is hot.
- size_t index = Atomic::add(1, &_hot_cache_idx) - 1;
+ size_t index = Atomic::add(1u, &_hot_cache_idx) - 1;
size_t masked_index = index & (_hot_cache_size - 1);
jbyte* current_ptr = _hot_cache[masked_index];
--- a/hotspot/src/share/vm/gc/g1/g1HotCardCache.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1HotCardCache.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@
size_t _hot_cache_size;
- int _hot_cache_par_chunk_size;
+ size_t _hot_cache_par_chunk_size;
// Avoids false sharing when concurrently updating _hot_cache_idx or
// _hot_cache_par_claimed_idx. These are never updated at the same time
--- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -243,7 +243,7 @@
bool marked_as_dirty = Atomic::cmpxchg(Dirty, &_in_dirty_region_buffer[region], Clean) == Clean;
if (marked_as_dirty) {
- size_t allocated = Atomic::add(1, &_cur_dirty_region) - 1;
+ size_t allocated = Atomic::add(1u, &_cur_dirty_region) - 1;
_dirty_region_buffer[allocated] = region;
}
}
--- a/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/gc/shared/vmGCOperations.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/vmGCOperations.hpp"
+#include "interpreter/oopMapCache.hpp"
#include "logging/log.hpp"
#include "memory/oopFactory.hpp"
#include "runtime/handles.inline.hpp"
@@ -111,6 +112,9 @@
void VM_GC_Operation::doit_epilogue() {
assert(Thread::current()->is_Java_thread(), "just checking");
+ // Clean up old interpreter OopMap entries that were replaced
+ // during the GC thread root traversal.
+ OopMapCache::cleanup_old_entries();
if (Universe::has_reference_pending_list()) {
Heap_lock->notify_all();
}
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -25,6 +25,7 @@
#include "precompiled.hpp"
#include "interpreter/oopMapCache.hpp"
#include "logging/log.hpp"
+#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
@@ -37,6 +38,9 @@
friend class OopMapCache;
friend class VerifyClosure;
+ private:
+ OopMapCacheEntry* _next;
+
protected:
// Initialization
void fill(const methodHandle& method, int bci);
@@ -54,8 +58,9 @@
public:
OopMapCacheEntry() : InterpreterOopMap() {
+ _next = NULL;
#ifdef ASSERT
- _resource_allocate_bit_mask = false;
+ _resource_allocate_bit_mask = false;
#endif
}
};
@@ -263,23 +268,26 @@
// Check if map is generated correctly
// (Use ?: operator to make sure all 'true' & 'false' are represented exactly the same so we can use == afterwards)
- if (TraceOopMapGeneration && Verbose) tty->print("Locals (%d): ", max_locals);
+ Log(interpreter, oopmap) logv;
+ LogStream st(logv.trace());
+ st.print("Locals (%d): ", max_locals);
for(int i = 0; i < max_locals; i++) {
bool v1 = is_oop(i) ? true : false;
bool v2 = vars[i].is_reference() ? true : false;
assert(v1 == v2, "locals oop mask generation error");
- if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0);
+ st.print("%d", v1 ? 1 : 0);
}
+ st.cr();
- if (TraceOopMapGeneration && Verbose) { tty->cr(); tty->print("Stack (%d): ", stack_top); }
+ st.print("Stack (%d): ", stack_top);
for(int j = 0; j < stack_top; j++) {
bool v1 = is_oop(max_locals + j) ? true : false;
bool v2 = stack[j].is_reference() ? true : false;
assert(v1 == v2, "stack oop mask generation error");
- if (TraceOopMapGeneration && Verbose) tty->print("%d", v1 ? 1 : 0);
+ st.print("%d", v1 ? 1 : 0);
}
- if (TraceOopMapGeneration && Verbose) tty->cr();
+ st.cr();
return true;
}
@@ -373,8 +381,6 @@
// verify bit mask
assert(verify_mask(vars, stack, max_locals, stack_top), "mask could not be verified");
-
-
}
void OopMapCacheEntry::flush() {
@@ -385,16 +391,6 @@
// Implementation of OopMapCache
-#ifndef PRODUCT
-
-static long _total_memory_usage = 0;
-
-long OopMapCache::memory_usage() {
- return _total_memory_usage;
-}
-
-#endif
-
void InterpreterOopMap::resource_copy(OopMapCacheEntry* from) {
assert(_resource_allocate_bit_mask,
"Should not resource allocate the _bit_mask");
@@ -435,15 +431,11 @@
^ ((unsigned int) method->size_of_parameters() << 6);
}
+OopMapCacheEntry* volatile OopMapCache::_old_entries = NULL;
-OopMapCache::OopMapCache() :
- _mut(Mutex::leaf, "An OopMapCache lock", true)
-{
- _array = NEW_C_HEAP_ARRAY(OopMapCacheEntry, _size, mtClass);
- // Cannot call flush for initialization, since flush
- // will check if memory should be deallocated
- for(int i = 0; i < _size; i++) _array[i].initialize();
- NOT_PRODUCT(_total_memory_usage += sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);)
+OopMapCache::OopMapCache() {
+ _array = NEW_C_HEAP_ARRAY(OopMapCacheEntry*, _size, mtClass);
+ for(int i = 0; i < _size; i++) _array[i] = NULL;
}
@@ -452,112 +444,152 @@
// Deallocate oop maps that are allocated out-of-line
flush();
// Deallocate array
- NOT_PRODUCT(_total_memory_usage -= sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);)
- FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array);
+ FREE_C_HEAP_ARRAY(OopMapCacheEntry*, _array);
}
OopMapCacheEntry* OopMapCache::entry_at(int i) const {
- return &_array[i % _size];
+ return (OopMapCacheEntry*)OrderAccess::load_ptr_acquire(&(_array[i % _size]));
+}
+
+bool OopMapCache::put_at(int i, OopMapCacheEntry* entry, OopMapCacheEntry* old) {
+ return Atomic::cmpxchg_ptr (entry, &_array[i % _size], old) == old;
}
void OopMapCache::flush() {
- for (int i = 0; i < _size; i++) _array[i].flush();
+ for (int i = 0; i < _size; i++) {
+ OopMapCacheEntry* entry = _array[i];
+ if (entry != NULL) {
+ _array[i] = NULL; // no barrier, only called in OopMapCache destructor
+ entry->flush();
+ FREE_C_HEAP_OBJ(entry);
+ }
+ }
}
void OopMapCache::flush_obsolete_entries() {
- for (int i = 0; i < _size; i++)
- if (!_array[i].is_empty() && _array[i].method()->is_old()) {
+ assert(SafepointSynchronize::is_at_safepoint(), "called by RedefineClasses in a safepoint");
+ for (int i = 0; i < _size; i++) {
+ OopMapCacheEntry* entry = _array[i];
+ if (entry != NULL && !entry->is_empty() && entry->method()->is_old()) {
// Cache entry is occupied by an old redefined method and we don't want
// to pin it down so flush the entry.
if (log_is_enabled(Debug, redefine, class, oopmap)) {
ResourceMark rm;
- log_debug(redefine, class, oopmap)
+ log_debug(redefine, class, interpreter, oopmap)
("flush: %s(%s): cached entry @%d",
- _array[i].method()->name()->as_C_string(), _array[i].method()->signature()->as_C_string(), i);
+ entry->method()->name()->as_C_string(), entry->method()->signature()->as_C_string(), i);
}
- _array[i].flush();
+ _array[i] = NULL;
+ entry->flush();
+ FREE_C_HEAP_OBJ(entry);
}
+ }
}
+// Called by GC for thread root scan during a safepoint only. The other interpreted frame oopmaps
+// are generated locally and not cached.
void OopMapCache::lookup(const methodHandle& method,
int bci,
- InterpreterOopMap* entry_for) const {
- MutexLocker x(&_mut);
+ InterpreterOopMap* entry_for) {
+ assert(SafepointSynchronize::is_at_safepoint(), "called by GC in a safepoint");
+ int probe = hash_value_for(method, bci);
+ int i;
+ OopMapCacheEntry* entry = NULL;
- OopMapCacheEntry* entry = NULL;
- int probe = hash_value_for(method, bci);
+ if (log_is_enabled(Debug, interpreter, oopmap)) {
+ static int count = 0;
+ ResourceMark rm;
+ log_debug(interpreter, oopmap)
+ ("%d - Computing oopmap at bci %d for %s at hash %d", ++count, bci,
+ method()->name_and_sig_as_C_string(), probe);
+ }
// Search hashtable for match
- int i;
for(i = 0; i < _probe_depth; i++) {
entry = entry_at(probe + i);
- if (entry->match(method, bci)) {
+ if (entry != NULL && !entry->is_empty() && entry->match(method, bci)) {
entry_for->resource_copy(entry);
assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
+ log_debug(interpreter, oopmap)("- found at hash %d", probe + i);
return;
}
}
- if (TraceOopMapGeneration) {
- static int count = 0;
- ResourceMark rm;
- tty->print("%d - Computing oopmap at bci %d for ", ++count, bci);
- method->print_value(); tty->cr();
- }
+ // Entry is not in hashtable.
+ // Compute entry
- // Entry is not in hashtable.
- // Compute entry and return it
+ OopMapCacheEntry* tmp = NEW_C_HEAP_OBJ(OopMapCacheEntry, mtClass);
+ tmp->initialize();
+ tmp->fill(method, bci);
+ entry_for->resource_copy(tmp);
if (method->should_not_be_cached()) {
// It is either not safe or not a good idea to cache this Method*
// at this time. We give the caller of lookup() a copy of the
// interesting info via parameter entry_for, but we don't add it to
// the cache. See the gory details in Method*.cpp.
- compute_one_oop_map(method, bci, entry_for);
+ FREE_C_HEAP_OBJ(tmp);
return;
}
// First search for an empty slot
for(i = 0; i < _probe_depth; i++) {
- entry = entry_at(probe + i);
- if (entry->is_empty()) {
- entry->fill(method, bci);
- entry_for->resource_copy(entry);
- assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
- return;
+ entry = entry_at(probe + i);
+ if (entry == NULL) {
+ if (put_at(probe + i, tmp, NULL)) {
+ assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
+ return;
+ }
}
}
- if (TraceOopMapGeneration) {
- ResourceMark rm;
- tty->print_cr("*** collision in oopmap cache - flushing item ***");
- }
+ log_debug(interpreter, oopmap)("*** collision in oopmap cache - flushing item ***");
// No empty slot (uncommon case). Use (some approximation of a) LRU algorithm
- //entry_at(probe + _probe_depth - 1)->flush();
- //for(i = _probe_depth - 1; i > 0; i--) {
- // // Coping entry[i] = entry[i-1];
- // OopMapCacheEntry *to = entry_at(probe + i);
- // OopMapCacheEntry *from = entry_at(probe + i - 1);
- // to->copy(from);
- // }
+ // where the first entry in the collision array is replaced with the new one.
+ OopMapCacheEntry* old = entry_at(probe + 0);
+ if (put_at(probe + 0, tmp, old)) {
+ enqueue_for_cleanup(old);
+ } else {
+ enqueue_for_cleanup(tmp);
+ }
- assert(method->is_method(), "gaga");
+ assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
+ return;
+}
+
+void OopMapCache::enqueue_for_cleanup(OopMapCacheEntry* entry) {
+ bool success = false;
+ OopMapCacheEntry* head;
+ do {
+ head = _old_entries;
+ entry->_next = head;
+ success = Atomic::cmpxchg_ptr (entry, &_old_entries, head) == head;
+ } while (!success);
- entry = entry_at(probe + 0);
- entry->fill(method, bci);
-
- // Copy the newly cached entry to input parameter
- entry_for->resource_copy(entry);
+ if (log_is_enabled(Debug, interpreter, oopmap)) {
+ ResourceMark rm;
+ log_debug(interpreter, oopmap)("enqueue %s at bci %d for cleanup",
+ entry->method()->name_and_sig_as_C_string(), entry->bci());
+ }
+}
- if (TraceOopMapGeneration) {
- ResourceMark rm;
- tty->print("Done with ");
- method->print_value(); tty->cr();
+// This is called after GC threads are done and nothing is accessing the old_entries
+// list, so no synchronization needed.
+void OopMapCache::cleanup_old_entries() {
+ OopMapCacheEntry* entry = _old_entries;
+ _old_entries = NULL;
+ while (entry != NULL) {
+ if (log_is_enabled(Debug, interpreter, oopmap)) {
+ ResourceMark rm;
+ log_debug(interpreter, oopmap)("cleanup entry %s at bci %d",
+ entry->method()->name_and_sig_as_C_string(), entry->bci());
+ }
+ OopMapCacheEntry* next = entry->_next;
+ entry->flush();
+ FREE_C_HEAP_OBJ(entry);
+ entry = next;
}
- assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
-
- return;
}
void OopMapCache::compute_one_oop_map(const methodHandle& method, int bci, InterpreterOopMap* entry) {
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -144,17 +144,19 @@
};
class OopMapCache : public CHeapObj<mtClass> {
+ static OopMapCacheEntry* volatile _old_entries;
private:
enum { _size = 32, // Use fixed size for now
_probe_depth = 3 // probe depth in case of collisions
};
- OopMapCacheEntry* _array;
+ OopMapCacheEntry* volatile * _array;
unsigned int hash_value_for(const methodHandle& method, int bci) const;
OopMapCacheEntry* entry_at(int i) const;
+ bool put_at(int i, OopMapCacheEntry* entry, OopMapCacheEntry* old);
- mutable Mutex _mut;
+ static void enqueue_for_cleanup(OopMapCacheEntry* entry);
void flush();
@@ -167,13 +169,11 @@
// Returns the oopMap for (method, bci) in parameter "entry".
// Returns false if an oop map was not found.
- void lookup(const methodHandle& method, int bci, InterpreterOopMap* entry) const;
+ void lookup(const methodHandle& method, int bci, InterpreterOopMap* entry);
// Compute an oop map without updating the cache or grabbing any locks (for debugging)
static void compute_one_oop_map(const methodHandle& method, int bci, InterpreterOopMap* entry);
-
- // Returns total no. of bytes allocated as part of OopMapCache's
- static long memory_usage() PRODUCT_RETURN0;
+ static void cleanup_old_entries();
};
#endif // SHARE_VM_INTERPRETER_OOPMAPCACHE_HPP
--- a/hotspot/src/share/vm/logging/logTag.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/logging/logTag.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -74,6 +74,7 @@
LOG_TAG(iklass) \
LOG_TAG(init) \
LOG_TAG(inlining) \
+ LOG_TAG(interpreter) \
LOG_TAG(itables) \
LOG_TAG(jit) \
LOG_TAG(jni) \
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1613,6 +1613,8 @@
tty->print_cr("Dumping objects to open archive heap region ...");
_open_archive_heap_regions = new GrowableArray<MemRegion>(2);
MetaspaceShared::dump_open_archive_heap_objects(_open_archive_heap_regions);
+
+ MetaspaceShared::destroy_archive_object_cache();
}
G1HeapVerifier::verify_archive_regions();
--- a/hotspot/src/share/vm/memory/metaspaceShared.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/memory/metaspaceShared.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -29,6 +29,7 @@
#include "memory/allocation.hpp"
#include "memory/memRegion.hpp"
#include "memory/virtualspace.hpp"
+#include "oops/oop.inline.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/macros.hpp"
#include "utilities/resourceHash.hpp"
@@ -96,11 +97,16 @@
return p1 == p2;
}
static unsigned obj_hash(oop const& p) {
- unsigned hash = (unsigned)((uintptr_t)&p);
- return hash ^ (hash >> LogMinObjAlignment);
+ assert(!p->mark()->has_bias_pattern(),
+ "this object should never have been locked"); // so identity_hash won't safepoin
+ unsigned hash = (unsigned)p->identity_hash();
+ return hash;
}
typedef ResourceHashtable<oop, oop,
- MetaspaceShared::obj_hash, MetaspaceShared::obj_equals> ArchivedObjectCache;
+ MetaspaceShared::obj_hash,
+ MetaspaceShared::obj_equals,
+ 15889, // prime number
+ ResourceObj::C_HEAP> ArchivedObjectCache;
static ArchivedObjectCache* _archive_object_cache;
public:
@@ -115,7 +121,10 @@
NOT_CDS_JAVA_HEAP(return false;)
}
static void create_archive_object_cache() {
- CDS_JAVA_HEAP_ONLY(_archive_object_cache = new ArchivedObjectCache(););
+ CDS_JAVA_HEAP_ONLY(_archive_object_cache = new (ResourceObj::C_HEAP, mtClass)ArchivedObjectCache(););
+ }
+ static void destroy_archive_object_cache() {
+ CDS_JAVA_HEAP_ONLY(delete _archive_object_cache; _archive_object_cache = NULL;);
}
static void fixup_mapped_heap_regions() NOT_CDS_JAVA_HEAP_RETURN;
--- a/hotspot/src/share/vm/oops/method.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/oops/method.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -214,26 +214,14 @@
}
void Method::mask_for(int bci, InterpreterOopMap* mask) {
-
- Thread* myThread = Thread::current();
- methodHandle h_this(myThread, this);
-#if defined(ASSERT) && !INCLUDE_JVMCI
- bool has_capability = myThread->is_VM_thread() ||
- myThread->is_ConcurrentGC_thread() ||
- myThread->is_GC_task_thread();
-
- if (!has_capability) {
- if (!VerifyStack && !VerifyLastFrame) {
- // verify stack calls this outside VM thread
- warning("oopmap should only be accessed by the "
- "VM, GC task or CMS threads (or during debugging)");
- InterpreterOopMap local_mask;
- method_holder()->mask_for(h_this, bci, &local_mask);
- local_mask.print();
- }
+ methodHandle h_this(Thread::current(), this);
+ // Only GC uses the OopMapCache during thread stack root scanning
+ // any other uses generate an oopmap but do not save it in the cache.
+ if (Universe::heap()->is_gc_active()) {
+ method_holder()->mask_for(h_this, bci, mask);
+ } else {
+ OopMapCache::compute_one_oop_map(h_this, bci, mask);
}
-#endif
- method_holder()->mask_for(h_this, bci, mask);
return;
}
--- a/hotspot/src/share/vm/oops/symbol.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/oops/symbol.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -219,7 +219,7 @@
void Symbol::decrement_refcount() {
if (_refcount >= 0) { // not a permanent symbol
- jshort new_value = Atomic::add(-1, &_refcount);
+ short new_value = Atomic::add(short(-1), &_refcount);
#ifdef ASSERT
if (new_value == -1) { // we have transitioned from 0 -> -1
print();
--- a/hotspot/src/share/vm/opto/c2compiler.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/opto/c2compiler.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -283,7 +283,7 @@
case vmIntrinsics::_weakCompareAndSetIntAcquire:
case vmIntrinsics::_weakCompareAndSetIntRelease:
case vmIntrinsics::_weakCompareAndSetInt:
- if (!Matcher::match_rule_supported(Op_WeakCompareAndSwapL)) return false;
+ if (!Matcher::match_rule_supported(Op_WeakCompareAndSwapI)) return false;
break;
/* CompareAndSet, Byte: */
--- a/hotspot/src/share/vm/runtime/atomic.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/atomic.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -26,11 +26,14 @@
#define SHARE_VM_RUNTIME_ATOMIC_HPP
#include "memory/allocation.hpp"
+#include "metaprogramming/conditional.hpp"
#include "metaprogramming/enableIf.hpp"
#include "metaprogramming/isIntegral.hpp"
+#include "metaprogramming/isPointer.hpp"
#include "metaprogramming/isSame.hpp"
#include "metaprogramming/primitiveConversions.hpp"
#include "metaprogramming/removeCV.hpp"
+#include "metaprogramming/removePointer.hpp"
#include "utilities/align.hpp"
#include "utilities/macros.hpp"
@@ -82,11 +85,17 @@
// Atomically add to a location. Returns updated value. add*() provide:
// <fence> add-value-to-dest <membar StoreLoad|StoreStore>
- inline static jshort add (jshort add_value, volatile jshort* dest);
- inline static jint add (jint add_value, volatile jint* dest);
- inline static size_t add (size_t add_value, volatile size_t* dest);
- inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
- inline static void* add_ptr(intptr_t add_value, volatile void* dest);
+
+ template<typename I, typename D>
+ inline static D add(I add_value, D volatile* dest);
+
+ inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest) {
+ return add(add_value, dest);
+ }
+
+ inline static void* add_ptr(intptr_t add_value, volatile void* dest) {
+ return add(add_value, reinterpret_cast<char* volatile*>(dest));
+ }
// Atomically increment location. inc*() provide:
// <fence> increment-dest <membar StoreLoad|StoreStore>
@@ -156,6 +165,74 @@
// that is needed here.
template<typename From, typename To> struct IsPointerConvertible;
+ // Dispatch handler for add. Provides type-based validity checking
+ // and limited conversions around calls to the platform-specific
+ // implementation layer provided by PlatformAdd.
+ template<typename I, typename D, typename Enable = void>
+ struct AddImpl;
+
+ // Platform-specific implementation of add. Support for sizes of 4
+ // bytes and (if different) pointer size bytes are required. The
+ // class is a function object that must be default constructable,
+ // with these requirements:
+ //
+ // - dest is of type D*, an integral or pointer type.
+ // - add_value is of type I, an integral type.
+ // - sizeof(I) == sizeof(D).
+ // - if D is an integral type, I == D.
+ // - platform_add is an object of type PlatformAdd<sizeof(D)>.
+ //
+ // Then
+ // platform_add(add_value, dest)
+ // must be a valid expression, returning a result convertible to D.
+ //
+ // No definition is provided; all platforms must explicitly define
+ // this class and any needed specializations.
+ template<size_t byte_size> struct PlatformAdd;
+
+ // Helper base classes for defining PlatformAdd. To use, define
+ // PlatformAdd or a specialization that derives from one of these,
+ // and include in the PlatformAdd definition the support function
+ // (described below) required by the base class.
+ //
+ // These classes implement the required function object protocol for
+ // PlatformAdd, using a support function template provided by the
+ // derived class. Let add_value (of type I) and dest (of type D) be
+ // the arguments the object is called with. If D is a pointer type
+ // P*, then let addend (of type I) be add_value * sizeof(P);
+ // otherwise, addend is add_value.
+ //
+ // FetchAndAdd requires the derived class to provide
+ // fetch_and_add(addend, dest)
+ // atomically adding addend to the value of dest, and returning the
+ // old value.
+ //
+ // AddAndFetch requires the derived class to provide
+ // add_and_fetch(addend, dest)
+ // atomically adding addend to the value of dest, and returning the
+ // new value.
+ //
+ // When D is a pointer type P*, both fetch_and_add and add_and_fetch
+ // treat it as if it were a uintptr_t; they do not perform any
+ // scaling of the addend, as that has already been done by the
+ // caller.
+public: // Temporary, can't be private: C++03 11.4/2. Fixed by C++11.
+ template<typename Derived> struct FetchAndAdd;
+ template<typename Derived> struct AddAndFetch;
+private:
+
+ // Support for platforms that implement some variants of add using a
+ // (typically out of line) non-template helper function. The
+ // generic arguments passed to PlatformAdd need to be translated to
+ // the appropriate type for the helper function, the helper function
+ // invoked on the translated arguments, and the result translated
+ // back. Type is the parameter / return type of the helper
+ // function. No scaling of add_value is performed when D is a pointer
+ // type, so this function can be used to implement the support function
+ // required by AddAndFetch.
+ template<typename Type, typename Fn, typename I, typename D>
+ static D add_using_helper(Fn fn, I add_value, D volatile* dest);
+
// Dispatch handler for cmpxchg. Provides type-based validity
// checking and limited conversions around calls to the
// platform-specific implementation layer provided by
@@ -219,6 +296,22 @@
static const bool value = (sizeof(yes) == sizeof(test(test_value)));
};
+// Define FetchAndAdd and AddAndFetch helper classes before including
+// platform file, which may use these as base classes, requiring they
+// be complete.
+
+template<typename Derived>
+struct Atomic::FetchAndAdd VALUE_OBJ_CLASS_SPEC {
+ template<typename I, typename D>
+ D operator()(I add_value, D volatile* dest) const;
+};
+
+template<typename Derived>
+struct Atomic::AddAndFetch VALUE_OBJ_CLASS_SPEC {
+ template<typename I, typename D>
+ D operator()(I add_value, D volatile* dest) const;
+};
+
// Define the class before including platform file, which may specialize
// the operator definition. No generic definition of specializations
// of the operator template are provided, nor are there any generic
@@ -255,8 +348,93 @@
#error size_t is not WORD_SIZE, interesting platform, but missing implementation here
#endif
-inline size_t Atomic::add(size_t add_value, volatile size_t* dest) {
- return (size_t) add_ptr((intptr_t) add_value, (volatile intptr_t*) dest);
+template<typename I, typename D>
+inline D Atomic::add(I add_value, D volatile* dest) {
+ return AddImpl<I, D>()(add_value, dest);
+}
+
+template<typename I, typename D>
+struct Atomic::AddImpl<
+ I, D,
+ typename EnableIf<IsIntegral<I>::value &&
+ IsIntegral<D>::value &&
+ (sizeof(I) <= sizeof(D)) &&
+ (IsSigned<I>::value == IsSigned<D>::value)>::type>
+ VALUE_OBJ_CLASS_SPEC
+{
+ D operator()(I add_value, D volatile* dest) const {
+ D addend = add_value;
+ return PlatformAdd<sizeof(D)>()(addend, dest);
+ }
+};
+
+template<typename I, typename P>
+struct Atomic::AddImpl<
+ I, P*,
+ typename EnableIf<IsIntegral<I>::value && (sizeof(I) <= sizeof(P*))>::type>
+ VALUE_OBJ_CLASS_SPEC
+{
+ P* operator()(I add_value, P* volatile* dest) const {
+ STATIC_ASSERT(sizeof(intptr_t) == sizeof(P*));
+ STATIC_ASSERT(sizeof(uintptr_t) == sizeof(P*));
+ typedef typename Conditional<IsSigned<I>::value,
+ intptr_t,
+ uintptr_t>::type CI;
+ CI addend = add_value;
+ return PlatformAdd<sizeof(P*)>()(addend, dest);
+ }
+};
+
+// Most platforms do not support atomic add on a 2-byte value. However,
+// if the value occupies the most significant 16 bits of an aligned 32-bit
+// word, then we can do this with an atomic add of (add_value << 16)
+// to the 32-bit word.
+//
+// The least significant parts of this 32-bit word will never be affected, even
+// in case of overflow/underflow.
+//
+// Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
+template<>
+struct Atomic::AddImpl<jshort, jshort> VALUE_OBJ_CLASS_SPEC {
+ jshort operator()(jshort add_value, jshort volatile* dest) const {
+#ifdef VM_LITTLE_ENDIAN
+ assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
+ jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
+#else
+ assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
+ jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
+#endif
+ return (jshort)(new_value >> 16); // preserves sign
+ }
+};
+
+template<typename Derived>
+template<typename I, typename D>
+inline D Atomic::FetchAndAdd<Derived>::operator()(I add_value, D volatile* dest) const {
+ I addend = add_value;
+ // If D is a pointer type P*, scale by sizeof(P).
+ if (IsPointer<D>::value) {
+ addend *= sizeof(typename RemovePointer<D>::type);
+ }
+ D old = static_cast<const Derived*>(this)->fetch_and_add(addend, dest);
+ return old + add_value;
+}
+
+template<typename Derived>
+template<typename I, typename D>
+inline D Atomic::AddAndFetch<Derived>::operator()(I add_value, D volatile* dest) const {
+ // If D is a pointer type P*, scale by sizeof(P).
+ if (IsPointer<D>::value) {
+ add_value *= sizeof(typename RemovePointer<D>::type);
+ }
+ return static_cast<const Derived*>(this)->add_and_fetch(add_value, dest);
+}
+
+template<typename Type, typename Fn, typename I, typename D>
+inline D Atomic::add_using_helper(Fn fn, I add_value, D volatile* dest) {
+ return PrimitiveConversions::cast<D>(
+ fn(PrimitiveConversions::cast<Type>(add_value),
+ reinterpret_cast<Type volatile*>(dest)));
}
inline void Atomic::inc(volatile size_t* dest) {
@@ -413,32 +591,12 @@
return (unsigned int)Atomic::xchg((jint)exchange_value, (volatile jint*)dest);
}
-inline jshort Atomic::add(jshort add_value, volatile jshort* dest) {
- // Most platforms do not support atomic add on a 2-byte value. However,
- // if the value occupies the most significant 16 bits of an aligned 32-bit
- // word, then we can do this with an atomic add of (add_value << 16)
- // to the 32-bit word.
- //
- // The least significant parts of this 32-bit word will never be affected, even
- // in case of overflow/underflow.
- //
- // Use the ATOMIC_SHORT_PAIR macro (see macros.hpp) to get the desired alignment.
-#ifdef VM_LITTLE_ENDIAN
- assert((intx(dest) & 0x03) == 0x02, "wrong alignment");
- jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest-1));
-#else
- assert((intx(dest) & 0x03) == 0x00, "wrong alignment");
- jint new_value = Atomic::add(add_value << 16, (volatile jint*)(dest));
-#endif
- return (jshort)(new_value >> 16); // preserves sign
-}
-
inline void Atomic::inc(volatile jshort* dest) {
- (void)add(1, dest);
+ (void)add(jshort(1), dest);
}
inline void Atomic::dec(volatile jshort* dest) {
- (void)add(-1, dest);
+ (void)add(jshort(-1), dest);
}
#endif // SHARE_VM_RUNTIME_ATOMIC_HPP
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1373,6 +1373,30 @@
}
+#if INCLUDE_JVMCI
+address Deoptimization::deoptimize_for_missing_exception_handler(CompiledMethod* cm) {
+ // there is no exception handler for this pc => deoptimize
+ cm->make_not_entrant();
+
+ // Use Deoptimization::deoptimize for all of its side-effects:
+ // revoking biases of monitors, gathering traps statistics, logging...
+ // it also patches the return pc but we do not care about that
+ // since we return a continuation to the deopt_blob below.
+ JavaThread* thread = JavaThread::current();
+ RegisterMap reg_map(thread, UseBiasedLocking);
+ frame runtime_frame = thread->last_frame();
+ frame caller_frame = runtime_frame.sender(®_map);
+ assert(caller_frame.cb()->as_nmethod_or_null() == cm, "expect top frame nmethod");
+ Deoptimization::deoptimize(thread, caller_frame, ®_map, Deoptimization::Reason_not_compiled_exception_handler);
+
+ MethodData* trap_mdo = get_method_data(thread, cm->method(), true);
+ if (trap_mdo != NULL) {
+ trap_mdo->inc_trap_count(Deoptimization::Reason_not_compiled_exception_handler);
+ }
+
+ return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+}
+#endif
void Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id, DeoptReason reason) {
assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(),
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -136,6 +136,10 @@
static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map);
static void deoptimize(JavaThread* thread, frame fr, RegisterMap *reg_map, DeoptReason reason);
+#if INCLUDE_JVMCI
+ static address deoptimize_for_missing_exception_handler(CompiledMethod* cm);
+#endif
+
private:
// Does the actual work for deoptimizing a single frame
static void deoptimize_single_frame(JavaThread* thread, frame fr, DeoptReason reason);
--- a/hotspot/src/share/vm/runtime/globals.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/globals.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -715,9 +715,6 @@
product(bool, PrintVMQWaitTime, false, \
"Print out the waiting time in VM operation queue") \
\
- develop(bool, TraceOopMapGeneration, false, \
- "Show OopMapGeneration") \
- \
product(bool, MethodFlushing, true, \
"Reclamation of zombie and not-entrant methods") \
\
--- a/hotspot/src/share/vm/runtime/memprofiler.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/memprofiler.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -129,7 +129,7 @@
fprintf(_log_fp, UINTX_FORMAT_W(6) "," UINTX_FORMAT_W(6) ",%6ld\n",
handles_memory_usage / K,
resource_memory_usage / K,
- OopMapCache::memory_usage() / K);
+ 0L);
fflush(_log_fp);
}
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -638,20 +638,7 @@
if (t != NULL) {
return cm->code_begin() + t->pco();
} else {
- // there is no exception handler for this pc => deoptimize
- cm->make_not_entrant();
-
- // Use Deoptimization::deoptimize for all of its side-effects:
- // revoking biases of monitors, gathering traps statistics, logging...
- // it also patches the return pc but we do not care about that
- // since we return a continuation to the deopt_blob below.
- JavaThread* thread = JavaThread::current();
- RegisterMap reg_map(thread, UseBiasedLocking);
- frame runtime_frame = thread->last_frame();
- frame caller_frame = runtime_frame.sender(®_map);
- Deoptimization::deoptimize(thread, caller_frame, ®_map, Deoptimization::Reason_not_compiled_exception_handler);
-
- return SharedRuntime::deopt_blob()->unpack_with_exception_in_tls();
+ return Deoptimization::deoptimize_for_missing_exception_handler(cm);
}
}
#endif // INCLUDE_JVMCI
--- a/hotspot/src/share/vm/runtime/synchronizer.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/synchronizer.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -1407,7 +1407,6 @@
assert(inf->header()->is_neutral(), "invariant");
assert(inf->object() == object, "invariant");
assert(ObjectSynchronizer::verify_objmon_isinpool(inf), "monitor is invalid");
- event.cancel(); // let's not post an inflation event, unless we did the deed ourselves
return inf;
}
--- a/hotspot/src/share/vm/runtime/vframe.cpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/runtime/vframe.cpp Tue Aug 29 17:17:58 2017 +0200
@@ -396,14 +396,7 @@
StackValueCollection* interpretedVFrame::stack_data(bool expressions) const {
InterpreterOopMap oop_mask;
- // oopmap for current bci
- if ((TraceDeoptimization && Verbose) JVMCI_ONLY( || PrintDeoptimizationDetails)) {
- methodHandle m_h(Thread::current(), method());
- OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask);
- } else {
- method()->mask_for(bci(), &oop_mask);
- }
-
+ method()->mask_for(bci(), &oop_mask);
const int mask_len = oop_mask.number_of_entries();
// If the method is native, method()->max_locals() is not telling the truth.
--- a/hotspot/src/share/vm/services/mallocTracker.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/services/mallocTracker.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -53,7 +53,7 @@
}
inline void allocate(size_t sz) {
- Atomic::add(1, &_count);
+ Atomic::inc(&_count);
if (sz > 0) {
Atomic::add(sz, &_size);
DEBUG_ONLY(_peak_size = MAX2(_peak_size, _size));
@@ -64,7 +64,7 @@
inline void deallocate(size_t sz) {
assert(_count > 0, "Nothing allocated yet");
assert(_size >= sz, "deallocation > allocated");
- Atomic::add(-1, &_count);
+ Atomic::dec(&_count);
if (sz > 0) {
// unary minus operator applied to unsigned type, result still unsigned
#pragma warning(suppress: 4146)
@@ -74,7 +74,7 @@
inline void resize(long sz) {
if (sz != 0) {
- Atomic::add(sz, &_size);
+ Atomic::add(size_t(sz), &_size);
DEBUG_ONLY(_peak_size = MAX2(_size, _peak_size);)
}
}
--- a/hotspot/src/share/vm/trace/traceDataTypes.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/trace/traceDataTypes.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
#include <stddef.h>
#include "utilities/globalDefinitions.hpp"
+#include "utilities/ticks.hpp"
enum {
CONTENT_TYPE_NONE = 0,
@@ -54,10 +55,11 @@
NUM_RESERVED_EVENTS = JVM_CONTENT_TYPES_END
};
-typedef enum ReservedEvent ReservedEvent;
-
typedef u8 traceid;
+class ClassLoaderData;
+class Klass;
+class Method;
class ModuleEntry;
class PackageEntry;
class Symbol;
--- a/hotspot/src/share/vm/trace/traceEvent.hpp Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/trace/traceEvent.hpp Tue Aug 29 17:17:58 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
#ifndef SHARE_VM_TRACE_TRACEEVENT_HPP
#define SHARE_VM_TRACE_TRACEEVENT_HPP
+#include "trace/traceTime.hpp"
#include "utilities/macros.hpp"
enum EventStartTime {
@@ -34,25 +35,18 @@
#if INCLUDE_TRACE
#include "trace/traceBackend.hpp"
-#include "trace/tracing.hpp"
#include "tracefiles/traceEventIds.hpp"
-#include "tracefiles/traceTypes.hpp"
#include "utilities/ticks.hpp"
template<typename T>
-class TraceEvent : public StackObj {
+class TraceEvent {
private:
bool _started;
-#ifdef ASSERT
- bool _committed;
- bool _cancelled;
- protected:
- bool _ignore_check;
-#endif
protected:
jlong _startTime;
jlong _endTime;
+ DEBUG_ONLY(bool _committed;)
void set_starttime(const TracingTime& time) {
_startTime = time;
@@ -67,10 +61,7 @@
_endTime(0),
_started(false)
#ifdef ASSERT
- ,
- _committed(false),
- _cancelled(false),
- _ignore_check(false)
+ , _committed(false)
#endif
{
if (T::is_enabled()) {
@@ -100,10 +91,9 @@
void commit() {
if (!should_commit()) {
- DEBUG_ONLY(cancel());
return;
}
- assert(!_cancelled, "Committing an event that has already been cancelled");
+ assert(!_committed, "event already committed");
if (_startTime == 0) {
static_cast<T*>(this)->set_starttime(Tracing::time());
} else if (_endTime == 0) {
@@ -111,8 +101,8 @@
}
if (static_cast<T*>(this)->should_write()) {
static_cast<T*>(this)->writeEvent();
+ DEBUG_ONLY(_committed = true;)
}
- DEBUG_ONLY(set_commited());
}
static TraceEventId id() {
@@ -134,32 +124,6 @@
static bool has_stacktrace() {
return T::hasStackTrace;
}
-
- void cancel() {
- assert(!_committed && !_cancelled,
- "event was already committed/cancelled");
- DEBUG_ONLY(_cancelled = true);
- }
-
- ~TraceEvent() {
- if (_started) {
- assert(_ignore_check || _committed || _cancelled,
- "event was not committed/cancelled");
- }
- }
-
-#ifdef ASSERT
- protected:
- void ignoreCheck() {
- _ignore_check = true;
- }
-
- private:
- void set_commited() {
- assert(!_committed, "event has already been committed");
- _committed = true;
- }
-#endif // ASSERT
};
#endif // INCLUDE_TRACE
--- a/hotspot/src/share/vm/trace/traceEventClasses.xsl Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/trace/traceEventClasses.xsl Tue Aug 29 17:17:58 2017 +0200
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -37,10 +37,10 @@
// INCLUDE_TRACE
#include "tracefiles/traceTypes.hpp"
+#include "utilities/macros.hpp"
+
+#if INCLUDE_TRACE
#include "trace/traceEvent.hpp"
-#include "utilities/macros.hpp"
-#include "utilities/ticks.hpp"
-#if INCLUDE_TRACE
#include "trace/traceStream.hpp"
#include "utilities/ostream.hpp"
@@ -57,7 +57,6 @@
bool should_commit() const { return false; }
static bool is_enabled() { return false; }
void commit() {}
- void cancel() {}
};
<xsl:apply-templates select="trace/events/struct" mode="empty"/>
--- a/hotspot/src/share/vm/trace/traceTypes.xsl Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/src/share/vm/trace/traceTypes.xsl Tue Aug 29 17:17:58 2017 +0200
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,7 @@
#ifndef TRACEFILES_TRACETYPES_HPP
#define TRACEFILES_TRACETYPES_HPP
-#include "oops/symbol.hpp"
#include "trace/traceDataTypes.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/ticks.hpp"
enum JVMContentType {
_not_a_content_type = (JVM_CONTENT_TYPES_START - 1),
--- a/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/JVM_GetJVMCIRuntimeTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -30,21 +30,21 @@
* @modules jdk.internal.vm.ci/jdk.vm.ci.runtime
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=true
- * -XX:+EnableJVMCI -Djvmci.Compiler=null
+ * -XX:+EnableJVMCI
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false
- * -XX:-EnableJVMCI
+ * -XX:-EnableJVMCI -XX:-UseJVMCICompiler
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=true
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.threaded=true
- * -XX:+EnableJVMCI -Djvmci.Compiler=null
+ * -XX:+EnableJVMCI
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.positive=false
* -Dcompiler.jvmci.JVM_GetJVMCIRuntimeTest.threaded=true
- * -XX:-EnableJVMCI
+ * -XX:-EnableJVMCI -XX:-UseJVMCICompiler
* compiler.jvmci.JVM_GetJVMCIRuntimeTest
*/
--- a/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/SecurityRestrictionsTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -43,11 +43,11 @@
* compiler.jvmci.SecurityRestrictionsTest
* ALL_PERM
* @run main/othervm -XX:+UnlockExperimentalVMOptions
- * -XX:+EnableJVMCI
+ * -XX:+EnableJVMCI -XX:-UseJVMCICompiler
* compiler.jvmci.SecurityRestrictionsTest
* NO_JVMCI_ACCESS_PERM
* @run main/othervm -XX:+UnlockExperimentalVMOptions
- * -XX:-EnableJVMCI
+ * -XX:-EnableJVMCI -XX:-UseJVMCICompiler
* compiler.jvmci.SecurityRestrictionsTest
* NO_JVMCI
*/
--- a/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/DisassembleCodeBlobTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -61,7 +61,6 @@
= new DisassembleCodeBlobTest();
List<CompileCodeTestCase> testCases
= CompileCodeTestCase.generate(/* bci = */ -1);
- testCases.addAll(CompileCodeTestCase.generate(/* bci = */ 0));
testCases.forEach(test::check);
testCases.stream().findAny().ifPresent(test::checkZero);
test.checkNull();
--- a/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/HasCompiledCodeForOSRTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -39,7 +39,7 @@
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- * -XX:-BackgroundCompilation -Djvmci.Compiler=null
+ * -XX:-BackgroundCompilation
* compiler.jvmci.compilerToVM.HasCompiledCodeForOSRTest
*/
--- a/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -42,7 +42,6 @@
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- * -Djvmci.Compiler=null
* compiler.jvmci.compilerToVM.InvalidateInstalledCodeTest
*/
--- a/hotspot/test/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/IsMatureVsReprofileTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -24,7 +24,7 @@
/*
* @test
* @bug 8136421
- * @requires vm.jvmci
+ * @requires vm.jvmci & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4)
* @library / /test/lib
* ../common/patches
* @modules java.base/jdk.internal.misc
@@ -38,7 +38,6 @@
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
* -XX:+WhiteBoxAPI -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -Xbatch
- * -Djvmci.Compiler=null
* compiler.jvmci.compilerToVM.IsMatureVsReprofileTest
*/
--- a/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/JVM_RegisterJVMCINatives.java Tue Aug 29 17:17:58 2017 +0200
@@ -35,9 +35,8 @@
* compiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives
* @run main/othervm -XX:+UnlockExperimentalVMOptions
* -Dcompiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives.positive=false
- * -XX:-EnableJVMCI
+ * -XX:-EnableJVMCI -XX:-UseJVMCICompiler
* compiler.jvmci.compilerToVM.JVM_RegisterJVMCINatives
-
*/
package compiler.jvmci.compilerToVM;
--- a/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -49,7 +49,6 @@
* -XX:+DoEscapeAnalysis -XX:-UseCounterDecay
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=true
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=false
- * -Djvmci.Compiler=null
* compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
* @run main/othervm -Xmixed -Xbatch -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
@@ -61,7 +60,6 @@
* -XX:+DoEscapeAnalysis -XX:-UseCounterDecay
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=false
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=false
- * -Djvmci.Compiler=null
* compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
* @run main/othervm -Xmixed -Xbatch -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
@@ -73,7 +71,6 @@
* -XX:+DoEscapeAnalysis -XX:-UseCounterDecay
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=true
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=true
- * -Djvmci.Compiler=null
* compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
* @run main/othervm -Xmixed -Xbatch -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
@@ -85,7 +82,6 @@
* -XX:+DoEscapeAnalysis -XX:-UseCounterDecay
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.materializeFirst=false
* -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=true
- * -Djvmci.Compiler=null
* compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
*/
--- a/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/compilerToVM/ReprofileTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -24,7 +24,7 @@
/**
* @test
* @bug 8136421
- * @requires vm.jvmci & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 3)
+ * @requires vm.jvmci & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4)
* @library /test/lib /
* @library ../common/patches
* @modules java.base/jdk.internal.misc
@@ -40,7 +40,7 @@
* @run main/othervm -Xbootclasspath/a:.
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- * -Xmixed -Xbatch -Djvmci.Compiler=null
+ * -Xmixed -Xbatch
* compiler.jvmci.compilerToVM.ReprofileTest
*/
--- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java Mon Aug 28 21:46:13 2017 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java Tue Aug 29 17:17:58 2017 +0200
@@ -74,7 +74,7 @@
"Unexpected exit code with -EnableJVMCI",
"Unexpected output with -EnableJVMCI", ExitCode.OK,
addTestVMOptions, "-XX:+UnlockExperimentalVMOptions",
- "-XX:-EnableJVMCI", "-Xbootclasspath/a:.",
+ "-XX:-EnableJVMCI", "-XX:-UseJVMCICompiler", "-Xbootclasspath/a:.",
JvmciShutdownEventListener.class.getName()
);
}