src/share/vm/jfr/recorder/checkpoint/types/jfrTypeManager.cpp

Mon, 12 Aug 2019 18:30:40 +0300

author
apetushkov
date
Mon, 12 Aug 2019 18:30:40 +0300
changeset 9858
b985cbb00e68
permissions
-rw-r--r--

8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens

     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  */
    25 #include "precompiled.hpp"
    26 #include "jfr/metadata/jfrSerializer.hpp"
    27 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
    28 #include "jfr/recorder/checkpoint/types/jfrType.hpp"
    29 #include "jfr/recorder/checkpoint/types/jfrTypeManager.hpp"
    30 #include "jfr/utilities/jfrDoublyLinkedList.hpp"
    31 #include "jfr/utilities/jfrIterator.hpp"
    32 #include "runtime/safepoint.hpp"
    33 #include "runtime/thread.inline.hpp"
    34 #include "utilities/exceptions.hpp"
    35 #include "runtime/semaphore.hpp"
    37 class JfrSerializerRegistration : public JfrCHeapObj {
    38  private:
    39   JfrSerializerRegistration* _next;
    40   JfrSerializerRegistration* _prev;
    41   JfrSerializer* _serializer;
    42   mutable JfrCheckpointBlobHandle _cache;
    43   JfrTypeId _id;
    44   bool _permit_cache;
    46  public:
    47   JfrSerializerRegistration(JfrTypeId id, bool permit_cache, JfrSerializer* serializer) :
    48     _next(NULL), _prev(NULL), _serializer(serializer), _cache(), _id(id), _permit_cache(permit_cache) {}
    50   ~JfrSerializerRegistration() {
    51     delete _serializer;
    52   }
    54   JfrSerializerRegistration* next() const {
    55     return _next;
    56   }
    58   void set_next(JfrSerializerRegistration* next) {
    59     _next = next;
    60   }
    62   JfrSerializerRegistration* prev() const {
    63     return _prev;
    64   }
    66   void set_prev(JfrSerializerRegistration* prev) {
    67     _prev = prev;
    68   }
    70   JfrTypeId id() const {
    71     return _id;
    72   }
    74   void invoke(JfrCheckpointWriter& writer) const;
    75 };
    77 void JfrSerializerRegistration::invoke(JfrCheckpointWriter& writer) const {
    78   if (_cache.valid()) {
    79     writer.increment();
    80     _cache->write(writer);
    81     return;
    82   }
    83   const JfrCheckpointContext ctx = writer.context();
    84   // serialize the type id before invoking callback
    85   writer.write_type(_id);
    86   const intptr_t start = writer.current_offset();
    87   // invoke the serializer routine
    88   _serializer->serialize(writer);
    89   if (start == writer.current_offset() ) {
    90     // the serializer implementation did nothing, rewind to restore
    91     writer.set_context(ctx);
    92     return;
    93   }
    94   if (_permit_cache) {
    95     _cache = writer.copy(&ctx);
    96   }
    97 }
    99 class SerializerRegistrationGuard : public StackObj {
   100  private:
   101   static Semaphore _mutex_semaphore;
   102  public:
   103   SerializerRegistrationGuard() {
   104     _mutex_semaphore.wait();
   105   }
   106   ~SerializerRegistrationGuard() {
   107     _mutex_semaphore.signal();
   108   }
   109 };
   111 Semaphore SerializerRegistrationGuard::_mutex_semaphore(1);
   113 typedef JfrDoublyLinkedList<JfrSerializerRegistration> List;
   114 typedef StopOnNullIterator<const List> Iterator;
   115 static List types;
   116 static List safepoint_types;
   118 void JfrTypeManager::clear() {
   119   SerializerRegistrationGuard guard;
   120   Iterator iter(types);
   121   JfrSerializerRegistration* registration;
   122   while (iter.has_next()) {
   123     registration = types.remove(iter.next());
   124     assert(registration != NULL, "invariant");
   125     delete registration;
   126   }
   127   Iterator sp_type_iter(safepoint_types);
   128   while (sp_type_iter.has_next()) {
   129     registration = safepoint_types.remove(sp_type_iter.next());
   130     assert(registration != NULL, "invariant");
   131     delete registration;
   132   }
   133 }
   135 void JfrTypeManager::write_types(JfrCheckpointWriter& writer) {
   136   const Iterator iter(types);
   137   while (iter.has_next()) {
   138     iter.next()->invoke(writer);
   139   }
   140 }
   142 void JfrTypeManager::write_safepoint_types(JfrCheckpointWriter& writer) {
   143   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   144   const Iterator iter(safepoint_types);
   145   while (iter.has_next()) {
   146     iter.next()->invoke(writer);
   147   }
   148 }
   150 void JfrTypeManager::write_type_set() {
   151   // can safepoint here because of PackageTable_lock
   152   MutexLockerEx lock(SafepointSynchronize::is_at_safepoint() ? NULL : PackageTable_lock);
   153   JfrCheckpointWriter writer(true, true, Thread::current());
   154   TypeSet set;
   155   set.serialize(writer);
   156 }
   158 void JfrTypeManager::write_type_set_for_unloaded_classes() {
   159   assert(SafepointSynchronize::is_at_safepoint(), "invariant");
   160   JfrCheckpointWriter writer(false, true, Thread::current());
   161   ClassUnloadTypeSet class_unload_set;
   162   class_unload_set.serialize(writer);
   163 }
   165 void JfrTypeManager::create_thread_checkpoint(JavaThread* jt) {
   166   assert(jt != NULL, "invariant");
   167   JfrThreadConstant type_thread(jt);
   168   JfrCheckpointWriter writer(false, true, jt);
   169   writer.write_type(TYPE_THREAD);
   170   type_thread.serialize(writer);
   171   // create and install a checkpoint blob
   172   jt->jfr_thread_local()->set_thread_checkpoint(writer.checkpoint_blob());
   173   assert(jt->jfr_thread_local()->has_thread_checkpoint(), "invariant");
   174 }
   176 void JfrTypeManager::write_thread_checkpoint(JavaThread* jt) {
   177   assert(jt != NULL, "JavaThread is NULL!");
   178   ResourceMark rm(jt);
   179   if (jt->jfr_thread_local()->has_thread_checkpoint()) {
   180     JfrCheckpointWriter writer(false, false, jt);
   181     jt->jfr_thread_local()->thread_checkpoint()->write(writer);
   182   } else {
   183     JfrThreadConstant type_thread(jt);
   184     JfrCheckpointWriter writer(false, true, jt);
   185     writer.write_type(TYPE_THREAD);
   186     type_thread.serialize(writer);
   187   }
   188 }
   190 #ifdef ASSERT
   191 static void assert_not_registered_twice(JfrTypeId id, List& list) {
   192   const Iterator iter(list);
   193   while (iter.has_next()) {
   194     assert(iter.next()->id() != id, "invariant");
   195   }
   196 }
   197 #endif
   199 static bool register_type(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer) {
   200   assert(serializer != NULL, "invariant");
   201   JfrSerializerRegistration* const registration = new JfrSerializerRegistration(id, permit_cache, serializer);
   202   if (registration == NULL) {
   203     delete serializer;
   204     return false;
   205   }
   206   if (require_safepoint) {
   207     assert(!safepoint_types.in_list(registration), "invariant");
   208     DEBUG_ONLY(assert_not_registered_twice(id, safepoint_types);)
   209     safepoint_types.prepend(registration);
   210   } else {
   211     assert(!types.in_list(registration), "invariant");
   212     DEBUG_ONLY(assert_not_registered_twice(id, types);)
   213     types.prepend(registration);
   214   }
   215   return true;
   216 }
   218 bool JfrTypeManager::initialize() {
   219   SerializerRegistrationGuard guard;
   221   // register non-safepointing type serialization
   222   register_type(TYPE_FLAGVALUEORIGIN, false, true, new FlagValueOriginConstant());
   223   register_type(TYPE_INFLATECAUSE, false, true, new MonitorInflateCauseConstant());
   224   register_type(TYPE_GCCAUSE, false, true, new GCCauseConstant());
   225   register_type(TYPE_GCNAME, false, true, new GCNameConstant());
   226   register_type(TYPE_GCWHEN, false, true, new GCWhenConstant());
   227   register_type(TYPE_G1HEAPREGIONTYPE, false, true, new G1HeapRegionTypeConstant());
   228   register_type(TYPE_GCTHRESHOLDUPDATER, false, true, new GCThresholdUpdaterConstant());
   229   register_type(TYPE_METADATATYPE, false, true, new MetadataTypeConstant());
   230   register_type(TYPE_METASPACEOBJECTTYPE, false, true, new MetaspaceObjectTypeConstant());
   231   register_type(TYPE_G1YCTYPE, false, true, new G1YCTypeConstant());
   232   register_type(TYPE_REFERENCETYPE, false, true, new ReferenceTypeConstant());
   233   register_type(TYPE_NARROWOOPMODE, false, true, new NarrowOopModeConstant());
   234   register_type(TYPE_COMPILERPHASETYPE, false, true, new CompilerPhaseTypeConstant());
   235   register_type(TYPE_CODEBLOBTYPE, false, true, new CodeBlobTypeConstant());
   236   register_type(TYPE_VMOPERATIONTYPE, false, true, new VMOperationTypeConstant());
   237   register_type(TYPE_THREADSTATE, false, true, new ThreadStateConstant());
   239   // register safepointing type serialization
   240   register_type(TYPE_THREADGROUP, true, false, new JfrThreadGroupConstant());
   241   register_type(TYPE_THREAD, true, false, new JfrThreadConstantSet());
   242   return true;
   243 }
   245 // implementation for the static registration function exposed in the JfrSerializer api
   246 bool JfrSerializer::register_serializer(JfrTypeId id, bool require_safepoint, bool permit_cache, JfrSerializer* serializer) {
   247   SerializerRegistrationGuard guard;
   248   return register_type(id, require_safepoint, permit_cache, serializer);
   249 }

mercurial