1 /*
2 * Copyright (c) 2022, 2025, 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_CONTINUATIONHELPER_HPP
26 #define SHARE_VM_RUNTIME_CONTINUATIONHELPER_HPP
27
28 #include "code/scopeDesc.hpp"
29 #include "compiler/oopMap.hpp"
30 #include "memory/allStatic.hpp"
31 #include "runtime/frame.hpp"
32 #include "runtime/stackValue.hpp"
33
34 // Helper, all-static
35 class ContinuationEntry;
36
37 class ContinuationHelper {
38 public:
39 static inline void set_anchor_pd(JavaFrameAnchor* anchor, intptr_t* sp);
40 static inline void set_anchor_to_entry_pd(JavaFrameAnchor* anchor, ContinuationEntry* entry);
41
42 template<typename FKind> static void update_register_map(const frame& f, RegisterMap* map);
43 static inline void update_register_map_with_callee(const frame& f, RegisterMap* map);
44
45 static inline void push_pd(const frame& f);
46
47 static inline address return_address_at(intptr_t* sp);
48 static inline void patch_return_address_at(intptr_t* sp, address pc);
49
50 static inline int frame_align_words(int size);
51 static inline intptr_t* frame_align_pointer(intptr_t* sp);
52
53 // Abstract helpers for describing frames in general
54 class Frame;
55 class NonInterpretedFrame;
56
57 // Concrete helpers for describing concrete types of frames
58 class InterpretedFrame;
59 class NonInterpretedUnknownFrame;
60 class CompiledFrame;
61 class NativeFrame;
62 class StubFrame;
63 };
64
65 class ContinuationHelper::Frame : public AllStatic {
66 public:
67 static const bool interpreted = false;
68 static const bool compiled = false;
69 static const bool stub = false;
70 static const bool native = false;
71
72 static inline intptr_t** callee_link_address(const frame& f);
73 static Method* frame_method(const frame& f);
74 static inline address real_pc(const frame& f);
75 static inline void patch_pc(const frame& f, address pc, bool callee_augmented = false);
76 static address* return_pc_address(const frame& f);
77 static address return_pc(const frame& f);
78 static bool is_stub(CodeBlob* cb);
79
80 #ifdef ASSERT
81 static inline intptr_t* frame_top(const frame &f);
82 static inline bool is_deopt_return(address pc, const frame& sender);
83 static bool assert_frame_laid_out(frame f);
84 #endif
85 };
86
87 class ContinuationHelper::InterpretedFrame : public ContinuationHelper::Frame {
88 public:
89 static const bool interpreted = true;
90
91 static inline intptr_t* frame_top(const frame& f, InterpreterOopMap* mask);
92 static inline intptr_t* frame_top(const frame& f);
93 static inline intptr_t* frame_top(const frame& f, int callee_argsize, bool callee_interpreted);
94 static inline intptr_t* frame_bottom(const frame& f);
95 static inline intptr_t* callers_sp(const frame& f);
96 static inline int stack_argsize(const frame& f);
97
98 static inline address* return_pc_address(const frame& f);
99 static address return_pc(const frame& f);
100 static void patch_sender_sp(frame& f, const frame& caller);
101
102 static int size(const frame& f);
103 static inline int expression_stack_size(const frame &f, InterpreterOopMap* mask);
104
105 #ifdef ASSERT
106 static bool is_owning_locks(const frame& f);
107 #endif
108
109 static bool is_instance(const frame& f);
110
111 typedef InterpreterOopMap* ExtraT;
112 };
113
114 class ContinuationHelper::NonInterpretedFrame : public ContinuationHelper::Frame {
115 public:
116 static inline intptr_t* frame_top(const frame& f, int callee_argsize, bool callee_interpreted);
117 static inline intptr_t* frame_top(const frame& f);
118 static inline intptr_t* frame_bottom(const frame& f);
119
120 static inline int size(const frame& f);
121 static inline int stack_argsize(const frame& f);
122 };
123
124 class ContinuationHelper::NonInterpretedUnknownFrame : public ContinuationHelper::NonInterpretedFrame {
125 public:
126 static bool is_instance(const frame& f);
127 };
128
129 class ContinuationHelper::CompiledFrame : public ContinuationHelper::NonInterpretedFrame {
130 public:
131 static const bool compiled = true;
132
133 static bool is_instance(const frame& f);
134
135 #ifdef ASSERT
136 template <typename RegisterMapT>
137 static bool is_owning_locks(JavaThread* thread, RegisterMapT* map, const frame& f);
138 #endif
139 };
140
141 class ContinuationHelper::NativeFrame : public ContinuationHelper::NonInterpretedFrame {
142 public:
143 static const bool native = true;
144
145 static bool is_instance(const frame& f);
146
147 #ifdef ASSERT
148 static bool is_owning_locks(JavaThread* current, const frame& f);
149 #endif
150
151 static int stack_argsize(const frame& f) { return 0; }
152 };
153
154 class ContinuationHelper::StubFrame : public ContinuationHelper::NonInterpretedFrame {
155 public:
156 static const bool stub = true;
157
158 static bool is_instance(const frame& f);
159 static int stack_argsize(const frame& f) { return 0; }
160 };
161
162 #endif // SHARE_VM_RUNTIME_CONTINUATIONHELPER_HPP