1 /*
2  * Copyright (c) 2000, 2019, 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), NULL },
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 pointer volatile field,
167 // e.g.: "static ObjectMonitor * volatile g_block_list;"
168 #define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type)    \
169  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&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), NULL, 0, offset_of(typeName, fieldName), NULL },
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), NULL, 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  { NULL, NULL, NULL, 0, 0, NULL }
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  {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName;                   \
193   assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
194 
195 // This macro checks the type of a volatile VMStructEntry by comparing pointer types
196 #define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)        \
197  {typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; }
198 
199 // This macro checks the type of a static VMStructEntry by comparing pointer types
200 #define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)                    \
201  {type* dummy = &typeName::fieldName; }
202 
203 // This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
204 // e.g.: "static ObjectMonitor * volatile g_block_list;"
205 #define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type)       \
206  {type volatile * dummy = &typeName::fieldName; }
207 
208 // This macro ensures the type of a field and its containing type are
209 // present in the type table. The assertion string is shorter than
210 // preferable because (incredibly) of a bug in Solstice NFS client
211 // which seems to prevent very long lines from compiling. This assertion
212 // means that an entry in VMStructs::localHotSpotVMStructs[] was not
213 // found in VMStructs::localHotSpotVMTypes[].
214 #define ENSURE_FIELD_TYPE_PRESENT(typeName, fieldName, type)                       \
215  { assert(findType(QUOTE(typeName)) != 0, "type \"" QUOTE(typeName) "\" not found in type table"); \
216    assert(findType(QUOTE(type)) != 0, "type \"" QUOTE(type) "\" not found in type table"); }
217 
218 // This is a no-op macro for unchecked fields
219 #define CHECK_NO_OP(a, b, c)
220 
221 #endif // ASSERT
222 
223 //--------------------------------------------------------------------------------
224 // VMTypeEntry macros
225 //
226 
227 #define GENERATE_VM_TYPE_ENTRY(type, superclass) \
228  { QUOTE(type), QUOTE(superclass), 0, 0, 0, sizeof(type) },
229 
230 #define GENERATE_TOPLEVEL_VM_TYPE_ENTRY(type) \
231  { QUOTE(type), NULL,              0, 0, 0, sizeof(type) },
232 
233 #define GENERATE_OOP_VM_TYPE_ENTRY(type) \
234  { QUOTE(type), NULL,              1, 0, 0, sizeof(type) },
235 
236 #define GENERATE_INTEGER_VM_TYPE_ENTRY(type) \
237  { QUOTE(type), NULL,              0, 1, 0, sizeof(type) },
238 
239 #define GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY(type) \
240  { QUOTE(type), NULL,              0, 1, 1, sizeof(type) },
241 
242 #define GENERATE_VM_TYPE_LAST_ENTRY() \
243  { NULL, NULL, 0, 0, 0, 0 }
244 
245 #define CHECK_VM_TYPE_ENTRY(type, superclass) \
246  { type* dummyObj = NULL; superclass* dummySuperObj = dummyObj; }
247 
248 #define CHECK_VM_TYPE_NO_OP(a)
249 #define CHECK_SINGLE_ARG_VM_TYPE_NO_OP(a)
250 
251 
252 //--------------------------------------------------------------------------------
253 // VMIntConstantEntry macros
254 //
255 
256 #define GENERATE_VM_INT_CONSTANT_ENTRY(name) \
257  { QUOTE(name), (int32_t) name },
258 
259 #define GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY(name, value) \
260  { (name), (int32_t)(value) },
261 
262 #define GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value) \
263  { name, (int32_t) value },
264 
265 // This macro generates the sentinel value indicating the end of the list
266 #define GENERATE_VM_INT_CONSTANT_LAST_ENTRY() \
267  { NULL, 0 }
268 
269 
270 //--------------------------------------------------------------------------------
271 // VMLongConstantEntry macros
272 //
273 
274 #define GENERATE_VM_LONG_CONSTANT_ENTRY(name) \
275   { QUOTE(name), name },
276 
277 #define GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY(name, value) \
278   { name, value },
279 
280 // This macro generates the sentinel value indicating the end of the list
281 #define GENERATE_VM_LONG_CONSTANT_LAST_ENTRY() \
282  { NULL, 0 }
283 
284 
285 //--------------------------------------------------------------------------------
286 // VMAddressEntry macros
287 //
288 
289 #define GENERATE_VM_ADDRESS_ENTRY(name) \
290   { QUOTE(name), (void*) (name) },
291 
292 #define GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY(name, value) \
293   { name, (void*) (value) },
294 
295 #define GENERATE_VM_FUNCTION_ENTRY(name) \
296   { QUOTE(name), CAST_FROM_FN_PTR(void*, &(name)) },
297 
298 // This macro generates the sentinel value indicating the end of the list
299 #define GENERATE_VM_ADDRESS_LAST_ENTRY() \
300  { NULL, NULL }
301 
302 #endif // SHARE_RUNTIME_VMSTRUCTS_HPP
303