1 /* 2 * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_RUNTIME_CONTINUATION_HPP 26 #define SHARE_VM_RUNTIME_CONTINUATION_HPP 27 28 #include "jni.h" 29 #include "classfile/javaClasses.hpp" 30 #include "memory/allStatic.hpp" 31 #include "oops/oopsHierarchy.hpp" 32 33 class ContinuationEntry; 34 class frame; 35 class FrameValues; 36 class Handle; 37 class outputStream; 38 class RegisterMap; 39 40 class Continuations : public AllStatic { 41 public: 42 static void init(); 43 static bool enabled(); 44 }; 45 46 void continuations_init(); 47 48 class javaVFrame; 49 class JavaThread; 50 51 // should match Continuation.toPreemptStatus() in Continuation.java 52 enum freeze_result { 53 freeze_ok = 0, 54 freeze_ok_bottom = 1, 55 freeze_pinned_cs = 2, 56 freeze_pinned_native = 3, 57 freeze_pinned_monitor = 4, 58 freeze_exception = 5, 59 freeze_not_mounted = 6, 60 unsupported = 7 61 }; 62 63 enum freeze_kind { 64 freeze_self_from_java = 0, 65 freeze_on_monitorenter = 1, 66 freeze_on_wait = 2 67 }; 68 69 class Continuation : AllStatic { 70 public: 71 72 enum thaw_kind { 73 thaw_top = 0, 74 thaw_return_barrier = 1, 75 thaw_return_barrier_exception = 2, 76 }; 77 78 static bool is_thaw_return_barrier(thaw_kind kind) { 79 return kind != thaw_top; 80 } 81 82 static bool is_thaw_return_barrier_exception(thaw_kind kind) { 83 bool r = (kind == thaw_return_barrier_exception); 84 assert(!r || is_thaw_return_barrier(kind), "must be"); 85 return r; 86 } 87 88 static void init(); 89 90 static address freeze_entry(); 91 static address freeze_preempt_entry(); 92 static int prepare_thaw(JavaThread* thread, bool return_barrier); 93 static address thaw_entry(); 94 95 static int try_preempt(JavaThread* target, oop continuation, int preempt_kind); 96 97 static ContinuationEntry* get_continuation_entry_for_continuation(JavaThread* thread, oop continuation); 98 static ContinuationEntry* get_continuation_entry_for_sp(JavaThread* thread, intptr_t* const sp); 99 static ContinuationEntry* get_continuation_entry_for_entry_frame(JavaThread* thread, const frame& f); 100 101 static bool is_continuation_mounted(JavaThread* thread, oop continuation); 102 static bool is_continuation_preempted(oop cont); 103 static bool is_continuation_done(oop cont); 104 105 106 static bool is_cont_barrier_frame(const frame& f); 107 static bool is_return_barrier_entry(const address pc); 108 static bool is_continuation_enterSpecial(const frame& f); 109 static bool is_continuation_entry_frame(const frame& f, const RegisterMap *map); 110 111 static bool is_frame_in_continuation(const ContinuationEntry* entry, const frame& f); 112 static bool is_frame_in_continuation(JavaThread* thread, const frame& f); 113 114 static bool has_last_Java_frame(oop continuation, frame* frame, RegisterMap* map); 115 static frame last_frame(oop continuation, RegisterMap *map); 116 static frame top_frame(const frame& callee, RegisterMap* map); 117 static javaVFrame* last_java_vframe(Handle continuation, RegisterMap *map); 118 static frame continuation_parent_frame(RegisterMap* map); 119 120 static oop continuation_scope(oop continuation); 121 static bool is_scope_bottom(oop cont_scope, const frame& fr, const RegisterMap* map); 122 123 static bool is_in_usable_stack(address addr, const RegisterMap* map); 124 125 // pins/unpins the innermost mounted continuation; returns true on success or false if there's no continuation or the operation failed 126 static bool pin(JavaThread* current); 127 static bool unpin(JavaThread* current); 128 129 static frame continuation_bottom_sender(JavaThread* thread, const frame& callee, intptr_t* sender_sp); 130 static address get_top_return_pc_post_barrier(JavaThread* thread, address pc); 131 static void set_cont_fastpath_thread_state(JavaThread* thread); 132 static void notify_deopt(JavaThread* thread, intptr_t* sp); 133 134 // access frame data 135 136 #ifndef PRODUCT 137 static void describe(FrameValues &values); 138 #endif 139 140 private: 141 friend class InstanceStackChunkKlass; 142 143 #ifdef ASSERT 144 public: 145 static void debug_verify_continuation(oop continuation); 146 static void print(oop continuation); 147 static void print_on(outputStream* st, oop continuation); 148 #endif 149 }; 150 151 void CONT_RegisterNativeMethods(JNIEnv *env, jclass cls); 152 153 #endif // SHARE_VM_RUNTIME_CONTINUATION_HPP