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 #include "oops/fieldInfo.inline.hpp" 26 #include "runtime/atomic.hpp" 27 28 void FieldInfo::print(outputStream* os, ConstantPool* cp) { 29 os->print_cr("index=%d name_index=%d name=%s signature_index=%d signature=%s offset=%d " 30 "AccessFlags=%d FieldFlags=%d " 31 "initval_index=%d gen_signature_index=%d, gen_signature=%s contended_group=%d", 32 index(), 33 name_index(), name(cp)->as_utf8(), 34 signature_index(), signature(cp)->as_utf8(), 35 offset(), 36 access_flags().as_field_flags(), 37 field_flags().as_uint(), 38 initializer_index(), 39 generic_signature_index(), 40 _field_flags.is_injected() ? lookup_symbol(generic_signature_index())->as_utf8() : cp->symbol_at(generic_signature_index())->as_utf8(), 41 contended_group()); 42 } 43 44 void FieldInfo::print_from_growable_array(outputStream* os, GrowableArray<FieldInfo>* array, ConstantPool* cp) { 45 for (int i = 0; i < array->length(); i++) { 46 array->adr_at(i)->print(os, cp); 47 } 48 } 49 50 Array<u1>* FieldInfoStream::create_FieldInfoStream(GrowableArray<FieldInfo>* fields, int java_fields, int injected_fields, 51 ClassLoaderData* loader_data, TRAPS) { 52 // The stream format described in fieldInfo.hpp is: 53 // FieldInfoStream := j=num_java_fields k=num_injected_fields Field[j+k] End 54 // Field := name sig offset access flags Optionals(flags) 55 // Optionals(i) := initval?[i&is_init] // ConstantValue attr 56 // gsig?[i&is_generic] // signature attr 57 // group?[i&is_contended] // Contended anno (group) 58 // End = 0 59 60 using StreamSizer = UNSIGNED5::Sizer<>; 61 using StreamFieldSizer = Mapper<StreamSizer>; 62 StreamSizer s; 63 StreamFieldSizer sizer(&s); 64 65 sizer.consumer()->accept_uint(java_fields); 66 sizer.consumer()->accept_uint(injected_fields); 67 for (int i = 0; i < fields->length(); i++) { 68 FieldInfo* fi = fields->adr_at(i); 69 sizer.map_field_info(*fi); 70 } 71 int storage_size = sizer.consumer()->position() + 1; 72 Array<u1>* const fis = MetadataFactory::new_array<u1>(loader_data, storage_size, CHECK_NULL); 73 74 using StreamWriter = UNSIGNED5::Writer<Array<u1>*, int, ArrayHelper<Array<u1>*, int>>; 75 using StreamFieldWriter = Mapper<StreamWriter>; 76 StreamWriter w(fis); 77 StreamFieldWriter writer(&w); 78 79 writer.consumer()->accept_uint(java_fields); 80 writer.consumer()->accept_uint(injected_fields); 81 for (int i = 0; i < fields->length(); i++) { 82 FieldInfo* fi = fields->adr_at(i); 83 writer.map_field_info(*fi); 84 } 85 86 #ifdef ASSERT 87 FieldInfoReader r(fis); 88 int jfc = r.next_uint(); 89 assert(jfc == java_fields, "Must be"); 90 int ifc = r.next_uint(); 91 assert(ifc == injected_fields, "Must be"); 92 for (int i = 0; i < jfc + ifc; i++) { 93 FieldInfo fi; 94 r.read_field_info(fi); 95 FieldInfo* fi_ref = fields->adr_at(i); 96 assert(fi_ref->name_index() == fi.name_index(), "Must be"); 97 assert(fi_ref->signature_index() == fi.signature_index(), "Must be"); 98 assert(fi_ref->offset() == fi.offset(), "Must be"); 99 assert(fi_ref->access_flags().as_field_flags() == fi.access_flags().as_field_flags(), "Must be"); 100 assert(fi_ref->field_flags().as_uint() == fi.field_flags().as_uint(), " Must be"); 101 if(fi_ref->field_flags().is_initialized()) { 102 assert(fi_ref->initializer_index() == fi.initializer_index(), "Must be"); 103 } 104 if (fi_ref->field_flags().is_generic()) { 105 assert(fi_ref->generic_signature_index() == fi.generic_signature_index(), "Must be"); 106 } 107 if (fi_ref->field_flags().is_contended()) { 108 assert(fi_ref->contended_group() == fi.contended_group(), "Must be"); 109 } 110 if (fi_ref->field_flags().is_flat()) { 111 assert(fi_ref->layout_kind() == fi.layout_kind(), "Must be"); 112 } 113 if (fi_ref->field_flags().has_null_marker()) { 114 assert(fi_ref->null_marker_offset() == fi.null_marker_offset(), "Must be"); 115 } 116 } 117 #endif // ASSERT 118 119 return fis; 120 } 121 122 GrowableArray<FieldInfo>* FieldInfoStream::create_FieldInfoArray(const Array<u1>* fis, int* java_fields_count, int* injected_fields_count) { 123 int length = FieldInfoStream::num_total_fields(fis); 124 GrowableArray<FieldInfo>* array = new GrowableArray<FieldInfo>(length); 125 FieldInfoReader r(fis); 126 *java_fields_count = r.next_uint(); 127 *injected_fields_count = r.next_uint(); 128 while (r.has_next()) { 129 FieldInfo fi; 130 r.read_field_info(fi); 131 array->append(fi); 132 } 133 assert(array->length() == length, "Must be"); 134 assert(array->length() == *java_fields_count + *injected_fields_count, "Must be"); 135 return array; 136 } 137 138 void FieldInfoStream::print_from_fieldinfo_stream(Array<u1>* fis, outputStream* os, ConstantPool* cp) { 139 int length = FieldInfoStream::num_total_fields(fis); 140 FieldInfoReader r(fis); 141 int java_field_count = r.next_uint(); 142 int injected_fields_count = r.next_uint(); 143 while (r.has_next()) { 144 FieldInfo fi; 145 r.read_field_info(fi); 146 fi.print(os, cp); 147 } 148 }