< prev index next >

src/hotspot/share/cds/aotClassInitializer.cpp

Print this page

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

 29 #include "classfile/vmSymbols.hpp"


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

 32 #include "runtime/javaCalls.hpp"

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

307     // MethodHandleStatics is an example of a class that must NOT get the aot-init treatment,
308     // because of its strong reliance on (a) final fields which are (b) environmentally determined.
309     //{"java/lang/invoke/InvokerBytecodeGenerator"},
310 
311       {nullptr}
312     };
313     if (is_allowed(indy_specs, ik)) {
314       return true;
315     }
316   }
317 
318   return false;
319 }
320 
321 // TODO: currently we have a hard-coded list. We should turn this into
322 // an annotation: @jdk.internal.vm.annotation.RuntimeSetupRequired
323 // See JDK-8342481.
324 bool AOTClassInitializer::is_runtime_setup_required(InstanceKlass* ik) {
325   return ik == vmClasses::Class_klass() ||
326          ik == vmClasses::internal_Unsafe_klass() ||
327          ik == vmClasses::ConcurrentHashMap_klass();



328 }
329 
330 void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) {
331   assert(ik->has_aot_initialized_mirror(), "sanity");
332   if (ik->is_runtime_setup_required()) {
333     if (log_is_enabled(Info, cds, init)) {
334       ResourceMark rm;
335       log_info(cds, init)("Calling %s::runtimeSetup()", ik->external_name());
336     }
337     JavaValue result(T_VOID);
338     JavaCalls::call_static(&result, ik,
339                            vmSymbols::runtimeSetup(),
340                            vmSymbols::void_method_signature(), current);
341     if (current->has_pending_exception()) {
342       // We cannot continue, as we might have cached instances of ik in the heap, but propagating the
343       // exception would cause ik to be in an error state.
344       AOTLinkedClassBulkLoader::exit_on_exception(current);
345     }
346   }
347 }






























































































































  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 {

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