# HG changeset patch # User eosterlund # Date 1418316699 0 # Thu Dec 11 16:51:39 2014 +0000 # Node ID bd6276c99ece15499063965ee7269ca59942c451 # Parent bdf65c8bc1a91f5ba02c43e2c62be461ffe370f0 Improved metaprogramming diff --git a/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/src/cpu/x86/vm/stubGenerator_x86_64.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -568,8 +568,8 @@ return start; } - // Support for jint atomic::atomic_cmpxchg(jint exchange_value, volatile jint* dest, - // jint compare_value) + // Support for jint atomic::cmpxchg(jint exchange_value, volatile jint* dest, + // jint compare_value) // // Arguments : // c_rarg0: exchange_value @@ -594,8 +594,8 @@ return start; } - // Support for jbyte atomic::atomic_cmpxchg(jbyte exchange_value, volatile jbyte* dest, - // jbyte compare_value) + // Support for jbyte atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, + // jbyte compare_value) // // Arguments : // c_rarg0: exchange_value @@ -620,9 +620,8 @@ return start; } - // Support for jlong atomic::atomic_cmpxchg(jlong exchange_value, - // volatile jlong* dest, - // jlong compare_value) + // Support for jlong atomic::cmpxchg(jlong exchange_value, volatile jlong* dest, + // jlong compare_value) // Arguments : // c_rarg0: exchange_value // c_rarg1: dest diff --git a/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp b/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp new file mode 100644 --- /dev/null +++ b/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP +#define OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP + +class AtomicPlatform : public AtomicBase { + public: + inline static jbyte cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value); +}; + +#endif // OS_CPU_BSD_X86_VM_ATOMIC_BSD_X86_HPP + diff --git a/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp b/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp --- a/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp +++ b/src/os_cpu/bsd_x86/vm/atomic_bsd_x86.inline.hpp @@ -88,8 +88,7 @@ return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); } -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { +inline jbyte AtomicPlatform::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { int mp = os::is_MP(); __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" : "=a" (exchange_value) @@ -98,7 +97,7 @@ return exchange_value; } -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { int mp = os::is_MP(); __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" : "=a" (exchange_value) diff --git a/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp b/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp new file mode 100644 --- /dev/null +++ b/src/os_cpu/linux_x86/vm/atomic_linux_x86.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP +#define OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP + +class AtomicPlatform : public AtomicBase { + public: + inline static jbyte cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value); +}; + +#endif // OS_CPU_LINUX_X86_VM_ATOMIC_LINUX_X86_HPP + diff --git a/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp b/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp --- a/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp +++ b/src/os_cpu/linux_x86/vm/atomic_linux_x86.inline.hpp @@ -84,12 +84,11 @@ return exchange_value; } -inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { +inline void* Atomic::xchg_ptr (void* exchange_value, volatile void* dest) { return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); } -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { +inline jbyte AtomicPlatform::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { int mp = os::is_MP(); __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgb %1,(%3)" : "=a" (exchange_value) @@ -98,7 +97,7 @@ return exchange_value; } -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { int mp = os::is_MP(); __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)" : "=a" (exchange_value) diff --git a/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp b/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp new file mode 100644 --- /dev/null +++ b/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP +#define OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP + +class AtomicPlatform : public AtomicBase { + public: + inline static jbyte cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value); +}; + +#endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP + diff --git a/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp b/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp --- a/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp +++ b/src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp @@ -84,16 +84,15 @@ return _Atomic_xchg(exchange_value, dest); } -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { +inline jbyte AtomicPlatform::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { return _Atomic_cmpxchg_byte(exchange_value, dest, compare_value IS_MP_ARG()); } -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { return _Atomic_cmpxchg(exchange_value, dest, compare_value IS_MP_ARG()); } -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { return _Atomic_cmpxchg_long(exchange_value, dest, compare_value IS_MP_ARG()); } diff --git a/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp b/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp new file mode 100644 --- /dev/null +++ b/src/os_cpu/windows_x86/vm/atomic_windows_x86.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP +#define OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP + +class AtomicPlatform : public AtomicBase { + public: + inline static jbyte cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value); +}; + +#endif // OS_CPU_WINDOWS_X86_VM_ATOMIC_WINDOWS_X86_HPP + diff --git a/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp b/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp --- a/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp +++ b/src/os_cpu/windows_x86/vm/atomic_windows_x86.inline.hpp @@ -119,24 +119,23 @@ return (void *)(os::atomic_xchg_ptr_func)((intptr_t)exchange_value, (volatile intptr_t*)dest); } -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value); } -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { +inline jbyte AtomicPlatform::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { return (*os::atomic_cmpxchg_byte_func)(exchange_value, dest, compare_value); } -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value); } -inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { +inline intptr_t Atomic::cmpxchg_ptr (intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { return (intptr_t)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); } -inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { +inline void* Atomic::cmpxchg_ptr (void* exchange_value, volatile void* dest, void* compare_value) { return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); } @@ -217,8 +216,7 @@ return (void*)xchg((jint)exchange_value, (volatile jint*)dest); } -#define VM_HAS_SPECIALIZED_CMPXCHG_BYTE -inline jbyte Atomic::cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { +inline jbyte AtomicPlatform::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { @@ -230,7 +228,7 @@ } } -inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { // alternative for InterlockedCompareExchange int mp = os::is_MP(); __asm { @@ -242,7 +240,7 @@ } } -inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { int mp = os::is_MP(); jint ex_lo = (jint)exchange_value; jint ex_hi = *( ((jint*)&exchange_value) + 1 ); diff --git a/src/share/vm/runtime/atomic.cpp b/src/share/vm/runtime/atomic.cpp --- a/src/share/vm/runtime/atomic.cpp +++ b/src/share/vm/runtime/atomic.cpp @@ -28,10 +28,9 @@ /* * This is the default implementation of byte-sized cmpxchg. It emulates jbyte-sized cmpxchg * in terms of jint-sized cmpxchg. Platforms may override this by defining their own inline definition - * as well as defining VM_HAS_SPECIALIZED_CMPXCHG_BYTE. This will cause the platform specific - * implementation to be used instead. + * in their AtomicPlatform class. */ -jbyte Atomic::cmpxchg_general(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { +jbyte AtomicBase::cmpxchg_general(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { assert(sizeof(jbyte) == 1, "assumption."); uintptr_t dest_addr = (uintptr_t)dest; uintptr_t offset = dest_addr % sizeof(jint); @@ -42,7 +41,7 @@ jbyte* new_val_as_bytes = (jbyte*)(&new_val); new_val_as_bytes[offset] = exchange_value; while (cur_as_bytes[offset] == compare_value) { - jint res = cmpxchg(new_val, dest_int, cur); + jint res = Atomic::cmpxchg(new_val, dest_int, cur); if (res == cur) break; cur = res; new_val = cur; diff --git a/src/share/vm/runtime/atomic.hpp b/src/share/vm/runtime/atomic.hpp --- a/src/share/vm/runtime/atomic.hpp +++ b/src/share/vm/runtime/atomic.hpp @@ -26,11 +26,42 @@ #define SHARE_VM_RUNTIME_ATOMIC_HPP #include "memory/allocation.hpp" +#include "utilities/traits/selectBaseClass.hpp" -class Atomic : AllStatic { - private: +class AtomicPlatform; + +class AtomicBase : AllStatic { + protected: static jbyte cmpxchg_general(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value); + public: + inline static jbyte cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { + return cmpxchg_general(exchange_value, dest, compare_value); + } +}; +// Linux +#ifdef TARGET_OS_ARCH_linux_x86 +# include "atomic_linux_x86.hpp" +#endif + +// Solaris +#ifdef TARGET_OS_ARCH_solaris_x86 +# include "atomic_solaris_x86.hpp" +#endif + +// Windows +#ifdef TARGET_OS_ARCH_windows_x86 +# include "atomic_windows_x86.hpp" +#endif + +// BSD +#ifdef TARGET_OS_ARCH_bsd_x86 +# include "atomic_bsd_x86.hpp" +#endif + +typedef SelectBaseClass::type AtomicSuper; + +class Atomic : public AtomicSuper { public: // Atomic operations on jlong types are not available on all 32-bit // platforms. If atomic ops on jlongs are defined here they must only diff --git a/src/share/vm/runtime/atomic.inline.hpp b/src/share/vm/runtime/atomic.inline.hpp --- a/src/share/vm/runtime/atomic.inline.hpp +++ b/src/share/vm/runtime/atomic.inline.hpp @@ -66,6 +66,7 @@ #ifdef TARGET_OS_ARCH_bsd_x86 # include "atomic_bsd_x86.inline.hpp" #endif + #ifdef TARGET_OS_ARCH_bsd_zero # include "atomic_bsd_zero.inline.hpp" #endif @@ -87,12 +88,8 @@ dec_ptr((volatile intptr_t*) dest); } -#ifndef VM_HAS_SPECIALIZED_CMPXCHG_BYTE -// See comment in atomic.cpp how to override. -inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte *dest, jbyte comparand) -{ - return cmpxchg_general(exchange_value, dest, comparand); +inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) { + return AtomicSuper::cmpxchg(exchange_value, dest, compare_value); } -#endif // VM_HAS_SPECIALIZED_CMPXCHG_BYTE #endif // SHARE_VM_RUNTIME_ATOMIC_INLINE_HPP diff --git a/src/share/vm/utilities/traits/isBaseOf.cpp b/src/share/vm/utilities/traits/isBaseOf.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/isBaseOf.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "utilities/debug.hpp" +#include "utilities/traits/isBaseOf.hpp" + +class IsBaseOfTest { + class A {}; + class B: A {}; + class C {}; + + class U; + + enum EnumType {}; + union UnionType {}; + typedef int PrimitiveType; + typedef int *PointerType; + + // A few tests that define the contract + static void test() { + STATIC_ASSERT((IsBaseOf::value)); + STATIC_ASSERT((IsBaseOf::value)); + STATIC_ASSERT((IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((IsBaseOf::value)); + STATIC_ASSERT((IsBaseOf::value)); + STATIC_ASSERT((IsBaseOf::value)); + STATIC_ASSERT((IsBaseOf::value)); + + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + STATIC_ASSERT((!IsBaseOf::value)); + + // The behaviour below is subject to change, when compiler compatibility is better + STATIC_ASSERT((IsBaseOf::value)); + } +}; + +class IsBaseOfAndDerivedTest { + class A {}; + class B: A {}; + class C {}; + + class U; + + enum EnumType {}; + union UnionType {}; + typedef int PrimitiveType; + typedef int *PointerType; + + // A few tests that define the contract + void test() { + STATIC_ASSERT((IsBaseOfAndDerived::value)); + STATIC_ASSERT((IsBaseOfAndDerived::value)); + STATIC_ASSERT((IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + STATIC_ASSERT((!IsBaseOfAndDerived::value)); + } +}; + diff --git a/src/share/vm/utilities/traits/isBaseOf.hpp b/src/share/vm/utilities/traits/isBaseOf.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/isBaseOf.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TRAITS_IS_BASE_OF_HPP +#define SHARE_VM_UTILITIES_TRAITS_IS_BASE_OF_HPP + +#include "utilities/traits/isClassOrUnion.hpp" +#include "utilities/traits/isSame.hpp" +#include "utilities/traits/removeCv.hpp" + +/** + * IsBaseOfAndDerived::value is true if Derived is a derived class of Base, disgarding their CV qualifiers. + * Returns false for non-class types. + */ +template +class IsBaseOfAndDerived { + typedef char yes[1]; + typedef char no[2]; + + template + static yes &check(Derived*, T); + static no &check(Base*, int); + + template + struct IsBaseOfHost { + operator B*() const; + operator D*(); + }; + + template + struct IsBaseOfAndDerivedInternal { + static const bool value = sizeof(check(IsBaseOfHost(), int())) == sizeof(yes); + }; + +public: + static const bool value = IsClassOrUnion::value && + IsBaseOfAndDerivedInternal::type, typename RemoveCv::type>::value && + !IsSame::type, typename RemoveCv::type>::value; +}; + +/** + * IsBaseOf::value is true if either Derived is a derived class of Base + * disregarding CV qualifiers or Derived and Base are the same type disregarding CV qualifiers. + * Returns false for all non-class types. + * Note: It can currently return true for unions, but that behaviour + * is subject to change when compiler compatibility for detecting unions is better, and hence + * that behaviour should not be relied upon. + */ +template +class IsBaseOf { +public: + static const bool value = (IsBaseOfAndDerived::value || + IsSame::type, typename RemoveCv::type>::value) && + IsClassOrUnion::value; +}; + +#endif // SHARE_VM_UTILITIES_TRAITS_IS_BASE_OF_HPP + diff --git a/src/share/vm/utilities/traits/isClassOrUnion.cpp b/src/share/vm/utilities/traits/isClassOrUnion.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/isClassOrUnion.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "utilities/debug.hpp" +#include "utilities/traits/isClassOrUnion.hpp" + +class IsClassOrUnionTest { + enum EnumType {}; + union UnionType {}; + class ClassType {}; + struct StructType {}; + typedef int PrimitiveType; + typedef void *PointerType; + + static void test() { + STATIC_ASSERT(IsClassOrUnion::value); + STATIC_ASSERT(IsClassOrUnion::value); + STATIC_ASSERT(IsClassOrUnion::value); + STATIC_ASSERT(!IsClassOrUnion::value); + STATIC_ASSERT(!IsClassOrUnion::value); + STATIC_ASSERT(!IsClassOrUnion::value); + } +}; + diff --git a/src/share/vm/utilities/traits/isClassOrUnion.hpp b/src/share/vm/utilities/traits/isClassOrUnion.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/isClassOrUnion.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TRAITS_IS_CLASS_OR_UNION_HPP +#define SHARE_VM_UTILITIES_TRAITS_IS_CLASS_OR_UNION_HPP + +/** + * IsClassOrUnion::value is true iff the type T is a class or union type. + */ +template +class IsClassOrUnion { + typedef char yes[1]; + typedef char no[2]; + + template + static yes &check(int U::*); + + template + static no &check(...); + +public: + static const bool value = (sizeof(check(0)) == sizeof(yes)); +}; + +#endif // SHARE_VM_UTILITIES_TRAITS_IS_CLASS_OR_UNION_HPP + diff --git a/src/share/vm/utilities/traits/isSame.cpp b/src/share/vm/utilities/traits/isSame.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/isSame.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "utilities/debug.hpp" +#include "utilities/traits/isSame.hpp" + +class IsSameTest { + enum EnumType {}; + enum EnumType2 {}; + union UnionType {}; + union UnionType2 {}; + class ClassType {}; + class ClassType2 {}; + class DerivedClassType: ClassType {}; + class DerivedClassType2: ClassType2 {}; + struct StructType {}; + struct StructType2 {}; + typedef int PrimitiveType; + typedef long PrimitiveType2; + + static void test() { + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + STATIC_ASSERT((IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((!IsSame::value)); + + STATIC_ASSERT((IsSame::value)); + } +}; + diff --git a/src/share/vm/utilities/traits/isSame.hpp b/src/share/vm/utilities/traits/isSame.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/isSame.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TRAITS_IS_SAME_HPP +#define SHARE_VM_UTILITIES_TRAITS_IS_SAME_HPP + +/** + * IsSame::value is true iff T and U are the same type. + */ +template +class IsSame { + template + struct IsSameInternal { + static const bool value = false; + }; + + template + struct IsSameInternal { + static const bool value = true; + }; +public: + static const bool value = IsSameInternal::value; +}; + +#endif // SHARE_VM_UTILITIES_TRAITS_IS_SAME_HPP + diff --git a/src/share/vm/utilities/traits/removeCv.cpp b/src/share/vm/utilities/traits/removeCv.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/removeCv.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "utilities/debug.hpp" +#include "utilities/traits/isSame.hpp" +#include "utilities/traits/removeCv.hpp" + +class RemoveCvTest { + enum EnumType {}; + union UnionType {}; + class ClassType {}; + struct StructType {}; + typedef int PrimitiveType; + + static void test() { + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + + // These are currently not part of contract + STATIC_ASSERT((!IsSame::type>::value)); + STATIC_ASSERT((!IsSame::type>::value)); + STATIC_ASSERT((!IsSame::type>::value)); + STATIC_ASSERT((!IsSame::type>::value)); + } +}; + diff --git a/src/share/vm/utilities/traits/removeCv.hpp b/src/share/vm/utilities/traits/removeCv.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/removeCv.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TRAITS_REMOVE_CV_HPP +#define SHARE_VM_UTILITIES_TRAITS_REMOVE_CV_HPP + +/** + * RemoveCv::type returns a type T without any CV qualifiers + */ +template +class RemoveCv { + template struct RemoveConst { typedef U type; }; + template struct RemoveConst { typedef U type; }; + + template struct RemoveVolatile { typedef U type; }; + template struct RemoveVolatile { typedef U type; }; + +public: + typedef typename RemoveVolatile::type>::type type; +}; + +#endif // SHARE_VM_UTILITIES_TRAITS_REMOVE_CV_HPP + diff --git a/src/share/vm/utilities/traits/selectBaseClass.cpp b/src/share/vm/utilities/traits/selectBaseClass.cpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/selectBaseClass.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "utilities/debug.hpp" +#include "utilities/traits/isSame.hpp" +#include "utilities/traits/selectBaseClass.hpp" + +class SelectBaseClassTest { + class ForwardDeclaredClass; + class Base {}; + class Derived: Base {}; + class Derived2: Derived {}; + class Unrelated {}; + + static void test() { + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + STATIC_ASSERT((IsSame::type>::value)); + } +}; + diff --git a/src/share/vm/utilities/traits/selectBaseClass.hpp b/src/share/vm/utilities/traits/selectBaseClass.hpp new file mode 100644 --- /dev/null +++ b/src/share/vm/utilities/traits/selectBaseClass.hpp @@ -0,0 +1,49 @@ +/* + * 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_UTILITIES_TRAITS_SELECT_BASE_CLASS_HPP +#define SHARE_VM_UTILITIES_TRAITS_SELECT_BASE_CLASS_HPP + +#include "utilities/traits/isBaseOf.hpp" + +// The ::type of this struct will be the Desired type if it was defined +// and is a subtype of Fallback, otherwise it will be Fallback. +// This is useful when optionally inheriting from a specialized subtype. +template +class SelectBaseClass { + template + struct CheckInheritance { + typedef T type; + }; + + template + struct CheckInheritance { + typedef U type; + }; +public: + typedef typename CheckInheritance::value, Fallback, Desired>::type type; +}; + +#endif // SHARE_VM_UTILITIES_TRAITS_SELECT_BASE_CLASS_HPP +