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 */ 24 25 #ifndef SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP 26 #define SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP 27 28 #include "memory/allocation.hpp" 29 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; 58 59 const u1* stable_top() const; 60 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 } 70 71 JfrBuffer* prev() const { 72 return _prev; 73 } 74 75 void set_next(JfrBuffer* next) { 76 _next = next; 77 } 78 79 void set_prev(JfrBuffer* prev) { 80 _prev = prev; 81 } 82 83 const u1* start() const { 84 return ((const u1*)this) + _header_size; 85 } 86 87 u1* start() { 88 return ((u1*)this) + _header_size; 89 } 90 91 const u1* end() const { 92 return start() + size(); 93 } 94 95 const u1* pos() const { 96 return _pos; 97 } 98 99 u1* pos() { 100 return _pos; 101 } 102 103 u1** pos_address() { 104 return (u1**)&_pos; 105 } 106 107 void set_pos(u1* new_pos) { 108 assert(new_pos <= end(), "invariant"); 109 _pos = new_pos; 110 } 111 112 void set_pos(size_t size) { 113 assert(_pos + size <= end(), "invariant"); 114 _pos += size; 115 } 116 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); 121 122 size_t header_size() const { 123 return _header_size; 124 } 125 126 size_t size() const { 127 return _size * BytesPerWord; 128 } 129 130 size_t total_size() const { 131 return header_size() + size(); 132 } 133 134 size_t free_size() const { 135 return end() - pos(); 136 } 137 138 size_t unflushed_size() const; 139 140 bool empty() const { 141 return pos() == start(); 142 } 143 144 const void* identity() const { 145 return _identity; 146 } 147 148 void clear_identity(); 149 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(); 155 156 void move(JfrBuffer* const to, size_t size); 157 void concurrent_move_and_reinitialize(JfrBuffer* const to, size_t size); 158 159 bool transient() const; 160 void set_transient(); 161 void clear_transient(); 162 163 bool lease() const; 164 void set_lease(); 165 void clear_lease(); 166 167 bool retired() const; 168 void set_retired(); 169 void clear_retired(); 170 }; 171 172 class JfrAgeNode : public JfrBuffer { 173 private: 174 JfrBuffer* _retired; 175 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 }; 185 186 #endif // SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP