mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 16:44:36 +02:00
8213845: ARM32: Interpreter doesn't call result handler after native calls
Reviewed-by: aph
This commit is contained in:
parent
e530ca5cc2
commit
b2cb5cee6d
5 changed files with 43 additions and 26 deletions
|
@ -82,11 +82,12 @@ uint64_t InterpreterRuntime::normalize_fast_native_fingerprint(uint64_t fingerpr
|
||||||
// For ARM, the fast signature handler only needs to know whether
|
// For ARM, the fast signature handler only needs to know whether
|
||||||
// the return value must be unboxed. T_OBJECT and T_ARRAY need not
|
// the return value must be unboxed. T_OBJECT and T_ARRAY need not
|
||||||
// be distinguished from each other and all other return values
|
// be distinguished from each other and all other return values
|
||||||
// behave like integers with respect to the handler.
|
// behave like integers with respect to the handler except T_BOOLEAN
|
||||||
|
// which must be mapped to the range 0..1.
|
||||||
bool unbox = (ret_type == T_OBJECT) || (ret_type == T_ARRAY);
|
bool unbox = (ret_type == T_OBJECT) || (ret_type == T_ARRAY);
|
||||||
if (unbox) {
|
if (unbox) {
|
||||||
ret_type = T_OBJECT;
|
ret_type = T_OBJECT;
|
||||||
} else {
|
} else if (ret_type != T_BOOLEAN) {
|
||||||
ret_type = T_INT;
|
ret_type = T_INT;
|
||||||
}
|
}
|
||||||
result |= ((uint64_t) ret_type) << shift;
|
result |= ((uint64_t) ret_type) << shift;
|
||||||
|
@ -226,9 +227,6 @@ void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprin
|
||||||
|
|
||||||
address result_handler = Interpreter::result_handler(result_type);
|
address result_handler = Interpreter::result_handler(result_type);
|
||||||
|
|
||||||
// Check that result handlers are not real handler on ARM (0 or -1).
|
|
||||||
// This ensures the signature handlers do not need symbolic information.
|
|
||||||
assert((result_handler == NULL)||(result_handler==(address)0xffffffff),"");
|
|
||||||
__ mov_slow(R0, (intptr_t)result_handler);
|
__ mov_slow(R0, (intptr_t)result_handler);
|
||||||
|
|
||||||
__ ret();
|
__ ret();
|
||||||
|
|
|
@ -941,6 +941,12 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* s, const char* f
|
||||||
bind(done);
|
bind(done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MacroAssembler::c2bool(Register x)
|
||||||
|
{
|
||||||
|
tst(x, 0xff); // Only look at the lowest byte
|
||||||
|
mov(x, 1, ne);
|
||||||
|
}
|
||||||
|
|
||||||
void MacroAssembler::null_check(Register reg, Register tmp, int offset) {
|
void MacroAssembler::null_check(Register reg, Register tmp, int offset) {
|
||||||
if (needs_explicit_null_check(offset)) {
|
if (needs_explicit_null_check(offset)) {
|
||||||
assert_different_registers(reg, tmp);
|
assert_different_registers(reg, tmp);
|
||||||
|
|
|
@ -853,6 +853,8 @@ public:
|
||||||
sub(dst, r1, AsmOperand(r2, lsl, shift));
|
sub(dst, r1, AsmOperand(r2, lsl, shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// C 'boolean' to Java boolean: x == 0 ? 0 : 1
|
||||||
|
void c2bool(Register x);
|
||||||
|
|
||||||
// klass oop manipulations if compressed
|
// klass oop manipulations if compressed
|
||||||
|
|
||||||
|
|
|
@ -1211,6 +1211,11 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
||||||
__ restore_default_fp_mode();
|
__ restore_default_fp_mode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure a Boolean result is mapped to 0..1
|
||||||
|
if (ret_type == T_BOOLEAN) {
|
||||||
|
__ c2bool(R0);
|
||||||
|
}
|
||||||
|
|
||||||
// Do a safepoint check while thread is in transition state
|
// Do a safepoint check while thread is in transition state
|
||||||
InlinedAddress safepoint_state(SafepointSynchronize::address_of_state());
|
InlinedAddress safepoint_state(SafepointSynchronize::address_of_state());
|
||||||
Label call_safepoint_runtime, return_to_java;
|
Label call_safepoint_runtime, return_to_java;
|
||||||
|
|
|
@ -316,13 +316,27 @@ address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, i
|
||||||
}
|
}
|
||||||
|
|
||||||
address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {
|
address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {
|
||||||
// Result handlers are not used on 32-bit ARM
|
address entry = __ pc();
|
||||||
// since the returned value is already in appropriate format.
|
|
||||||
__ should_not_reach_here(); // to avoid empty code block
|
|
||||||
|
|
||||||
// The result handler non-zero indicates an object is returned and this is
|
switch (type) {
|
||||||
// used in the native entry code.
|
case T_CHAR : /* Nothing to do */ break;
|
||||||
return type == T_OBJECT ? (address)(-1) : NULL;
|
case T_BYTE : /* Nothing to do */ break;
|
||||||
|
case T_SHORT : /* Nothing to do */ break;
|
||||||
|
case T_INT : /* Nothing to do */ break;
|
||||||
|
case T_LONG : /* Nothing to do */ break;
|
||||||
|
case T_VOID : /* Nothing to do */ break;
|
||||||
|
case T_DOUBLE : /* Nothing to do */ break;
|
||||||
|
case T_FLOAT : /* Nothing to do */ break;
|
||||||
|
case T_BOOLEAN : __ c2bool(R0); break;
|
||||||
|
case T_OBJECT :
|
||||||
|
__ ldr(R0, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
|
||||||
|
__ verify_oop(R0);
|
||||||
|
break;
|
||||||
|
default : __ should_not_reach_here(); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
__ ret();
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
|
address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
|
||||||
|
@ -985,8 +999,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||||
// Unbox oop result, e.g. JNIHandles::resolve result if it's an oop.
|
// Unbox oop result, e.g. JNIHandles::resolve result if it's an oop.
|
||||||
{
|
{
|
||||||
Label Lnot_oop;
|
Label Lnot_oop;
|
||||||
// For ARM32, Rresult_handler is -1 for oop result, 0 otherwise.
|
__ mov_slow(Rtemp, AbstractInterpreter::result_handler(T_OBJECT));
|
||||||
__ cbz(Rresult_handler, Lnot_oop);
|
__ cmp(Rtemp, Rresult_handler);
|
||||||
|
__ b(Lnot_oop, ne);
|
||||||
Register value = Rsaved_result_lo;
|
Register value = Rsaved_result_lo;
|
||||||
__ resolve_jobject(value, // value
|
__ resolve_jobject(value, // value
|
||||||
Rtemp, // tmp1
|
Rtemp, // tmp1
|
||||||
|
@ -1028,10 +1043,9 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||||
// not properly paired (was bug - gri 11/22/99).
|
// not properly paired (was bug - gri 11/22/99).
|
||||||
__ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI, true, Rsaved_result_lo, Rsaved_result_hi, saved_result_fp);
|
__ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI, true, Rsaved_result_lo, Rsaved_result_hi, saved_result_fp);
|
||||||
|
|
||||||
// Restore the result. Oop result is restored from the stack.
|
// Restore the result. Oop result is restored from the stack by the
|
||||||
__ cmp(Rresult_handler, 0);
|
// result handler.
|
||||||
__ ldr(R0, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize), ne);
|
__ mov(R0, Rsaved_result_lo);
|
||||||
__ mov(R0, Rsaved_result_lo, eq);
|
|
||||||
__ mov(R1, Rsaved_result_hi);
|
__ mov(R1, Rsaved_result_hi);
|
||||||
|
|
||||||
#ifdef __ABI_HARD__
|
#ifdef __ABI_HARD__
|
||||||
|
@ -1039,15 +1053,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
|
||||||
__ fcpyd(D0, D8);
|
__ fcpyd(D0, D8);
|
||||||
#endif // __ABI_HARD__
|
#endif // __ABI_HARD__
|
||||||
|
|
||||||
#ifdef ASSERT
|
__ blx(Rresult_handler);
|
||||||
if (VerifyOops) {
|
|
||||||
Label L;
|
|
||||||
__ cmp(Rresult_handler, 0);
|
|
||||||
__ b(L, eq);
|
|
||||||
__ verify_oop(R0);
|
|
||||||
__ bind(L);
|
|
||||||
}
|
|
||||||
#endif // ASSERT
|
|
||||||
|
|
||||||
// Restore FP/LR, sender_sp and return
|
// Restore FP/LR, sender_sp and return
|
||||||
__ mov(Rtemp, FP);
|
__ mov(Rtemp, FP);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue