1.1 --- a/src/cpu/x86/vm/vm_version_x86.cpp Mon Mar 17 13:42:16 2014 +0100 1.2 +++ b/src/cpu/x86/vm/vm_version_x86.cpp Fri Mar 14 17:28:58 2014 -0700 1.3 @@ -50,8 +50,13 @@ 1.4 const char* VM_Version::_features_str = ""; 1.5 VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, }; 1.6 1.7 +// Address of instruction which causes SEGV 1.8 +address VM_Version::_cpuinfo_segv_addr = 0; 1.9 +// Address of instruction after the one which causes SEGV 1.10 +address VM_Version::_cpuinfo_cont_addr = 0; 1.11 + 1.12 static BufferBlob* stub_blob; 1.13 -static const int stub_size = 550; 1.14 +static const int stub_size = 600; 1.15 1.16 extern "C" { 1.17 typedef void (*getPsrInfo_stub_t)(void*); 1.18 @@ -234,9 +239,9 @@ 1.19 // Check if OS has enabled XGETBV instruction to access XCR0 1.20 // (OSXSAVE feature flag) and CPU supports AVX 1.21 // 1.22 - __ andl(rcx, 0x18000000); 1.23 + __ andl(rcx, 0x18000000); // cpuid1 bits osxsave | avx 1.24 __ cmpl(rcx, 0x18000000); 1.25 - __ jccb(Assembler::notEqual, sef_cpuid); 1.26 + __ jccb(Assembler::notEqual, sef_cpuid); // jump if AVX is not supported 1.27 1.28 // 1.29 // XCR0, XFEATURE_ENABLED_MASK register 1.30 @@ -247,6 +252,47 @@ 1.31 __ movl(Address(rsi, 0), rax); 1.32 __ movl(Address(rsi, 4), rdx); 1.33 1.34 + __ andl(rax, 0x6); // xcr0 bits sse | ymm 1.35 + __ cmpl(rax, 0x6); 1.36 + __ jccb(Assembler::notEqual, sef_cpuid); // jump if AVX is not supported 1.37 + 1.38 + // 1.39 + // Some OSs have a bug when upper 128bits of YMM 1.40 + // registers are not restored after a signal processing. 1.41 + // Generate SEGV here (reference through NULL) 1.42 + // and check upper YMM bits after it. 1.43 + // 1.44 + VM_Version::set_avx_cpuFeatures(); // Enable temporary to pass asserts 1.45 + 1.46 + // load value into all 32 bytes of ymm7 register 1.47 + __ movl(rcx, VM_Version::ymm_test_value()); 1.48 + 1.49 + __ movdl(xmm0, rcx); 1.50 + __ pshufd(xmm0, xmm0, 0x00); 1.51 + __ vinsertf128h(xmm0, xmm0, xmm0); 1.52 + __ vmovdqu(xmm7, xmm0); 1.53 +#ifdef _LP64 1.54 + __ vmovdqu(xmm8, xmm0); 1.55 + __ vmovdqu(xmm15, xmm0); 1.56 +#endif 1.57 + 1.58 + __ xorl(rsi, rsi); 1.59 + VM_Version::set_cpuinfo_segv_addr( __ pc() ); 1.60 + // Generate SEGV 1.61 + __ movl(rax, Address(rsi, 0)); 1.62 + 1.63 + VM_Version::set_cpuinfo_cont_addr( __ pc() ); 1.64 + // Returns here after signal. Save xmm0 to check it later. 1.65 + __ lea(rsi, Address(rbp, in_bytes(VM_Version::ymm_save_offset()))); 1.66 + __ vmovdqu(Address(rsi, 0), xmm0); 1.67 + __ vmovdqu(Address(rsi, 32), xmm7); 1.68 +#ifdef _LP64 1.69 + __ vmovdqu(Address(rsi, 64), xmm8); 1.70 + __ vmovdqu(Address(rsi, 96), xmm15); 1.71 +#endif 1.72 + 1.73 + VM_Version::clean_cpuFeatures(); 1.74 + 1.75 // 1.76 // cpuid(0x7) Structured Extended Features 1.77 // 1.78 @@ -540,14 +586,28 @@ 1.79 if (MaxVectorSize > 32) { 1.80 FLAG_SET_DEFAULT(MaxVectorSize, 32); 1.81 } 1.82 - if (MaxVectorSize > 16 && UseAVX == 0) { 1.83 - // Only supported with AVX+ 1.84 + if (MaxVectorSize > 16 && (UseAVX == 0 || !os_supports_avx_vectors())) { 1.85 + // 32 bytes vectors (in YMM) are only supported with AVX+ 1.86 FLAG_SET_DEFAULT(MaxVectorSize, 16); 1.87 } 1.88 if (UseSSE < 2) { 1.89 - // Only supported with SSE2+ 1.90 + // Vectors (in XMM) are only supported with SSE2+ 1.91 FLAG_SET_DEFAULT(MaxVectorSize, 0); 1.92 } 1.93 +#ifdef ASSERT 1.94 + if (supports_avx() && PrintMiscellaneous && Verbose && TraceNewVectors) { 1.95 + tty->print_cr("State of YMM registers after signal handle:"); 1.96 + int nreg = 2 LP64_ONLY(+2); 1.97 + const char* ymm_name[4] = {"0", "7", "8", "15"}; 1.98 + for (int i = 0; i < nreg; i++) { 1.99 + tty->print("YMM%s:", ymm_name[i]); 1.100 + for (int j = 7; j >=0; j--) { 1.101 + tty->print(" %x", _cpuid_info.ymm_save[i*8 + j]); 1.102 + } 1.103 + tty->cr(); 1.104 + } 1.105 + } 1.106 +#endif 1.107 } 1.108 #endif 1.109 1.110 @@ -678,14 +738,6 @@ 1.111 } 1.112 } 1.113 } 1.114 -#if defined(COMPILER2) && defined(_ALLBSD_SOURCE) 1.115 - if (MaxVectorSize > 16) { 1.116 - // Limit vectors size to 16 bytes on BSD until it fixes 1.117 - // restoring upper 128bit of YMM registers on return 1.118 - // from signal handler. 1.119 - FLAG_SET_DEFAULT(MaxVectorSize, 16); 1.120 - } 1.121 -#endif // COMPILER2 1.122 1.123 // Use count leading zeros count instruction if available. 1.124 if (supports_lzcnt()) { 1.125 @@ -814,6 +866,11 @@ 1.126 if (UseAES) { 1.127 tty->print(" UseAES=1"); 1.128 } 1.129 +#ifdef COMPILER2 1.130 + if (MaxVectorSize > 0) { 1.131 + tty->print(" MaxVectorSize=%d", MaxVectorSize); 1.132 + } 1.133 +#endif 1.134 tty->cr(); 1.135 tty->print("Allocation"); 1.136 if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {