Skip to content

Commit 55097dd

Browse files
author
Volodymyr Paprotski
committed
8344802: Crash in StubRoutines::verify_mxcsr with -XX:+EnableX86ECoreOpts and -Xcheck:jni
Reviewed-by: jwaters, kvn, sviswanathan
1 parent b8576eb commit 55097dd

File tree

9 files changed

+73
-61
lines changed

9 files changed

+73
-61
lines changed

src/hotspot/cpu/x86/macroAssembler_x86.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,9 +778,17 @@ void MacroAssembler::warn(const char* msg) {
778778
andq(rsp, -16); // align stack as required by push_CPU_state and call
779779
push_CPU_state(); // keeps alignment at 16 bytes
780780

781+
#ifdef _WIN64
782+
// Windows always allocates space for its register args
783+
subq(rsp, frame::arg_reg_save_area_bytes);
784+
#endif
781785
lea(c_rarg0, ExternalAddress((address) msg));
782786
call(RuntimeAddress(CAST_FROM_FN_PTR(address, warning)));
783787

788+
#ifdef _WIN64
789+
// restore stack pointer
790+
addq(rsp, frame::arg_reg_save_area_bytes);
791+
#endif
784792
pop_CPU_state();
785793
mov(rsp, rbp);
786794
pop(rbp);
@@ -2379,6 +2387,22 @@ void MacroAssembler::jump_cc(Condition cc, AddressLiteral dst, Register rscratch
23792387
}
23802388
}
23812389

