< prev index next >

src/hotspot/cpu/arm/templateInterpreterGenerator_arm.cpp

Print this page
rev 54072 : 8213845: ARM32: Interpreter doesn't call result handler after native calls
Summary: Fix mapping of native jboolean result to 0..1 on ARM32
Reviewed-by: aph, phh
Contributed-by: christoph.goettschkes@microdoc.com


 334 
 335   // handle exceptions
 336   { Label L;
 337     __ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
 338     __ cbz(Rtemp, L);
 339     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
 340     __ should_not_reach_here();
 341     __ bind(L);
 342   }
 343 
 344   if (continuation == NULL) {
 345     __ dispatch_next(state, step);
 346   } else {
 347     __ jump_to_entry(continuation);
 348   }
 349 
 350   return entry;
 351 }
 352 
 353 address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {
 354 #ifdef AARCH64
 355   address entry = __ pc();
 356   switch (type) {
 357     case T_BOOLEAN:
 358       __ tst(R0, 0xff);
 359       __ cset(R0, ne);
 360       break;
 361     case T_CHAR   : __ zero_extend(R0, R0, 16);  break;
 362     case T_BYTE   : __ sign_extend(R0, R0,  8);  break;
 363     case T_SHORT  : __ sign_extend(R0, R0, 16);  break;
 364     case T_INT    : // fall through
 365     case T_LONG   : // fall through
 366     case T_VOID   : // fall through
 367     case T_FLOAT  : // fall through
 368     case T_DOUBLE : /* nothing to do */          break;
 369     case T_OBJECT :
 370       // retrieve result from frame
 371       __ ldr(R0, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
 372       // and verify it
 373       __ verify_oop(R0);
 374       break;
 375     default       : ShouldNotReachHere();
 376   }
 377   __ ret();
 378   return entry;
 379 #else
 380   // Result handlers are not used on 32-bit ARM
 381   // since the returned value is already in appropriate format.
 382   __ should_not_reach_here();  // to avoid empty code block
 383 
 384   // The result handler non-zero indicates an object is returned and this is
 385   // used in the native entry code.
 386   return type == T_OBJECT ? (address)(-1) : NULL;
 387 #endif // AARCH64
 388 }
 389 
 390 address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
 391   address entry = __ pc();
 392   __ push(state);
 393   __ call_VM(noreg, runtime_entry);
 394 
 395   // load current bytecode
 396   __ ldrb(R3_bytecode, Address(Rbcp));
 397   __ dispatch_only_normal(vtos);
 398   return entry;
 399 }
 400 
 401 
 402 // Helpers for commoning out cases in the various type of method entries.
 403 //
 404 
 405 // increment invocation count & check for overflow
 406 //
 407 // Note: checking for negative value instead of overflow


