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