diff --git a/src/hotspot/share/runtime/coroutine.cpp b/src/hotspot/share/runtime/coroutine.cpp index a09b5a43139..182d2aa85b1 100644 --- a/src/hotspot/share/runtime/coroutine.cpp +++ b/src/hotspot/share/runtime/coroutine.cpp @@ -205,7 +205,7 @@ Coroutine::~Coroutine() { } } -void Coroutine::frames_do(FrameClosure* fc) { +void Coroutine::frames_do(FrameClosure* fc, bool process_frames) { switch (_state) { case Coroutine::_created: // the coroutine has never been run @@ -214,7 +214,7 @@ void Coroutine::frames_do(FrameClosure* fc) { // the contents of this coroutine have already been visited break; case Coroutine::_onstack: - _stack->frames_do(fc); + _stack->frames_do(fc, process_frames); break; case Coroutine::_dead: // coroutine is dead, ignore @@ -301,9 +301,7 @@ class oops_do_Closure: public FrameClosure { void frames_do(frame* fr, RegisterMap* map) { fr->oops_do(_f, _cf, map); } }; -void Coroutine::oops_do(OopClosure* f, CodeBlobClosure* cf) { - oops_do_Closure fc(f, cf); - frames_do(&fc); +void Coroutine::oops_do_no_frames(OopClosure* f, CodeBlobClosure* cf) { if (_state == _onstack) { assert(_handle_area != NULL, "_onstack coroutine should have _handle_area"); DEBUG_CORO_ONLY(tty->print_cr("collecting handle area %08x", _handle_area)); @@ -319,6 +317,11 @@ void Coroutine::oops_do(OopClosure* f, CodeBlobClosure* cf) { } } +void Coroutine::oops_do_frames(OopClosure* f, CodeBlobClosure* cf) { + oops_do_Closure fc(f, cf); + frames_do(&fc, false); +} + class nmethods_do_Closure: public FrameClosure { private: CodeBlobClosure* _cf; @@ -329,7 +332,7 @@ class nmethods_do_Closure: public FrameClosure { void Coroutine::nmethods_do(CodeBlobClosure* cf) { nmethods_do_Closure fc(cf); - frames_do(&fc); + frames_do(&fc, true); } class compiledMethods_do_Closure: public FrameClosure { @@ -342,7 +345,7 @@ class compiledMethods_do_Closure: public FrameClosure { void Coroutine::compiledMethods_do(CodeBlobClosure* cf) { compiledMethods_do_Closure fc(cf); - frames_do(&fc); + frames_do(&fc, true); } class metadata_do_Closure: public FrameClosure { @@ -360,7 +363,7 @@ void Coroutine::metadata_do(MetadataClosure* f) { } } metadata_do_Closure fc(f); - frames_do(&fc); + frames_do(&fc, true); } class frames_do_Closure: public FrameClosure { @@ -373,7 +376,7 @@ class frames_do_Closure: public FrameClosure { void Coroutine::frames_do(void f(frame*, const RegisterMap* map)) { frames_do_Closure fc(f); - frames_do(&fc); + frames_do(&fc, true); } bool Coroutine::is_disposable() { @@ -450,7 +453,7 @@ void CoroutineStack::free_stack(CoroutineStack* stack, JavaThread* thread) { delete stack; } -void CoroutineStack::frames_do(FrameClosure* fc) { +void CoroutineStack::frames_do(FrameClosure* fc, bool process_frames) { assert(_last_sp != NULL, "CoroutineStack with NULL last_sp"); DEBUG_CORO_ONLY(tty->print_cr("frames_do stack %08x", _stack_base)); @@ -469,7 +472,7 @@ void CoroutineStack::frames_do(FrameClosure* fc) { } #endif - StackFrameStream fst(_thread, fr, true /* update */, true /* process_frames */); + StackFrameStream fst(_thread, fr, true /* update */, process_frames); fst.register_map()->set_location(get_fp_reg()->as_VMReg(), (address)_last_sp); fst.register_map()->set_include_argument_oops(false); for(; !fst.is_done(); fst.next()) { diff --git a/src/hotspot/share/runtime/coroutine.hpp b/src/hotspot/share/runtime/coroutine.hpp index 0285f3537dc..55d155724d3 100644 --- a/src/hotspot/share/runtime/coroutine.hpp +++ b/src/hotspot/share/runtime/coroutine.hpp @@ -138,7 +138,7 @@ class Coroutine: public CHeapObj, public DoublyLinkedList { // objects of this type can only be created via static functions Coroutine() { } - void frames_do(FrameClosure* fc); + void frames_do(FrameClosure* fc, bool process_frames); static void set_coroutine_base(intptr_t **&base, JavaThread* thread, jobject obj, Coroutine *coro, oop coroutineObj, address coroutine_start); @@ -222,7 +222,8 @@ class Coroutine: public CHeapObj, public DoublyLinkedList { bool in_critical(JavaThread* thread); // GC support - void oops_do(OopClosure* f, CodeBlobClosure* cf); + void oops_do_no_frames(OopClosure* f, CodeBlobClosure* cf); + void oops_do_frames(OopClosure* f, CodeBlobClosure* cf); void nmethods_do(CodeBlobClosure* cf); void compiledMethods_do(CodeBlobClosure* cf); void metadata_do(MetadataClosure* f); @@ -304,7 +305,7 @@ class CoroutineStack: public CHeapObj, public DoublyLinkedListoops_do(f, cf); + current->oops_do_no_frames(f, cf); current = current->next(); } while (current != _coroutine_list); } @@ -2142,6 +2142,15 @@ void JavaThread::oops_do_frames(OopClosure* f, CodeBlobClosure* cf) { for (StackFrameStream fst(this, true /* update */, false /* process_frames */); !fst.is_done(); fst.next()) { fst.current()->oops_do(f, cf, fst.register_map()); } + + if (EnableCoroutine) { + CoroutineSupportLocker csl(this); + Coroutine* current = _coroutine_list; + do { + current->oops_do_frames(f, cf); + current = current->next(); + } while (current != _coroutine_list); + } } #ifdef ASSERT