1 /* 2 * Copyright (c) 2023, 2025, 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_OOPS_FIELDINFO_INLINE_HPP 26 #define SHARE_OOPS_FIELDINFO_INLINE_HPP 27 28 #include "oops/fieldInfo.hpp" 29 30 #include "memory/metadataFactory.hpp" 31 #include "oops/constantPool.hpp" 32 #include "oops/instanceKlass.hpp" 33 #include "oops/symbol.hpp" 34 #include "runtime/atomic.hpp" 35 #include "utilities/checkedCast.hpp" 36 37 inline Symbol* FieldInfo::name(ConstantPool* cp) const { 38 int index = _name_index; 39 if (_field_flags.is_injected()) { 40 return lookup_symbol(index); 41 } 42 return cp->symbol_at(index); 43 } 44 45 inline Symbol* FieldInfo::signature(ConstantPool* cp) const { 46 int index = _signature_index; 47 if (_field_flags.is_injected()) { 48 return lookup_symbol(index); 49 } 50 return cp->symbol_at(index); 51 } 52 53 inline Symbol* FieldInfo::lookup_symbol(int symbol_index) const { 54 assert(_field_flags.is_injected(), "only injected fields"); 55 return Symbol::vm_symbol_at(static_cast<vmSymbolID>(symbol_index)); 56 } 57 58 inline int FieldInfoStream::num_injected_java_fields(const Array<u1>* fis) { 59 FieldInfoReader fir(fis); 60 int java_fields_count; 61 int injected_fields_count; 62 fir.read_field_counts(&java_fields_count, &injected_fields_count); 63 return injected_fields_count; 64 } 65 66 inline int FieldInfoStream::num_total_fields(const Array<u1>* fis) { 67 FieldInfoReader fir(fis); 68 int java_fields_count; 69 int injected_fields_count; 70 fir.read_field_counts(&java_fields_count, &injected_fields_count); 71 return java_fields_count + injected_fields_count; 72 } 73 74 inline int FieldInfoStream::num_java_fields(const Array<u1>* fis) { 75 FieldInfoReader fir(fis); 76 int java_fields_count; 77 int injected_fields_count; 78 fir.read_field_counts(&java_fields_count, &injected_fields_count); 79 return java_fields_count; 80 } 81 82 template<typename CON> 83 inline void Mapper<CON>::map_field_info(const FieldInfo& fi) { 84 _next_index++; // pre-increment 85 _consumer->accept_uint(fi.name_index()); 86 _consumer->accept_uint(fi.signature_index()); 87 _consumer->accept_uint(fi.offset()); 88 _consumer->accept_uint(fi.access_flags().as_field_flags()); 89 _consumer->accept_uint(fi.field_flags().as_uint()); 90 if(fi.field_flags().has_any_optionals()) { 91 if (fi.field_flags().is_initialized()) { 92 _consumer->accept_uint(fi.initializer_index()); 93 } 94 if (fi.field_flags().is_generic()) { 95 _consumer->accept_uint(fi.generic_signature_index()); 96 } 97 if (fi.field_flags().is_contended()) { 98 _consumer->accept_uint(fi.contention_group()); 99 } 100 if (fi.field_flags().is_flat()) { 101 assert(fi.layout_kind() != LayoutKind::UNKNOWN, "Must be set"); 102 _consumer->accept_uint((uint32_t)fi.layout_kind()); 103 } 104 if (fi.field_flags().has_null_marker()) { 105 _consumer->accept_uint(fi.null_marker_offset()); 106 } 107 } else { 108 assert(fi.initializer_index() == 0, ""); 109 assert(fi.generic_signature_index() == 0, ""); 110 assert(fi.contention_group() == 0, ""); 111 assert(fi.null_marker_offset() == 0, ""); 112 } 113 } 114 115 116 inline FieldInfoReader::FieldInfoReader(const Array<u1>* fi) 117 : _r(fi->data(), fi->length()), 118 _next_index(0) { } 119 120 inline void FieldInfoReader::read_field_counts(int* java_fields, int* injected_fields) { 121 *java_fields = next_uint(); 122 *injected_fields = next_uint(); 123 } 124 125 inline void FieldInfoReader::read_name_and_signature(u2* name_index, u2* signature_index) { 126 *name_index = checked_cast<u2>(next_uint()); 127 *signature_index = checked_cast<u2>(next_uint()); 128 } 129 130 inline void FieldInfoReader::read_field_info(FieldInfo& fi) { 131 fi._index = _next_index++; 132 read_name_and_signature(&fi._name_index, &fi._signature_index); 133 fi._offset = next_uint(); 134 fi._access_flags = AccessFlags(checked_cast<u2>(next_uint())); 135 fi._field_flags = FieldInfo::FieldFlags(next_uint()); 136 if (fi._field_flags.is_initialized()) { 137 fi._initializer_index = checked_cast<u2>(next_uint()); 138 } else { 139 fi._initializer_index = 0; 140 } 141 if (fi._field_flags.is_generic()) { 142 fi._generic_signature_index = checked_cast<u2>(next_uint()); 143 } else { 144 fi._generic_signature_index = 0; 145 } 146 if (fi._field_flags.is_contended()) { 147 fi._contention_group = checked_cast<u2>(next_uint()); 148 } else { 149 fi._contention_group = 0; 150 } 151 if (fi._field_flags.is_flat()) { 152 fi._layout_kind = static_cast<LayoutKind>(next_uint()); 153 } 154 if (fi._field_flags.has_null_marker()) { 155 fi._null_marker_offset = next_uint(); 156 } else { 157 fi._null_marker_offset = 0; 158 } 159 } 160 161 inline FieldInfoReader& FieldInfoReader::skip_field_info() { 162 _next_index++; 163 const int name_sig_af_off = 4; // four items 164 skip(name_sig_af_off); 165 FieldInfo::FieldFlags ff(next_uint()); 166 if (ff.has_any_optionals()) { 167 const int init_gen_cont = (ff.is_initialized() + 168 ff.is_generic() + 169 ff.is_contended() + 170 ff.is_flat() + 171 ff.has_null_marker()); 172 skip(init_gen_cont); // up to three items 173 } 174 return *this; 175 } 176 177 // Skip to the nth field. If the reader is freshly initialized to 178 // the zero index, this will call skip_field_info() n times. 179 inline FieldInfoReader& FieldInfoReader::skip_to_field_info(int n) { 180 assert(n >= _next_index, "already past that index"); 181 const int count = n - _next_index; 182 for (int i = 0; i < count; i++) skip_field_info(); 183 assert(_next_index == n, ""); 184 return *this; 185 } 186 187 // for random access, if you know where to go up front: 188 inline FieldInfoReader& FieldInfoReader::set_position_and_next_index(int position, int next_index) { 189 _r.set_position(position); 190 _next_index = next_index; 191 return *this; 192 } 193 194 inline void FieldStatus::atomic_set_bits(u1& flags, u1 mask) { 195 Atomic::fetch_then_or(&flags, mask); 196 } 197 198 inline void FieldStatus::atomic_clear_bits(u1& flags, u1 mask) { 199 Atomic::fetch_then_and(&flags, (u1)(~mask)); 200 } 201 202 inline void FieldStatus::update_flag(FieldStatusBitPosition pos, bool z) { 203 if (z) atomic_set_bits(_flags, flag_mask(pos)); 204 else atomic_clear_bits(_flags, flag_mask(pos)); 205 } 206 207 inline void FieldStatus::update_access_watched(bool z) { update_flag(_fs_access_watched, z); } 208 inline void FieldStatus::update_modification_watched(bool z) { update_flag(_fs_modification_watched, z); } 209 inline void FieldStatus::update_strict_static_unset(bool z) { update_flag(_fs_strict_static_unset, z); } 210 inline void FieldStatus::update_strict_static_unread(bool z) { update_flag(_fs_strict_static_unread, z); } 211 inline void FieldStatus::update_initialized_final_update(bool z) { update_flag(_initialized_final_update, z); } 212 213 #endif // SHARE_OOPS_FIELDINFO_INLINE_HPP