8320892: AArch64: Restore FPU control state after JNI

Reviewed-by: adinn, stuefe
This commit is contained in:
Andrew Haley 2023-12-06 15:32:35 +00:00
parent 0217b5ac8b
commit 50f3124055
5 changed files with 28 additions and 2 deletions

@ -278,6 +278,9 @@ void DowncallLinker::StubGenerator::generate() {
Label L_reguard;
Label L_after_reguard;
if (_needs_transition) {
// Restore cpu control state after JNI call
__ restore_cpu_control_state_after_jni(rscratch1, tmp1);
__ mov(tmp1, _thread_in_native_trans);
__ strw(tmp1, Address(rthread, JavaThread::thread_state_offset()));

@ -4428,6 +4428,23 @@ void MacroAssembler::load_klass(Register dst, Register src) {
}
}
void MacroAssembler::restore_cpu_control_state_after_jni(Register tmp1, Register tmp2) {
if (RestoreMXCSROnJNICalls) {
Label OK;
get_fpcr(tmp1);
mov(tmp2, tmp1);
// Set FPCR to the state we need. We do want Round to Nearest. We
// don't want non-IEEE rounding modes or floating-point traps.
bfi(tmp1, zr, 22, 4); // Clear DN, FZ, and Rmode
bfi(tmp1, zr, 8, 5); // Clear exception-control bits (8-12)
bfi(tmp1, zr, 0, 2); // Clear AH:FIZ
eor(tmp2, tmp1, tmp2);
cbz(tmp2, OK); // Only reset FPCR if it's wrong
set_fpcr(tmp1);
bind(OK);
}
}
// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result, Register tmp1, Register tmp2) {
// OopHandle::resolve is an indirection.

@ -1047,8 +1047,8 @@ public:
#define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__)
#define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__)
// only if +VerifyFPU
void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
// Restore cpu control state after JNI call
void restore_cpu_control_state_after_jni(Register tmp1, Register tmp2);
// prints msg, dumps registers and stops execution
void stop(const char* msg);

@ -1838,6 +1838,9 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
intptr_t return_pc = (intptr_t) __ pc();
oop_maps->add_gc_map(return_pc - start, map);
// Verify or restore cpu control state after JNI call
__ restore_cpu_control_state_after_jni(rscratch1, rscratch2);
// Unpack native results.
switch (ret_type) {
case T_BOOLEAN: __ c2bool(r0); break;

@ -1383,6 +1383,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ get_method(rmethod);
// result potentially in r0 or v0
// Restore cpu control state after JNI call
__ restore_cpu_control_state_after_jni(rscratch1, rscratch2);
// make room for the pushes we're about to do
__ sub(rscratch1, esp, 4 * wordSize);
__ andr(sp, rscratch1, -16);