Mercurial > hg > graal-compiler
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 } |