1 /*
   2  * Copyright (c) 2016, 2018, 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_JFR_METADATA_JFRSERIALIZER_HPP
  26 #define SHARE_VM_JFR_METADATA_JFRSERIALIZER_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
  30 #include "jfrfiles/jfrTypes.hpp"
  31 
  32 /*
  33  * A "type" in Jfr is a binary relation defined by enumerating a set of <key, value> ordered pairs:
  34  *
  35  * { <1, myvalue>, <2, mysecondvalue>, ... }
  36  *
  37  * The key should be a type relative unique id. A value is an instance of the type.
  38  *
  39  * By defining and registering a type, keys can be written to event fields and the
  40  * framework will maintain the mapping to the corresponding value (if you register as below).
  41  *
  42  * Inherit JfrSerializer, create a CHeapObj instance and then use JfrSerializer::register_serializer(...) to register.
  43  * Once registered, the ownership of the serializer instance is transferred to Jfr.
  44  *
  45  * How to register:
  46  *
  47  * bool register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer)
  48  *
  49  * The type identifiers are machine generated into an enum located in jfrfiles/jfrTypes.hpp (included).
  50  *
  51  *  enum JfrTypeId {
  52  *    ...
  53  *    TYPE_THREADGROUP,
  54  *    TYPE_CLASSLOADER,
  55  *    TYPE_METHOD,
  56  *    TYPE_SYMBOL,
  57  *    TYPE_THREADSTATE,
  58  *    TYPE_INFLATECAUSE,
  59  *    ...
  60  *
  61  * id                 this is the id of the type your are defining (see the enum above).
  62  * require_safepoint  indicate if your type need to be evaluated and serialized under a safepoint.
  63  * permit_cache       indicate if your type constants are stable to be cached.
  64  *                    (implies the callback is invoked only once and the contents will be cached. Set this to true for static information).
  65  * serializer         the serializer instance.
  66  *
  67  * See below for guidance about how to implement serialize().
  68  *
  69  */
  70 class JfrSerializer : public CHeapObj<mtTracing> {
  71  public:
  72   virtual ~JfrSerializer() {}
  73   static bool register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer);
  74   virtual void serialize(JfrCheckpointWriter& writer) = 0;
  75 };
  76 
  77 /*
  78  * Defining serialize(JfrCheckpointWriter& writer):
  79  *
  80  *  Invoke writer.write_count(N) for the number of ordered pairs (cardinality) to be defined.
  81  *
  82  *  You then write each individual ordered pair, <key, value> ...
  83  *
  84  *  Here is a simple example, describing a type defining string constants:
  85  *
  86  *  void MyType::serialize(JfrCheckpointWriter& writer) {
  87  *    const int nof_causes = ObjectSynchronizer::inflate_cause_nof;
  88  *    writer.write_count(nof_causes);                           // write number of ordered pairs (mappings) to follow
  89  *    for (int i = 0; i < nof_causes; i++) {
  90  *      writer.write_key(i);                                    // write key
  91  *      writer.write(ObjectSynchronizer::inflate_cause_name((ObjectSynchronizer::InflateCause)i)); // write value
  92  *    }
  93  *  }
  94  *
  95  * Note that values can be complex, and can also referer to other types.
  96  *
  97  * Please see jfr/recorder/checkpoint/types/jfrType.cpp for reference.
  98  */
  99 
 100 #endif // SHARE_VM_JFR_METADATA_JFRSERIALIZER_HPP