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 // Warning -- this is fragile!!! 38 // 39 // This is a hard-coded list of classes that are safe to preinitialize at dump time. It needs 40 // to be updated if the Java source code changes. 41 bool AOTClassInitializer::is_forced_preinit_class(InstanceKlass* ik) { 42 if (!CDSConfig::is_dumping_invokedynamic()) { 43 return false; 44 } 45 46 static const char* forced_preinit_classes[] = { 47 "java/util/HexFormat", 48 "jdk/internal/util/ClassFileDumper", 49 "java/lang/reflect/ClassFileFormatVersion", 50 "java/lang/Character$CharacterCache", 51 "java/lang/invoke/Invokers", 52 "java/lang/invoke/Invokers$Holder", 53 "java/lang/invoke/MethodHandle", 54 "java/lang/invoke/MethodHandleStatics", 55 "java/lang/invoke/DelegatingMethodHandle", 56 "java/lang/invoke/DelegatingMethodHandle$Holder", 57 "java/lang/invoke/LambdaForm", 58 "java/lang/invoke/LambdaForm$NamedFunction", 59 "java/lang/invoke/ClassSpecializer", 60 "java/lang/invoke/DirectMethodHandle", 61 "java/lang/invoke/DirectMethodHandle$Holder", 62 "java/lang/invoke/BoundMethodHandle$Specializer", 63 "java/lang/invoke/MethodHandles$Lookup", 64 65 // TODO: 66 // This is needed since JDK-8338532. Without this, when 67 // archived heap objects are used, the class init order is not 68 // expected by the jdk/internal/constant bootstrap code and we 69 // will get a null pointer exception. 70 // 71 // When bootstraping has intricated/fragile order, it's probably 72 // better to archive all related classes in an initialized state 73 // (i.e., take a snapshot). The existing approach in 74 // heapShared::resolve_or_init_classes_for_subgraph_of() won't work. 75 "jdk/internal/constant/PrimitiveClassDescImpl", 76 "jdk/internal/constant/ReferenceClassDescImpl", 77 "java/lang/constant/ConstantDescs", 78 "sun/invoke/util/Wrapper", 79 80 //TODO: these use java.lang.ClassValue$Entry which is a subtype of WeakReference 81 //"java/lang/reflect/Proxy$ProxyBuilder", 82 //"java/lang/reflect/Proxy", 83 84 // TODO -- need to clear internTable, etc 85 //"java/lang/invoke/MethodType", 86 87 // TODO -- these need to link to native code 88 //"java/lang/invoke/BoundMethodHandle", 89 //"java/lang/invoke/BoundMethodHandle$Holder", 90 //"java/lang/invoke/MemberName", 91 //"java/lang/invoke/MethodHandleNatives", 92 }; 93 94 for (const char* class_name : forced_preinit_classes) { 95 if (ik->name()->equals(class_name)) { 96 if (log_is_enabled(Info, cds, init)) { 97 ResourceMark rm; 98 log_info(cds, init)("Force initialization %s", ik->external_name()); 99 } 100 return true; 101 } 102 } 103 104 return false; 105 } 106 107 // check_can_be_preinited() is quite costly, so we cache the results inside 108 // DumpTimeClassInfo::_can_be_preinited. See also AOTClassInitializer::reset_preinit_check(). 109 bool AOTClassInitializer::check_can_be_preinited(InstanceKlass* ik) { 110 ResourceMark rm; 111 112 if (!SystemDictionaryShared::is_builtin(ik)) { 113 log_info(cds, init)("cannot initialize %s (not built-in loader)", ik->external_name()); 114 return false; 115 } 116 117 InstanceKlass* super = ik->java_super(); 118 if (super != nullptr && !can_be_preinited_locked(super)) { 119 log_info(cds, init)("cannot initialize %s (super %s not initable)", ik->external_name(), super->external_name()); 120 return false; 121 } 122 123 Array<InstanceKlass*>* interfaces = ik->local_interfaces(); 124 for (int i = 0; i < interfaces->length(); i++) { 125 if (!can_be_preinited_locked(interfaces->at(i))) { 126 log_info(cds, init)("cannot initialize %s (interface %s not initable)", 127 ik->external_name(), interfaces->at(i)->external_name()); 128 return false; 129 } 130 } 131 132 if (HeapShared::is_lambda_form_klass(ik) || is_forced_preinit_class(ik)) { 133 // We allow only these to have <clinit> or non-default static fields 134 } else { 135 if (ik->class_initializer() != nullptr) { 136 log_info(cds, init)("cannot initialize %s (has <clinit>)", ik->external_name()); 137 return false; 138 } 139 if (ik->is_initialized() && !has_non_default_static_fields(ik)) { 140 return false; 141 } 142 } 143 144 return true; 145 } 146 147 bool AOTClassInitializer::has_non_default_static_fields(InstanceKlass* ik) { 148 oop mirror = ik->java_mirror(); 149 150 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { 151 if (fs.access_flags().is_static()) { 152 fieldDescriptor& fd = fs.field_descriptor(); 153 int offset = fd.offset(); 154 bool is_default = true; 155 bool has_initval = fd.has_initial_value(); 156 switch (fd.field_type()) { 157 case T_OBJECT: 158 case T_ARRAY: 159 is_default = mirror->obj_field(offset) == nullptr; 160 break; 161 case T_BOOLEAN: 162 is_default = mirror->bool_field(offset) == (has_initval ? fd.int_initial_value() : 0); 163 break; 164 case T_BYTE: 165 is_default = mirror->byte_field(offset) == (has_initval ? fd.int_initial_value() : 0); 166 break; 167 case T_SHORT: 168 is_default = mirror->short_field(offset) == (has_initval ? fd.int_initial_value() : 0); 169 break; 170 case T_CHAR: 171 is_default = mirror->char_field(offset) == (has_initval ? fd.int_initial_value() : 0); 172 break; 173 case T_INT: 174 is_default = mirror->int_field(offset) == (has_initval ? fd.int_initial_value() : 0); 175 break; 176 case T_LONG: 177 is_default = mirror->long_field(offset) == (has_initval ? fd.long_initial_value() : 0); 178 break; 179 case T_FLOAT: 180 is_default = mirror->float_field(offset) == (has_initval ? fd.float_initial_value() : 0); 181 break; 182 case T_DOUBLE: 183 is_default = mirror->double_field(offset) == (has_initval ? fd.double_initial_value() : 0); 184 break; 185 default: 186 ShouldNotReachHere(); 187 } 188 189 if (!is_default) { 190 log_info(cds, init)("cannot initialize %s (static field %s has non-default value)", 191 ik->external_name(), fd.name()->as_C_string()); 192 return false; 193 } 194 } 195 } 196 197 return true; 198 } 199 200 bool AOTClassInitializer::can_be_preinited(InstanceKlass* ik) { 201 MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); 202 return can_be_preinited_locked(ik); 203 } 204 205 bool AOTClassInitializer::can_be_preinited_locked(InstanceKlass* ik) { 206 if (!CDSConfig::is_initing_classes_at_dump_time()) { 207 return false; 208 } 209 210 assert_lock_strong(DumpTimeTable_lock); 211 DumpTimeClassInfo* info = SystemDictionaryShared::get_info_locked(ik); 212 if (!info->has_done_preinit_check()) { 213 info->set_can_be_preinited(AOTClassInitializer::check_can_be_preinited(ik)); 214 } 215 return info->can_be_preinited(); 216 } 217 218 // Initialize a class at dump time, if possible. 219 void AOTClassInitializer::maybe_preinit_class(InstanceKlass* ik, TRAPS) { 220 if (!ik->is_initialized() && AOTClassInitializer::can_be_preinited(ik)) { 221 if (log_is_enabled(Info, cds, init)) { 222 ResourceMark rm; 223 log_info(cds, init)("preinitializing %s", ik->external_name()); 224 } 225 ik->initialize(CHECK); 226 } 227 } 228 229 // AOTClassInitializer::can_be_preinited(ik) is called in two different phases: 230 // 231 // [1] Before the VM_PopulateDumpSharedSpace safepoint: 232 // when MetaspaceShared::link_shared_classes calls AOTClassInitializer::maybe_preinit_class(ik) 233 // [2] Inside the VM_PopulateDumpSharedSpace safepoint 234 // when HeapShared::archive_java_mirrors() calls AOTClassInitializer::can_archive_preinitialized_mirror(ik) 235 // 236 // Between the two phases, some Java code may have been executed to contaminate the 237 // some initialized mirrors. So we call reset_preinit_check() at the beginning of the 238 // [2] so that we will re-run has_non_default_static_fields() on all the classes. 239 // As a result, phase [2] may archive fewer mirrors that were initialized in phase [1]. 240 void AOTClassInitializer::reset_preinit_check() { 241 auto iterator = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { 242 if (info.can_be_preinited()) { 243 info.reset_preinit_check(); 244 } 245 }; 246 SystemDictionaryShared::dumptime_table()->iterate_all_live_classes(iterator); 247 } 248 249 bool AOTClassInitializer::can_archive_preinitialized_mirror(InstanceKlass* ik) { 250 assert(!ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass"); 251 if (!CDSConfig::is_initing_classes_at_dump_time()) { 252 return false; 253 } 254 255 if (ik->is_hidden()) { 256 return HeapShared::is_archivable_hidden_klass(ik); 257 } else if (ik->is_initialized()) { 258 if (ik->java_super() == vmClasses::Enum_klass()) { 259 return true; 260 } 261 Symbol* name = ik->name(); 262 if (name->equals("jdk/internal/constant/PrimitiveClassDescImpl") || 263 name->equals("jdk/internal/constant/ReferenceClassDescImpl") || 264 name->equals("java/lang/constant/ConstantDescs") || 265 name->equals("sun/invoke/util/Wrapper")) { 266 return true; 267 } 268 if (CDSConfig::is_dumping_invokedynamic()) { 269 if (name->equals("java/lang/invoke/DirectMethodHandle$AOTHolder") || 270 name->equals("java/lang/invoke/LambdaForm$NamedFunction$AOTHolder") || 271 name->equals("java/lang/invoke/MethodType$AOTHolder")) { 272 return true; 273 } 274 } 275 } 276 277 return AOTClassInitializer::can_be_preinited_locked(ik); 278 }