From a38525256690882b1b658a37c0bf08a529520a5e Mon Sep 17 00:00:00 2001 From: kvn Date: Mon, 31 Mar 2014 13:08:03 -0700 Subject: [PATCH] 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 --- src/cpu/x86/vm/vm_version_x86.cpp | 32 +++++++++++++++++-------- src/cpu/x86/vm/vm_version_x86.hpp | 1 + src/os/windows/vm/os_windows.cpp | 2 -- src/os/windows/vm/os_windows.hpp | 2 -- src/os/windows/vm/os_windows.inline.hpp | 6 ++--- src/share/vm/prims/jni.cpp | 2 +- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/cpu/x86/vm/vm_version_x86.cpp b/src/cpu/x86/vm/vm_version_x86.cpp index 28b79b784..ba5fcb383 100644 --- a/src/cpu/x86/vm/vm_version_x86.cpp +++ b/src/cpu/x86/vm/vm_version_x86.cpp @@ -59,9 +59,9 @@ static BufferBlob* stub_blob; 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 @@ class VM_Version_StubGenerator: public StubCodeGenerator { 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 @@ class VM_Version_StubGenerator: public StubCodeGenerator { 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 @@ 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() { _cpu = 4; // 486 by default @@ -395,7 +403,11 @@ void VM_Version::get_processor_features() { 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 @@ void VM_Version::initialize() { 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(); } diff --git a/src/cpu/x86/vm/vm_version_x86.hpp b/src/cpu/x86/vm/vm_version_x86.hpp index a3be0995a..51f6e4f2f 100644 --- a/src/cpu/x86/vm/vm_version_x86.hpp +++ b/src/cpu/x86/vm/vm_version_x86.hpp @@ -507,6 +507,7 @@ public: // 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; } diff --git a/src/os/windows/vm/os_windows.cpp b/src/os/windows/vm/os_windows.cpp index b973c3266..360643c83 100644 --- a/src/os/windows/vm/os_windows.cpp +++ b/src/os/windows/vm/os_windows.cpp @@ -2716,7 +2716,6 @@ address os::win32::fast_jni_accessor_wrapper(BasicType type) { } #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. @@ -2727,7 +2726,6 @@ void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) { // Nothing to do. } } -#endif // Virtual Memory diff --git a/src/os/windows/vm/os_windows.hpp b/src/os/windows/vm/os_windows.hpp index c9c4840bb..f7c3790ff 100644 --- a/src/os/windows/vm/os_windows.hpp +++ b/src/os/windows/vm/os_windows.hpp @@ -97,9 +97,7 @@ class win32 { 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); diff --git a/src/os/windows/vm/os_windows.inline.hpp b/src/os/windows/vm/os_windows.inline.hpp index 5303743ae..a824b84fa 100644 --- a/src/os/windows/vm/os_windows.inline.hpp +++ b/src/os/windows/vm/os_windows.inline.hpp @@ -107,9 +107,7 @@ inline int os::close(int fd) { return ::close(fd); } -#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 diff --git a/src/share/vm/prims/jni.cpp b/src/share/vm/prims/jni.cpp index 6ee151006..eb7de64f4 100644 --- a/src/share/vm/prims/jni.cpp +++ b/src/share/vm/prims/jni.cpp @@ -5208,7 +5208,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v } #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 -- GitLab