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/aotLinkedClassBulkLoader.hpp"
27 #include "cds/archiveBuilder.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/heapShared.hpp"
30 #include "cds/regeneratedClasses.hpp"
31 #include "classfile/symbolTable.hpp"
32 #include "classfile/systemDictionaryShared.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "oops/instanceKlass.inline.hpp"
35 #include "oops/symbol.hpp"
36 #include "runtime/java.hpp"
37 #include "runtime/javaCalls.hpp"
38
39 DEBUG_ONLY(InstanceKlass* _aot_init_class = nullptr;)
40
41 bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
42 assert(!ArchiveBuilder::is_active() || !ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass");
43 if (!CDSConfig::is_initing_classes_at_dump_time()) {
44 return false;
45 }
46
47 if (RegeneratedClasses::is_regenerated_object(ik)) {
48 ik = RegeneratedClasses::get_original_object(ik);
49 }
50
51 if (!ik->is_initialized() && !ik->is_being_initialized()) {
52 return false;
53 }
54
55 // About "static field that may hold a different value" errors:
56 //
57 // Automatic selection for aot-inited classes
228
229 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
230 assert(ik->has_aot_initialized_mirror(), "sanity");
231 if (ik->is_runtime_setup_required()) {
232 if (log_is_enabled(Info, aot, init)) {
233 ResourceMark rm;
234 log_info(aot, init)("Calling %s::runtimeSetup()", ik->external_name());
235 }
236 JavaValue result(T_VOID);
237 JavaCalls::call_static(&result, ik,
238 vmSymbols::runtimeSetup(),
239 vmSymbols::void_method_signature(), current);
240 if (current->has_pending_exception()) {
241 // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
242 // exception would cause ik to be in an error state.
243 AOTLinkedClassBulkLoader::exit_on_exception(current);
244 }
245 }
246 }
247
248 #ifdef ASSERT
249 void AOTClassInitializer::init_test_class(TRAPS) {
250 // -XX:AOTInitTestClass is used in regression tests for adding additional AOT-initialized classes
251 // and heap objects into the AOT cache. The tests must be carefully written to avoid including
252 // any classes that cannot be AOT-initialized.
253 //
254 // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into
255 // the AOT cache. Therefore, this option is NOT available in product JVM.
256 if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time()) {
257 log_info(aot)("Debug build only: force initialization of AOTInitTestClass %s", AOTInitTestClass);
258 TempNewSymbol class_name = SymbolTable::new_symbol(AOTInitTestClass);
259 Handle app_loader(THREAD, SystemDictionary::java_system_loader());
260 Klass* k = SystemDictionary::resolve_or_null(class_name, app_loader, CHECK);
261 if (k == nullptr) {
262 vm_exit_during_initialization("AOTInitTestClass not found", AOTInitTestClass);
263 }
264 if (!k->is_instance_klass()) {
265 vm_exit_during_initialization("Invalid name for AOTInitTestClass", AOTInitTestClass);
266 }
267
|
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/aotLinkedClassBulkLoader.hpp"
27 #include "cds/archiveBuilder.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/heapShared.hpp"
30 #include "cds/regeneratedClasses.hpp"
31 #include "classfile/symbolTable.hpp"
32 #include "classfile/systemDictionaryShared.hpp"
33 #include "classfile/vmSymbols.hpp"
34 #include "dumpTimeClassInfo.inline.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "oops/fieldStreams.inline.hpp"
37 #include "oops/instanceKlass.inline.hpp"
38 #include "oops/symbol.hpp"
39 #include "runtime/fieldDescriptor.inline.hpp"
40 #include "runtime/java.hpp"
41 #include "runtime/javaCalls.hpp"
42 #include "runtime/mutexLocker.hpp"
43
44 DEBUG_ONLY(InstanceKlass* _aot_init_class = nullptr;)
45
46 bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) {
47 assert(!ArchiveBuilder::is_active() || !ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass");
48 if (!CDSConfig::is_initing_classes_at_dump_time()) {
49 return false;
50 }
51
52 if (RegeneratedClasses::is_regenerated_object(ik)) {
53 ik = RegeneratedClasses::get_original_object(ik);
54 }
55
56 if (!ik->is_initialized() && !ik->is_being_initialized()) {
57 return false;
58 }
59
60 // About "static field that may hold a different value" errors:
61 //
62 // Automatic selection for aot-inited classes
233
234 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
235 assert(ik->has_aot_initialized_mirror(), "sanity");
236 if (ik->is_runtime_setup_required()) {
237 if (log_is_enabled(Info, aot, init)) {
238 ResourceMark rm;
239 log_info(aot, init)("Calling %s::runtimeSetup()", ik->external_name());
240 }
241 JavaValue result(T_VOID);
242 JavaCalls::call_static(&result, ik,
243 vmSymbols::runtimeSetup(),
244 vmSymbols::void_method_signature(), current);
245 if (current->has_pending_exception()) {
246 // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
247 // exception would cause ik to be in an error state.
248 AOTLinkedClassBulkLoader::exit_on_exception(current);
249 }
250 }
251 }
252
253 // check_can_be_preinited() is quite costly, so we cache the results inside
254 // DumpTimeClassInfo::_can_be_preinited. See also AOTClassInitializer::reset_preinit_check().
255 bool AOTClassInitializer::check_can_be_preinited(InstanceKlass* ik) {
256 ResourceMark rm;
257
258 if (!SystemDictionaryShared::is_builtin(ik)) {
259 log_info(cds, init)("cannot initialize %s (not built-in loader)", ik->external_name());
260 return false;
261 }
262
263 InstanceKlass* super = ik->java_super();
264 if (super != nullptr && !can_be_preinited_locked(super)) {
265 log_info(cds, init)("cannot initialize %s (super %s not initable)", ik->external_name(), super->external_name());
266 return false;
267 }
268
269 Array<InstanceKlass*>* interfaces = ik->local_interfaces();
270 for (int i = 0; i < interfaces->length(); i++) {
271 if (!can_be_preinited_locked(interfaces->at(i))) {
272 log_info(cds, init)("cannot initialize %s (interface %s not initable)",
273 ik->external_name(), interfaces->at(i)->external_name());
274 return false;
275 }
276 }
277
278 if (HeapShared::is_lambda_form_klass(ik)) {
279 // We allow only these to have <clinit> or non-default static fields
280 return true;
281 }
282
283 if (ik->class_initializer() != nullptr) {
284 log_info(cds, init)("cannot initialize %s (has <clinit>)", ik->external_name());
285 return false;
286 }
287 if (ik->is_initialized() && !has_default_static_fields(ik)) {
288 return false;
289 }
290
291 return true;
292 }
293
294 bool AOTClassInitializer::has_default_static_fields(InstanceKlass* ik) {
295 oop mirror = ik->java_mirror();
296
297 for (JavaFieldStream fs(ik); !fs.done(); fs.next()) {
298 if (fs.access_flags().is_static()) {
299 fieldDescriptor& fd = fs.field_descriptor();
300 int offset = fd.offset();
301 bool is_default = true;
302 bool has_initval = fd.has_initial_value();
303 switch (fd.field_type()) {
304 case T_OBJECT:
305 case T_ARRAY:
306 is_default = mirror->obj_field(offset) == nullptr;
307 break;
308 case T_BOOLEAN:
309 is_default = mirror->bool_field(offset) == (has_initval ? fd.int_initial_value() : 0);
310 break;
311 case T_BYTE:
312 is_default = mirror->byte_field(offset) == (has_initval ? fd.int_initial_value() : 0);
313 break;
314 case T_SHORT:
315 is_default = mirror->short_field(offset) == (has_initval ? fd.int_initial_value() : 0);
316 break;
317 case T_CHAR:
318 is_default = mirror->char_field(offset) == (has_initval ? fd.int_initial_value() : 0);
319 break;
320 case T_INT:
321 is_default = mirror->int_field(offset) == (has_initval ? fd.int_initial_value() : 0);
322 break;
323 case T_LONG:
324 is_default = mirror->long_field(offset) == (has_initval ? fd.long_initial_value() : 0);
325 break;
326 case T_FLOAT:
327 is_default = mirror->float_field(offset) == (has_initval ? fd.float_initial_value() : 0);
328 break;
329 case T_DOUBLE:
330 is_default = mirror->double_field(offset) == (has_initval ? fd.double_initial_value() : 0);
331 break;
332 default:
333 ShouldNotReachHere();
334 }
335
336 if (!is_default) {
337 log_info(cds, init)("cannot initialize %s (static field %s has non-default value)",
338 ik->external_name(), fd.name()->as_C_string());
339 return false;
340 }
341 }
342 }
343
344 return true;
345 }
346
347 bool AOTClassInitializer::can_be_preinited(InstanceKlass* ik) {
348 MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag);
349 return can_be_preinited_locked(ik);
350 }
351
352 bool AOTClassInitializer::can_be_preinited_locked(InstanceKlass* ik) {
353 if (!CDSConfig::is_initing_classes_at_dump_time()) {
354 return false;
355 }
356
357 assert_lock_strong(DumpTimeTable_lock);
358 DumpTimeClassInfo* info = SystemDictionaryShared::get_info_locked(ik);
359 if (!info->has_done_preinit_check()) {
360 info->set_can_be_preinited(AOTClassInitializer::check_can_be_preinited(ik));
361 }
362 return info->can_be_preinited();
363 }
364
365 // Initialize a class at dump time, if possible.
366 void AOTClassInitializer::maybe_preinit_class(InstanceKlass* ik, TRAPS) {
367 #if 0 // FIXME -- leyden+JEP483 merge
368 if (!ik->is_initialized() && AOTClassInitializer::can_be_preinited(ik)) {
369 if (log_is_enabled(Info, cds, init)) {
370 ResourceMark rm;
371 log_info(cds, init)("preinitializing %s", ik->external_name());
372 }
373 ik->initialize(CHECK);
374 }
375 #endif
376 }
377
378 #ifdef ASSERT
379 void AOTClassInitializer::init_test_class(TRAPS) {
380 // -XX:AOTInitTestClass is used in regression tests for adding additional AOT-initialized classes
381 // and heap objects into the AOT cache. The tests must be carefully written to avoid including
382 // any classes that cannot be AOT-initialized.
383 //
384 // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into
385 // the AOT cache. Therefore, this option is NOT available in product JVM.
386 if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time()) {
387 log_info(aot)("Debug build only: force initialization of AOTInitTestClass %s", AOTInitTestClass);
388 TempNewSymbol class_name = SymbolTable::new_symbol(AOTInitTestClass);
389 Handle app_loader(THREAD, SystemDictionary::java_system_loader());
390 Klass* k = SystemDictionary::resolve_or_null(class_name, app_loader, CHECK);
391 if (k == nullptr) {
392 vm_exit_during_initialization("AOTInitTestClass not found", AOTInitTestClass);
393 }
394 if (!k->is_instance_klass()) {
395 vm_exit_during_initialization("Invalid name for AOTInitTestClass", AOTInitTestClass);
396 }
397
|