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

apetushkov@9858 1 /*
apetushkov@9858 2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
apetushkov@9858 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
apetushkov@9858 4 *
apetushkov@9858 5 * This code is free software; you can redistribute it and/or modify it
apetushkov@9858 6 * under the terms of the GNU General Public License version 2 only, as
apetushkov@9858 7 * published by the Free Software Foundation.
apetushkov@9858 8 *
apetushkov@9858 9 * This code is distributed in the hope that it will be useful, but WITHOUT
apetushkov@9858 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
apetushkov@9858 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
apetushkov@9858 12 * version 2 for more details (a copy is included in the LICENSE file that
apetushkov@9858 13 * accompanied this code).
apetushkov@9858 14 *
apetushkov@9858 15 * You should have received a copy of the GNU General Public License version
apetushkov@9858 16 * 2 along with this work; if not, write to the Free Software Foundation,
apetushkov@9858 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
apetushkov@9858 18 *
apetushkov@9858 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
apetushkov@9858 20 * or visit www.oracle.com if you need additional information or have any
apetushkov@9858 21 * questions.
apetushkov@9858 22 *
apetushkov@9858 23 */
apetushkov@9858 24
apetushkov@9858 25 #ifndef SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP
apetushkov@9858 26 #define SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP
apetushkov@9858 27
apetushkov@9858 28 #include "memory/allocation.hpp"
apetushkov@9858 29
apetushkov@9858 30 //
apetushkov@9858 31 // Represents a piece of committed memory.
apetushkov@9858 32 //
apetushkov@9858 33 // u1* _pos <-- next store position
apetushkov@9858 34 // u1* _top <-- next unflushed position
apetushkov@9858 35 //
apetushkov@9858 36 // const void* _identity <-- acquired by
apetushkov@9858 37 //
apetushkov@9858 38 // Must be the owner before attempting stores.
apetushkov@9858 39 // Use acquire() and/or try_acquire() for exclusive access
apetushkov@9858 40 // to the (entire) buffer (cas identity).
apetushkov@9858 41 //
apetushkov@9858 42 // Stores to the buffer should uphold transactional semantics.
apetushkov@9858 43 // A new _pos must be updated only after all intended stores have completed.
apetushkov@9858 44 // The relation between _pos and _top must hold atomically,
apetushkov@9858 45 // e.g. the delta must always be fully parsable.
apetushkov@9858 46 // _top can move concurrently by other threads but is always <= _pos.
apetushkov@9858 47 //
apetushkov@9858 48 class JfrBuffer {
apetushkov@9858 49 private:
apetushkov@9858 50 JfrBuffer* _next;
apetushkov@9858 51 JfrBuffer* _prev;
apetushkov@9858 52 const void* volatile _identity;
apetushkov@9858 53 u1* _pos;
apetushkov@9858 54 mutable const u1* volatile _top;
apetushkov@9858 55 u2 _flags;
apetushkov@9858 56 u2 _header_size;
apetushkov@9858 57 u4 _size;
apetushkov@9858 58
apetushkov@9858 59 const u1* stable_top() const;
apetushkov@9858 60
apetushkov@9858 61 public:
apetushkov@9858 62 JfrBuffer();
apetushkov@9858 63 bool initialize(size_t header_size, size_t size, const void* id = NULL);
apetushkov@9858 64 void reinitialize();
apetushkov@9858 65 void concurrent_reinitialization();
apetushkov@9858 66 size_t discard();
apetushkov@9858 67 JfrBuffer* next() const {
apetushkov@9858 68 return _next;
apetushkov@9858 69 }
apetushkov@9858 70
apetushkov@9858 71 JfrBuffer* prev() const {
apetushkov@9858 72 return _prev;
apetushkov@9858 73 }
apetushkov@9858 74
apetushkov@9858 75 void set_next(JfrBuffer* next) {
apetushkov@9858 76 _next = next;
apetushkov@9858 77 }
apetushkov@9858 78
apetushkov@9858 79 void set_prev(JfrBuffer* prev) {
apetushkov@9858 80 _prev = prev;
apetushkov@9858 81 }
apetushkov@9858 82
apetushkov@9858 83 const u1* start() const {
apetushkov@9858 84 return ((const u1*)this) + _header_size;
apetushkov@9858 85 }
apetushkov@9858 86
apetushkov@9858 87 u1* start() {
apetushkov@9858 88 return ((u1*)this) + _header_size;
apetushkov@9858 89 }
apetushkov@9858 90
apetushkov@9858 91 const u1* end() const {
apetushkov@9858 92 return start() + size();
apetushkov@9858 93 }
apetushkov@9858 94
apetushkov@9858 95 const u1* pos() const {
apetushkov@9858 96 return _pos;
apetushkov@9858 97 }
apetushkov@9858 98
apetushkov@9858 99 u1* pos() {
apetushkov@9858 100 return _pos;
apetushkov@9858 101 }
apetushkov@9858 102
apetushkov@9858 103 u1** pos_address() {
apetushkov@9858 104 return (u1**)&_pos;
apetushkov@9858 105 }
apetushkov@9858 106
apetushkov@9858 107 void set_pos(u1* new_pos) {
apetushkov@9858 108 assert(new_pos <= end(), "invariant");
apetushkov@9858 109 _pos = new_pos;
apetushkov@9858 110 }
apetushkov@9858 111
apetushkov@9858 112 void set_pos(size_t size) {
apetushkov@9858 113 assert(_pos + size <= end(), "invariant");
apetushkov@9858 114 _pos += size;
apetushkov@9858 115 }
apetushkov@9858 116
apetushkov@9858 117 const u1* top() const;
apetushkov@9858 118 void set_top(const u1* new_top);
apetushkov@9858 119 const u1* concurrent_top() const;
apetushkov@9858 120 void set_concurrent_top(const u1* new_top);
apetushkov@9858 121
apetushkov@9858 122 size_t header_size() const {
apetushkov@9858 123 return _header_size;
apetushkov@9858 124 }
apetushkov@9858 125
apetushkov@9858 126 size_t size() const {
apetushkov@9858 127 return _size * BytesPerWord;
apetushkov@9858 128 }
apetushkov@9858 129
apetushkov@9858 130 size_t total_size() const {
apetushkov@9858 131 return header_size() + size();
apetushkov@9858 132 }
apetushkov@9858 133
apetushkov@9858 134 size_t free_size() const {
apetushkov@9858 135 return end() - pos();
apetushkov@9858 136 }
apetushkov@9858 137
apetushkov@9858 138 size_t unflushed_size() const;
apetushkov@9858 139
apetushkov@9858 140 bool empty() const {
apetushkov@9858 141 return pos() == start();
apetushkov@9858 142 }
apetushkov@9858 143
apetushkov@9858 144 const void* identity() const {
apetushkov@9858 145 return _identity;
apetushkov@9858 146 }
apetushkov@9858 147
apetushkov@9858 148 void clear_identity();
apetushkov@9858 149
apetushkov@9858 150 void acquire(const void* id);
apetushkov@9858 151 bool try_acquire(const void* id);
apetushkov@9928 152 bool acquired_by(const void* id) const;
apetushkov@9928 153 bool acquired_by_self() const;
apetushkov@9858 154 void release();
apetushkov@9858 155
apetushkov@9858 156 void move(JfrBuffer* const to, size_t size);
apetushkov@9858 157 void concurrent_move_and_reinitialize(JfrBuffer* const to, size_t size);
apetushkov@9858 158
apetushkov@9858 159 bool transient() const;
apetushkov@9858 160 void set_transient();
apetushkov@9858 161 void clear_transient();
apetushkov@9858 162
apetushkov@9858 163 bool lease() const;
apetushkov@9858 164 void set_lease();
apetushkov@9858 165 void clear_lease();
apetushkov@9858 166
apetushkov@9858 167 bool retired() const;
apetushkov@9858 168 void set_retired();
apetushkov@9858 169 void clear_retired();
apetushkov@9858 170 };
apetushkov@9858 171
apetushkov@9858 172 class JfrAgeNode : public JfrBuffer {
apetushkov@9858 173 private:
apetushkov@9858 174 JfrBuffer* _retired;
apetushkov@9858 175
apetushkov@9858 176 public:
apetushkov@9858 177 JfrAgeNode() : _retired(NULL) {}
apetushkov@9858 178 void set_retired_buffer(JfrBuffer* retired) {
apetushkov@9858 179 _retired = retired;
apetushkov@9858 180 }
apetushkov@9858 181 JfrBuffer* retired_buffer() const {
apetushkov@9858 182 return _retired;
apetushkov@9858 183 }
apetushkov@9858 184 };
apetushkov@9858 185
apetushkov@9858 186 #endif // SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP

mercurial