1199   __ restore_method();
1200 #endif
1201 #endif // AARCH64
1202   }
1203 
1204   // Perform Native->Java thread transition
1205   __ mov(Rtemp, _thread_in_Java);
1206   __ str_32(Rtemp, Address(Rthread, JavaThread::thread_state_offset()));
1207 
1208   // Zero handles and last_java_sp
1209   __ reset_last_Java_frame(Rtemp);
1210   __ ldr(R3, Address(Rthread, JavaThread::active_handles_offset()));
1211   __ str_32(__ zero_register(Rtemp), Address(R3, JNIHandleBlock::top_offset_in_bytes()));
1212   if (CheckJNICalls) {
1213     __ str(__ zero_register(Rtemp), Address(Rthread, JavaThread::pending_jni_exception_check_fn_offset()));
1214   }
1215 
1216   // Unbox oop result, e.g. JNIHandles::resolve result if it's an oop.
1217   {
1218     Label Lnot_oop;
1219 #ifdef AARCH64
1220     __ mov_slow(Rtemp, AbstractInterpreter::result_handler(T_OBJECT));
1221     __ cmp(Rresult_handler, Rtemp);
1222     __ b(Lnot_oop, ne);
1223 #else // !AARCH64
1224     // For ARM32, Rresult_handler is -1 for oop result, 0 otherwise.
1225     __ cbz(Rresult_handler, Lnot_oop);
1226 #endif // !AARCH64
1227     Register value = AARCH64_ONLY(Rsaved_result) NOT_AARCH64(Rsaved_result_lo);
1228     __ resolve_jobject(value,   // value
1229                        Rtemp,   // tmp1
1230                        R1_tmp); // tmp2
1231     // Store resolved result in frame for GC visibility.
1232     __ str(value, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
1233     __ bind(Lnot_oop);
1234   }
1235 
1236 #ifdef AARCH64
1237   // Restore SP (drop native parameters area), to keep SP in sync with extended_sp in frame
1238   __ restore_sp_after_call(Rtemp);
1239   __ check_stack_top();
1240 #endif // AARCH64
1241 
1242   // reguard stack if StackOverflow exception happened while in native.
1243   {
1244     __ ldr_u32(Rtemp, Address(Rthread, JavaThread::stack_guard_state_offset()));
1245     __ cmp_32(Rtemp, JavaThread::stack_guard_yellow_reserved_disabled);
1246 #ifdef AARCH64


1279   }
1280 
1281   // jvmti/dtrace support
1282   // Note: This must happen _after_ handling/throwing any exceptions since
1283   //       the exception handler code notifies the runtime of method exits
1284   //       too. If this happens before, method entry/exit notifications are
1285   //       not properly paired (was bug - gri 11/22/99).
1286 #ifdef AARCH64
1287   __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI, true, Rsaved_result, noreg, Dsaved_result);
1288 #else
1289   __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI, true, Rsaved_result_lo, Rsaved_result_hi, saved_result_fp);
1290 #endif // AARCH64
1291 
1292   // Restore the result. Oop result is restored from the stack.
1293 #ifdef AARCH64
1294   __ mov(R0, Rsaved_result);
1295   __ fmov_d(D0, Dsaved_result);
1296 
1297   __ blr(Rresult_handler);
1298 #else
1299   __ cmp(Rresult_handler, 0);
1300   __ ldr(R0, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize), ne);
1301   __ mov(R0, Rsaved_result_lo, eq);
1302   __ mov(R1, Rsaved_result_hi);
1303 
1304 #ifdef __ABI_HARD__
1305   // reload native FP result
1306   __ fcpyd(D0, D8);
1307 #endif // __ABI_HARD__
1308 
1309 #ifdef ASSERT
1310   if (VerifyOops) {
1311     Label L;
1312     __ cmp(Rresult_handler, 0);
1313     __ b(L, eq);
1314     __ verify_oop(R0);
1315     __ bind(L);
1316   }
1317 #endif // ASSERT
1318 #endif // AARCH64
1319 
1320   // Restore FP/LR, sender_sp and return
1321 #ifdef AARCH64
1322   __ ldr(Rtemp, Address(FP, frame::interpreter_frame_sender_sp_offset * wordSize));
1323   __ ldp(FP, LR, Address(FP));
1324   __ mov(SP, Rtemp);
1325 #else
1326   __ mov(Rtemp, FP);
1327   __ ldmia(FP, RegisterSet(FP) | RegisterSet(LR));
1328   __ ldr(SP, Address(Rtemp, frame::interpreter_frame_sender_sp_offset * wordSize));
1329 #endif // AARCH64
1330 
1331   __ ret();
1332 
1333   if (inc_counter) {
1334     // Handle overflow of counter and compile method
1335     __ bind(invocation_counter_overflow);
1336     generate_counter_overflow(continue_after_compile);
1337   }




 334 
 335   // handle exceptions
 336   { Label L;
 337     __ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
 338     __ cbz(Rtemp, L);
 339     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_pending_exception));
 340     __ should_not_reach_here();
 341     __ bind(L);
 342   }
 343 
 344   if (continuation == NULL) {
 345     __ dispatch_next(state, step);
 346   } else {
 347     __ jump_to_entry(continuation);
 348   }
 349 
 350   return entry;
 351 }
 352 
 353 address TemplateInterpreterGenerator::generate_result_handler_for(BasicType type) {

 354   address entry = __ pc();
 355   switch (type) {
 356     case T_BOOLEAN: __ c2bool(R0); break;
 357     case T_CHAR   : AARCH64_ONLY(__ zero_extend(R0, R0, 16);)  break;
 358     case T_BYTE   : AARCH64_ONLY(__ sign_extend(R0, R0,  8);)  break;
 359     case T_SHORT  : AARCH64_ONLY(__ sign_extend(R0, R0, 16);)  break;



 360     case T_INT    : // fall through
 361     case T_LONG   : // fall through
 362     case T_VOID   : // fall through
 363     case T_FLOAT  : // fall through
 364     case T_DOUBLE : /* nothing to do */          break;
 365     case T_OBJECT :
 366       // retrieve result from frame
 367       __ ldr(R0, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
 368       // and verify it
 369       __ verify_oop(R0);
 370       break;
 371     default       : __ should_not_reach_here(); break;
 372   }
 373   __ ret();
 374   return entry;









 375 }
 376 
 377 address TemplateInterpreterGenerator::generate_safept_entry_for(TosState state, address runtime_entry) {
 378   address entry = __ pc();
 379   __ push(state);
 380   __ call_VM(noreg, runtime_entry);
 381 
 382   // load current bytecode
 383   __ ldrb(R3_bytecode, Address(Rbcp));
 384   __ dispatch_only_normal(vtos);
 385   return entry;
 386 }
 387 
 388 
 389 // Helpers for commoning out cases in the various type of method entries.
 390 //
 391 
 392 // increment invocation count & check for overflow
 393 //
 394 // Note: checking for negative value instead of overflow


1186   __ restore_method();
1187 #endif
1188 #endif // AARCH64
1189   }
1190 
1191   // Perform Native->Java thread transition
1192   __ mov(Rtemp, _thread_in_Java);
1193   __ str_32(Rtemp, Address(Rthread, JavaThread::thread_state_offset()));
1194 
1195   // Zero handles and last_java_sp
1196   __ reset_last_Java_frame(Rtemp);
1197   __ ldr(R3, Address(Rthread, JavaThread::active_handles_offset()));
1198   __ str_32(__ zero_register(Rtemp), Address(R3, JNIHandleBlock::top_offset_in_bytes()));
1199   if (CheckJNICalls) {
1200     __ str(__ zero_register(Rtemp), Address(Rthread, JavaThread::pending_jni_exception_check_fn_offset()));
1201   }
1202 
1203   // Unbox oop result, e.g. JNIHandles::resolve result if it's an oop.
1204   {
1205     Label Lnot_oop;

1206     __ mov_slow(Rtemp, AbstractInterpreter::result_handler(T_OBJECT));
1207     __ cmp(Rresult_handler, Rtemp);
1208     __ b(Lnot_oop, ne);




1209     Register value = AARCH64_ONLY(Rsaved_result) NOT_AARCH64(Rsaved_result_lo);
1210     __ resolve_jobject(value,   // value
1211                        Rtemp,   // tmp1
1212                        R1_tmp); // tmp2
1213     // Store resolved result in frame for GC visibility.
1214     __ str(value, Address(FP, frame::interpreter_frame_oop_temp_offset * wordSize));
1215     __ bind(Lnot_oop);
1216   }
1217 
1218 #ifdef AARCH64
1219   // Restore SP (drop native parameters area), to keep SP in sync with extended_sp in frame
1220   __ restore_sp_after_call(Rtemp);
1221   __ check_stack_top();
1222 #endif // AARCH64
1223 
1224   // reguard stack if StackOverflow exception happened while in native.
1225   {
1226     __ ldr_u32(Rtemp, Address(Rthread, JavaThread::stack_guard_state_offset()));
1227     __ cmp_32(Rtemp, JavaThread::stack_guard_yellow_reserved_disabled);
1228 #ifdef AARCH64


1261   }
1262 
1263   // jvmti/dtrace support
1264   // Note: This must happen _after_ handling/throwing any exceptions since
1265   //       the exception handler code notifies the runtime of method exits
1266   //       too. If this happens before, method entry/exit notifications are
1267   //       not properly paired (was bug - gri 11/22/99).
1268 #ifdef AARCH64
1269   __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI, true, Rsaved_result, noreg, Dsaved_result);
1270 #else
1271   __ notify_method_exit(vtos, InterpreterMacroAssembler::NotifyJVMTI, true, Rsaved_result_lo, Rsaved_result_hi, saved_result_fp);
1272 #endif // AARCH64
1273 
1274   // Restore the result. Oop result is restored from the stack.
1275 #ifdef AARCH64
1276   __ mov(R0, Rsaved_result);
1277   __ fmov_d(D0, Dsaved_result);
1278 
1279   __ blr(Rresult_handler);
1280 #else
1281   __ mov(R0, Rsaved_result_lo);


1282   __ mov(R1, Rsaved_result_hi);
1283 
1284 #ifdef __ABI_HARD__
1285   // reload native FP result
1286   __ fcpyd(D0, D8);
1287 #endif // __ABI_HARD__
1288   __ blx(Rresult_handler);









1289 #endif // AARCH64
1290 
1291   // Restore FP/LR, sender_sp and return
1292 #ifdef AARCH64
1293   __ ldr(Rtemp, Address(FP, frame::interpreter_frame_sender_sp_offset * wordSize));
1294   __ ldp(FP, LR, Address(FP));
1295   __ mov(SP, Rtemp);
1296 #else
1297   __ mov(Rtemp, FP);
1298   __ ldmia(FP, RegisterSet(FP) | RegisterSet(LR));
1299   __ ldr(SP, Address(Rtemp, frame::interpreter_frame_sender_sp_offset * wordSize));
1300 #endif // AARCH64
1301 
1302   __ ret();
1303 
1304   if (inc_counter) {
1305     // Handle overflow of counter and compile method
1306     __ bind(invocation_counter_overflow);
1307     generate_counter_overflow(continue_after_compile);
1308   }


< prev index next >