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