1 /* 2 * Copyright (c) 2024, 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 "cds/aotClassInitializer.hpp" 26 #include "cds/archiveBuilder.hpp" 27 #include "cds/cdsConfig.hpp" 28 #include "dumpTimeClassInfo.inline.hpp" 29 #include "cds/heapShared.hpp" 30 #include "classfile/symbolTable.hpp" 31 #include "classfile/systemDictionaryShared.hpp" 32 #include "classfile/vmSymbols.hpp" 33 #include "memory/resourceArea.hpp" 34 #include "oops/fieldStreams.inline.hpp" 35 #include "oops/instanceKlass.inline.hpp" 36 #include "oops/symbol.hpp" 37 #include "runtime/fieldDescriptor.inline.hpp" 38 #include "runtime/java.hpp" 39 #include "runtime/javaCalls.hpp" 40 #include "runtime/mutexLocker.hpp" 41 42 DEBUG_ONLY(InstanceKlass* _aot_init_class = nullptr;) 43 44 // Detector for class names we wish to handle specially. 45 // It is either an exact string match or a string prefix match. 46 class AOTClassInitializer::AllowedSpec { 47 const char* _class_name; 48 bool _is_prefix; 49 int _len; 50 public: 51 AllowedSpec(const char* class_name, bool is_prefix = false) 52 : _class_name(class_name), _is_prefix(is_prefix) 53 { 54 _len = (class_name == nullptr) ? 0 : (int)strlen(class_name); 55 } 56 const char* class_name() { return _class_name; } 57 58 bool matches(Symbol* name, int len) { 59 assert(_class_name != nullptr, "caller resp."); 60 if (_is_prefix) { 61 return len >= _len && name->starts_with(_class_name); 62 } else { 63 return len == _len && name->equals(_class_name); 64 } 65 } 66 }; 67 68 69 // Tell if ik has a name that matches one of the given specs. 70 bool AOTClassInitializer::is_allowed(AllowedSpec* specs, InstanceKlass* ik) { 71 Symbol* name = ik->name(); 72 int len = name->utf8_length(); 73 for (AllowedSpec* s = specs; s->class_name() != nullptr; s++) { 74 if (s->matches(name, len)) { 75 // If a type is included in the tables inside can_archive_initialized_mirror(), we require that 76 // - all super classes must be included 77 // - all super interfaces that have <clinit> must be included. 78 // This ensures that in the production run, we don't run the <clinit> of a supertype but skips 79 // ik's <clinit>. 80 if (ik->java_super() != nullptr) { 81 DEBUG_ONLY(ResourceMark rm); 82 assert(AOTClassInitializer::can_archive_initialized_mirror(ik->java_super()), 83 "super class %s of %s must be aot-initialized", ik->java_super()->external_name(), 84 ik->external_name()); 85 } 86 87 Array<InstanceKlass*>* interfaces = ik->local_interfaces(); 88 int len = interfaces->length(); 89 for (int i = 0; i < len; i++) { 90 InstanceKlass* intf = interfaces->at(i); 91 if (intf->class_initializer() != nullptr) { 92 assert(AOTClassInitializer::can_archive_initialized_mirror(intf), 93 "super interface %s (which has <clinit>) of %s must be aot-initialized", intf->external_name(), 94 ik->external_name()); 95 } 96 } 97 98 return true; 99 } 100 } 101 return false; 102 } 103 104 105 bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) { 106 assert(!ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass"); 107 if (!CDSConfig::is_initing_classes_at_dump_time()) { 108 return false; 109 } 110 111 if (!ik->is_initialized()) { 112 return false; 113 } 114 115 // About "static field that may hold a different value" errors: 116 // 117 // Automatic selection for aot-inited classes 118 // ========================================== 119 // 120 // When CDSConfig::is_initing_classes_at_dump_time is enabled, 121 // AOTArtifactFinder::find_artifacts() finds the classes of all 122 // heap objects that are reachable from HeapShared::_run_time_special_subgraph, 123 // and mark these classes as aot-inited. This preserves the initialized 124 // mirrors of these classes, and their <clinit> methods are NOT executed 125 // at runtime. See aotArtifactFinder.hpp for more info. 126 // 127 // For example, with -XX:+AOTInvokeDynamicLinking, _run_time_special_subgraph 128 // will contain some DirectMethodHandle objects. As a result, the DirectMethodHandle 129 // class is automatically marked as aot-inited. 130 // 131 // When a class is aot-inited, its static fields are already set up 132 // by executing the <clinit> method at AOT assembly time. Later on 133 // in the production run, when the class would normally be 134 // initialized, the VM performs guarding and synchronization as if 135 // it were going to run the <clinit> again, but instead it simply 136 // observes that that class was aot-inited. The VM assumes that, if 137 // it were to run <clinit> again, it would get a semantically 138 // equivalent set of final field values, so it just adopts the 139 // existing field values (from AOT assembly) and skips the call to 140 // <clinit>. There may at that point be fixups performed by ad hoc 141 // code, if the VM recognizes a request in the library. 142 // 143 // It is true that this is not generally correct for all possible 144 // Java code. A <clinit> method might have a side effect beyond 145 // initializing the static fields. It might send an email somewhere 146 // noting the current time of day. In that case, such an email 147 // would have been sent during the AOT assembly phase, and the email 148 // would NOT be sent again during production. This is clearly NOT 149 // what a user would want, if this were a general purpose facility. 150 // But in fact it is only for certain well-behaved classes, which 151 // are known NOT to have such side effects. We know this because 152 // the optimization (of skipping <clinit> for aot-init classes) is 153 // only applied to classes fully defined by the JDK. 154 // 155 // (A day may come when we figure out how to gracefully extend this 156 // optimization to untrusted third parties, but it is not this day.) 157 // 158 // Manual selection 159 // ================ 160 // 161 // There are important cases where one aot-init class has a side 162 // effect on another aot-class, a side effect which is not captured 163 // in any static field value in either class. The simplest example 164 // is class A forces the initialization of class B. In that case, 165 // we need to aot-init either both classes or neither. From looking 166 // at the JDK state after AOT assembly is done, it is hard to tell 167 // that A "touched" B and B might escape our notice. Another common 168 // example is A copying a field value from B. We don't know where A 169 // got the value, but it would be wrong to re-initialize B at 170 // startup, while keeping the snapshot of the old B value in A. In 171 // general, if we aot-init A, we need to aot-init every class B that 172 // somehow contributed to A's initial state, and every class C that 173 // was somehow side-effected by A's initialization. We say that the 174 // aot-init of A is "init-coupled" to those of B and C. 175 // 176 // So there are init-coupled classes that cannot be automatically discovered. For 177 // example, DirectMethodHandle::IMPL_NAMES points to MethodHandles::IMPL_NAMES, 178 // but the MethodHandles class is not automatically marked because there are 179 // no archived instances of the MethodHandles type. 180 // 181 // If we aot-initialize DirectMethodHandle, but allow MethodHandles to be 182 // initialized at runtime, MethodHandles::IMPL_NAMES will get a different 183 // value than DirectMethodHandle::IMPL_NAMES. This *may or may not* be a problem, 184 // but to ensure compatibility, we should try to preserve the identity equality 185 // of these two fields. 186 // 187 // To do that, we add MethodHandles to the indy_specs[] table below. 188 // 189 // Luckily we do not need to be all-knowing in order to choose which 190 // items to add to that table. We have tools to help detect couplings. 191 // 192 // Automatic validation 193 // ==================== 194 // 195 // CDSHeapVerifier is used to detect potential problems with identity equality. 196 // 197 // A class B is assumed to be init-coupled to some aot-init class if 198 // B has a field which points to a live object X in the AOT heap. 199 // The live object X was created by some other class A which somehow 200 // used B's reference to X, perhaps with the help of an intermediate 201 // class Z. Or, B pulled the reference to X from some other class 202 // Y, and B obtained that reference from Y (or an intermediate Z). 203 // It is not certain how X got into the heap, nor whether B 204 // contributed it, but it is a good heuristic that B is init-coupled 205 // to X's class or some other aot-init class. In any case, B should 206 // be made an aot-init class as well, unless a manual inspection 207 // shows that would be a problem. If there is a problem, then the 208 // JDK code for B and/or X probably needs refactoring. If there is 209 // no problem, we add B to the list. Typically the same scan will 210 // find any other accomplices Y, Z, etc. One failure would be a 211 // class Q whose only initialization action is to scribble a special 212 // value into B, from which the value X is derived and then makes 213 // its way into the heap. In that case, the heuristic does not 214 // identify Q. It is (currently) a human responsibility, of JDK 215 // engineers, not to write such dirty JDK code, or to repair it if 216 // it crops up. Eventually we may have tools, or even a user mode 217 // with design rules and checks, that will vet our code base more 218 // automatically. 219 // 220 // To see how the tool detects the problem with MethodHandles::IMPL_NAMES: 221 // 222 // - Comment out all the lines in indy_specs[] except the {nullptr} line. 223 // - Rebuild the JDK 224 // 225 // Then run the following: 226 // java -XX:AOTMode=record -XX:AOTConfiguration=jc.aotconfig com.sun.tools.javac.Main 227 // java -XX:AOTMode=create -Xlog:cds -XX:AOTCache=jc.aot -XX:AOTConfiguration=jc.aotconfig 228 // 229 // You will see an error like this: 230 // 231 // Archive heap points to a static field that may hold a different value at runtime: 232 // Field: java/lang/invoke/MethodHandles::IMPL_NAMES 233 // Value: java.lang.invoke.MemberName$Factory 234 // {0x000000060e906ae8} - klass: 'java/lang/invoke/MemberName$Factory' - flags: 235 // 236 // - ---- fields (total size 2 words): 237 // --- trace begin --- 238 // [ 0] {0x000000060e8deeb0} java.lang.Class (java.lang.invoke.DirectMethodHandle::IMPL_NAMES) 239 // [ 1] {0x000000060e906ae8} java.lang.invoke.MemberName$Factory 240 // --- trace end --- 241 // 242 // Trouble-shooting 243 // ================ 244 // 245 // If you see a "static field that may hold a different value" error, it's probably 246 // because you've made some changes in the JDK core libraries (most likely 247 // java.lang.invoke). 248 // 249 // - Did you add a new static field to a class that could be referenced by 250 // cached object instances of MethodType, MethodHandle, etc? You may need 251 // to add that class to indy_specs[]. 252 // - Did you modify the <clinit> of the classes in java.lang.invoke such that 253 // a static field now points to an object that should not be cached (e.g., 254 // a native resource such as a file descriptior, or a Thread)? 255 // 256 // Note that these potential problems only occur when one class gets 257 // the aot-init treatment, AND another class is init-coupled to it, 258 // AND the coupling is not detected. Currently there are a number 259 // classes that get the aot-init treatment, in java.lang.invoke 260 // because of invokedynamic. They are few enough for now to be 261 // manually tracked. There may be more in the future. 262 263 // IS_PREFIX means that we match all class names that start with a 264 // prefix. Otherwise, it is an exact match, of just one class name. 265 const bool IS_PREFIX = true; 266 267 { 268 static AllowedSpec specs[] = { 269 // everybody's favorite super 270 {"java/lang/Object"}, 271 272 {nullptr} 273 }; 274 if (is_allowed(specs, ik)) { 275 return true; 276 } 277 } 278 279 if (CDSConfig::is_dumping_method_handles()) { 280 // This table was created with the help of CDSHeapVerifier. 281 // Also, some $Holder classes are needed. E.g., Invokers.<clinit> explicitly 282 // initializes Invokers$Holder. Since Invokers.<clinit> won't be executed 283 // at runtime, we need to make sure Invokers$Holder is also aot-inited. 284 // 285 // We hope we can reduce the size of this list over time, and move 286 // the responsibility for identifying such classes into the JDK 287 // code itself. See tracking RFE JDK-8342481. 288 static AllowedSpec indy_specs[] = { 289 {"java/lang/constant/ConstantDescs"}, 290 {"java/lang/constant/DynamicConstantDesc"}, 291 {"java/lang/invoke/BoundMethodHandle"}, 292 {"java/lang/invoke/BoundMethodHandle$Specializer"}, 293 {"java/lang/invoke/BoundMethodHandle$Species_", IS_PREFIX}, 294 {"java/lang/invoke/ClassSpecializer"}, 295 {"java/lang/invoke/ClassSpecializer$", IS_PREFIX}, 296 {"java/lang/invoke/DelegatingMethodHandle"}, 297 {"java/lang/invoke/DelegatingMethodHandle$Holder"}, // UNSAFE.ensureClassInitialized() 298 {"java/lang/invoke/DirectMethodHandle"}, 299 {"java/lang/invoke/DirectMethodHandle$Constructor"}, 300 {"java/lang/invoke/DirectMethodHandle$Holder"}, // UNSAFE.ensureClassInitialized() 301 {"java/lang/invoke/Invokers"}, 302 {"java/lang/invoke/Invokers$Holder"}, // UNSAFE.ensureClassInitialized() 303 {"java/lang/invoke/LambdaForm"}, 304 {"java/lang/invoke/LambdaForm$Holder"}, // UNSAFE.ensureClassInitialized() 305 {"java/lang/invoke/LambdaForm$NamedFunction"}, 306 {"java/lang/invoke/MethodHandle"}, 307 {"java/lang/invoke/MethodHandles"}, 308 {"java/lang/invoke/SimpleMethodHandle"}, 309 {"java/util/Collections"}, 310 {"java/util/stream/Collectors"}, 311 {"jdk/internal/constant/ConstantUtils"}, 312 {"jdk/internal/constant/PrimitiveClassDescImpl"}, 313 {"jdk/internal/constant/ReferenceClassDescImpl"}, 314 315 // Can't include this, as it will pull in MethodHandleStatics which has many environment 316 // dependencies (on system properties, etc). 317 // MethodHandleStatics is an example of a class that must NOT get the aot-init treatment, 318 // because of its strong reliance on (a) final fields which are (b) environmentally determined. 319 //{"java/lang/invoke/InvokerBytecodeGenerator"}, 320 321 {nullptr} 322 }; 323 if (is_allowed(indy_specs, ik)) { 324 return true; 325 } 326 } 327 328 #ifdef ASSERT 329 if (ik == _aot_init_class) { 330 return true; 331 } 332 #endif 333 334 return false; 335 } 336 337 // TODO: currently we have a hard-coded list. We should turn this into 338 // an annotation: @jdk.internal.vm.annotation.RuntimeSetupRequired 339 // See JDK-8342481. 340 bool AOTClassInitializer::is_runtime_setup_required(InstanceKlass* ik) { 341 return ik == vmClasses::Class_klass() || 342 ik == vmClasses::internal_Unsafe_klass() || 343 ik == vmClasses::ConcurrentHashMap_klass() || 344 ik == vmClasses::Reference_klass() || 345 ik->name()->equals("java/net/URI") || 346 ik->name()->equals("java/lang/module/ModuleDescriptor"); 347 } 348 349 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) { 350 assert(ik->has_aot_initialized_mirror(), "sanity"); 351 if (ik->is_runtime_setup_required()) { 352 if (log_is_enabled(Info, cds, init)) { 353 ResourceMark rm; 354 log_info(cds, init)("Calling %s::runtimeSetup()", ik->external_name()); 355 } 356 JavaValue result(T_VOID); 357 JavaCalls::call_static(&result, ik, 358 vmSymbols::runtimeSetup(), 359 vmSymbols::void_method_signature(), current); 360 if (current->has_pending_exception()) { 361 // We cannot continue, as we might have cached instances of ik in the heap, but propagating the 362 // exception would cause ik to be in an error state. 363 AOTLinkedClassBulkLoader::exit_on_exception(current); 364 } 365 } 366 } 367 368 // check_can_be_preinited() is quite costly, so we cache the results inside 369 // DumpTimeClassInfo::_can_be_preinited. See also AOTClassInitializer::reset_preinit_check(). 370 bool AOTClassInitializer::check_can_be_preinited(InstanceKlass* ik) { 371 ResourceMark rm; 372 373 if (!SystemDictionaryShared::is_builtin(ik)) { 374 log_info(cds, init)("cannot initialize %s (not built-in loader)", ik->external_name()); 375 return false; 376 } 377 378 InstanceKlass* super = ik->java_super(); 379 if (super != nullptr && !can_be_preinited_locked(super)) { 380 log_info(cds, init)("cannot initialize %s (super %s not initable)", ik->external_name(), super->external_name()); 381 return false; 382 } 383 384 Array<InstanceKlass*>* interfaces = ik->local_interfaces(); 385 for (int i = 0; i < interfaces->length(); i++) { 386 if (!can_be_preinited_locked(interfaces->at(i))) { 387 log_info(cds, init)("cannot initialize %s (interface %s not initable)", 388 ik->external_name(), interfaces->at(i)->external_name()); 389 return false; 390 } 391 } 392 393 if (HeapShared::is_lambda_form_klass(ik)) { 394 // We allow only these to have <clinit> or non-default static fields 395 return true; 396 } 397 398 if (ik->class_initializer() != nullptr) { 399 log_info(cds, init)("cannot initialize %s (has <clinit>)", ik->external_name()); 400 return false; 401 } 402 if (ik->is_initialized() && !has_default_static_fields(ik)) { 403 return false; 404 } 405 406 return true; 407 } 408 409 bool AOTClassInitializer::has_default_static_fields(InstanceKlass* ik) { 410 oop mirror = ik->java_mirror(); 411 412 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { 413 if (fs.access_flags().is_static()) { 414 fieldDescriptor& fd = fs.field_descriptor(); 415 int offset = fd.offset(); 416 bool is_default = true; 417 bool has_initval = fd.has_initial_value(); 418 switch (fd.field_type()) { 419 case T_OBJECT: 420 case T_ARRAY: 421 is_default = mirror->obj_field(offset) == nullptr; 422 break; 423 case T_BOOLEAN: 424 is_default = mirror->bool_field(offset) == (has_initval ? fd.int_initial_value() : 0); 425 break; 426 case T_BYTE: 427 is_default = mirror->byte_field(offset) == (has_initval ? fd.int_initial_value() : 0); 428 break; 429 case T_SHORT: 430 is_default = mirror->short_field(offset) == (has_initval ? fd.int_initial_value() : 0); 431 break; 432 case T_CHAR: 433 is_default = mirror->char_field(offset) == (has_initval ? fd.int_initial_value() : 0); 434 break; 435 case T_INT: 436 is_default = mirror->int_field(offset) == (has_initval ? fd.int_initial_value() : 0); 437 break; 438 case T_LONG: 439 is_default = mirror->long_field(offset) == (has_initval ? fd.long_initial_value() : 0); 440 break; 441 case T_FLOAT: 442 is_default = mirror->float_field(offset) == (has_initval ? fd.float_initial_value() : 0); 443 break; 444 case T_DOUBLE: 445 is_default = mirror->double_field(offset) == (has_initval ? fd.double_initial_value() : 0); 446 break; 447 default: 448 ShouldNotReachHere(); 449 } 450 451 if (!is_default) { 452 log_info(cds, init)("cannot initialize %s (static field %s has non-default value)", 453 ik->external_name(), fd.name()->as_C_string()); 454 return false; 455 } 456 } 457 } 458 459 return true; 460 } 461 462 bool AOTClassInitializer::can_be_preinited(InstanceKlass* ik) { 463 MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); 464 return can_be_preinited_locked(ik); 465 } 466 467 bool AOTClassInitializer::can_be_preinited_locked(InstanceKlass* ik) { 468 if (!CDSConfig::is_initing_classes_at_dump_time()) { 469 return false; 470 } 471 472 assert_lock_strong(DumpTimeTable_lock); 473 DumpTimeClassInfo* info = SystemDictionaryShared::get_info_locked(ik); 474 if (!info->has_done_preinit_check()) { 475 info->set_can_be_preinited(AOTClassInitializer::check_can_be_preinited(ik)); 476 } 477 return info->can_be_preinited(); 478 } 479 480 // Initialize a class at dump time, if possible. 481 void AOTClassInitializer::maybe_preinit_class(InstanceKlass* ik, TRAPS) { 482 #if 0 // FIXME -- leyden+JEP483 merge 483 if (!ik->is_initialized() && AOTClassInitializer::can_be_preinited(ik)) { 484 if (log_is_enabled(Info, cds, init)) { 485 ResourceMark rm; 486 log_info(cds, init)("preinitializing %s", ik->external_name()); 487 } 488 ik->initialize(CHECK); 489 } 490 #endif 491 } 492 493 #ifdef ASSERT 494 void AOTClassInitializer::init_test_class(TRAPS) { 495 // -XX:AOTInitTestClass is used in regression tests for adding additional AOT-initialized classes 496 // and heap objects into the AOT cache. The tests must be carefully written to avoid including 497 // any classes that cannot be AOT-initialized. 498 // 499 // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into 500 // the AOT cache. Therefore, this option is NOT available in product JVM. 501 if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time()) { 502 log_info(cds)("Debug build only: force initialization of AOTInitTestClass %s", AOTInitTestClass); 503 TempNewSymbol class_name = SymbolTable::new_symbol(AOTInitTestClass); 504 Handle app_loader(THREAD, SystemDictionary::java_system_loader()); 505 Klass* k = SystemDictionary::resolve_or_null(class_name, app_loader, CHECK); 506 if (k == nullptr) { 507 vm_exit_during_initialization("AOTInitTestClass not found", AOTInitTestClass); 508 } 509 if (!k->is_instance_klass()) { 510 vm_exit_during_initialization("Invalid name for AOTInitTestClass", AOTInitTestClass); 511 } 512 513 _aot_init_class = InstanceKlass::cast(k); 514 _aot_init_class->initialize(CHECK); 515 } 516 } 517 518 bool AOTClassInitializer::has_test_class() { 519 return _aot_init_class != nullptr; 520 } 521 #endif