359 // The registers have been saved in the standard places. Perform
360 // an exception lookup in the caller and dispatch to the handler
361 // if found. Otherwise unwind and dispatch to the callers
362 // exception handler.
363 oop_map = generate_oop_map(sasm, 1 /*thread*/);
364
365 // load and clear pending exception oop into r0
366 __ ldr(exception_oop, Address(rthread, Thread::pending_exception_offset()));
367 __ str(zr, Address(rthread, Thread::pending_exception_offset()));
368
369 // load issuing PC (the return address for this stub) into r3
370 __ ldr(exception_pc, Address(rfp, 1*BytesPerWord));
371
372 // make sure that the vm_results are cleared (may be unnecessary)
373 __ str(zr, Address(rthread, JavaThread::vm_result_offset()));
374 __ str(zr, Address(rthread, JavaThread::vm_result_2_offset()));
375 break;
376 case handle_exception_nofpu_id:
377 case handle_exception_id:
378 // At this point all registers MAY be live.
379 oop_map = save_live_registers(sasm, id == handle_exception_nofpu_id);
380 break;
381 case handle_exception_from_callee_id: {
382 // At this point all registers except exception oop (r0) and
383 // exception pc (lr) are dead.
384 const int frame_size = 2 /*fp, return address*/;
385 oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0);
386 sasm->set_frame_size(frame_size);
387 break;
388 }
389 default:
390 __ should_not_reach_here();
391 break;
392 }
393
394 // verify that only r0 and r3 are valid at this time
395 __ invalidate_registers(false, true, true, false, true, true);
396 // verify that r0 contains a valid exception
397 __ verify_not_null_oop(exception_oop);
398
399 #ifdef ASSERT
423 // compute the exception handler.
424 // the exception oop and the throwing pc are read from the fields in JavaThread
425 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
426 oop_maps->add_gc_map(call_offset, oop_map);
427
428 // r0: handler address
429 // will be the deopt blob if nmethod was deoptimized while we looked up
430 // handler regardless of whether handler existed in the nmethod.
431
432 // only r0 is valid at this time, all other registers have been destroyed by the runtime call
433 __ invalidate_registers(false, true, true, true, true, true);
434
435 // patch the return address, this stub will directly return to the exception handler
436 __ str(r0, Address(rfp, 1*BytesPerWord));
437
438 switch (id) {
439 case forward_exception_id:
440 case handle_exception_nofpu_id:
441 case handle_exception_id:
442 // Restore the registers that were saved at the beginning.
443 restore_live_registers(sasm, id == handle_exception_nofpu_id);
444 break;
445 case handle_exception_from_callee_id:
446 // Pop the return address since we are possibly changing SP (restoring from BP).
447 __ leave();
448
449 // Restore SP from FP if the exception PC is a method handle call site.
450 {
451 Label nope;
452 __ ldrw(rscratch1, Address(rthread, JavaThread::is_method_handle_return_offset()));
453 __ cbzw(rscratch1, nope);
454 __ mov(sp, rfp);
455 __ bind(nope);
456 }
457
458 __ ret(lr); // jump to exception handler
459 break;
460 default: ShouldNotReachHere();
461 }
462
463 return oop_maps;
|
359 // The registers have been saved in the standard places. Perform
360 // an exception lookup in the caller and dispatch to the handler
361 // if found. Otherwise unwind and dispatch to the callers
362 // exception handler.
363 oop_map = generate_oop_map(sasm, 1 /*thread*/);
364
365 // load and clear pending exception oop into r0
366 __ ldr(exception_oop, Address(rthread, Thread::pending_exception_offset()));
367 __ str(zr, Address(rthread, Thread::pending_exception_offset()));
368
369 // load issuing PC (the return address for this stub) into r3
370 __ ldr(exception_pc, Address(rfp, 1*BytesPerWord));
371
372 // make sure that the vm_results are cleared (may be unnecessary)
373 __ str(zr, Address(rthread, JavaThread::vm_result_offset()));
374 __ str(zr, Address(rthread, JavaThread::vm_result_2_offset()));
375 break;
376 case handle_exception_nofpu_id:
377 case handle_exception_id:
378 // At this point all registers MAY be live.
379 oop_map = save_live_registers(sasm, id != handle_exception_nofpu_id);
380 break;
381 case handle_exception_from_callee_id: {
382 // At this point all registers except exception oop (r0) and
383 // exception pc (lr) are dead.
384 const int frame_size = 2 /*fp, return address*/;
385 oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0);
386 sasm->set_frame_size(frame_size);
387 break;
388 }
389 default:
390 __ should_not_reach_here();
391 break;
392 }
393
394 // verify that only r0 and r3 are valid at this time
395 __ invalidate_registers(false, true, true, false, true, true);
396 // verify that r0 contains a valid exception
397 __ verify_not_null_oop(exception_oop);
398
399 #ifdef ASSERT
423 // compute the exception handler.
424 // the exception oop and the throwing pc are read from the fields in JavaThread
425 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
426 oop_maps->add_gc_map(call_offset, oop_map);
427
428 // r0: handler address
429 // will be the deopt blob if nmethod was deoptimized while we looked up
430 // handler regardless of whether handler existed in the nmethod.
431
432 // only r0 is valid at this time, all other registers have been destroyed by the runtime call
433 __ invalidate_registers(false, true, true, true, true, true);
434
435 // patch the return address, this stub will directly return to the exception handler
436 __ str(r0, Address(rfp, 1*BytesPerWord));
437
438 switch (id) {
439 case forward_exception_id:
440 case handle_exception_nofpu_id:
441 case handle_exception_id:
442 // Restore the registers that were saved at the beginning.
443 restore_live_registers(sasm, id != handle_exception_nofpu_id);
444 break;
445 case handle_exception_from_callee_id:
446 // Pop the return address since we are possibly changing SP (restoring from BP).
447 __ leave();
448
449 // Restore SP from FP if the exception PC is a method handle call site.
450 {
451 Label nope;
452 __ ldrw(rscratch1, Address(rthread, JavaThread::is_method_handle_return_offset()));
453 __ cbzw(rscratch1, nope);
454 __ mov(sp, rfp);
455 __ bind(nope);
456 }
457
458 __ ret(lr); // jump to exception handler
459 break;
460 default: ShouldNotReachHere();
461 }
462
463 return oop_maps;
|