1 /*
  2  * Copyright (c) 2024, 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 "cds/aotClassInitializer.hpp"
 27 #include "cds/archiveBuilder.hpp"
 28 #include "cds/cdsConfig.hpp"
 29 #include "dumpTimeClassInfo.inline.hpp"
 30 #include "cds/heapShared.hpp"
 31 #include "classfile/systemDictionaryShared.hpp"
 32 #include "memory/resourceArea.hpp"
 33 #include "oops/fieldStreams.inline.hpp"
 34 #include "oops/instanceKlass.inline.hpp"
 35 #include "runtime/mutexLocker.hpp"
 36 
 37 // check_can_be_preinited() is quite costly, so we cache the results inside
 38 // DumpTimeClassInfo::_can_be_preinited. See also AOTClassInitializer::reset_preinit_check().
 39 bool AOTClassInitializer::check_can_be_preinited(InstanceKlass* ik) {
 40   ResourceMark rm;
 41 
 42   if (!SystemDictionaryShared::is_builtin(ik)) {
 43     log_info(cds, init)("cannot initialize %s (not built-in loader)", ik->external_name());
 44     return false;
 45   }
 46 
 47   InstanceKlass* super = ik->java_super();
 48   if (super != nullptr && !can_be_preinited_locked(super)) {
 49     log_info(cds, init)("cannot initialize %s (super %s not initable)", ik->external_name(), super->external_name());
 50     return false;
 51   }
 52 
 53   Array<InstanceKlass*>* interfaces = ik->local_interfaces();
 54   for (int i = 0; i < interfaces->length(); i++) {
 55     if (!can_be_preinited_locked(interfaces->at(i))) {
 56       log_info(cds, init)("cannot initialize %s (interface %s not initable)",
 57                           ik->external_name(), interfaces->at(i)->external_name());
 58       return false;
 59     }
 60   }
 61 
 62   if (HeapShared::is_lambda_form_klass(ik)) {
 63     // We allow only these to have <clinit> or non-default static fields
 64     return true;
 65   }
 66 
 67   if (ik->class_initializer() != nullptr) {
 68     log_info(cds, init)("cannot initialize %s (has <clinit>)", ik->external_name());
 69     return false;
 70   }
 71   if (ik->is_initialized() && !has_default_static_fields(ik)) {
 72     return false;
 73   }
 74 
 75   return true;
 76 }
 77 
 78 bool AOTClassInitializer::has_default_static_fields(InstanceKlass* ik) {
 79   oop mirror = ik->java_mirror();
 80 
 81   for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
 82     if (fs.access_flags().is_static()) {
 83       fieldDescriptor& fd = fs.field_descriptor();
 84       int offset = fd.offset();
 85       bool is_default = true;
 86       bool has_initval = fd.has_initial_value();
 87       switch (fd.field_type()) {
 88       case T_OBJECT:
 89       case T_ARRAY:
 90         is_default = mirror->obj_field(offset) == nullptr;
 91         break;
 92       case T_BOOLEAN:
 93         is_default = mirror->bool_field(offset) == (has_initval ? fd.int_initial_value() : 0);
 94         break;
 95       case T_BYTE:
 96         is_default = mirror->byte_field(offset) == (has_initval ? fd.int_initial_value() : 0);
 97         break;
 98       case T_SHORT:
 99         is_default = mirror->short_field(offset) == (has_initval ? fd.int_initial_value() : 0);
100         break;
101       case T_CHAR:
102         is_default = mirror->char_field(offset) == (has_initval ? fd.int_initial_value() : 0);
103         break;
104       case T_INT:
105         is_default = mirror->int_field(offset) == (has_initval ? fd.int_initial_value() : 0);
106         break;
107       case T_LONG:
108         is_default = mirror->long_field(offset) == (has_initval ? fd.long_initial_value() : 0);
109         break;
110       case T_FLOAT:
111         is_default = mirror->float_field(offset) == (has_initval ? fd.float_initial_value() : 0);
112         break;
113       case T_DOUBLE:
114         is_default = mirror->double_field(offset) == (has_initval ? fd.double_initial_value() : 0);
115         break;
116       default:
117         ShouldNotReachHere();
118       }
119 
120       if (!is_default) {
121         log_info(cds, init)("cannot initialize %s (static field %s has non-default value)",
122                             ik->external_name(), fd.name()->as_C_string());
123         return false;
124       }
125     }
126   }
127 
128   return true;
129 }
130 
131 bool AOTClassInitializer::can_be_preinited(InstanceKlass* ik) {
132   MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
133   return can_be_preinited_locked(ik);
134 }
135 
136 bool AOTClassInitializer::can_be_preinited_locked(InstanceKlass* ik) {
137   if (!CDSConfig::is_initing_classes_at_dump_time()) {
138     return false;
139   }
140 
141   assert_lock_strong(DumpTimeTable_lock);
142   DumpTimeClassInfo* info = SystemDictionaryShared::get_info_locked(ik);
143   if (!info->has_done_preinit_check()) {
144     info->set_can_be_preinited(AOTClassInitializer::check_can_be_preinited(ik));
145   }
146   return info->can_be_preinited();
147 }
148 
149 // Initialize a class at dump time, if possible.
150 void AOTClassInitializer::maybe_preinit_class(InstanceKlass* ik, TRAPS) {
151   if (!ik->is_initialized() && AOTClassInitializer::can_be_preinited(ik)) {
152     if (log_is_enabled(Info, cds, init)) {
153       ResourceMark rm;
154       log_info(cds, init)("preinitializing %s", ik->external_name());
155     }
156     ik->initialize(CHECK);
157   }
158 }
159 
160 // AOTClassInitializer::can_be_preinited(ik) is called in two different phases:
161 //
162 // [1] Before the VM_PopulateDumpSharedSpace safepoint:
163 //     when MetaspaceShared::link_shared_classes calls AOTClassInitializer::maybe_preinit_class(ik)
164 // [2] Inside the VM_PopulateDumpSharedSpace safepoint
165 //     when HeapShared::archive_java_mirrors() calls AOTClassInitializer::can_archive_initialized_mirror(ik)
166 //
167 // Between the two phases, some Java code may have been executed to contaminate the
168 // some initialized mirrors. So we call reset_preinit_check() at the beginning of the
169 // [2] so that we will re-run has_default_static_fields() on all the classes.
170 // As a result, phase [2] may archive fewer mirrors that were initialized in phase [1].
171 void AOTClassInitializer::reset_preinit_check() {
172   auto iterator = [&] (InstanceKlass* k, DumpTimeClassInfo& info) {
173     if (info.can_be_preinited()) {
174       info.reset_preinit_check();
175     }
176   };
177   SystemDictionaryShared::dumptime_table()->iterate_all_live_classes(iterator);
178 }
179 
180 bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
181   assert(!ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass");
182   if (!CDSConfig::is_initing_classes_at_dump_time()) {
183     return false;
184   }
185 
186   if (ik->is_hidden()) {
187     return HeapShared::is_archivable_hidden_klass(ik);
188   }
189 
190   if (ik->is_initialized() && ik->java_super() == vmClasses::Enum_klass()) {
191     return true;
192   }
193 
194   Symbol* name = ik->name();
195   if (name->equals("jdk/internal/constant/PrimitiveClassDescImpl") ||
196       name->equals("jdk/internal/constant/ReferenceClassDescImpl") ||
197       name->equals("java/lang/constant/ConstantDescs")) {
198     assert(ik->is_initialized(), "must be");
199     // The above 3 classes are special cases needed to support the aot-caching of
200     // java.lang.invoke.MethodType instances:
201     // - MethodType points to sun.invoke.util.Wrapper enums
202     // - The Wrapper enums point to static final fields in the above 3 classes.
203     //   E.g., ConstantDescs.CD_Boolean.
204     // - If we re-run the <clinit> of these 3 classes again during the production
205     //   run, ConstantDescs.CD_Boolean will get a new value that has a different
206     //   object identity than the value referenced by the the Wrapper enums.
207     // - However, Wrapper requires object identity (it allows the use of == to
208     //   test the equality of ClassDesc, etc).
209     // Therefore, we must preserve the static fields of these 3 classes from
210     // the assembly phase.
211     return true;
212   }
213   if (CDSConfig::is_dumping_invokedynamic()) {
214     if (name->equals("java/lang/Boolean$AOTHolder") ||
215         name->equals("java/lang/Character$CharacterCache") ||
216         name->equals("java/lang/invoke/BoundMethodHandle$AOTHolder") ||
217         name->equals("java/lang/invoke/BoundMethodHandle$Specializer") ||
218         name->equals("java/lang/invoke/ClassSpecializer") ||
219         name->equals("java/lang/invoke/DelegatingMethodHandle") ||
220         name->equals("java/lang/invoke/DelegatingMethodHandle$Holder") ||
221         name->equals("java/lang/invoke/DirectMethodHandle") ||
222         name->equals("java/lang/invoke/DirectMethodHandle$AOTHolder") ||
223         name->equals("java/lang/invoke/DirectMethodHandle$Holder") ||
224         name->equals("java/lang/invoke/Invokers") ||
225         name->equals("java/lang/invoke/Invokers$Holder") ||
226         name->equals("java/lang/invoke/LambdaForm") ||
227         name->equals("java/lang/invoke/LambdaForm$NamedFunction") ||
228         name->equals("java/lang/invoke/LambdaForm$NamedFunction$AOTHolder") ||
229         name->equals("java/lang/invoke/MethodHandle") ||
230         name->equals("java/lang/invoke/MethodHandles$Lookup") ||
231         name->equals("java/lang/invoke/MethodType$AOTHolder") ||
232         name->starts_with("java/lang/invoke/BoundMethodHandle$Species_") ||
233         name->starts_with("java/lang/invoke/ClassSpecializer$")) {
234       assert(ik->is_initialized(), "must be");
235       return true;
236     }
237   }
238 
239   return AOTClassInitializer::can_be_preinited_locked(ik);
240 }