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