< prev index next >

src/hotspot/share/ci/ciMethodData.cpp

Print this page
@@ -29,10 +29,11 @@
  #include "compiler/compiler_globals.hpp"
  #include "memory/allocation.inline.hpp"
  #include "memory/resourceArea.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/methodData.inline.hpp"
+ #include "oops/trainingData.hpp"
  #include "runtime/deoptimization.hpp"
  #include "utilities/copy.hpp"
  
  // ciMethodData
  

@@ -52,10 +53,19 @@
    // Initialize the escape information (to "don't know.");
    _eflags(0), _arg_local(0), _arg_stack(0), _arg_returned(0),
    _invocation_counter(0),
    _orig() {}
  
+ 
+ static bool is_klass_loaded(Klass* k) {
+   if (TrainingData::have_data()) {
+     // If we're running in AOT mode some classes may not be loaded yet
+     return !k->is_instance_klass() || InstanceKlass::cast(k)->is_loaded();
+   }
+   return true;
+ }
+ 
  // Check for entries that reference an unloaded method
  class PrepareExtraDataClosure : public CleanExtraDataClosure {
    MethodData*            _mdo;
    SafepointStateTracker  _safepoint_tracker;
    GrowableArray<Method*> _uncached_methods;

@@ -66,11 +76,12 @@
        _safepoint_tracker(SafepointSynchronize::safepoint_state_tracker()),
        _uncached_methods()
    { }
  
    bool is_live(Method* m) {
-     if (!m->method_holder()->is_loader_alive()) {
+     Klass* holder = m->method_holder();
+     if (holder == nullptr || !holder->is_loader_present_and_alive() || !is_klass_loaded(holder)) {
        return false;
      }
      if (CURRENT_ENV->cached_metadata(m) == nullptr) {
        // Uncached entries need to be pre-populated.
        _uncached_methods.append(m);

@@ -301,11 +312,11 @@
  }
  
  void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
    for (uint row = 0; row < row_limit(); row++) {
      Klass* k = data->as_ReceiverTypeData()->receiver(row);
-     if (k != nullptr) {
+     if (k != nullptr && k->class_loader_data() != nullptr && is_klass_loaded(k)) {
        if (k->is_loader_alive()) {
          ciKlass* klass = CURRENT_ENV->get_klass(k);
          set_receiver(row, klass);
        } else {
          // With concurrent class unloading, the MDO could have stale metadata; override it

@@ -319,11 +330,11 @@
  
  void ciTypeStackSlotEntries::translate_type_data_from(const TypeStackSlotEntries* entries) {
    for (int i = 0; i < number_of_entries(); i++) {
      intptr_t k = entries->type(i);
      Klass* klass = (Klass*)klass_part(k);
-     if (klass != nullptr && !klass->is_loader_alive()) {
+     if (klass == nullptr || !klass->is_loader_present_and_alive() || !is_klass_loaded(klass)) {
        // With concurrent class unloading, the MDO could have stale metadata; override it
        TypeStackSlotEntries::set_type(i, TypeStackSlotEntries::with_status((Klass*)nullptr, k));
      } else {
        TypeStackSlotEntries::set_type(i, translate_klass(k));
      }

@@ -331,11 +342,11 @@
  }
  
  void ciReturnTypeEntry::translate_type_data_from(const ReturnTypeEntry* ret) {
    intptr_t k = ret->type();
    Klass* klass = (Klass*)klass_part(k);
-   if (klass != nullptr && !klass->is_loader_alive()) {
+   if (klass == nullptr || !klass->is_loader_present_and_alive() || !is_klass_loaded(klass)) {
      // With concurrent class unloading, the MDO could have stale metadata; override it
      set_type(ReturnTypeEntry::with_status((Klass*)nullptr, k));
    } else {
      set_type(translate_klass(k));
    }
< prev index next >