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