< prev index next >

src/hotspot/share/oops/trainingData.cpp

Print this page
@@ -35,10 +35,11 @@
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
  #include "oops/method.hpp"
  #include "oops/method.inline.hpp"
  #include "oops/methodCounters.hpp"
+ #include "oops/recompilationSchedule.hpp"
  #include "oops/trainingData.hpp"
  #include "runtime/arguments.hpp"
  #include "runtime/javaThread.inline.hpp"
  #include "runtime/jniHandles.inline.hpp"
  #include "utilities/growableArray.hpp"

@@ -66,25 +67,29 @@
  }
  
  void TrainingData::initialize() {
    // this is a nop if training modes are not enabled
    if (have_data() || need_data()) {
-     // Data structures that we have do not currently support iterative training. So you cannot replay
-     // and train at the same time. Going forward we may want to adjust iteration/search to enable that.
-     guarantee(have_data() != need_data(), "Iterative training is not supported");
      TrainingDataLocker::initialize();
    }
+   RecompilationSchedule::initialize();
+   if (have_data() && need_data()) {
+     TrainingDataLocker l;
+     archived_training_data_dictionary()->iterate_all([&](TrainingData* td) {
+       training_data_set()->install(td);
+     });
+   }
  }
  
  static void verify_archived_entry(TrainingData* td, const TrainingData::Key* k) {
    guarantee(TrainingData::Key::can_compute_cds_hash(k), "");
    TrainingData* td1 = TrainingData::lookup_archived_training_data(k);
    guarantee(td == td1, "");
  }
  
  void TrainingData::verify() {
-   if (TrainingData::have_data() && !TrainingData::assembling_data()) {
+   if (have_data() && !need_data() && !assembling_data()) {
      archived_training_data_dictionary()->iterate_all([&](TrainingData* td) {
        if (td->is_KlassTrainingData()) {
          KlassTrainingData* ktd = td->as_KlassTrainingData();
          if (ktd->has_holder() && ktd->holder()->is_loaded()) {
            Key k(ktd->holder());

@@ -99,11 +104,11 @@
          }
          mtd->verify(/*verify_dep_counter*/true);
        }
      });
    }
-   if (TrainingData::need_data()) {
+   if (need_data()) {
      TrainingDataLocker l;
      training_data_set()->iterate([&](TrainingData* td) {
        if (td->is_KlassTrainingData()) {
          KlassTrainingData* ktd = td->as_KlassTrainingData();
          ktd->verify();

@@ -147,11 +152,11 @@
    }
  
    TrainingData* td = nullptr;
  
    Key key(method());
-   if (have_data()) {
+   if (have_data() && !need_data()) {
      td = lookup_archived_training_data(&key);
      if (td != nullptr) {
        mtd = td->as_MethodTrainingData();
      } else {
        mtd = nullptr;

@@ -307,32 +312,31 @@
  void CompileTrainingData::notice_jit_observation(ciEnv* env, ciBaseObject* what) {
    // A JIT is starting to look at class k.
    // We could follow the queries that it is making, but it is
    // simpler to assume, conservatively, that the JIT will
    // eventually depend on the initialization state of k.
-   CompileTask* task = env->task();
-   assert(task != nullptr, "");
-   Method* method = task->method();
-   if (what->is_metadata()) {
-     ciMetadata* md = what->as_metadata();
-     if (md->is_loaded() && md->is_instance_klass()) {
-       ciInstanceKlass* cik = md->as_instance_klass();
- 
-       if (cik->is_initialized()) {
-         InstanceKlass* ik = md->as_instance_klass()->get_instanceKlass();
-         KlassTrainingData* ktd = KlassTrainingData::make(ik);
-         if (ktd == nullptr) {
-           // Allocation failure or snapshot in progress
-           return;
-         }
-         // This JIT task is (probably) requesting that ik be initialized,
-         // so add him to my _init_deps list.
-         TrainingDataLocker l;
-         if (l.can_add()) {
-           add_init_dep(ktd);
-         }
-       }
+   ciMetadata* md = nullptr;
+   if (what->is_object()) {
+     md = what->as_object()->klass();
+   } else if (what->is_metadata()) {
+     md = what->as_metadata();
+   }
+   if (md != nullptr && md->is_loaded() && md->is_instance_klass()) {
+     ciInstanceKlass* cik = md->as_instance_klass();
+     if (!cik->is_initialized()) {
+       return;
+     }
+     KlassTrainingData* ktd = KlassTrainingData::make(cik->get_instanceKlass());
+     if (ktd == nullptr) {
+       // Allocation failure or snapshot in progress
+       return;
+     }
+     // This JIT task is (probably) requesting that ik be initialized,
+     // so add it to my _init_deps list.
+     TrainingDataLocker l;
+     if (l.can_add()) {
+       add_init_dep(ktd);
      }
    }
  }
  
  void KlassTrainingData::prepare(Visitor& visitor) {

@@ -374,11 +378,11 @@
    _ci_records.prepare();
  }
  
  KlassTrainingData* KlassTrainingData::make(InstanceKlass* holder, bool null_if_not_found) {
    Key key(holder);
-   TrainingData* td = CDS_ONLY(have_data() ? lookup_archived_training_data(&key) :) nullptr;
+   TrainingData* td = CDS_ONLY((have_data() && !need_data()) ? lookup_archived_training_data(&key) :) nullptr;
    KlassTrainingData* ktd = nullptr;
    if (td != nullptr) {
      ktd = td->as_KlassTrainingData();
      guarantee(!ktd->has_holder() || ktd->holder() == holder, "");
      if (ktd->has_holder()) {

@@ -461,12 +465,11 @@
    }
    holder()->set_has_init_deps_processed();
  }
  
  void TrainingData::init_dumptime_table(TRAPS) {
-   precond((!assembling_data() && !need_data()) || need_data() != assembling_data());
-   if (assembling_data()) {
+   if (assembling_data() && !need_data()) {
      _dumptime_training_data_dictionary = new DumptimeTrainingDataDictionary();
      _archived_training_data_dictionary.iterate_all([&](TrainingData* record) {
        _dumptime_training_data_dictionary->append(record);
      });
    }

@@ -482,10 +485,12 @@
          _dumptime_training_data_dictionary->append(td);
        }
      });
    }
  
+   RecompilationSchedule::prepare(CHECK);
+ 
    if (AOTVerifyTrainingData) {
      TrainingData::verify();
    }
  }
  

@@ -493,10 +498,11 @@
    if (_dumptime_training_data_dictionary != nullptr) {
      for (int i = 0; i < _dumptime_training_data_dictionary->length(); i++) {
        _dumptime_training_data_dictionary->at(i).metaspace_pointers_do(it);
      }
    }
+   RecompilationSchedule::iterate_roots(it);
  }
  
  void TrainingData::dump_training_data() {
    if (_dumptime_training_data_dictionary != nullptr) {
      CompactHashtableStats stats;

@@ -539,10 +545,11 @@
        }
        j++;
      }
      _dumptime_training_data_dictionary->trunc_to(j);
    }
+   RecompilationSchedule::cleanup();
  }
  
  void KlassTrainingData::cleanup(Visitor& visitor) {
    if (visitor.is_visited(this)) {
      return;

@@ -652,10 +659,11 @@
    if (soc->writing()) {
      _archived_training_data_dictionary_for_dumping.serialize_header(soc);
    } else {
      _archived_training_data_dictionary.serialize_header(soc);
    }
+   RecompilationSchedule::serialize(soc);
  }
  
  class TrainingDataPrinter : StackObj {
    outputStream* _st;
    int _index;

@@ -691,10 +699,11 @@
  void TrainingData::print_archived_training_data_on(outputStream* st) {
    st->print_cr("Archived TrainingData Dictionary");
    TrainingDataPrinter tdp(st);
    TrainingDataLocker::initialize();
    _archived_training_data_dictionary.iterate_all(&tdp);
+   RecompilationSchedule::print_archived_training_data_on(st);
  }
  
  void TrainingData::Key::metaspace_pointers_do(MetaspaceClosure *iter) {
    iter->push(const_cast<Metadata**>(&_meta));
  }

@@ -710,10 +719,11 @@
  uint TrainingData::Key::cds_hash(const Key* const& k) {
    return SystemDictionaryShared::hash_for_shared_dictionary((address)k->meta());
  }
  
  TrainingData* TrainingData::lookup_archived_training_data(const Key* k) {
+   assert(!need_data(), "Should be used only in read-only mode");
    // For this to work, all components of the key must be in shared metaspace.
    if (!TrainingData::Key::can_compute_cds_hash(k) || _archived_training_data_dictionary.empty()) {
      return nullptr;
    }
    uint hash = TrainingData::Key::cds_hash(k);

@@ -767,10 +777,11 @@
      int len = _deps_dyn->length();
      _deps = MetadataFactory::new_array_from_c_heap<T>(len, mtClassShared);
      for (int i = 0; i < len; i++) {
        _deps->at_put(i, _deps_dyn->at(i)); // copy
      }
+     _deps_dyn = nullptr;
    }
  }
  
  void KlassTrainingData::remove_unshareable_info() {
    TrainingData::remove_unshareable_info();
< prev index next >