< prev index next >

src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp

Print this page
*** 610,10 ***
--- 610,45 ---
    __ membar(Assembler::AnyAny);
    __ dispatch_via(vtos, Interpreter::_normal_table.table_for(vtos));
    return entry;
  }
  
+ address TemplateInterpreterGenerator::generate_cont_resume_interpreter_adapter() {
+   if (!Continuations::enabled()) return nullptr;
+   address start = __ pc();
+ 
+   // Restore rfp first since we need it to restore rest of registers
+   __ leave();
+ 
+   // Restore constant pool cache
+   __ ldr(rcpool, Address(rfp, frame::interpreter_frame_cache_offset * wordSize));
+ 
+   // Restore Java expression stack pointer
+   __ ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
+   __ lea(esp, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize)));
+   // and NULL it as marker that esp is now tos until next java call
+   __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
+ 
+   // Restore machine SP
+   __ ldr(rscratch1, Address(rfp, frame::interpreter_frame_extended_sp_offset * wordSize));
+   __ lea(sp, Address(rfp, rscratch1, Address::lsl(LogBytesPerWord)));
+ 
+   // Prepare for adjustment on return to call_VM_leaf_base()
+   __ ldr(rmethod, Address(rfp, frame::interpreter_frame_method_offset * wordSize));
+   __ stp(rscratch1, rmethod, Address(__ pre(sp, -2 * wordSize)));
+ 
+   // Restore dispatch
+   uint64_t offset;
+   __ adrp(rdispatch, ExternalAddress((address)Interpreter::dispatch_table()), offset);
+   __ add(rdispatch, rdispatch, offset);
+ 
+   __ ret(lr);
+ 
+   return start;
+ }
+ 
+ 
  // Helpers for commoning out cases in the various type of method entries.
  //
  
  
  // increment invocation count & check for overflow

*** 1317,10 ***
--- 1352,12 ---
  
  
    // result handler is in r0
    // set result handler
    __ mov(result_handler, r0);
+   __ str(r0, Address(rfp, frame::interpreter_frame_result_handler_offset * wordSize));
+ 
    // pass mirror handle if static call
    {
      Label L;
      __ ldrw(t, Address(rmethod, Method::access_flags_offset()));
      __ tbz(t, exact_log2(JVM_ACC_STATIC), L);

*** 1355,12 ***
    __ add(c_rarg0, rthread, in_bytes(JavaThread::jni_environment_offset()));
  
    // Set the last Java PC in the frame anchor to be the return address from
    // the call to the native method: this will allow the debugger to
    // generate an accurate stack trace.
!   Label native_return;
!   __ set_last_Java_frame(esp, rfp, native_return, rscratch1);
  
    // change thread state
  #ifdef ASSERT
    {
      Label L;
--- 1392,12 ---
    __ add(c_rarg0, rthread, in_bytes(JavaThread::jni_environment_offset()));
  
    // Set the last Java PC in the frame anchor to be the return address from
    // the call to the native method: this will allow the debugger to
    // generate an accurate stack trace.
!   Label resume_pc;
!   __ set_last_Java_frame(esp, rfp, resume_pc, rscratch1);
  
    // change thread state
  #ifdef ASSERT
    {
      Label L;

*** 1375,13 ***
    // Change state to native
    __ mov(rscratch1, _thread_in_native);
    __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
    __ stlrw(rscratch1, rscratch2);
  
    // Call the native method.
    __ blr(r10);
!   __ bind(native_return);
    __ get_method(rmethod);
    // result potentially in r0 or v0
  
    // Restore cpu control state after JNI call
    __ restore_cpu_control_state_after_jni(rscratch1, rscratch2);
--- 1412,17 ---
    // Change state to native
    __ mov(rscratch1, _thread_in_native);
    __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
    __ stlrw(rscratch1, rscratch2);
  
+   __ push_cont_fastpath();
+ 
    // Call the native method.
    __ blr(r10);
! 
+   __ pop_cont_fastpath();
+ 
    __ get_method(rmethod);
    // result potentially in r0 or v0
  
    // Restore cpu control state after JNI call
    __ restore_cpu_control_state_after_jni(rscratch1, rscratch2);

*** 1442,10 ***
--- 1483,22 ---
    // change thread state
    __ mov(rscratch1, _thread_in_Java);
    __ lea(rscratch2, Address(rthread, JavaThread::thread_state_offset()));
    __ stlrw(rscratch1, rscratch2);
  
+   // Check preemption for Object.wait()
+   Label not_preempted;
+   __ ldr(rscratch1, Address(rthread, JavaThread::preempt_alternate_return_offset()));
+   __ cbz(rscratch1, not_preempted);
+   __ str(zr, Address(rthread, JavaThread::preempt_alternate_return_offset()));
+   __ br(rscratch1);
+   __ bind(resume_pc);
+   // On resume we need to set up stack as expected
+   __ push(dtos);
+   __ push(ltos);
+   __ bind(not_preempted);
+ 
    // reset_last_Java_frame
    __ reset_last_Java_frame(true);
  
    if (CheckJNICalls) {
      // clear_pending_jni_exception_check

*** 1460,10 ***
--- 1513,11 ---
    // and result handler will pick it up
  
    {
      Label no_oop;
      __ adr(t, ExternalAddress(AbstractInterpreter::result_handler(T_OBJECT)));
+     __ ldr(result_handler, Address(rfp, frame::interpreter_frame_result_handler_offset*wordSize));
      __ cmp(t, result_handler);
      __ br(Assembler::NE, no_oop);
      // Unbox oop result, e.g. JNIHandles::resolve result.
      __ pop(ltos);
      __ resolve_jobject(r0, t, rscratch2);
< prev index next >