2390+
void MacroAssembler::cmp32_mxcsr_std(Address mxcsr_save, Register tmp, Register rscratch) {
2391+
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
2392+
assert(rscratch != noreg || always_reachable(mxcsr_std), "missing");
2393+
2394+
stmxcsr(mxcsr_save);
2395+
movl(tmp, mxcsr_save);
2396+
if (EnableX86ECoreOpts) {
2397+
// The mxcsr_std has status bits set for performance on ECore
2398+
orl(tmp, 0x003f);
2399+
} else {
2400+
// Mask out status bits (only check control and mask bits)
2401+
andl(tmp, 0xFFC0);
2402+
}
2403+
cmp32(tmp, mxcsr_std, rscratch);
2404+
}
2405+
23822406
void MacroAssembler::ldmxcsr(AddressLiteral src, Register rscratch) {
23832407
assert(rscratch != noreg || always_reachable(src), "missing");
23842408

src/hotspot/cpu/x86/macroAssembler_x86.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,7 @@ class MacroAssembler: public Assembler {
11351135
void fmul_s(AddressLiteral src) { Assembler::fmul_s(as_Address(src)); }
11361136
#endif // !_LP64
11371137

1138+
void cmp32_mxcsr_std(Address mxcsr_save, Register tmp, Register rscratch = noreg);
11381139
void ldmxcsr(Address src) { Assembler::ldmxcsr(src); }
11391140
void ldmxcsr(AddressLiteral src, Register rscratch = noreg);
11401141

src/hotspot/cpu/x86/stubGenerator_x86_32.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161

6262
#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
6363

64-
const int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions
6564
const int FPU_CNTRL_WRD_MASK = 0xFFFF;
6665

6766
ATTRIBUTE_ALIGNED(16) static const uint32_t KEY_SHUFFLE_MASK[] = {
@@ -175,11 +174,7 @@ class StubGenerator: public StubCodeGenerator {
175174
// save and initialize %mxcsr
176175
if (sse_save) {
177176
Label skip_ldmx;
178-
__ stmxcsr(mxcsr_save);
179-
__ movl(rax, mxcsr_save);
180-
__ andl(rax, MXCSR_MASK); // Only check control and mask bits
181-
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
182-
__ cmp32(rax, mxcsr_std);
177+
__ cmp32_mxcsr_std(mxcsr_save, rax);
183178
__ jcc(Assembler::equal, skip_ldmx);
184179
__ ldmxcsr(mxcsr_std);
185180
__ bind(skip_ldmx);
@@ -465,17 +460,14 @@ class StubGenerator: public StubCodeGenerator {
465460

466461
if (CheckJNICalls && UseSSE > 0 ) {
467462
Label ok_ret;
468-
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
469463
__ push(rax);
470464
__ subptr(rsp, wordSize); // allocate a temp location
471-
__ stmxcsr(mxcsr_save);
472-
__ movl(rax, mxcsr_save);
473-
__ andl(rax, MXCSR_MASK);
474-
__ cmp32(rax, mxcsr_std);
465+
__ cmp32_mxcsr_std(mxcsr_save, rax);
475466
__ jcc(Assembler::equal, ok_ret);
476467

477468
__ warn("MXCSR changed by native JNI code.");
478469

470+
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
479471
__ ldmxcsr(mxcsr_std);
480472

481473
__ bind(ok_ret);

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -248,12 +248,9 @@ address StubGenerator::generate_call_stub(address& return_address) {
248248
const Address mxcsr_save(rbp, mxcsr_off * wordSize);
249249
{
250250
Label skip_ldmx;
251-
__ stmxcsr(mxcsr_save);
252-
__ movl(rax, mxcsr_save);
253-
__ andl(rax, 0xFFC0); // Mask out any pending exceptions (only check control and mask bits)
254-
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
255-
__ cmp32(rax, mxcsr_std, rscratch1);
251+
__ cmp32_mxcsr_std(mxcsr_save, rax, rscratch1);
256252
__ jcc(Assembler::equal, skip_ldmx);
253+
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
257254
__ ldmxcsr(mxcsr_std, rscratch1);
258255
__ bind(skip_ldmx);
259256
}
@@ -579,10 +576,7 @@ address StubGenerator::generate_verify_mxcsr() {
579576
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
580577
__ push(rax);
581578
__ subptr(rsp, wordSize); // allocate a temp location
582-
__ stmxcsr(mxcsr_save);
583-
__ movl(rax, mxcsr_save);
584-
__ andl(rax, 0xFFC0); // Mask out any pending exceptions (only check control and mask bits)
585-
__ cmp32(rax, mxcsr_std, rscratch1);
579+
__ cmp32_mxcsr_std(mxcsr_save, rax, rscratch1);
586580
__ jcc(Assembler::equal, ok_ret);
587581

588582
__ warn("MXCSR changed by native JNI code, use -XX:+RestoreMXCSROnJNICall");

src/hotspot/cpu/x86/upcallLinker_x86_64.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ static int compute_reg_save_area_size(const ABIDescriptor& abi) {
7676
return size;
7777
}
7878

79-
constexpr int MXCSR_MASK = 0xFFC0; // Mask out any pending exceptions
80-
8179
static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDescriptor& abi, int reg_save_area_offset) {
8280
// 1. iterate all registers in the architecture
8381
// - check if they are volatile or not for the given abi
@@ -114,12 +112,9 @@ static void preserve_callee_saved_registers(MacroAssembler* _masm, const ABIDesc
114112
{
115113
const Address mxcsr_save(rsp, offset);
116114
Label skip_ldmx;
117-
__ stmxcsr(mxcsr_save);
118-
__ movl(rax, mxcsr_save);
119-
__ andl(rax, MXCSR_MASK); // Only check control and mask bits
120-
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
121-
__ cmp32(rax, mxcsr_std, rscratch1);
115+
__ cmp32_mxcsr_std(mxcsr_save, rax, rscratch1);
122116
__ jcc(Assembler::equal, skip_ldmx);
117+
ExternalAddress mxcsr_std(StubRoutines::x86::addr_mxcsr_std());
123118
__ ldmxcsr(mxcsr_std, rscratch1);
124119
__ bind(skip_ldmx);
125120
}

src/hotspot/os/windows/os_windows.cpp

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,38 +2589,6 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
25892589
return EXCEPTION_CONTINUE_EXECUTION;
25902590
}
25912591

2592-
#if defined(_M_AMD64)
2593-
//-----------------------------------------------------------------------------
2594-
static bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2595-
// handle exception caused by native method modifying control word
2596-
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
2597-
2598-
switch (exception_code) {
2599-
case EXCEPTION_FLT_DENORMAL_OPERAND:
2600-
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
2601-
case EXCEPTION_FLT_INEXACT_RESULT:
2602-
case EXCEPTION_FLT_INVALID_OPERATION:
2603-
case EXCEPTION_FLT_OVERFLOW:
2604-
case EXCEPTION_FLT_STACK_CHECK:
2605-
case EXCEPTION_FLT_UNDERFLOW: {
2606-
PCONTEXT ctx = exceptionInfo->ContextRecord;
2607-
// On Windows, the mxcsr control bits are non-volatile across calls
2608-
// See also CR 6192333
2609-
//
2610-
jint MxCsr = INITIAL_MXCSR;
2611-
// we can't use StubRoutines::x86::addr_mxcsr_std()
2612-
// because in Win64 mxcsr is not saved there
2613-
if (MxCsr != ctx->MxCsr) {
2614-
ctx->MxCsr = MxCsr;
2615-
return true;
2616-
}
2617-
}
2618-
}
2619-
2620-
return false;
2621-
}
2622-
#endif
2623-
26242592
static inline void report_error(Thread* t, DWORD exception_code,
26252593
address addr, void* siginfo, void* context) {
26262594
VMError::report_and_die(t, exception_code, addr, siginfo, context);
@@ -2805,6 +2773,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
28052773
}
28062774

28072775
#if defined(_M_AMD64)
2776+
extern bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo);
28082777
if ((in_java || in_native) && handle_FLT_exception(exceptionInfo)) {
28092778
return EXCEPTION_CONTINUE_EXECUTION;
28102779
}

src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,43 @@ bool os::win32::register_code_area(char *low, char *high) {
159159
return true;
160160
}
161161

162+
#if defined(_M_AMD64)
163+
//-----------------------------------------------------------------------------
164+
bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
165+
// handle exception caused by native method modifying control word
166+
DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
167+
168+
switch (exception_code) {
169+
case EXCEPTION_FLT_DENORMAL_OPERAND:
170+
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
171+
case EXCEPTION_FLT_INEXACT_RESULT:
172+
case EXCEPTION_FLT_INVALID_OPERATION:
173+
case EXCEPTION_FLT_OVERFLOW:
174+
case EXCEPTION_FLT_STACK_CHECK:
175+
case EXCEPTION_FLT_UNDERFLOW: {
176+
PCONTEXT ctx = exceptionInfo->ContextRecord;
177+
// On Windows, the mxcsr control bits are non-volatile across calls
178+
// See also CR 6192333
179+
//
180+
jint MxCsr = INITIAL_MXCSR; // set to 0x1f80` in winnt.h
181+
if (EnableX86ECoreOpts) {
182+
// On ECore restore with status bits enabled
183+
MxCsr |= 0x3F;
184+
}
185+
186+
// we can't use StubRoutines::x86::addr_mxcsr_std()
187+
// because in Win64 mxcsr is not saved there
188+
if (MxCsr != ctx->MxCsr) {
189+
ctx->MxCsr = MxCsr;
190+
return true;
191+
}
192+
}
193+
}
194+
195+
return false;
196+
}
197+
#endif
198+
162199
#ifdef HAVE_PLATFORM_PRINT_NATIVE_STACK
163200
/*
164201
* Windows/x64 does not use stack frames the way expected by Java:

test/jdk/java/lang/String/IndexOf.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* @summary test String indexOf() intrinsic
3535
* @requires vm.cpu.features ~= ".*avx2.*"
3636
* @requires vm.compiler2.enabled
37-
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation -XX:UseAVX=2 -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:-CheckJNICalls IndexOf
37+
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation -XX:UseAVX=2 -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts IndexOf
3838
*/
3939

4040
public class IndexOf {

test/jdk/java/lang/StringBuffer/ECoreIndexOf.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* @summary Test indexOf and lastIndexOf
3535
* @requires vm.cpu.features ~= ".*avx2.*"
3636
* @requires vm.compiler2.enabled
37-
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:-CheckJNICalls -XX:UseAVX=2 -Xbatch -XX:-TieredCompilation -XX:CompileCommand=dontinline,ECoreIndexOf.indexOfKernel ECoreIndexOf
37+
* @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:UseAVX=2 -Xbatch -XX:-TieredCompilation -XX:CompileCommand=dontinline,ECoreIndexOf.indexOfKernel ECoreIndexOf
3838
* @key randomness
3939
*/
4040

0 commit comments

Comments
 (0)