--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Thu Mar 13 14:55:34 2014 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Fri Mar 14 17:28:58 2014 -0700
@@ -229,6 +229,9 @@
// 0 if this instruction is not available
static const char* _features_str;
+ static address _cpuinfo_segv_addr; // address of instruction which causes SEGV
+ static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV
+
enum {
CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX)
CPU_CMOV = (1 << 1),
@@ -361,6 +364,9 @@
// extended control register XCR0 (the XFEATURE_ENABLED_MASK register)
XemXcr0Eax xem_xcr0_eax;
uint32_t xem_xcr0_edx; // reserved
+
+ // Space to save ymm registers after signal handle
+ int ymm_save[8*4]; // Save ymm0, ymm7, ymm8, ymm15
};
// The actual cpuid info block
@@ -460,6 +466,21 @@
return result;
}
+ static bool os_supports_avx_vectors() {
+ if (!supports_avx()) {
+ return false;
+ }
+ // Verify that OS save/restore all bits of AVX registers
+ // during signal processing.
+ int nreg = 2 LP64_ONLY(+2);
+ for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register
+ if (_cpuid_info.ymm_save[i] != ymm_test_value()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
static void get_processor_features();
public:
@@ -476,6 +497,19 @@
static ByteSize tpl_cpuidB1_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB1_eax); }
static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); }
static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); }
+ static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); }
+
+ // The value used to check ymm register after signal handle
+ static int ymm_test_value() { return 0xCAFEBABE; }
+
+ static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; }
+ static bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; }
+ static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; }
+ static address cpuinfo_cont_addr() { return _cpuinfo_cont_addr; }
+
+ static void clean_cpuFeatures() { _cpuFeatures = 0; }
+ static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); }
+
// Initialization
static void initialize();