src/hotspot/share/runtime/vmStructs.hpp
changeset 47216 71c04702a3d5
parent 46943 3cd94e2be178
child 51605 2ca553d34949
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2000, 2017, 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_VM_RUNTIME_VMSTRUCTS_HPP
       
    26 #define SHARE_VM_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 SparcWorks 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();
       
   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();
       
   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();
       
   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();
       
   133 
       
   134   /**
       
   135    * Table of addresses.
       
   136    */
       
   137   static VMAddressEntry localHotSpotVMAddresses[];
       
   138 
       
   139   // This is used to run any checking code necessary for validation of
       
   140   // the data structure (debug build only)
       
   141   static void init();
       
   142 
       
   143 #ifndef PRODUCT
       
   144   // Execute unit tests
       
   145   static void test();
       
   146 #endif
       
   147 
       
   148 private:
       
   149   // Look up a type in localHotSpotVMTypes using strcmp() (debug build only).
       
   150   // Returns 1 if found, 0 if not.
       
   151   //  debug_only(static int findType(const char* typeName);)
       
   152   static int findType(const char* typeName);
       
   153 };
       
   154 
       
   155 // This utility macro quotes the passed string
       
   156 #define QUOTE(x) #x
       
   157 
       
   158 //--------------------------------------------------------------------------------
       
   159 // VMStructEntry macros
       
   160 //
       
   161 
       
   162 // This macro generates a VMStructEntry line for a nonstatic field
       
   163 #define GENERATE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)              \
       
   164  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 0, offset_of(typeName, fieldName), NULL },
       
   165 
       
   166 // This macro generates a VMStructEntry line for a static field
       
   167 #define GENERATE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)                 \
       
   168  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
       
   169 
       
   170 // This macro generates a VMStructEntry line for a static pointer volatile field,
       
   171 // e.g.: "static ObjectMonitor * volatile gBlockList;"
       
   172 #define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type)    \
       
   173  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
       
   174 
       
   175 // This macro generates a VMStructEntry line for an unchecked
       
   176 // nonstatic field, in which the size of the type is also specified.
       
   177 // The type string is given as NULL, indicating an "opaque" type.
       
   178 #define GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, size)    \
       
   179   { QUOTE(typeName), QUOTE(fieldName), NULL, 0, offset_of(typeName, fieldName), NULL },
       
   180 
       
   181 // This macro generates a VMStructEntry line for an unchecked
       
   182 // static field, in which the size of the type is also specified.
       
   183 // The type string is given as NULL, indicating an "opaque" type.
       
   184 #define GENERATE_UNCHECKED_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, size)       \
       
   185  { QUOTE(typeName), QUOTE(fieldName), NULL, 1, 0, (void*) &typeName::fieldName },
       
   186 
       
   187 // This macro generates the sentinel value indicating the end of the list
       
   188 #define GENERATE_VM_STRUCT_LAST_ENTRY() \
       
   189  { NULL, NULL, NULL, 0, 0, NULL }
       
   190 
       
   191 // This macro checks the type of a VMStructEntry by comparing pointer types
       
   192 #define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)                 \
       
   193  {typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName;                   \
       
   194   assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
       
   195 
       
   196 // This macro checks the type of a volatile VMStructEntry by comparing pointer types
       
   197 #define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)        \
       
   198  {typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; }
       
   199 
       
   200 // This macro checks the type of a static VMStructEntry by comparing pointer types
       
   201 #define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type)                    \
       
   202  {type* dummy = &typeName::fieldName; }
       
   203 
       
   204 // This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
       
   205 // e.g.: "static ObjectMonitor * volatile gBlockList;"
       
   206 #define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type)       \
       
   207  {type volatile * dummy = &typeName::fieldName; }
       
   208 
       
   209 // This macro ensures the type of a field and its containing type are
       
   210 // present in the type table. The assertion string is shorter than
       
   211 // preferable because (incredibly) of a bug in Solstice NFS client
       
   212 // which seems to prevent very long lines from compiling. This assertion
       
   213 // means that an entry in VMStructs::localHotSpotVMStructs[] was not
       
   214 // found in VMStructs::localHotSpotVMTypes[].
       
   215 #define ENSURE_FIELD_TYPE_PRESENT(typeName, fieldName, type)                       \
       
   216  { assert(findType(QUOTE(typeName)) != 0, "type \"" QUOTE(typeName) "\" not found in type table"); \
       
   217    assert(findType(QUOTE(type)) != 0, "type \"" QUOTE(type) "\" not found in type table"); }
       
   218 
       
   219 // This is a no-op macro for unchecked fields
       
   220 #define CHECK_NO_OP(a, b, c)
       
   221 
       
   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_VM_RUNTIME_VMSTRUCTS_HPP