< prev index next >

src/hotspot/share/interpreter/interpreterRuntime.cpp

Print this page

        

*** 1115,1124 **** --- 1115,1274 ---- 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 >