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