src/share/vm/jfr/recorder/storage/jfrStorageUtils.inline.hpp

Wed, 17 Jun 2020 11:43:05 +0300

author
apetushkov
date
Wed, 17 Jun 2020 11:43:05 +0300
changeset 9928
d2c2cd90513e
parent 9858
b985cbb00e68
permissions
-rw-r--r--

8220293: Deadlock in JFR string pool
Reviewed-by: rehn, egahlin

     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 #ifndef SHARE_VM_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_INLINE_HPP
    26 #define SHARE_VM_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_INLINE_HPP
    28 #include "jfr/recorder/storage/jfrStorageUtils.hpp"
    29 #include "runtime/thread.inline.hpp"
    31 template <typename T>
    32 inline bool UnBufferedWriteToChunk<T>::write(T* t, const u1* data, size_t size) {
    33   _writer.write_unbuffered(data, size);
    34   _processed += size;
    35   return true;
    36 }
    38 template <typename T>
    39 inline bool DefaultDiscarder<T>::discard(T* t, const u1* data, size_t size) {
    40   _processed += size;
    41   return true;
    42 }
    44 template <typename Operation>
    45 inline bool ConcurrentWriteOp<Operation>::process(typename Operation::Type* t) {
    46   const u1* const current_top = t->concurrent_top();
    47   const size_t unflushed_size = t->pos() - current_top;
    48   if (unflushed_size == 0) {
    49     t->set_concurrent_top(current_top);
    50     return true;
    51   }
    52   const bool result = _operation.write(t, current_top, unflushed_size);
    53   t->set_concurrent_top(current_top + unflushed_size);
    54   return result;
    55 }
    57 template <typename Operation>
    58 inline bool ConcurrentWriteOpExcludeRetired<Operation>::process(typename Operation::Type* t) {
    59   if (t->retired()) {
    60     assert(t->empty(), "invariant");
    61     return true;
    62   }
    63   return ConcurrentWriteOp<Operation>::process(t);
    64 }
    66 template <typename Operation>
    67 inline bool MutexedWriteOp<Operation>::process(typename Operation::Type* t) {
    68   assert(t != NULL, "invariant");
    69   const u1* const current_top = t->top();
    70   const size_t unflushed_size = t->pos() - current_top;
    71   if (unflushed_size == 0) {
    72     return true;
    73   }
    74   const bool result = _operation.write(t, current_top, unflushed_size);
    75   t->set_top(current_top + unflushed_size);
    76   return result;
    77 }
    79 template <typename Type>
    80 static void retired_sensitive_acquire(Type* t) {
    81   assert(t != NULL, "invariant");
    82   if (t->retired()) {
    83     return;
    84   }
    85   Thread* const thread = Thread::current();
    86   while (!t->try_acquire(thread)) {
    87     if (t->retired()) {
    88       return;
    89     }
    90   }
    91 }
    93 template <typename Operation>
    94 inline bool ExclusiveOp<Operation>::process(typename Operation::Type* t) {
    95   retired_sensitive_acquire(t);
    96   assert(t->acquired_by_self() || t->retired(), "invariant");
    97   // User is required to ensure proper release of the acquisition
    98   return MutexedWriteOp<Operation>::process(t);
    99 }
   101 template <typename Operation>
   102 inline bool DiscardOp<Operation>::process(typename Operation::Type* t) {
   103   assert(t != NULL, "invariant");
   104   const u1* const current_top = _mode == concurrent ? t->concurrent_top() : t->top();
   105   const size_t unflushed_size = t->pos() - current_top;
   106   if (unflushed_size == 0) {
   107     if (_mode == concurrent) {
   108       t->set_concurrent_top(current_top);
   109     }
   110     return true;
   111   }
   112   const bool result = _operation.discard(t, current_top, unflushed_size);
   113   if (_mode == concurrent) {
   114     t->set_concurrent_top(current_top + unflushed_size);
   115   } else {
   116     t->set_top(current_top + unflushed_size);
   117   }
   118   return result;
   119 }
   121 #endif // SHARE_VM_JFR_RECORDER_STORAGE_JFRSTORAGEUTILS_INLINE_HPP

mercurial