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 "jni.h" 29 #include "memory/allocation.hpp" 30 31 // 32 // Represents a piece of committed memory. 33 // 34 // u1* _pos <-- next store position 35 // u1* _top <-- next unflushed position 36 // 37 // const void* _identity <<-- acquired by 38 // 39 // Must be the owner before attempting stores. 40 // Use acquire() and/or try_acquire() for exclusive access 41 // to the (entire) buffer (cas identity). 42 // 43 // Stores to the buffer should uphold transactional semantics. 44 // A new _pos must be updated only after all intended stores have completed. 45 // The relation between _pos and _top must hold atomically, 46 // e.g. the delta must always be fully parsable. 47 // _top can move concurrently by other threads but is always <= _pos. 48 // 49 class JfrBuffer { 50 private: 51 JfrBuffer* _next; 52 JfrBuffer* _prev; 53 const void* volatile _identity; 54 u1* _pos; 55 mutable const u1* volatile _top; 56 u2 _flags; 57 u2 _header_size; 58 u4 _size; 59 60 const u1* stable_top() const; 61 void clear_flags(); 62 63 public: 64 JfrBuffer(); 65 bool initialize(size_t header_size, size_t size, const void* id = NULL); 66 void reinitialize(); 67 void concurrent_reinitialization(); 68 size_t discard(); 69 JfrBuffer* next() const { 70 return _next; 71 } 72 73 JfrBuffer* prev() const { 74 return _prev; 75 } 76 77 void set_next(JfrBuffer* next) { 78 _next = next; 79 } 80 81 void set_prev(JfrBuffer* prev) { 82 _prev = prev; 83 } 84 85 const u1* start() const { 86 return ((const u1*)this) + _header_size; 87 } 88 89 u1* start() { 90 return ((u1*)this) + _header_size; 91 } 92 93 const u1* end() const { 94 return start() + size(); 95 } 96 97 const u1* pos() const { 98 return _pos; 99 } 100 101 u1* pos() { 102 return _pos; 103 } 104 105 u1** pos_address() { 106 return (u1**)&_pos; 107 } 108 109 void set_pos(u1* new_pos) { 110 assert(new_pos <= end(), "invariant"); 111 _pos = new_pos; 112 } 113 114 void set_pos(size_t size) { 115 assert(_pos + size <= end(), "invariant"); 116 _pos += size; 117 } 118 119 const u1* top() const; 120 void set_top(const u1* new_top); 121 const u1* concurrent_top() const; 122 void set_concurrent_top(const u1* new_top); 123 124 size_t header_size() const { 125 return _header_size; 126 } 127 128 size_t size() const { 129 return _size * BytesPerWord; 130 } 131 132 size_t total_size() const { 133 return header_size() + size(); 134 } 135 136 size_t free_size() const { 137 return end() - pos(); 138 } 139 140 size_t unflushed_size() const; 141 142 bool empty() const { 143 return pos() == start(); 144 } 145 146 const void* identity() const { 147 return _identity; 148 } 149 150 void clear_identity(); 151 152 void acquire(const void* id); 153 bool try_acquire(const void* id); 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 debug_only(bool acquired_by_self() const;) 172 }; 173 174 class JfrAgeNode : public JfrBuffer { 175 private: 176 JfrBuffer* _retired; 177 178 public: 179 JfrAgeNode() : _retired(NULL) {} 180 void set_retired_buffer(JfrBuffer* retired) { 181 _retired = retired; 182 } 183 JfrBuffer* retired_buffer() const { 184 return _retired; 185 } 186 }; 187 188 #endif // SHARE_VM_JFR_RECORDER_STORAGE_JFRBUFFER_HPP