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 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