1 /*
  2  * Copyright (c) 2022, 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_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