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
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Mon Mar 31 10:35:06 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Mon Mar 31 13:08:03 2014 -0700
@@ -59,9 +59,9 @@
static const int stub_size = 600;
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 {
@@ -69,7 +69,7 @@
VM_Version_StubGenerator(CodeBuffer *c) : StubCodeGenerator(c) {}
- address generate_getPsrInfo() {
+ address generate_get_cpu_info() {
// Flags to test CPU type.
const uint32_t HS_EFL_AC = 0x40000;
const uint32_t HS_EFL_ID = 0x200000;
@@ -81,13 +81,13 @@
Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4;
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->
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
@@ -385,6 +385,14 @@
};
+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() {
_cpu = 4; // 486 by default
@@ -395,7 +403,11 @@
if (!Use486InstrsOnly) {
// 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();
_cpu = extended_cpu_family();
_model = extended_cpu_model();
@@ -986,14 +998,14 @@
ResourceMark rm;
// 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) {
- vm_exit_during_initialization("Unable to allocate getPsrInfo_stub");
+ vm_exit_during_initialization("Unable to allocate get_cpu_info_stub");
}
CodeBuffer c(stub_blob);
VM_Version_StubGenerator g(&c);
- getPsrInfo_stub = CAST_TO_FN_PTR(getPsrInfo_stub_t,
- g.generate_getPsrInfo());
+ get_cpu_info_stub = CAST_TO_FN_PTR(get_cpu_info_stub_t,
+ g.generate_get_cpu_info());
get_processor_features();
}
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Mon Mar 31 10:35:06 2014 +0200
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp Mon Mar 31 13:08:03 2014 -0700
@@ -507,6 +507,7 @@
// The value used to check ymm register after signal handle
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 bool is_cpuinfo_segv_addr(address pc) { return _cpuinfo_segv_addr == pc; }
static void set_cpuinfo_cont_addr(address pc) { _cpuinfo_cont_addr = pc; }
--- a/hotspot/src/os/windows/vm/os_windows.cpp Mon Mar 31 10:35:06 2014 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.cpp Mon Mar 31 13:08:03 2014 -0700
@@ -2702,7 +2702,6 @@
}
#endif
-#ifndef PRODUCT
void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {
// Install a win32 structured exception handler around the test
// function call so the VM can generate an error dump if needed.
@@ -2713,7 +2712,6 @@
// Nothing to do.
}
}
-#endif
// Virtual Memory
--- a/hotspot/src/os/windows/vm/os_windows.hpp Mon Mar 31 10:35:06 2014 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.hpp Mon Mar 31 13:08:03 2014 -0700
@@ -101,9 +101,7 @@
static address fast_jni_accessor_wrapper(BasicType);
#endif
-#ifndef PRODUCT
static void call_test_func_with_wrapper(void (*funcPtr)(void));
-#endif
// filter function to ignore faults on serializations page
static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
--- a/hotspot/src/os/windows/vm/os_windows.inline.hpp Mon Mar 31 10:35:06 2014 +0200
+++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp Mon Mar 31 13:08:03 2014 -0700
@@ -111,9 +111,7 @@
return win32::_has_performance_count;
}
-#ifndef PRODUCT
- #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \
- os::win32::call_test_func_with_wrapper(f)
-#endif
+#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \
+ os::win32::call_test_func_with_wrapper(f)
#endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
--- a/hotspot/src/share/vm/prims/jni.cpp Mon Mar 31 10:35:06 2014 +0200
+++ b/hotspot/src/share/vm/prims/jni.cpp Mon Mar 31 13:08:03 2014 -0700
@@ -4001,7 +4001,7 @@
}
#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()
#endif