comparison src/cpu/x86/vm/vm_version_x86.cpp @ 17829:0118c8c7b80f

8038633: crash in VM_Version::get_processor_features() on startup Summary: Windows need an exception wrapper around getPsrInfo_stub() call in order to properly handle SEGV for YMM registers test. Reviewed-by: iveresov, iignatyev
author kvn
date Mon, 31 Mar 2014 13:08:03 -0700
parents 606acabe7b5c
children 1eba0601f0dd
comparison
equal deleted inserted replaced
17828:8a84bedf7173 17829:0118c8c7b80f
57 57
58 static BufferBlob* stub_blob; 58 static BufferBlob* stub_blob;
59 static const int stub_size = 600; 59 static const int stub_size = 600;
60 60
61 extern "C" { 61 extern "C" {
62 typedef void (*getPsrInfo_stub_t)(void*); 62 typedef void (*get_cpu_info_stub_t)(void*);
63 } 63 }
64 static getPsrInfo_stub_t getPsrInfo_stub = NULL; 64 static get_cpu_info_stub_t get_cpu_info_stub = NULL;
65 65
66 66
67 class VM_Version_StubGenerator: public StubCodeGenerator { 67 class VM_Version_StubGenerator: public StubCodeGenerator {
68 public: 68 public:
69 69
70 VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} 70 VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
71 71
72 address generate_getPsrInfo() { 72 address generate_get_cpu_info() {
73 // Flags to test CPU type. 73 // Flags to test CPU type.
74 const uint32_t HS_EFL_AC = 0x40000; 74 const uint32_t HS_EFL_AC = 0x40000;
75 const uint32_t HS_EFL_ID = 0x200000; 75 const uint32_t HS_EFL_ID = 0x200000;
76 // Values for when we don't have a CPUID instruction. 76 // Values for when we don't have a CPUID instruction.
77 const int CPU_FAMILY_SHIFT = 8; 77 const int CPU_FAMILY_SHIFT = 8;
79 const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT); 79 const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
80 80
81 Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4; 81 Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4;
82 Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done; 82 Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done;
83 83
84 StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); 84 StubCodeMark mark(this, "VM_Version", "get_cpu_info_stub");
85 # define __ _masm-> 85 # define __ _masm->
86 86
87 address start = __ pc(); 87 address start = __ pc();
88 88
89 // 89 //
90 // void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); 90 // void get_cpu_info(VM_Version::CpuidInfo* cpuid_info);
91 // 91 //
92 // LP64: rcx and rdx are first and second argument registers on windows 92 // LP64: rcx and rdx are first and second argument registers on windows
93 93
94 __ push(rbp); 94 __ push(rbp);
95 #ifdef _LP64 95 #ifdef _LP64
383 return start; 383 return start;
384 }; 384 };
385 }; 385 };
386 386
387 387
388 void VM_Version::get_cpu_info_wrapper() {
389 get_cpu_info_stub(&_cpuid_info);
390 }
391
392 #ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED
393 #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
394 #endif
395
388 void VM_Version::get_processor_features() { 396 void VM_Version::get_processor_features() {
389 397
390 _cpu = 4; // 486 by default 398 _cpu = 4; // 486 by default
391 _model = 0; 399 _model = 0;
392 _stepping = 0; 400 _stepping = 0;
393 _cpuFeatures = 0; 401 _cpuFeatures = 0;
394 _logical_processors_per_package = 1; 402 _logical_processors_per_package = 1;
395 403
396 if (!Use486InstrsOnly) { 404 if (!Use486InstrsOnly) {
397 // Get raw processor info 405 // Get raw processor info
398 getPsrInfo_stub(&_cpuid_info); 406
407 // Some platforms (like Win*) need a wrapper around here
408 // in order to properly handle SEGV for YMM registers test.
409 CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(get_cpu_info_wrapper);
410
399 assert_is_initialized(); 411 assert_is_initialized();
400 _cpu = extended_cpu_family(); 412 _cpu = extended_cpu_family();
401 _model = extended_cpu_model(); 413 _model = extended_cpu_model();
402 _stepping = cpu_stepping(); 414 _stepping = cpu_stepping();
403 415
984 996
985 void VM_Version::initialize() { 997 void VM_Version::initialize() {
986 ResourceMark rm; 998 ResourceMark rm;
987 // Making this stub must be FIRST use of assembler 999 // Making this stub must be FIRST use of assembler
988 1000
989 stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size); 1001 stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
990 if (stub_blob == NULL) { 1002 if (stub_blob == NULL) {
991 vm_exit_during_initialization("Unable to allocate getPsrInfo_stub"); 1003 vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
992 } 1004 }
993 CodeBuffer c(stub_blob); 1005 CodeBuffer c(stub_blob);
994 VM_Version_StubGenerator g(&c); 1006 VM_Version_StubGenerator g(&c);
995 getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t, 1007 get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
996 g.generate_getPsrInfo()); 1008 g.generate_get_cpu_info());
997 1009
998 get_processor_features(); 1010 get_processor_features();
999 } 1011 }