1 /* 2 * Copyright (c) 2018, 2024, 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 "memory/allStatic.hpp" 30 #include "oops/oopsHierarchy.hpp" 31 32 class ContinuationEntry; 33 class frame; 34 class FrameValues; 35 class Handle; 36 class outputStream; 37 class RegisterMap; 38 39 class Continuations : public AllStatic { 40 public: 41 static void init(); 42 static bool enabled(); 43 }; 44 45 void continuations_init(); 46 47 class javaVFrame; 48 class JavaThread; 49 50 // should match Continuation.toPreemptStatus() in Continuation.java 51 enum freeze_result { 52 freeze_ok = 0, 53 freeze_ok_bottom = 1, 54 freeze_pinned_cs = 2, 55 freeze_pinned_native = 3, 56 freeze_pinned_monitor = 4, 57 freeze_exception = 5, 58 freeze_not_mounted = 6, 59 freeze_unsupported = 7 60 }; 61 62 class Continuation : AllStatic { 63 public: 64 65 enum preempt_kind { 66 freeze_on_monitorenter = 1, 67 freeze_on_wait = 2 68 }; 69 70 enum thaw_kind { 71 thaw_top = 0, 72 thaw_return_barrier = 1, 73 thaw_return_barrier_exception = 2, 74 }; 75 76 static bool is_thaw_return_barrier(thaw_kind kind) { 77 return kind != thaw_top; 78 } 79 80 static bool is_thaw_return_barrier_exception(thaw_kind kind) { 81 bool r = (kind == thaw_return_barrier_exception); 82 assert(!r || is_thaw_return_barrier(kind), "must be"); 83 return r; 84 } 85 86 static void init(); 87 88 static address freeze_entry(); 89 static address freeze_preempt_entry(); 90 static int prepare_thaw(JavaThread* thread, bool return_barrier); 91 static address thaw_entry(); 92 93 static int try_preempt(JavaThread* target, oop continuation) NOT_LOOM_MONITOR_SUPPORT({ return freeze_unsupported; }); 94 95 static ContinuationEntry* get_continuation_entry_for_continuation(JavaThread* thread, oop continuation); 96 static ContinuationEntry* get_continuation_entry_for_sp(JavaThread* thread, intptr_t* const sp); 97 static ContinuationEntry* get_continuation_entry_for_entry_frame(JavaThread* thread, const frame& f); 98 99 static bool is_continuation_mounted(JavaThread* thread, oop continuation); 100 101 static bool is_cont_barrier_frame(const frame& f); 102 static bool is_return_barrier_entry(const address pc); 103 static bool is_continuation_enterSpecial(const frame& f); 104 static bool is_continuation_entry_frame(const frame& f, const RegisterMap *map); 105 106 static bool is_frame_in_continuation(const ContinuationEntry* entry, const frame& f); 107 static bool is_frame_in_continuation(JavaThread* thread, const frame& f); 108 109 static bool has_last_Java_frame(oop continuation, frame* frame, RegisterMap* map); 110 static frame last_frame(oop continuation, RegisterMap *map); 111 static frame top_frame(const frame& callee, RegisterMap* map); 112 static javaVFrame* last_java_vframe(Handle continuation, RegisterMap *map); 113 static frame continuation_parent_frame(RegisterMap* map); 114 115 static oop continuation_scope(oop continuation); 116 static bool is_scope_bottom(oop cont_scope, const frame& fr, const RegisterMap* map); 117 118 static bool is_in_usable_stack(address addr, const RegisterMap* map); 119 120 // pins/unpins the innermost mounted continuation; returns true on success or false if there's no continuation or the operation failed 121 static bool pin(JavaThread* current); 122 static bool unpin(JavaThread* current); 123 124 static frame continuation_bottom_sender(JavaThread* thread, const frame& callee, intptr_t* sender_sp); 125 static address get_top_return_pc_post_barrier(JavaThread* thread, address pc); 126 static void set_cont_fastpath_thread_state(JavaThread* thread); 127 static void notify_deopt(JavaThread* thread, intptr_t* sp); 128 129 // access frame data 130 131 #ifndef PRODUCT 132 static void describe(FrameValues &values); 133 #endif 134 135 private: 136 friend class InstanceStackChunkKlass; 137 138 #ifdef ASSERT 139 public: 140 static void debug_verify_continuation(oop continuation); 141 static void print(oop continuation); 142 static void print_on(outputStream* st, oop continuation); 143 #endif 144 }; 145 146 void CONT_RegisterNativeMethods(JNIEnv *env, jclass cls); 147 148 #endif // SHARE_VM_RUNTIME_CONTINUATION_HPP