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 void clear_flags(); 61 62 public: 63 JfrBuffer(); 64 bool initialize(size_t header_size, size_t size, const void* id = NULL); 65 void reinitialize(); 66 void concurrent_reinitialization(); 67 size_t discard(); 68 JfrBuffer* next() const { 69 return _next; 70 } 71 72 JfrBuffer* prev() const { 73 return _prev; 74 } 75 76 void set_next(JfrBuffer* next) { 77 _next = next; 78 } 79 80 void set_prev(JfrBuffer* prev) { 81 _prev = prev; 82 } 83 84 const u1* start() const { 85 return ((const u1*)this) + _header_size; 86 } 87 88 u1* start() { 89 return ((u1*)this) + _header_size; 90 } 91 92 const u1* end() const { 93 return start() + size(); 94 } 95 96 const u1* pos() const { 97 return _pos; 98 } 99 100 u1* pos() { 101 return _pos; 102 } 103 104 u1** pos_address() { 105 return (u1**)&_pos; 106 } 107 108 void set_pos(u1* new_pos) { 109 assert(new_pos <= end(), "invariant"); 110 _pos = new_pos; 111 } 112 113 void set_pos(size_t size) { 114 assert(_pos + size <= end(), "invariant"); 115 _pos += size; 116 } 117 118 const u1* top() const; 119 void set_top(const u1* new_top); 120 const u1* concurrent_top() const; 121 void set_concurrent_top(const u1* new_top); 122 123 size_t header_size() const { 124 return _header_size; 125 } 126 127 size_t size() const { 128 return _size * BytesPerWord; 129 } 130 131 size_t total_size() const { 132 return header_size() + size(); 133 } 134 135 size_t free_size() const { 136 return end() - pos(); 137 } 138 139 size_t unflushed_size() const; 140 141 bool empty() const { 142 return pos() == start(); 143 } 144 145 const void* identity() const { 146 return _identity; 147 } 148 149 void clear_identity(); 150 151 void acquire(const void* id); 152 bool try_acquire(const void* id); 153 void release(); 154 155 void move(JfrBuffer* const to, size_t size); 156 void concurrent_move_and_reinitialize(JfrBuffer* const to, size_t size); 157 158 bool transient() const; 159 void set_transient(); 160 void clear_transient(); 161 162 bool lease() const; 163 void set_lease(); 164 void clear_lease(); 165 166 bool retired() const; 167 void set_retired(); 168 void clear_retired(); 169 170 debug_only(bool acquired_by_self() const;) 171 }; 172 173 class JfrAgeNode : public JfrBuffer { 174 private: 175 JfrBuffer* _retired; 176 177 public: 178 JfrAgeNode() : _retired(NULL) {} 179 void set_retired_buffer(JfrBuffer* retired) { 180 _retired = retired; 181 } 182 JfrBuffer* retired_buffer() const { 183 return _retired; 184 } 185 }; 186 187 #endif // SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP