diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp index e6e94ca9a99..4e001030849 100644 --- a/src/hotspot/cpu/x86/vm_version_x86.hpp +++ b/src/hotspot/cpu/x86/vm_version_x86.hpp @@ -261,7 +261,9 @@ class VM_Version : public Abstract_VM_Version { uint32_t : 2, avx512_4vnniw : 1, avx512_4fmaps : 1, - : 28; + : 10, + serialize : 1, + : 17; } bits; }; @@ -359,7 +361,8 @@ protected: \ decl(AVX512_VBMI2, "avx512_vbmi2", 44) /* VBMI2 shift left double instructions */ \ decl(AVX512_VBMI, "avx512_vbmi", 45) /* Vector BMI instructions */ \ - decl(HV, "hv", 46) /* Hypervisor instructions */ + decl(HV, "hv", 46) /* Hypervisor instructions */ \ + decl(SERIALIZE, "serialize", 47) /* CPU SERIALIZE */ #define DECLARE_CPU_FEATURE_FLAG(id, name, bit) CPU_##id = (1ULL << bit), CPU_FEATURE_FLAGS(DECLARE_CPU_FEATURE_FLAG) @@ -646,6 +649,8 @@ enum Extended_Family { if (_cpuid_info.sef_cpuid7_ebx.bits.clwb != 0) { result |= CPU_CLWB; } + if (_cpuid_info.sef_cpuid7_edx.bits.serialize != 0) + result |= CPU_SERIALIZE; } // ZX features. @@ -896,6 +901,7 @@ public: static bool supports_avx512_vbmi() { return (_features & CPU_AVX512_VBMI) != 0; } static bool supports_avx512_vbmi2() { return (_features & CPU_AVX512_VBMI2) != 0; } static bool supports_hv() { return (_features & CPU_HV) != 0; } + static bool supports_serialize() { return (_features & CPU_SERIALIZE) != 0; } // Intel features static bool is_intel_family_core() { return is_intel() && diff --git a/src/hotspot/os_cpu/linux_x86/orderAccess_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/orderAccess_linux_x86.hpp index 076cc5e8f3b..fc389eda688 100644 --- a/src/hotspot/os_cpu/linux_x86/orderAccess_linux_x86.hpp +++ b/src/hotspot/os_cpu/linux_x86/orderAccess_linux_x86.hpp @@ -25,6 +25,7 @@ #ifndef OS_CPU_LINUX_X86_ORDERACCESS_LINUX_X86_HPP #define OS_CPU_LINUX_X86_ORDERACCESS_LINUX_X86_HPP +#include OS_HEADER_INLINE(os) // Included in orderAccess.hpp header file. // Compiler version last used for testing: gcc 4.8.2 @@ -56,14 +57,18 @@ inline void OrderAccess::fence() { } inline void OrderAccess::cross_modify_fence_impl() { - int idx = 0; + if (os::supports_serialize()) { + __asm__ volatile (".byte 0x0f, 0x01, 0xe8\n\t" : : :); //serialize + } else { + int idx = 0; #ifdef AMD64 - __asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory"); + __asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory"); #else - // On some x86 systems EBX is a reserved register that cannot be - // clobbered, so we must protect it around the CPUID. - __asm__ volatile ("xchg %%esi, %%ebx; cpuid; xchg %%esi, %%ebx " : "+a" (idx) : : "esi", "ecx", "edx", "memory"); + // On some x86 systems EBX is a reserved register that cannot be + // clobbered, so we must protect it around the CPUID. + __asm__ volatile ("xchg %%esi, %%ebx; cpuid; xchg %%esi, %%ebx " : "+a" (idx) : : "esi", "ecx", "edx", "memory"); #endif + } } #endif // OS_CPU_LINUX_X86_ORDERACCESS_LINUX_X86_HPP diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp index cc71b0d2780..6707ee6a5bc 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp @@ -458,6 +458,10 @@ bool os::supports_sse() { #endif // AMD64 } +bool os::supports_serialize(){ + return VM_Version::supports_serialize(); +} + juint os::cpu_microcode_revision() { juint result = 0; char data[2048] = {0}; // lines should fit in 2K buf diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp index 979006035cc..56778ad65f5 100644 --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.hpp @@ -27,6 +27,7 @@ static void setup_fpu(); static bool supports_sse(); + static bool supports_serialize(); static juint cpu_microcode_revision(); static jlong rdtsc();