src/share/vm/jfr/recorder/storage/jfrBuffer.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) 2012, 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_JFRBUFFER_HPP
    26 #define SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP
    28 #include "memory/allocation.hpp"
    30 //
    31 // Represents a piece of committed memory.
    32 //
    33 // u1* _pos <-- next store position
    34 // u1* _top <-- next unflushed position
    35 //
    36 // const void* _identity <-- acquired by
    37 //
    38 // Must be the owner before attempting stores.
    39 // Use acquire() and/or try_acquire() for exclusive access
    40 // to the (entire) buffer (cas identity).
    41 //
    42 // Stores to the buffer should uphold transactional semantics.
    43 // A new _pos must be updated only after all intended stores have completed.
    44 // The relation between _pos and _top must hold atomically,
    45 // e.g. the delta must always be fully parsable.
    46 // _top can move concurrently by other threads but is always <= _pos.
    47 //
    48 class JfrBuffer {
    49  private:
    50   JfrBuffer* _next;
    51   JfrBuffer* _prev;
    52   const void* volatile _identity;
    53   u1* _pos;
    54   mutable const u1* volatile _top;
    55   u2 _flags;
    56   u2 _header_size;
    57   u4 _size;
    59   const u1* stable_top() const;
    61  public:
    62   JfrBuffer();
    63   bool initialize(size_t header_size, size_t size, const void* id = NULL);
    64   void reinitialize();
    65   void concurrent_reinitialization();
    66   size_t discard();
    67   JfrBuffer* next() const {
    68     return _next;
    69   }
    71   JfrBuffer* prev() const {
    72     return _prev;
    73   }
    75   void set_next(JfrBuffer* next) {
    76     _next = next;
    77   }
    79   void set_prev(JfrBuffer* prev) {
    80     _prev = prev;
    81   }
    83   const u1* start() const {
    84     return ((const u1*)this) + _header_size;
    85   }
    87   u1* start() {
    88     return ((u1*)this) + _header_size;
    89   }
    91   const u1* end() const {
    92     return start() + size();
    93   }
    95   const u1* pos() const {
    96     return _pos;
    97   }
    99   u1* pos() {
   100     return _pos;
   101   }
   103   u1** pos_address() {
   104     return (u1**)&_pos;
   105   }
   107   void set_pos(u1* new_pos) {
   108     assert(new_pos <= end(), "invariant");
   109     _pos = new_pos;
   110   }
   112   void set_pos(size_t size) {
   113     assert(_pos + size <= end(), "invariant");
   114     _pos += size;
   115   }
   117   const u1* top() const;
   118   void set_top(const u1* new_top);
   119   const u1* concurrent_top() const;
   120   void set_concurrent_top(const u1* new_top);
   122   size_t header_size() const {
   123     return _header_size;
   124   }
   126   size_t size() const {
   127     return _size * BytesPerWord;
   128   }
   130   size_t total_size() const {
   131     return header_size() + size();
   132   }
   134   size_t free_size() const {
   135     return end() - pos();
   136   }
   138   size_t unflushed_size() const;
   140   bool empty() const {
   141     return pos() == start();
   142   }
   144   const void* identity() const {
   145     return _identity;
   146   }
   148   void clear_identity();
   150   void acquire(const void* id);
   151   bool try_acquire(const void* id);
   152   bool acquired_by(const void* id) const;
   153   bool acquired_by_self() const;
   154   void release();
   156   void move(JfrBuffer* const to, size_t size);
   157   void concurrent_move_and_reinitialize(JfrBuffer* const to, size_t size);
   159   bool transient() const;
   160   void set_transient();
   161   void clear_transient();
   163   bool lease() const;
   164   void set_lease();
   165   void clear_lease();
   167   bool retired() const;
   168   void set_retired();
   169   void clear_retired();
   170 };
   172 class JfrAgeNode : public JfrBuffer {
   173  private:
   174   JfrBuffer* _retired;
   176  public:
   177   JfrAgeNode() : _retired(NULL) {}
   178   void set_retired_buffer(JfrBuffer* retired) {
   179     _retired = retired;
   180   }
   181   JfrBuffer* retired_buffer() const {
   182     return _retired;
   183   }
   184 };
   186 #endif // SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP

mercurial