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