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 }
|