comparison src/cpu/x86/vm/vm_version_x86.cpp @ 17739:98af1e198e73

8037226: compiler/7196199/Test7196199.java fails on 32-bit linux with MaxVectorSize > 16 Summary: verify YMM registers after signal processing and set limit on vector's size. Reviewed-by: iveresov, twisti
author kvn
date Fri, 14 Mar 2014 17:28:58 -0700
parents 8a8ff6b577ed
children 606acabe7b5c
comparison
equal deleted inserted replaced
17737:0d2ce7411240 17739:98af1e198e73
48 int VM_Version::_stepping; 48 int VM_Version::_stepping;
49 int VM_Version::_cpuFeatures; 49 int VM_Version::_cpuFeatures;
50 const char* VM_Version::_features_str = ""; 50 const char* VM_Version::_features_str = "";
51 VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, }; 51 VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, };
52 52
53 // Address of instruction which causes SEGV
54 address VM_Version::_cpuinfo_segv_addr = 0;
55 // Address of instruction after the one which causes SEGV
56 address VM_Version::_cpuinfo_cont_addr = 0;
57
53 static BufferBlob* stub_blob; 58 static BufferBlob* stub_blob;
54 static const int stub_size = 550; 59 static const int stub_size = 600;
55 60
56 extern "C" { 61 extern "C" {
57 typedef void (*getPsrInfo_stub_t)(void*); 62 typedef void (*getPsrInfo_stub_t)(void*);
58 } 63 }
59 static getPsrInfo_stub_t getPsrInfo_stub = NULL; 64 static getPsrInfo_stub_t getPsrInfo_stub = NULL;
232 237
233 // 238 //
234 // Check if OS has enabled XGETBV instruction to access XCR0 239 // Check if OS has enabled XGETBV instruction to access XCR0
235 // (OSXSAVE feature flag) and CPU supports AVX 240 // (OSXSAVE feature flag) and CPU supports AVX
236 // 241 //
237 __ andl(rcx, 0x18000000); 242 __ andl(rcx, 0x18000000); // cpuid1 bits osxsave | avx
238 __ cmpl(rcx, 0x18000000); 243 __ cmpl(rcx, 0x18000000);
239 __ jccb(Assembler::notEqual, sef_cpuid); 244 __ jccb(Assembler::notEqual, sef_cpuid); // jump if AVX is not supported
240 245
241 // 246 //
242 // XCR0, XFEATURE_ENABLED_MASK register 247 // XCR0, XFEATURE_ENABLED_MASK register
243 // 248 //
244 __ xorl(rcx, rcx); // zero for XCR0 register 249 __ xorl(rcx, rcx); // zero for XCR0 register
245 __ xgetbv(); 250 __ xgetbv();
246 __ lea(rsi, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset()))); 251 __ lea(rsi, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset())));
247 __ movl(Address(rsi, 0), rax); 252 __ movl(Address(rsi, 0), rax);
248 __ movl(Address(rsi, 4), rdx); 253 __ movl(Address(rsi, 4), rdx);
254
255 __ andl(rax, 0x6); // xcr0 bits sse | ymm
256 __ cmpl(rax, 0x6);
257 __ jccb(Assembler::notEqual, sef_cpuid); // jump if AVX is not supported
258
259 //
260 // Some OSs have a bug when upper 128bits of YMM
261 // registers are not restored after a signal processing.
262 // Generate SEGV here (reference through NULL)
263 // and check upper YMM bits after it.
264 //
265 VM_Version::set_avx_cpuFeatures(); // Enable temporary to pass asserts
266
267 // load value into all 32 bytes of ymm7 register
268 __ movl(rcx, VM_Version::ymm_test_value());
269
270 __ movdl(xmm0, rcx);
271 __ pshufd(xmm0, xmm0, 0x00);
272 __ vinsertf128h(xmm0, xmm0, xmm0);
273 __ vmovdqu(xmm7, xmm0);
274 #ifdef _LP64
275 __ vmovdqu(xmm8, xmm0);
276 __ vmovdqu(xmm15, xmm0);
277 #endif
278
279 __ xorl(rsi, rsi);
280 VM_Version::set_cpuinfo_segv_addr( __ pc() );
281 // Generate SEGV
282 __ movl(rax, Address(rsi, 0));
283
284 VM_Version::set_cpuinfo_cont_addr( __ pc() );
285 // Returns here after signal. Save xmm0 to check it later.
286 __ lea(rsi, Address(rbp, in_bytes(VM_Version::ymm_save_offset())));
287 __ vmovdqu(Address(rsi, 0), xmm0);
288 __ vmovdqu(Address(rsi, 32), xmm7);
289 #ifdef _LP64
290 __ vmovdqu(Address(rsi, 64), xmm8);
291 __ vmovdqu(Address(rsi, 96), xmm15);
292 #endif
293
294 VM_Version::clean_cpuFeatures();
249 295
250 // 296 //
251 // cpuid(0x7) Structured Extended Features 297 // cpuid(0x7) Structured Extended Features
252 // 298 //
253 __ bind(sef_cpuid); 299 __ bind(sef_cpuid);
538 FLAG_SET_DEFAULT(MaxVectorSize, 32); 584 FLAG_SET_DEFAULT(MaxVectorSize, 32);
539 } 585 }
540 if (MaxVectorSize > 32) { 586 if (MaxVectorSize > 32) {
541 FLAG_SET_DEFAULT(MaxVectorSize, 32); 587 FLAG_SET_DEFAULT(MaxVectorSize, 32);
542 } 588 }
543 if (MaxVectorSize > 16 && UseAVX == 0) { 589 if (MaxVectorSize > 16 && (UseAVX == 0 || !os_supports_avx_vectors())) {
544 // Only supported with AVX+ 590 // 32 bytes vectors (in YMM) are only supported with AVX+
545 FLAG_SET_DEFAULT(MaxVectorSize, 16); 591 FLAG_SET_DEFAULT(MaxVectorSize, 16);
546 } 592 }
547 if (UseSSE < 2) { 593 if (UseSSE < 2) {
548 // Only supported with SSE2+ 594 // Vectors (in XMM) are only supported with SSE2+
549 FLAG_SET_DEFAULT(MaxVectorSize, 0); 595 FLAG_SET_DEFAULT(MaxVectorSize, 0);
550 } 596 }
597 #ifdef ASSERT
598 if (supports_avx() && PrintMiscellaneous && Verbose && TraceNewVectors) {
599 tty->print_cr("State of YMM registers after signal handle:");
600 int nreg = 2 LP64_ONLY(+2);
601 const char* ymm_name[4] = {"0", "7", "8", "15"};
602 for (int i = 0; i < nreg; i++) {
603 tty->print("YMM%s:", ymm_name[i]);
604 for (int j = 7; j >=0; j--) {
605 tty->print(" %x", _cpuid_info.ymm_save[i*8 + j]);
606 }
607 tty->cr();
608 }
609 }
610 #endif
551 } 611 }
552 #endif 612 #endif
553 613
554 // On new cpus instructions which update whole XMM register should be used 614 // On new cpus instructions which update whole XMM register should be used
555 // to prevent partial register stall due to dependencies on high half. 615 // to prevent partial register stall due to dependencies on high half.
676 UseSSE42Intrinsics = true; 736 UseSSE42Intrinsics = true;
677 } 737 }
678 } 738 }
679 } 739 }
680 } 740 }
681 #if defined(COMPILER2) && defined(_ALLBSD_SOURCE)
682 if (MaxVectorSize > 16) {
683 // Limit vectors size to 16 bytes on BSD until it fixes
684 // restoring upper 128bit of YMM registers on return
685 // from signal handler.
686 FLAG_SET_DEFAULT(MaxVectorSize, 16);
687 }
688 #endif // COMPILER2
689 741
690 // Use count leading zeros count instruction if available. 742 // Use count leading zeros count instruction if available.
691 if (supports_lzcnt()) { 743 if (supports_lzcnt()) {
692 if (FLAG_IS_DEFAULT(UseCountLeadingZerosInstruction)) { 744 if (FLAG_IS_DEFAULT(UseCountLeadingZerosInstruction)) {
693 UseCountLeadingZerosInstruction = true; 745 UseCountLeadingZerosInstruction = true;
812 tty->print(" UseAVX=%d",UseAVX); 864 tty->print(" UseAVX=%d",UseAVX);
813 } 865 }
814 if (UseAES) { 866 if (UseAES) {
815 tty->print(" UseAES=1"); 867 tty->print(" UseAES=1");
816 } 868 }
869 #ifdef COMPILER2
870 if (MaxVectorSize > 0) {
871 tty->print(" MaxVectorSize=%d", MaxVectorSize);
872 }
873 #endif
817 tty->cr(); 874 tty->cr();
818 tty->print("Allocation"); 875 tty->print("Allocation");
819 if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) { 876 if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {
820 tty->print_cr(": no prefetching"); 877 tty->print_cr(": no prefetching");
821 } else { 878 } else {