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