1 /*
  2  * Copyright (c) 2000, 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_RUNTIME_VMSTRUCTS_HPP
 26 #define SHARE_RUNTIME_VMSTRUCTS_HPP
 27 
 28 #include "utilities/debug.hpp"
 29 #include "utilities/globalDefinitions.hpp"
 30 #ifdef COMPILER1
 31 #include "c1/c1_Runtime1.hpp"
 32 #endif
 33 
 34 // This table encapsulates the debugging information required by the
 35 // serviceability agent in order to run. Specifically, we need to
 36 // understand the layout of certain C data structures (offsets, in
 37 // bytes, of their fields.)
 38 //
 39 // There are alternatives for the design of this mechanism, including
 40 // parsing platform-specific debugging symbols from a debug build into
 41 // a program database. While this current mechanism can be considered
 42 // to be a workaround for the inability to debug arbitrary C and C++
 43 // programs at the present time, it does have certain advantages.
 44 // First, it is platform-independent, which will vastly simplify the
 45 // initial bringup of the system both now and on future platforms.
 46 // Second, it is embedded within the VM, as opposed to being in a
 47 // separate program database; experience has shown that whenever
 48 // portions of a system are decoupled, version skew is problematic.
 49 // Third, generating a program database, for example for a product
 50 // build, would probably require two builds to be done: the desired
 51 // product build as well as an intermediary build with the PRODUCT
 52 // flag turned on but also compiled with -g, leading to a doubling of
 53 // the time required to get a serviceability agent-debuggable product
 54 // build. Fourth, and very significantly, this table probably
 55 // preserves more information about field types than stabs do; for
 56 // example, it preserves the fact that a field is a "jlong" rather
 57 // than transforming the type according to the typedef in jni_md.h,
 58 // which allows the Java-side code to identify "Java-sized" fields in
 59 // C++ data structures. If the symbol parsing mechanism was redone
 60 // using stabs, it might still be necessary to have a table somewhere
 61 // containing this information.
 62 //
 63 // Do not change the sizes or signedness of the integer values in
 64 // these data structures; they are fixed over in the serviceability
 65 // agent's Java code (for bootstrapping).
 66 
 67 typedef struct {
 68   const char* typeName;            // The type name containing the given field (example: "Klass")
 69   const char* fieldName;           // The field name within the type           (example: "_name")
 70   const char* typeString;          // Quoted name of the type of this field (example: "Symbol*";
 71                                    // parsed in Java to ensure type correctness
 72   int32_t  isStatic;               // Indicates whether following field is an offset or an address
 73   uint64_t offset;                 // Offset of field within structure; only used for nonstatic fields
 74   void* address;                   // Address of field; only used for static fields
 75                                    // ("offset" can not be reused because of apparent solstudio compiler bug
 76                                    // in generation of initializer data)
 77 } VMStructEntry;
 78 
 79 typedef struct {
 80   const char* typeName;            // Type name (example: "Method")
 81   const char* superclassName;      // Superclass name, or null if none (example: "oopDesc")
 82   int32_t isOopType;               // Does this type represent an oop typedef? (i.e., "Method*" or
 83                                    // "Klass*", but NOT "Method")
 84   int32_t isIntegerType;           // Does this type represent an integer type (of arbitrary size)?
 85   int32_t isUnsigned;              // If so, is it unsigned?
 86   uint64_t size;                   // Size, in bytes, of the type
 87 } VMTypeEntry;
 88 
 89 typedef struct {
 90   const char* name;                // Name of constant (example: "_thread_in_native")
 91   int32_t value;                   // Value of constant
 92 } VMIntConstantEntry;
 93 
 94 typedef struct {
 95   const char* name;                // Name of constant (example: "_thread_in_native")
 96   uint64_t value;                  // Value of constant
 97 } VMLongConstantEntry;
 98 
 99 typedef struct {
100   const char* name;                // Name of address (example: "SharedRuntime::register_finalizer")
101   void* value;                     // Value of address
102 } VMAddressEntry;
103 
104 // This class is a friend of most classes, to be able to access
105 // private fields
106 class VMStructs {
107 public:
108   // The last entry is identified over in the serviceability agent by
109   // the fact that it has a null fieldName
110   static VMStructEntry localHotSpotVMStructs[];
111   // The function to get localHotSpotVMStructs length
112   static size_t localHotSpotVMStructsLength() NOT_VM_STRUCTS_RETURN_(0);
113 
114   // The last entry is identified over in the serviceability agent by
115   // the fact that it has a null typeName
116   static VMTypeEntry   localHotSpotVMTypes[];
117   // The function to get localHotSpotVMTypes length
118   static size_t localHotSpotVMTypesLength() NOT_VM_STRUCTS_RETURN_(0);
119 
120   // Table of integer constants required by the serviceability agent.
121   // The last entry is identified over in the serviceability agent by
122   // the fact that it has a null typeName
123   static VMIntConstantEntry localHotSpotVMIntConstants[];
124   // The function to get localHotSpotVMIntConstants length
125   static size_t localHotSpotVMIntConstantsLength() NOT_VM_STRUCTS_RETURN_(0);
126 
127   // Table of long constants required by the serviceability agent.
128   // The last entry is identified over in the serviceability agent by
129   // the fact that it has a null typeName
130   static VMLongConstantEntry localHotSpotVMLongConstants[];
131   // The function to get localHotSpotVMIntConstants length
132   static size_t localHotSpotVMLongConstantsLength() NOT_VM_STRUCTS_RETURN_(0);
133 
134   /**
135    * Table of addresses.
136    */
137   static VMAddressEntry localHotSpotVMAddresses[];
138 
139 #ifdef ASSERT
140   // This is used to run any checking code necessary for validation of
141   // the data structure (debug build only)
142   static void init() NOT_VM_STRUCTS_RETURN;
143 
144 private:
145   // Look up a type in localHotSpotVMTypes using strcmp() (debug build only).
146   // Returns 1 if found, 0 if not.
147   static int findType(const char* typeName) NOT_VM_STRUCTS_RETURN_(0);
148 #endif // ASSERT
149 };
150 
151 // This utility macro quotes the passed string
152 #define QUOTE(x) #x
153 
154 //--------------------------------------------------------------------------------
155 // VMStructEntry macros
156 //
157 
158 // This macro generates a VMStructEntry line for a nonstatic field
159 #define GENERATE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)              \
160  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 0, offset_of(typeName, fieldName), nullptr },
161 
162 // This macro generates a VMStructEntry line for a static field
163 #define GENERATE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)                 \
164  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
165 
166 // This macro generates a VMStructEntry line for a static volatile field,
167 // e.g.: "static ObjectMonitor * volatile g_block_list;"
168 #define GENERATE_VOLATILE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)    \
169   { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (type*)&typeName::fieldName },
170 
171 // This macro generates a VMStructEntry line for an unchecked
172 // nonstatic field, in which the size of the type is also specified.
173 // The type string is given as null, indicating an "opaque" type.
174 #define GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, size)    \
175   { QUOTE(typeName), QUOTE(fieldName), nullptr, 0, offset_of(typeName, fieldName), nullptr },
176 
177 // This macro generates a VMStructEntry line for an unchecked
178 // static field, in which the size of the type is also specified.
179 // The type string is given as null, indicating an "opaque" type.
180 #define GENERATE_UNCHECKED_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, size)       \
181  { QUOTE(typeName), QUOTE(fieldName), nullptr, 1, 0, (void*) &typeName::fieldName },
182 
183 // This macro generates the sentinel value indicating the end of the list
184 #define GENERATE_VM_STRUCT_LAST_ENTRY() \
185  { nullptr, nullptr, nullptr, 0, 0, nullptr }
186 
187 
188 #ifdef ASSERT
189 
190 // This macro checks the type of a VMStructEntry by comparing pointer types
191 #define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) { \
192   static_assert( \
193     std::is_convertible< \
194       std::add_pointer_t<decltype(declval<typeName>().fieldName)>, \
195       std::add_pointer_t<type>>::value, \
196     "type mismatch for " XSTR(fieldName) " member of " XSTR(typeName)); \
197   assert(offset_of(typeName, fieldName) < sizeof(typeName), "..."); \
198 }
199 
200 // This macro checks the type of a volatile VMStructEntry by comparing pointer types
201 #define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
202   CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, std::add_volatile_t<type>)
203 
204 // This macro checks the type of a static VMStructEntry by comparing pointer types
205 #define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)                    \
206  {type* dummy = &typeName::fieldName; }
207 
208 // This macro checks the type of a static volatile VMStructEntry by comparing pointer types,
209 // e.g.: "static ObjectMonitor * volatile g_block_list;"
210 #define CHECK_VOLATILE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)       \
211  {type volatile * dummy = &typeName::fieldName; }
212 
213 // This macro ensures the type of a field and its containing type are
214 // present in the type table. The assertion string is shorter than
215 // preferable because (incredibly) of a bug in Solstice NFS client
216 // which seems to prevent very long lines from compiling. This assertion
217 // means that an entry in VMStructs::localHotSpotVMStructs[] was not
218 // found in VMStructs::localHotSpotVMTypes[].
219 #define ENSURE_FIELD_TYPE_PRESENT(typeName, fieldName, type)                       \
220  { assert(findType(QUOTE(typeName)) != 0, "type \"" QUOTE(typeName) "\" not found in type table"); \
221    assert(findType(QUOTE(type)) != 0, "type \"" QUOTE(type) "\" not found in type table"); }
222 
223 // This is a no-op macro for unchecked fields
224 #define CHECK_NO_OP(a, b, c)
225 
226 #endif // ASSERT
227 
228 //--------------------------------------------------------------------------------
229 // VMTypeEntry macros
230 //
231 
232 #define GENERATE_VM_TYPE_ENTRY(type, superclass) \
233  { QUOTE(type), QUOTE(superclass), 0, 0, 0, sizeof(type) },
234 
235 #define GENERATE_TOPLEVEL_VM_TYPE_ENTRY(type) \
236  { QUOTE(type), nullptr,              0, 0, 0, sizeof(type) },
237 
238 #define GENERATE_OOP_VM_TYPE_ENTRY(type) \
239  { QUOTE(type), nullptr,              1, 0, 0, sizeof(type) },
240 
241 #define GENERATE_INTEGER_VM_TYPE_ENTRY(type) \
242  { QUOTE(type), nullptr,              0, 1, 0, sizeof(type) },
243 
244 #define GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY(type) \
245  { QUOTE(type), nullptr,              0, 1, 1, sizeof(type) },
246 
247 #define GENERATE_VM_TYPE_LAST_ENTRY() \
248  { nullptr, nullptr, 0, 0, 0, 0 }
249 
250 #define CHECK_VM_TYPE_ENTRY(type, superclass) \
251  { type* dummyObj = nullptr; superclass* dummySuperObj = dummyObj; }
252 
253 #define CHECK_VM_TYPE_NO_OP(a)
254 #define CHECK_SINGLE_ARG_VM_TYPE_NO_OP(a)
255 
256 
257 //--------------------------------------------------------------------------------
258 // VMIntConstantEntry macros
259 //
260 
261 #define GENERATE_VM_INT_CONSTANT_ENTRY(name) \
262  { QUOTE(name), (int32_t) name },
263 
264 #define GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY(name, value) \
265  { (name), (int32_t)(value) },
266 
267 #define GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value) \
268  { name, (int32_t) value },
269 
270 // This macro generates the sentinel value indicating the end of the list
271 #define GENERATE_VM_INT_CONSTANT_LAST_ENTRY() \
272  { nullptr, 0 }
273 
274 
275 //--------------------------------------------------------------------------------
276 // VMLongConstantEntry macros
277 //
278 
279 #define GENERATE_VM_LONG_CONSTANT_ENTRY(name) \
280   { QUOTE(name), name },
281 
282 #define GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY(name, value) \
283   { name, value },
284 
285 // This macro generates the sentinel value indicating the end of the list
286 #define GENERATE_VM_LONG_CONSTANT_LAST_ENTRY() \
287  { nullptr, 0 }
288 
289 
290 //--------------------------------------------------------------------------------
291 // VMAddressEntry macros
292 //
293 
294 #define GENERATE_VM_ADDRESS_ENTRY(name) \
295   { QUOTE(name), (void*) (name) },
296 
297 #define GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY(name, value) \
298   { name, (void*) (value) },
299 
300 #define GENERATE_VM_FUNCTION_ENTRY(name) \
301   { QUOTE(name), CAST_FROM_FN_PTR(void*, &(name)) },
302 
303 // This macro generates the sentinel value indicating the end of the list
304 #define GENERATE_VM_ADDRESS_LAST_ENTRY() \
305  { nullptr, nullptr }
306 
307 #endif // SHARE_RUNTIME_VMSTRUCTS_HPP