< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page

        

@@ -1115,10 +1115,160 @@
     LastFrameAccessor last_frame(thread);
     JvmtiExport::at_single_stepping_point(thread, last_frame.method(), last_frame.bcp());
   }
 IRT_END
 
+// all the continuation methods read the current continuation from the thread.
+
+
+static bool freeze_continuation(JavaThread* thread, oop cont, address _fp, address _sp, address _pc) {
+  HandleMark hm(thread);
+
+  tty->print_cr("AA 0000 %p %p %p", _pc, _fp, _sp);
+
+  intptr_t* bottom = (intptr_t*)java_lang_Continuation::entrySP(cont); // watch for off-by-n
+  intptr_t* top = (intptr_t*)_sp;
+  int size = (bottom - top) * sizeof(intptr_t); // in bytes
+
+  tty->print_cr("size: %d", size);
+
+  Handle conth(thread, cont);
+  JavaCallArguments args;
+  args.push_oop(conth);
+  args.push_int(size);
+  JavaValue result(T_VOID);
+  JavaCalls::call_virtual(&result, SystemDictionary::Continuation_klass(), vmSymbols::getStack_name(), vmSymbols::continuationGetStack_signature(), &args, thread);
+  assert(java_lang_Continuation::stack_size(cont) >= size, "sanity check");
+
+  int lastSenderSP = java_lang_Continuation::lastSenderSP(cont);
+  int* hstack = (int*)java_lang_Continuation::stack_base(cont);
+  
+  address limit = (address)(hstack + lastSenderSP - 1); // this is the last byte, inclusive, we'll write to
+  assert(limit - (address)hstack >= size, "sanity check");
+  intptr_t* target = (intptr_t*)(limit - size);
+
+  // set lastSenderSP
+  
+  ResourceMark rm(thread); // for vframes/symbols -- debug only
+  RegisterMap map(thread, false);
+
+  frame f(_sp, _fp, _pc);
+  address source = _sp;
+
+  while(true) {
+    tty->print_cr("= Frame: fp: %p sp: %p pc: %p", f.fp(), f.sp(), f.pc());
+    os::print_location(tty, *(intptr_t*)((address)f.fp() + frame::return_addr_offset));
+    os::print_location(tty, (intptr_t)f.fp());
+    os::print_location(tty, (intptr_t)f.sp());
+    os::print_location(tty, *(intptr_t*)f.pc(), true);
+
+    intptr_t* sp = f.sp();
+    intptr_t* fp = f.fp();
+
+    if (fp < bottom) {// I test FP because I want to print one more frame
+      tty->print_cr("Found entry frame: %s", f.interpreter_frame_method()->name()->as_C_string());
+      break;
+    }
+
+    bool is_interpreted = f.is_interpreted_frame();
+    bool is_compiled = f.is_compiled_frame();
+
+    if (is_interpreted) {
+      tty->print_cr("Frame: %s", f.interpreter_frame_method()->name()->as_C_string());
+
+      if (f.interpreter_frame_monitor_end() < f.interpreter_frame_monitor_begin()) {
+        // pinned by monitors. Clear data copied so far from continuation.
+        assert(false, "Monitors held -- unsupported");
+        return false;
+      }
+    } else if (f.is_native_frame()) {
+      // pinned; call continuation's pinned handler method. Clear data copied so far from continuation.
+      assert(false, "Native frame -- unsupported");
+      return false;
+    }
+
+    int fpoffset = fp - sp;
+
+    f = f.sender(&map);
+
+    int fsize = (f.sp() - sp)*sizeof(intptr_t);
+
+    Copy::conjoint_memory_atomic(source, target, fsize);
+
+    if (is_interpreted) {
+      // patch
+      intptr_t* hfp = target + fpoffset;
+      tty->print_cr("hfp: %p", (void*)*hfp);
+
+      // relativize pointers
+      // *(hfp + frame::link_offset) = *(hfp + frame::link_offset) - (hfp + frame::link_offset);
+      // *(hfp + frame::interpreter_frame_sender_sp_offset) = *(hfp + frame::interpreter_frame_sender_sp_offset) - (hfp + frame::interpreter_frame_sender_sp_offset);
+    } else {
+      assert(false, "Compiled frame -- unsupported");
+    }
+    
+    source += fsize;
+    target += fsize;
+
+    assert(source == (address)f.sp(), "sanity");
+  }
+  return true;
+}
+// returns the continuation yielding (based on context), or NULL for failure (due to pinning)
+// it freezes multiple continuations, depending on contex
+// it must set Continuation.stackSize
+// sets Continuation.lastFP/SP to relative indices
+IRT_ENTRY(void, InterpreterRuntime::freeze(JavaThread* thread, FrameInfo* fi, oop context))
+  HandleMark hm(thread);
+  oop cont = java_lang_Thread::continuation(thread->threadObj());
+
+  tty->print_cr("freeze cont: %p", cont);
+
+  if (false) {
+    // while(cont.context != context)
+    bool res = freeze_continuation(thread, cont, fi->fp, fi->sp, fi->pc);
+    if (!res) {
+      fi->fp = 0;
+      fi->sp = 0;
+      fi->pc = 0;
+      return;
+    }
+  }
+  
+  java_lang_Thread::set_continuation(thread->threadObj(), cont);
+  tty->print_cr("freeze cont3: %p", cont);
+
+  fi->sp = java_lang_Continuation::entrySP(cont);
+  fi->fp = java_lang_Continuation::entryFP(cont);
+  fi->pc = java_lang_Continuation::entryPC(cont);
+IRT_END
+
+// patches the return address of the bottom-most frame returned to the return barrier codelet
+// returns the pc of the topmost frame, or 0 if no more frames (in fi)
+// or, maybe, doesn't patch the return adress if it's the last frame, so the last frame won't go through the return barrier
+void InterpreterRuntime::pop_and_thaw0(JavaThread* thread, FrameInfo* fi, int num_frames, bool pop) {
+  HandleMark hm(thread);
+  oop cont = java_lang_Thread::continuation(thread->threadObj());
+  
+  // fi->pc is the return address to patch
+  // when copying nmethods, we need to check for them being made non-reentrant, in which case we need to deopt them
+  // and turn them into interpreter frames.
+
+  // if no more frames, jump to entry:
+  fi->sp = java_lang_Continuation::entrySP(cont);
+  fi->fp = java_lang_Continuation::entryFP(cont);
+  fi->pc = java_lang_Continuation::entryPC(cont);
+}
+
+IRT_ENTRY(void, InterpreterRuntime::pop_and_thaw(JavaThread* thread, FrameInfo* fi, int num_frames))
+  pop_and_thaw0(thread, fi, num_frames, true);
+IRT_END
+
+IRT_ENTRY(void, InterpreterRuntime::thaw(JavaThread* thread, FrameInfo* fi, int num_frames))
+  pop_and_thaw0(thread, fi, num_frames, false);
+IRT_END
+
 IRT_ENTRY(void, InterpreterRuntime::post_field_access(JavaThread *thread, oopDesc* obj,
 ConstantPoolCacheEntry *cp_entry))
 
   // check the access_flags for the field in the klass
 
< prev index next >