1 /*
  2  * Copyright (c) 2020, 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_OOPS_INSTANCESTACKCHUNKKLASS_HPP
 26 #define SHARE_OOPS_INSTANCESTACKCHUNKKLASS_HPP
 27 
 28 #include "oops/instanceKlass.hpp"
 29 #include "oops/oopsHierarchy.hpp"
 30 #include "utilities/macros.hpp"
 31 #include "utilities/ostream.hpp"
 32 
 33 class ClassFileParser;
 34 class MemRegion;
 35 
 36 // An InstanceStackChunkKlass is a specialization of the InstanceKlass.
 37 //
 38 // The stackChunkOops have a header containing metadata, and a blob containing a
 39 // stack segment (some integral number of stack frames).
 40 //
 41 // A chunk is said to be "mixed" if it contains interpreter frames or stubs
 42 // (which can only be a safepoint stub as the topmost frame). Otherwise, it
 43 // must contain only compiled Java frames.
 44 //
 45 // Interpreter frames in chunks have their internal pointers converted to
 46 // relative offsets from fp. Derived pointers in compiled frames might also
 47 // be converted to relative offsets from their base.
 48 
 49 /************************************************
 50 
 51 Chunk layout:
 52 
 53                    +--------------------------------+
 54                    |                                |
 55                    |  oop bitmap                    |
 56                    |                                |
 57                    | ------------------------------ |
 58                    |                                |
 59                    |  [empty]                       |
 60                    |                                |
 61                   -|================================|
 62                 /  |                                |
 63                |   | caller stack args              |   argsize
 64                |   | [metadata at frame top (1)]    | + frame::metadata_words_at_top
 65                |   | ------------------------------ |   words
 66                |   | [metadata at frame bottom (2)] |
 67          ^     |   | frame                          |
 68          |     |   |                                |
 69          |   size  | ------------------------------ |
 70          |   words |                                |
 71          |     |   | frame                          |
 72          |     |   |                                |
 73  Address |     |   | ------------------------------ |
 74          |     |   |                                |
 75          |     |   | frame                          |
 76          |     |   |                                |
 77          |     |   | callee stack args              |
 78          |     |   | [metadata at frame top (1)]    |<--\
 79          |     |   | ------------------------------ |   |
 80          |     |   | [metadata at frame bottom (2)  |   |
 81          |     |   |  i.e. rbp, pc]                 |   |
 82          |     |   |                                |   |
 83          |     |   | [empty]                        |   |
 84          |     \   |                                |   |
 85                  - |================================|   |
 86                    | int maxSize                    |   |
 87                    | long pc                        |   |
 88             header | byte flags                     |   |
 89                    | int argsize                    |   |
 90                    | int sp                         +---/
 91                    | int size                       |
 92                    +--------------------------------+
 93 
 94  (1) Metadata at frame top (see frame::metadata_words_at_top)
 95      Used on ppc64, empty on x86_64, aarch64
 96  (2) Metadata at the frame bottom (see frame::metadata_words_at_bottom)
 97      Used on x86_64 (saved rbp, ret.addr.), aarch64, empty on ppc64
 98 
 99 ************************************************/
100 
101 
102 class InstanceStackChunkKlass: public InstanceKlass {
103   friend class InstanceKlass;
104   friend class Continuations;
105 
106 public:
107   static const KlassKind Kind = InstanceStackChunkKlassKind;
108 
109 private:
110   static int _offset_of_stack;
111 
112   InstanceStackChunkKlass(const ClassFileParser& parser);
113 
114 public:
115   InstanceStackChunkKlass();
116 
117   // Casting from Klass*
118   static InstanceStackChunkKlass* cast(Klass* k) {
119     assert(k->is_stack_chunk_instance_klass(), "cast to InstanceStackChunkKlass");
120     return static_cast<InstanceStackChunkKlass*>(k);
121   }
122 
123   inline size_t instance_size(size_t stack_size_in_words) const;
124 
125   static inline size_t bitmap_size_in_bits(size_t stack_size_in_words); // In bits
126   static inline size_t bitmap_size(size_t stack_size_in_words); // In words
127   static inline size_t gc_data_size(size_t stack_size_in_words); // In words
128 
129   // Returns the size of the instance including the stack data.
130   size_t oop_size(oop obj, markWord mark) const override;
131 
132   static void serialize_offsets(class SerializeClosure* f) NOT_CDS_RETURN;
133 
134   static void print_chunk(const stackChunkOop chunk, bool verbose, outputStream* st = tty);
135 
136 #ifndef PRODUCT
137   void oop_print_on(oop obj, outputStream* st) override;
138 #endif
139 
140   // Stack offset is an offset into the Heap
141   static int offset_of_stack() { return _offset_of_stack; }
142   static void init_offset_of_stack();
143 
144   // Oop fields (and metadata) iterators
145   //
146   // The InstanceClassLoaderKlass iterators also visit the CLD pointer (or mirror of anonymous klasses).
147 
148   // Forward iteration
149   // Iterate over the oop fields and metadata.
150   template <typename T, class OopClosureType>
151   inline void oop_oop_iterate(oop obj, OopClosureType* closure);
152 
153   // Reverse iteration
154   // Iterate over the oop fields and metadata.
155   template <typename T, class OopClosureType>
156   inline void oop_oop_iterate_reverse(oop obj, OopClosureType* closure);
157 
158   // Bounded range iteration
159   // Iterate over the oop fields and metadata.
160   template <typename T, class OopClosureType>
161   inline void oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
162 
163 private:
164   template <typename T, class OopClosureType>
165   inline void oop_oop_iterate_header(stackChunkOop chunk, OopClosureType* closure);
166 
167   template <typename T, class OopClosureType>
168   inline void oop_oop_iterate_header_bounded(stackChunkOop chunk, OopClosureType* closure, MemRegion mr);
169 
170   template <typename T, class OopClosureType>
171   inline void oop_oop_iterate_stack(stackChunkOop chunk, OopClosureType* closure);
172 
173   template <typename T, class OopClosureType>
174   inline void oop_oop_iterate_stack_bounded(stackChunkOop chunk, OopClosureType* closure, MemRegion mr);
175 
176   template <typename T, class OopClosureType>
177   inline void oop_oop_iterate_stack_with_bitmap(stackChunkOop chunk, OopClosureType* closure, intptr_t* start, intptr_t* end);
178 
179   template <typename OopT>
180   void oop_oop_iterate_lockstack(stackChunkOop chunk, OopIterateClosure* closure, MemRegion mr);
181 
182   void do_methods(stackChunkOop chunk, OopIterateClosure* cl);
183 
184   void oop_oop_iterate_stack_slow(stackChunkOop chunk, OopIterateClosure* closure, MemRegion mr);
185 };
186 
187 #endif // SHARE_OOPS_INSTANCESTACKCHUNKKLASS_HPP