< prev index next >

src/hotspot/share/cds/aotClassInitializer.cpp

Print this page

  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 "cds/heapShared.hpp"

 30 #include "classfile/vmSymbols.hpp"


 31 #include "oops/instanceKlass.inline.hpp"
 32 #include "oops/symbol.hpp"

 33 #include "runtime/javaCalls.hpp"

 34 
 35 // Detector for class names we wish to handle specially.
 36 // It is either an exact string match or a string prefix match.
 37 class AOTClassInitializer::AllowedSpec {
 38   const char* _class_name;
 39   bool _is_prefix;
 40   int _len;
 41 public:
 42   AllowedSpec(const char* class_name, bool is_prefix = false)
 43     : _class_name(class_name), _is_prefix(is_prefix)
 44   {
 45     _len = (class_name == nullptr) ? 0 : (int)strlen(class_name);
 46   }
 47   const char* class_name() { return _class_name; }
 48 
 49   bool matches(Symbol* name, int len) {
 50     assert(_class_name != nullptr, "caller resp.");
 51     if (_is_prefix) {
 52       return len >= _len && name->starts_with(_class_name);
 53     } else {

340 
341 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
342   assert(ik->has_aot_initialized_mirror(), "sanity");
343   if (ik->is_runtime_setup_required()) {
344     if (log_is_enabled(Info, cds, init)) {
345       ResourceMark rm;
346       log_info(cds, init)("Calling %s::runtimeSetup()", ik->external_name());
347     }
348     JavaValue result(T_VOID);
349     JavaCalls::call_static(&result, ik,
350                            vmSymbols::runtimeSetup(),
351                            vmSymbols::void_method_signature(), current);
352     if (current->has_pending_exception()) {
353       // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
354       // exception would cause ik to be in an error state.
355       AOTLinkedClassBulkLoader::exit_on_exception(current);
356     }
357   }
358 }
359 





























































































































  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 {

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 }
< prev index next >