提交 a3852525 编写于 作者: K kvn

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
上级 5f3ea7b3
...@@ -59,9 +59,9 @@ static BufferBlob* stub_blob; ...@@ -59,9 +59,9 @@ static BufferBlob* stub_blob;
static const int stub_size = 600; static const int stub_size = 600;
extern "C" { extern "C" {
typedef void (*getPsrInfo_stub_t)(void*); typedef void (*get_cpu_info_stub_t)(void*);
} }
static getPsrInfo_stub_t getPsrInfo_stub = NULL; static get_cpu_info_stub_t get_cpu_info_stub = NULL;
class VM_Version_StubGenerator: public StubCodeGenerator { class VM_Version_StubGenerator: public StubCodeGenerator {
...@@ -69,7 +69,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator { ...@@ -69,7 +69,7 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {} VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
address generate_getPsrInfo() { address generate_get_cpu_info() {
// Flags to test CPU type. // Flags to test CPU type.
const uint32_t HS_EFL_AC = 0x40000; const uint32_t HS_EFL_AC = 0x40000;
const uint32_t HS_EFL_ID = 0x200000; const uint32_t HS_EFL_ID = 0x200000;
...@@ -81,13 +81,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator { ...@@ -81,13 +81,13 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4; Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4;
Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done; Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done;
StubCodeMark mark(this, "VM_Version", "getPsrInfo_stub"); StubCodeMark mark(this, "VM_Version", "get_cpu_info_stub");
# define __ _masm-> # define __ _masm->
address start = __ pc(); address start = __ pc();
// //
// void getPsrInfo(VM_Version::CpuidInfo* cpuid_info); // void get_cpu_info(VM_Version::CpuidInfo* cpuid_info);
// //
// LP64: rcx and rdx are first and second argument registers on windows // LP64: rcx and rdx are first and second argument registers on windows
...@@ -385,6 +385,14 @@ class VM_Version_StubGenerator: public StubCodeGenerator { ...@@ -385,6 +385,14 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
}; };
void VM_Version::get_cpu_info_wrapper() {
get_cpu_info_stub(&_cpuid_info);
}
#ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED
#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
#endif
void VM_Version::get_processor_features() { void VM_Version::get_processor_features() {
_cpu = 4; // 486 by default _cpu = 4; // 486 by default
...@@ -395,7 +403,11 @@ void VM_Version::get_processor_features() { ...@@ -395,7 +403,11 @@ void VM_Version::get_processor_features() {
if (!Use486InstrsOnly) { if (!Use486InstrsOnly) {
// Get raw processor info // Get raw processor info
getPsrInfo_stub(&_cpuid_info);
// Some platforms (like Win*) need a wrapper around here
// in order to properly handle SEGV for YMM registers test.
CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(get_cpu_info_wrapper);
assert_is_initialized(); assert_is_initialized();
_cpu = extended_cpu_family(); _cpu = extended_cpu_family();
_model = extended_cpu_model(); _model = extended_cpu_model();
...@@ -986,14 +998,14 @@ void VM_Version::initialize() { ...@@ -986,14 +998,14 @@ void VM_Version::initialize() {
ResourceMark rm; ResourceMark rm;
// Making this stub must be FIRST use of assembler // Making this stub must be FIRST use of assembler
stub_blob = BufferBlob::create("getPsrInfo_stub", stub_size); stub_blob = BufferBlob::create("get_cpu_info_stub", stub_size);
if (stub_blob == NULL) { if (stub_blob == NULL) {
vm_exit_during_initialization("Unable to allocate getPsrInfo_stub"); vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
} }
CodeBuffer c(stub_blob); CodeBuffer c(stub_blob);
VM_Version_StubGenerator g(&c); VM_Version_StubGenerator g(&c);
getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t, get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
g.generate_getPsrInfo()); g.generate_get_cpu_info());
get_processor_features(); get_processor_features();
} }
...@@ -507,6 +507,7 @@ public: ...@@ -507,6 +507,7 @@ public:
// The value used to check ymm register after signal handle // The value used to check ymm register after signal handle
static int ymm_test_value() { return 0xCAFEBABE; } static int ymm_test_value() { return 0xCAFEBABE; }
static void get_cpu_info_wrapper();
static void set_cpuinfo_segv_addr(address pc) { _cpuinfo_segv_addr = pc; } 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 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 void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; }
......
...@@ -2716,7 +2716,6 @@ address os::win32::fast_jni_accessor_wrapper(BasicType type) { ...@@ -2716,7 +2716,6 @@ address os::win32::fast_jni_accessor_wrapper(BasicType type) {
} }
#endif #endif
#ifndef PRODUCT
void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) { void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {
// Install a win32 structured exception handler around the test // Install a win32 structured exception handler around the test
// function call so the VM can generate an error dump if needed. // function call so the VM can generate an error dump if needed.
...@@ -2727,7 +2726,6 @@ void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) { ...@@ -2727,7 +2726,6 @@ void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {
// Nothing to do. // Nothing to do.
} }
} }
#endif
// Virtual Memory // Virtual Memory
......
...@@ -97,9 +97,7 @@ class win32 { ...@@ -97,9 +97,7 @@ class win32 {
static address fast_jni_accessor_wrapper(BasicType); static address fast_jni_accessor_wrapper(BasicType);
#endif #endif
#ifndef PRODUCT
static void call_test_func_with_wrapper(void (*funcPtr)(void)); static void call_test_func_with_wrapper(void (*funcPtr)(void));
#endif
// filter function to ignore faults on serializations page // filter function to ignore faults on serializations page
static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e); static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
......
...@@ -107,9 +107,7 @@ inline int os::close(int fd) { ...@@ -107,9 +107,7 @@ inline int os::close(int fd) {
return ::close(fd); return ::close(fd);
} }
#ifndef PRODUCT #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \
#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \ os::win32::call_test_func_with_wrapper(f)
os::win32::call_test_func_with_wrapper(f)
#endif
#endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP #endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
...@@ -5208,7 +5208,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v ...@@ -5208,7 +5208,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v
} }
#ifndef PRODUCT #ifndef PRODUCT
#ifndef TARGET_OS_FAMILY_windows #ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED
#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f() #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册