1 /*
  2  * Copyright (c) 2020, 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_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 VMStructs;
104   friend class InstanceKlass;
105   friend class Continuations;
106 
107 public:
108   static const KlassKind Kind = InstanceStackChunkKlassKind;
109 
110 private:
111   static int _offset_of_stack;
112 
113   InstanceStackChunkKlass(const ClassFileParser& parser);
114 
115 public:
116   InstanceStackChunkKlass();
117 
118   // Casting from Klass*
119   static InstanceStackChunkKlass* cast(Klass* k) {
120     assert(k->is_stack_chunk_instance_klass(), "cast to InstanceStackChunkKlass");
121     return static_cast<InstanceStackChunkKlass*>(k);
122   }
123 
124   inline size_t instance_size(size_t stack_size_in_words) const;
125 
126   static inline size_t bitmap_size_in_bits(size_t stack_size_in_words); // In bits
127   static inline size_t bitmap_size(size_t stack_size_in_words); // In words
128   static inline size_t gc_data_size(size_t stack_size_in_words); // In words
129 
130   // Returns the size of the instance including the stack data.
131   virtual size_t oop_size(oop obj) const override;
132 
133   static void serialize_offsets(class SerializeClosure* f) NOT_CDS_RETURN;
134 
135   static void print_chunk(const stackChunkOop chunk, bool verbose, outputStream* st = tty);
136 
137 #ifndef PRODUCT
138   void oop_print_on(oop obj, outputStream* st) override;
139 #endif
140 
141   // Stack offset is an offset into the Heap
142   static int offset_of_stack() { return _offset_of_stack; }
143   static void init_offset_of_stack();
144 
145   // Oop fields (and metadata) iterators
146   //
147   // The InstanceClassLoaderKlass iterators also visit the CLD pointer (or mirror of anonymous klasses).
148 
149   // Forward iteration
150   // Iterate over the oop fields and metadata.
151   template <typename T, class OopClosureType>
152   inline void oop_oop_iterate(oop obj, OopClosureType* closure);
153 
154   // Reverse iteration
155   // Iterate over the oop fields and metadata.
156   template <typename T, class OopClosureType>
157   inline void oop_oop_iterate_reverse(oop obj, OopClosureType* closure);
158 
159   // Bounded range iteration
160   // Iterate over the oop fields and metadata.
161   template <typename T, class OopClosureType>
162   inline void oop_oop_iterate_bounded(oop obj, OopClosureType* closure, MemRegion mr);
163 
164 private:
165   template <typename T, class OopClosureType>
166   inline void oop_oop_iterate_header(stackChunkOop chunk, OopClosureType* closure);
167 
168   template <typename T, class OopClosureType>
169   inline void oop_oop_iterate_header_bounded(stackChunkOop chunk, OopClosureType* closure, MemRegion mr);
170 
171   template <typename T, class OopClosureType>
172   inline void oop_oop_iterate_stack(stackChunkOop chunk, OopClosureType* closure);
173 
174   template <typename T, class OopClosureType>
175   inline void oop_oop_iterate_stack_bounded(stackChunkOop chunk, OopClosureType* closure, MemRegion mr);
176 
177   template <typename T, class OopClosureType>
178   inline void oop_oop_iterate_stack_with_bitmap(stackChunkOop chunk, OopClosureType* closure, intptr_t* start, intptr_t* end);
179 
180   template <typename OopT>
181   void oop_oop_iterate_lockstack(stackChunkOop chunk, OopIterateClosure* closure, MemRegion mr);
182 
183   void do_methods(stackChunkOop chunk, OopIterateClosure* cl);
184 
185   void oop_oop_iterate_stack_slow(stackChunkOop chunk, OopIterateClosure* closure, MemRegion mr);
186 };
187 
188 #endif // SHARE_OOPS_INSTANCESTACKCHUNKKLASS_HPP