1 /*
  2  * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  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/archiveBuilder.hpp>
 26 #include <classfile/systemDictionaryShared.hpp>
 27 #include <compiler/compileBroker.hpp>
 28 #include "precompiled.hpp"
 29 #include "ci/ciEnv.hpp"
 30 #include "ci/ciMetadata.hpp"
 31 #include "cds/archiveBuilder.hpp"
 32 #include "cds/cdsConfig.hpp"
 33 #include "cds/metaspaceShared.hpp"
 34 #include "cds/methodDataDictionary.hpp"
 35 #include "cds/methodProfiler.hpp"
 36 #include "cds/runTimeClassInfo.hpp"
 37 #include "classfile/classLoaderData.hpp"
 38 #include "classfile/compactHashtable.hpp"
 39 #include "classfile/javaClasses.hpp"
 40 #include "classfile/symbolTable.hpp"
 41 #include "classfile/systemDictionaryShared.hpp"
 42 #include "compiler/compileTask.hpp"
 43 #include "memory/metadataFactory.hpp"
 44 #include "memory/metaspaceClosure.hpp"
 45 #include "memory/resourceArea.hpp"
 46 #include "oops/fieldStreams.inline.hpp"
 47 #include "oops/method.hpp"
 48 #include "oops/methodCounters.hpp"
 49 #include "oops/trainingData.hpp"
 50 #include "runtime/arguments.hpp"
 51 #include "runtime/fieldDescriptor.inline.hpp"
 52 #include "runtime/javaThread.inline.hpp"
 53 #include "runtime/jniHandles.inline.hpp"
 54 #include "runtime/os.hpp"
 55 #include "utilities/growableArray.hpp"
 56 #include "utilities/xmlstream.hpp"
 57 
 58 TrainingData::TrainingDataSet TrainingData::_training_data_set(1024, 0x3fffffff);
 59 TrainingDataDictionary TrainingData::_archived_training_data_dictionary;
 60 TrainingDataDictionary TrainingData::_archived_training_data_dictionary_for_dumping;
 61 GrowableArrayCHeap<DumpTimeTrainingDataInfo, mtClassShared>* TrainingData::_dumptime_training_data_dictionary = nullptr;
 62 Array<MethodTrainingData*>* TrainingData::_recompilation_schedule = nullptr;
 63 Array<MethodTrainingData*>* TrainingData::_recompilation_schedule_for_dumping = nullptr;
 64 volatile bool* TrainingData::_recompilation_status = nullptr;
 65 int TrainingData::TrainingDataLocker::_lock_mode;
 66 
 67 MethodTrainingData::MethodTrainingData() {
 68   assert(CDSConfig::is_dumping_static_archive() || UseSharedSpaces, "only for CDS");
 69 }
 70 
 71 KlassTrainingData::KlassTrainingData() {
 72   assert(CDSConfig::is_dumping_static_archive() || UseSharedSpaces, "only for CDS");
 73 }
 74 
 75 CompileTrainingData::CompileTrainingData() : _level(-1), _compile_id(-1) {
 76   assert(CDSConfig::is_dumping_static_archive() || UseSharedSpaces, "only for CDS");
 77 }
 78 
 79 void TrainingData::initialize() {
 80   // this is a nop if training modes are not enabled
 81   if (have_data() || need_data()) {
 82     TrainingDataLocker::initialize();
 83   }
 84   if (have_data()) {
 85     if (_recompilation_schedule != nullptr && _recompilation_schedule->length() > 0) {
 86       const int size = _recompilation_schedule->length();
 87       _recompilation_status = NEW_C_HEAP_ARRAY(bool, size, mtCompiler);
 88       for (int i = 0; i < size; i++) {
 89         _recompilation_status[i] = false;
 90       }
 91     }
 92   }
 93 }
 94 
 95 static void verify_archived_entry(TrainingData* td, const TrainingData::Key* k) {
 96   ResourceMark rm;
 97   guarantee(TrainingData::Key::can_compute_cds_hash(k), "%s %s " INTPTR_FORMAT,
 98             (k->name1() != nullptr ? k->name1()->as_C_string() : "(null)"),
 99             (k->name2() != nullptr ? k->name2()->as_C_string() : "(null)"),
100             p2i(k->holder()));
101 
102   TrainingData* td1 = TrainingData::lookup_archived_training_data(k);
103   guarantee(td == td1, "%s %s " INTPTR_FORMAT ": " INTPTR_FORMAT " != " INTPTR_FORMAT,
104             (k->name1() != nullptr ? k->name1()->as_C_string() : "(null)"),
105             (k->name2() != nullptr ? k->name2()->as_C_string() : "(null)"),
106             p2i(k->holder()), p2i(td), p2i(td1));
107 }
108 
109 void TrainingData::verify() {
110   if (TrainingData::have_data()) {
111     archived_training_data_dictionary()->iterate([&](TrainingData* td) {
112       if (td->is_KlassTrainingData()) {
113         KlassTrainingData* ktd = td->as_KlassTrainingData();
114         if (ktd->has_holder() && ktd->holder()->is_loaded()) {
115           Key k(ktd->holder());
116           verify_archived_entry(td, &k);
117         }
118         ktd->verify();
119       } else if (td->is_MethodTrainingData()) {
120         MethodTrainingData* mtd = td->as_MethodTrainingData();
121         if (mtd->has_holder() && mtd->holder()->method_holder()->is_loaded()) {
122           Key k(mtd);
123           verify_archived_entry(td, &k);
124         }
125         mtd->verify();
126       } else if (td->is_CompileTrainingData()) {
127         td->as_CompileTrainingData()->verify();
128       }
129     });
130   }
131 }
132 
133 
134 TrainingData::Key::Key(const KlassTrainingData* klass, Symbol* method_name, Symbol* signature)
135   : Key(method_name, signature, klass) {}
136 
137 TrainingData::Key::Key(const InstanceKlass* klass)
138   : Key(klass->name(), klass->class_loader_name_and_id()) {
139   // Often the loader is either null or the string "'app'" (w/ extra quotes).
140   // It can also be "'platform'".
141 }
142 
143 TrainingData::Key::Key(const Method* method, KlassTrainingData* holder)
144   : Key(method->name(), method->signature(), holder)
145 {
146   assert(method->method_holder() == holder->holder(), "mismatch");
147 }
148 
149 TrainingData::Key::Key(const MethodTrainingData* method) : Key(method->holder(), method->klass()) {}
150 
151 MethodTrainingData* MethodTrainingData::make(const methodHandle& method,
152                                              bool null_if_not_found) {
153   MethodTrainingData* mtd = nullptr;
154   if (!have_data() && !need_data()) {
155     return mtd;
156   }
157   // Try grabbing the cached value first.
158   MethodCounters* mcs = method->method_counters();
159   if (mcs != nullptr) {
160     mtd = mcs->method_training_data();
161     if (mtd != nullptr) {
162       return mtd;
163     }
164   } else {
165     mcs = Method::build_method_counters(Thread::current(), method());
166   }
167 
168   KlassTrainingData* holder = KlassTrainingData::make(method->method_holder(), null_if_not_found);
169   if (holder == nullptr) {
170     return nullptr; // allocation failure
171   }
172   Key key(method->name(), method->signature(), holder);
173   TrainingData* td = have_data()? lookup_archived_training_data(&key) : nullptr;
174   if (td != nullptr) {
175     mtd = td->as_MethodTrainingData();
176     mtd->refresh_from(method());
177     method->init_training_data(mtd);  // Cache the pointer for next time.
178     return mtd;
179   } else {
180     TrainingDataLocker l;
181     td = training_data_set()->find(&key);
182     if (td == nullptr && null_if_not_found) {
183       return nullptr;
184     }
185     if (td != nullptr) {
186       mtd = td->as_MethodTrainingData();
187       mtd->refresh_from(method());
188       method->init_training_data(mtd); // Cache the pointer for next time.
189       return mtd;
190     }
191   }
192   assert(td == nullptr && mtd == nullptr && !null_if_not_found, "Should return if have result");
193   KlassTrainingData* ktd = KlassTrainingData::make(method->method_holder());
194   if (ktd != nullptr) {
195     TrainingDataLocker l;
196     td = training_data_set()->find(&key);
197     if (td == nullptr) {
198       mtd = MethodTrainingData::allocate(ktd, method());
199       if (mtd == nullptr) {
200         return nullptr; // allocation failure
201       }
202       td = training_data_set()->install(mtd);
203       assert(td == mtd, "");
204     } else {
205       mtd = td->as_MethodTrainingData();
206     }
207     mtd->refresh_from(method());
208     method->init_training_data(mtd);
209   }
210   return mtd;
211 }
212 
213 void MethodTrainingData::print_on(outputStream* st, bool name_only) const {
214   _klass->print_on(st, true);
215   st->print(".");
216   name()->print_symbol_on(st);
217   signature()->print_symbol_on(st);
218   if (name_only) {
219     return;
220   }
221   if (!has_holder()) {
222     st->print("[SYM]");
223   }
224   if (_level_mask) {
225     st->print(" LM%d", _level_mask);
226   }
227   st->print(" mc=%p mdo=%p", _final_counters, _final_profile);
228 }
229 
230 void MethodTrainingData::refresh_from(const Method* method) {
231   if (method == nullptr || method == _holder) {
232     return;
233   }
234   _holder = method;
235 }
236 
237 CompileTrainingData* CompileTrainingData::make(CompileTask* task) {
238   int level = task->comp_level();
239   int compile_id = task->compile_id();
240   Thread* thread = Thread::current();
241   methodHandle m(thread, task->method());
242   MethodTrainingData* mtd = MethodTrainingData::make(m);
243   if (mtd == nullptr) {
244     return nullptr; // allocation failure
245   }
246   mtd->notice_compilation(level);
247 
248   CompileTrainingData* ctd = CompileTrainingData::allocate(mtd, level, compile_id);
249   if (ctd != nullptr) {
250     TrainingDataLocker l;
251     if (mtd->_last_toplevel_compiles[level - 1] != nullptr) {
252       if (mtd->_last_toplevel_compiles[level - 1]->compile_id() < compile_id) {
253         mtd->_last_toplevel_compiles[level - 1]->clear_init_deps();
254         mtd->_last_toplevel_compiles[level - 1] = ctd;
255         mtd->_highest_top_level = MAX2(mtd->_highest_top_level, level);
256       }
257     } else {
258       mtd->_last_toplevel_compiles[level - 1] = ctd;
259       mtd->_highest_top_level = MAX2(mtd->_highest_top_level, level);
260     }
261   }
262   return ctd;
263 }
264 
265 
266 void CompileTrainingData::dec_init_deps_left(KlassTrainingData* ktd) {
267   LogStreamHandle(Trace, training) log;
268   if (log.is_enabled()) {
269     log.print("CTD "); print_on(&log); log.cr();
270     log.print("KTD "); ktd->print_on(&log); log.cr();
271   }
272   assert(ktd!= nullptr && ktd->has_holder(), "");
273   assert(_init_deps.contains(ktd), "");
274   assert(_init_deps_left > 0, "");
275 
276   uint init_deps_left1 = Atomic::sub(&_init_deps_left, 1);
277 
278   if (log.is_enabled()) {
279     uint init_deps_left2 = compute_init_deps_left();
280     log.print("init_deps_left: %d (%d)", init_deps_left1, init_deps_left2);
281     ktd->print_on(&log, true);
282   }
283 }
284 
285 uint CompileTrainingData::compute_init_deps_left(bool count_initialized) {
286   int left = 0;
287   for (int i = 0; i < _init_deps.length(); i++) {
288     KlassTrainingData* ktd = _init_deps.at(i);
289     // Ignore symbolic refs and already initialized classes (unless explicitly requested).
290     if (ktd->has_holder()) {
291       InstanceKlass* holder = ktd->holder();
292       if (!ktd->holder()->is_initialized() || count_initialized) {
293         ++left;
294       } else if (holder->is_shared_unregistered_class()) {
295         Key k(holder);
296         if (!Key::can_compute_cds_hash(&k)) {
297           ++left; // FIXME: !!! init tracking doesn't work well for custom loaders !!!
298         }
299       }
300     }
301   }
302   return left;
303 }
304 
305 void CompileTrainingData::print_on(outputStream* st, bool name_only) const {
306   _method->print_on(st, true);
307   st->print("#%dL%d", _compile_id, _level);
308   if (name_only) {
309     return;
310   }
311   #define MAYBE_TIME(Q, _qtime) \
312     if (_qtime != 0) st->print(" " #Q "%.3f", _qtime)
313   MAYBE_TIME(Q, _qtime);
314   MAYBE_TIME(S, _stime);
315   MAYBE_TIME(E, _etime);
316   if (_init_deps.length() > 0) {
317     if (_init_deps_left > 0) {
318       st->print(" udeps=%d", _init_deps_left);
319     }
320     for (int i = 0, len = _init_deps.length(); i < len; i++) {
321       st->print(" dep:");
322       _init_deps.at(i)->print_on(st, true);
323     }
324   }
325 }
326 
327 void CompileTrainingData::record_compilation_queued(CompileTask* task) {
328   _qtime = tty->time_stamp().seconds();
329 }
330 void CompileTrainingData::record_compilation_start(CompileTask* task) {
331   _stime = tty->time_stamp().seconds();
332 }
333 void CompileTrainingData::record_compilation_end(CompileTask* task) {
334   _etime = tty->time_stamp().seconds();
335   if (task->is_success()) {   // record something about the nmethod output
336     _nm_total_size = task->nm_total_size();
337   }
338 }
339 void CompileTrainingData::notice_inlined_method(CompileTask* task,
340                                                 const methodHandle& method) {
341   MethodTrainingData* mtd = MethodTrainingData::make(method);
342   if (mtd != nullptr) {
343     mtd->notice_compilation(task->comp_level(), true);
344   }
345 }
346 
347 void CompileTrainingData::notice_jit_observation(ciEnv* env, ciBaseObject* what) {
348   // A JIT is starting to look at class k.
349   // We could follow the queries that it is making, but it is
350   // simpler to assume, conservatively, that the JIT will
351   // eventually depend on the initialization state of k.
352   CompileTask* task = env->task();
353   assert(task != nullptr, "");
354   Method* method = task->method();
355   InstanceKlass* compiling_klass = method->method_holder();
356   if (what->is_metadata()) {
357     ciMetadata* md = what->as_metadata();
358     if (md->is_loaded() && md->is_instance_klass()) {
359       ciInstanceKlass* cik = md->as_instance_klass();
360 
361       if (cik->is_initialized()) {
362         InstanceKlass* ik = md->as_instance_klass()->get_instanceKlass();
363         KlassTrainingData* ktd = KlassTrainingData::make(ik);
364         assert(ktd != nullptr, "");
365         // This JIT task is (probably) requesting that ik be initialized,
366         // so add him to my _init_deps list.
367         TrainingDataLocker l;
368         add_init_dep(ktd);
369       }
370     }
371   }
372 }
373 
374 void KlassTrainingData::prepare(Visitor& visitor) {
375   if (visitor.is_visited(this)) {
376     return;
377   }
378   visitor.visit(this);
379   ClassLoaderData* loader_data = nullptr;
380   if (_holder != nullptr) {
381     loader_data = _holder->class_loader_data();
382   } else {
383     loader_data = java_lang_ClassLoader::loader_data(SystemDictionary::java_system_loader()); // default CLD
384   }
385   _comp_deps.prepare(loader_data);
386 }
387 
388 void MethodTrainingData::prepare(Visitor& visitor) {
389   if (visitor.is_visited(this)) {
390     return;
391   }
392   visitor.visit(this);
393   klass()->prepare(visitor);
394   if (has_holder()) {
395     _final_counters = holder()->method_counters();
396     _final_profile  = holder()->method_data();
397     assert(_final_profile == nullptr || _final_profile->method() == holder(), "");
398   }
399   for (int i = 0; i < CompLevel_count; i++) {
400     CompileTrainingData* ctd = _last_toplevel_compiles[i];
401     if (ctd != nullptr) {
402       ctd->prepare(visitor);
403     }
404   }
405 }
406 
407 void CompileTrainingData::prepare(Visitor& visitor) {
408   if (visitor.is_visited(this)) {
409     return;
410   }
411   visitor.visit(this);
412   method()->prepare(visitor);
413   ClassLoaderData* loader_data = _method->klass()->class_loader_data();
414   _init_deps.prepare(loader_data);
415   _ci_records.prepare(loader_data);
416 }
417 
418 KlassTrainingData* KlassTrainingData::make(InstanceKlass* holder, bool null_if_not_found) {
419   Key key(holder);
420   TrainingData* td = have_data() ? lookup_archived_training_data(&key) : nullptr;
421   KlassTrainingData* ktd = nullptr;
422   if (td != nullptr) {
423     ktd = td->as_KlassTrainingData();
424     ktd->refresh_from(holder);
425     guarantee(ktd->has_holder() && ktd->holder() == holder, "");
426     return ktd;
427   }
428   TrainingDataLocker l;
429   td = training_data_set()->find(&key);
430   if (td == nullptr) {
431     if (null_if_not_found) {
432       return nullptr;
433     }
434     ktd = KlassTrainingData::allocate(holder);
435     if (ktd == nullptr) {
436       return nullptr; // allocation failure
437     }
438     td = training_data_set()->install(ktd);
439     assert(ktd == td, "");
440   } else {
441     ktd = td->as_KlassTrainingData();
442   }
443   assert(ktd != nullptr, "");
444   ktd->refresh_from(holder);
445   guarantee(ktd->has_holder() && ktd->holder() == holder, "");
446   return ktd;
447 }
448 
449 void KlassTrainingData::print_on(outputStream* st, bool name_only) const {
450   name()->print_symbol_on(st);
451   if (has_holder()) {
452     switch (holder()->init_state()) {
453       case InstanceKlass::allocated:            st->print("[A]"); break;
454       case InstanceKlass::loaded:               st->print("[D]"); break;
455       case InstanceKlass::being_linked:         st->print("[l]"); break;
456       case InstanceKlass::linked:               st->print("[L]"); break;
457       case InstanceKlass::being_initialized:    st->print("[i]"); break;
458       case InstanceKlass::fully_initialized:    /*st->print("");*/ break;
459       case InstanceKlass::initialization_error: st->print("[E]"); break;
460       default: fatal("unknown state: %d", holder()->init_state());
461     }
462     if (holder()->is_interface()) {
463       st->print("I");
464     }
465   } else {
466     st->print("[SYM]");
467   }
468   if (name_only) {
469     return;
470   }
471   if (_comp_deps.length() > 0) {
472     for (int i = 0, len = _comp_deps.length(); i < len; i++) {
473       st->print(" dep:");
474       _comp_deps.at(i)->print_on(st, true);
475     }
476   }
477 }
478 
479 void KlassTrainingData::refresh_from(const InstanceKlass* klass) {
480   if (!has_holder()) {
481     init_holder(klass);
482   }
483 }
484 
485 void KlassTrainingData::init_holder(const InstanceKlass* klass) {
486   if (holder() == klass) {
487     return;   // no change to make
488   }
489 
490   jobject hmj = _holder_mirror;
491   if (hmj != nullptr) {   // clear out previous handle, if any
492     _holder_mirror = nullptr;
493     assert(JNIHandles::is_global_handle(hmj), "");
494     JNIHandles::destroy_global(hmj);
495   }
496 
497   // Keep the klass alive during the training run, unconditionally.
498   //
499   // FIXME: Revisit this decision; we could allow training runs to
500   // unload classes in the normal way.  We might use make_weak_global
501   // instead of make_global.
502   //
503   // The data from the training run would mention the name of the
504   // unloaded class (and of its loader).  Is it worth the complexity
505   // to track and then unload classes, remembering just their names?
506 
507   if (klass != nullptr) {
508     Handle hm(JavaThread::current(), klass->java_mirror());
509     hmj = JNIHandles::make_global(hm);
510     Atomic::release_store(&_holder_mirror, hmj);
511   }
512 
513   Atomic::release_store(&_holder, const_cast<InstanceKlass*>(klass));
514   assert(holder() == klass, "");
515 }
516 
517 void KlassTrainingData::notice_fully_initialized() {
518   ResourceMark rm;
519   assert(has_holder(), "");
520   assert(holder()->is_initialized(), "wrong state: %s %s",
521          holder()->name()->as_C_string(), holder()->init_state_name());
522 
523   TrainingDataLocker l; // Not a real lock if we don't collect the data,
524                         // that's why we need the atomic decrement below.
525   for (int i = 0; i < comp_dep_count(); i++) {
526     comp_dep(i)->dec_init_deps_left(this);
527   }
528   holder()->set_has_init_deps_processed();
529 }
530 
531 void TrainingData::init_dumptime_table(TRAPS) {
532   if (!need_data()) {
533     return;
534   }
535   _dumptime_training_data_dictionary = new GrowableArrayCHeap<DumpTimeTrainingDataInfo, mtClassShared>();
536   if (CDSConfig::is_dumping_final_static_archive()) {
537     _archived_training_data_dictionary.iterate([&](TrainingData* record) {
538       _dumptime_training_data_dictionary->append(record);
539     });
540   } else {
541     TrainingDataLocker l;
542 
543     ResourceMark rm;
544     Visitor visitor(training_data_set()->size());
545     training_data_set()->iterate_all([&](const TrainingData::Key* k, TrainingData* td) {
546       td->prepare(visitor);
547       if (!td->is_CompileTrainingData()) {
548         _dumptime_training_data_dictionary->append(td);
549       }
550     });
551 
552     if (VerifyTrainingData) {
553       training_data_set()->verify();
554     }
555   }
556 
557   prepare_recompilation_schedule(CHECK);
558 }
559 
560 void TrainingData::prepare_recompilation_schedule(TRAPS) {
561   if (!need_data()) {
562     return;
563   }
564   auto nmethods = MethodProfiler::sampled_nmethods();
565   GrowableArray<MethodTrainingData*> dyn_recompilation_schedule;
566   for (auto it = nmethods->begin(); it != nmethods->end(); ++it) {
567     nmethod* nm = *it;
568     if (RecordOnlyTopCompilations && nm->method_profiling_count() == 0) {
569       break;
570     }
571     if (nm->method() != nullptr) {
572       MethodTrainingData* mtd = nm->method()->training_data_or_null();
573       if (mtd != nullptr) {
574         dyn_recompilation_schedule.append(mtd);
575       }
576     }
577   }
578   delete nmethods;
579   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
580   _recompilation_schedule_for_dumping = MetadataFactory::new_array<MethodTrainingData*>(loader_data, dyn_recompilation_schedule.length(), CHECK);
581   int i = 0;
582   for (auto it = dyn_recompilation_schedule.begin(); it != dyn_recompilation_schedule.end(); ++it) {
583     _recompilation_schedule_for_dumping->at_put(i++, *it);
584   }
585 }
586 
587 #if INCLUDE_CDS
588 void TrainingData::iterate_roots(MetaspaceClosure* it) {
589   if (!need_data()) {
590     return;
591   }
592   assert(_dumptime_training_data_dictionary != nullptr, "");
593   for (int i = 0; i < _dumptime_training_data_dictionary->length(); i++) {
594     _dumptime_training_data_dictionary->at(i).metaspace_pointers_do(it);
595   }
596   it->push(&_recompilation_schedule_for_dumping);
597 }
598 
599 void TrainingData::dump_training_data() {
600   if (!need_data()) {
601     return;
602   }
603   write_training_data_dictionary(&_archived_training_data_dictionary_for_dumping);
604 }
605 
606 void TrainingData::cleanup_training_data() {
607   if (_dumptime_training_data_dictionary != nullptr) {
608     ResourceMark rm;
609     Visitor visitor(_dumptime_training_data_dictionary->length());
610     for (int i = 0; i < _dumptime_training_data_dictionary->length(); i++) {
611       TrainingData* td = _dumptime_training_data_dictionary->at(i).training_data();
612       td->cleanup(visitor);
613     }
614   }
615   _recompilation_status = nullptr;
616 }
617 
618 void KlassTrainingData::cleanup(Visitor& visitor) {
619   if (visitor.is_visited(this)) {
620     return;
621   }
622   visitor.visit(this);
623   if (holder() != nullptr) {
624     bool is_excluded = !holder()->is_loaded() || SystemDictionaryShared::check_for_exclusion(holder(), nullptr);
625     if (is_excluded) {
626       ResourceMark rm;
627       log_debug(cds)("Cleanup KTD %s", name()->as_klass_external_name());
628       _holder = nullptr; // reset
629     }
630   }
631   for (int i = 0; i < _comp_deps.length(); i++) {
632     _comp_deps.at(i)->cleanup(visitor);
633   }
634 }
635 
636 void MethodTrainingData::cleanup(Visitor& visitor) {
637   if (visitor.is_visited(this)) {
638     return;
639   }
640   visitor.visit(this);
641   if (has_holder()) {
642     if (SystemDictionaryShared::check_for_exclusion(holder()->method_holder(), nullptr)) {
643       log_debug(cds)("Cleanup MTD %s::%s", name()->as_klass_external_name(), signature()->as_utf8());
644       if (_final_profile != nullptr && _final_profile->method() != _holder) {
645         // FIXME: MDO still points at the stale method; either completely drop the MDO or zero out the link
646         log_warning(cds)("Stale MDO for  %s::%s", name()->as_klass_external_name(), signature()->as_utf8());
647       }
648       _holder = nullptr;
649     }
650   }
651   for (int i = 0; i < CompLevel_count; i++) {
652     CompileTrainingData* ctd = _last_toplevel_compiles[i];
653     if (ctd != nullptr) {
654       ctd->cleanup(visitor);
655     }
656   }
657 }
658 
659 void KlassTrainingData::verify() {
660   for (int i = 0; i < comp_dep_count(); i++) {
661     CompileTrainingData* ctd = comp_dep(i);
662     if (!ctd->_init_deps.contains(this)) {
663       print_on(tty); tty->cr();
664       ctd->print_on(tty); tty->cr();
665     }
666     guarantee(ctd->_init_deps.contains(this), "");
667   }
668 }
669 
670 void MethodTrainingData::verify() {
671   iterate_all_compiles([](CompileTrainingData* ctd) {
672     ctd->verify();
673 
674     int init_deps_left1 = ctd->init_deps_left();
675     int init_deps_left2 = ctd->compute_init_deps_left();
676 
677     if (init_deps_left1 != init_deps_left2) {
678       ctd->print_on(tty); tty->cr();
679     }
680     guarantee(init_deps_left1 == init_deps_left2, "mismatch: %d %d %d",
681               init_deps_left1, init_deps_left2, ctd->init_deps_left());
682   });
683 }
684 
685 void CompileTrainingData::verify() {
686   for (int i = 0; i < init_dep_count(); i++) {
687     KlassTrainingData* ktd = init_dep(i);
688     if (ktd->has_holder() && ktd->holder()->is_shared_unregistered_class()) {
689       LogStreamHandle(Warning, training) log;
690       if (log.is_enabled()) {
691         ResourceMark rm;
692         log.print("CTD "); print_value_on(&log);
693         log.print(" depends on unregistered class %s", ktd->holder()->name()->as_C_string());
694       }
695     }
696     if (!ktd->_comp_deps.contains(this)) {
697       print_on(tty); tty->cr();
698       ktd->print_on(tty); tty->cr();
699     }
700     guarantee(ktd->_comp_deps.contains(this), "");
701   }
702 }
703 
704 void CompileTrainingData::cleanup(Visitor& visitor) {
705   if (visitor.is_visited(this)) {
706     return;
707   }
708   visitor.visit(this);
709   method()->cleanup(visitor);
710 }
711 
712 void TrainingData::serialize_training_data(SerializeClosure* soc) {
713   if (soc->writing()) {
714     _archived_training_data_dictionary_for_dumping.serialize_header(soc);
715     soc->do_ptr(&_recompilation_schedule_for_dumping);
716   } else {
717     _archived_training_data_dictionary.serialize_header(soc);
718     soc->do_ptr(&_recompilation_schedule);
719   }
720 }
721 
722 void TrainingData::print_archived_training_data_on(outputStream* st) {
723   st->print_cr("Archived TrainingData Dictionary");
724   TrainingDataPrinter tdp(st);
725   TrainingDataLocker::initialize();
726   _archived_training_data_dictionary.iterate(&tdp);
727   if (_recompilation_schedule != nullptr && _recompilation_schedule->length() > 0) {
728     st->print_cr("Archived TrainingData Recompilation Schedule");
729     for (int i = 0; i < _recompilation_schedule->length(); i++) {
730       st->print("%4d: ", i);
731       MethodTrainingData* mtd = _recompilation_schedule->at(i);
732       if (mtd != nullptr) {
733         mtd->print_on(st);
734       } else {
735         st->print("nullptr");
736       }
737       st->cr();
738     }
739   }
740 }
741 
742 void TrainingData::Key::metaspace_pointers_do(MetaspaceClosure *iter) {
743   iter->push(&_name1);
744   iter->push(&_name2);
745   iter->push((TrainingData**)&_holder);
746 }
747 
748 void TrainingData::metaspace_pointers_do(MetaspaceClosure* iter) {
749   _key.metaspace_pointers_do(iter);
750 }
751 
752 bool TrainingData::Key::can_compute_cds_hash(const Key* const& k) {
753   return (k->name1() == nullptr || MetaspaceObj::is_shared(k->name1())) &&
754          (k->name2() == nullptr || MetaspaceObj::is_shared(k->name2())) &&
755          (k->holder() == nullptr || MetaspaceObj::is_shared(k->holder()));
756 }
757 
758 uint TrainingData::Key::cds_hash(const Key* const& k) {
759   uint hash = 0;
760   if (k->holder() != nullptr) {
761     hash += SystemDictionaryShared::hash_for_shared_dictionary((address)k->holder());
762   }
763   if (k->name1() != nullptr) {
764     hash += SystemDictionaryShared::hash_for_shared_dictionary((address)k->name1());
765   }
766   if (k->name2() != nullptr) {
767     hash += SystemDictionaryShared::hash_for_shared_dictionary((address)k->name2());
768   }
769   return hash;
770 }
771 
772 void TrainingData::write_training_data_dictionary(TrainingDataDictionary* dictionary) {
773   if (!need_data()) {
774     return;
775   }
776   assert(_dumptime_training_data_dictionary != nullptr, "");
777   CompactHashtableStats stats;
778   dictionary->reset();
779   CompactHashtableWriter writer(_dumptime_training_data_dictionary->length(), &stats);
780   for (int i = 0; i < _dumptime_training_data_dictionary->length(); i++) {
781     TrainingData* td = _dumptime_training_data_dictionary->at(i).training_data();
782 #ifdef ASSERT
783     for (int j = i+1; j < _dumptime_training_data_dictionary->length(); j++) {
784       TrainingData* td1 = _dumptime_training_data_dictionary->at(j).training_data();
785       assert(!TrainingData::Key::equals(td1, td->key(), -1), "conflict");
786     }
787 #endif // ASSERT
788     td = ArchiveBuilder::current()->get_buffered_addr(td);
789     uint hash = TrainingData::Key::cds_hash(td->key());
790     u4 delta = ArchiveBuilder::current()->buffer_to_offset_u4((address)td);
791     writer.add(hash, delta);
792   }
793   writer.dump(dictionary, "training data dictionary");
794 }
795 
796 size_t TrainingData::estimate_size_for_archive() {
797   if (_dumptime_training_data_dictionary != nullptr) {
798     return CompactHashtableWriter::estimate_size(_dumptime_training_data_dictionary->length());
799   } else {
800     return 0;
801   }
802 }
803 
804 TrainingData* TrainingData::lookup_archived_training_data(const Key* k) {
805   // For this to work, all components of the key must be in shared metaspace.
806   if (!TrainingData::Key::can_compute_cds_hash(k) || _archived_training_data_dictionary.empty()) {
807     return nullptr;
808   }
809   uint hash = TrainingData::Key::cds_hash(k);
810   TrainingData* td = _archived_training_data_dictionary.lookup(k, hash, -1 /*unused*/);
811   if (td != nullptr) {
812     if ((td->is_KlassTrainingData()  && td->as_KlassTrainingData()->has_holder()) ||
813         (td->is_MethodTrainingData() && td->as_MethodTrainingData()->has_holder())) {
814       return td;
815     } else {
816       // FIXME: decide what to do with symbolic TD
817       LogStreamHandle(Trace, training) log;
818       if (log.is_enabled()) {
819         ResourceMark rm;
820         log.print_cr("Ignored symbolic TrainingData:");
821         log.print_cr("  Key: %s %s",
822                      (k->name1() != nullptr ? k->name1()->as_C_string() : "(null)"),
823                      (k->name2() != nullptr ? k->name2()->as_C_string() : "(null)"));
824         td->print_on(&log);
825         log.cr();
826       }
827     }
828   }
829   return nullptr;
830 }
831 #endif
832 
833 KlassTrainingData* TrainingData::lookup_for(InstanceKlass* ik) {
834   if (TrainingData::have_data() && ik != nullptr && ik->is_loaded()) {
835     TrainingData::Key key(ik);
836     TrainingData* td = TrainingData::lookup_archived_training_data(&key);
837     if (td != nullptr && td->is_KlassTrainingData()) {
838       return td->as_KlassTrainingData();
839     }
840   }
841   return nullptr;
842 }
843 
844 MethodTrainingData* TrainingData::lookup_for(Method* m) {
845   if (TrainingData::have_data() && m != nullptr) {
846     KlassTrainingData* holder_ktd = TrainingData::lookup_for(m->method_holder());
847     if (holder_ktd != nullptr) {
848       TrainingData::Key key(m->name(), m->signature(), holder_ktd);
849       TrainingData* td = TrainingData::lookup_archived_training_data(&key);
850       if (td != nullptr && td->is_MethodTrainingData()) {
851         return td->as_MethodTrainingData();
852       }
853     }
854   }
855   return nullptr;
856 }
857 
858 template <typename T>
859 void TrainingData::DepList<T>::metaspace_pointers_do(MetaspaceClosure* iter) {
860   iter->push(&_deps);
861 }
862 
863 void KlassTrainingData::metaspace_pointers_do(MetaspaceClosure* iter) {
864   log_trace(cds)("Iter(KlassTrainingData): %p", this);
865   TrainingData::metaspace_pointers_do(iter);
866   _comp_deps.metaspace_pointers_do(iter);
867   iter->push(&_holder);
868 }
869 
870 void MethodTrainingData::metaspace_pointers_do(MetaspaceClosure* iter) {
871   log_trace(cds)("Iter(MethodTrainingData): %p", this);
872   TrainingData::metaspace_pointers_do(iter);
873   iter->push(&_klass);
874   iter->push((Method**)&_holder);
875   for (int i = 0; i < CompLevel_count; i++) {
876     iter->push(&_last_toplevel_compiles[i]);
877   }
878   iter->push(&_final_profile);
879   iter->push(&_final_counters);
880 }
881 
882 void CompileTrainingData::metaspace_pointers_do(MetaspaceClosure* iter) {
883   log_trace(cds)("Iter(CompileTrainingData): %p", this);
884   TrainingData::metaspace_pointers_do(iter);
885   _init_deps.metaspace_pointers_do(iter);
886   _ci_records.metaspace_pointers_do(iter);
887   iter->push(&_method);
888 }
889 
890 template <typename T>
891 void TrainingData::DepList<T>::prepare(ClassLoaderData* loader_data) {
892   if (_deps == nullptr && _deps_dyn != nullptr) {
893     int len = _deps_dyn->length();
894     _deps = MetadataFactory::new_array_from_c_heap<T>(len, mtClassShared);
895     for (int i = 0; i < len; i++) {
896       _deps->at_put(i, _deps_dyn->at(i)); // copy
897     }
898   }
899 }
900 
901 KlassTrainingData* KlassTrainingData::allocate(InstanceKlass* holder) {
902   assert(need_data() || have_data(), "");
903   return new (mtClassShared) KlassTrainingData(holder);
904 }
905 
906 MethodTrainingData* MethodTrainingData::allocate(KlassTrainingData* ktd, Method* m) {
907   assert(need_data() || have_data(), "");
908   return new (mtClassShared) MethodTrainingData(ktd, m->name(), m->signature());
909 }
910 
911 CompileTrainingData* CompileTrainingData::allocate(MethodTrainingData* mtd, int level, int compile_id) {
912   assert(need_data() || have_data(), "");
913   return new (mtClassShared) CompileTrainingData(mtd, level, compile_id);
914 }
915 
916 void TrainingDataPrinter::do_value(TrainingData* td) {
917 #ifdef ASSERT
918   TrainingData::Key key(td->key()->name1(), td->key()->name2(), td->key()->holder());
919   assert(td == TrainingData::archived_training_data_dictionary()->lookup(td->key(), TrainingData::Key::cds_hash(td->key()), -1), "");
920   assert(td == TrainingData::archived_training_data_dictionary()->lookup(&key, TrainingData::Key::cds_hash(&key), -1), "");
921 #endif // ASSERT
922 
923   const char* type = (td->is_KlassTrainingData()   ? "K" :
924                       td->is_MethodTrainingData()  ? "M" :
925                       td->is_CompileTrainingData() ? "C" : "?");
926   _st->print("%4d: %p %s ", _index++, td, type);
927   td->print_on(_st);
928   _st->cr();
929   if (td->is_KlassTrainingData()) {
930     td->as_KlassTrainingData()->iterate_all_comp_deps([&](CompileTrainingData* ctd) {
931       ResourceMark rm;
932       _st->print_raw("  C ");
933       ctd->print_on(_st);
934       _st->cr();
935     });
936   } else if (td->is_MethodTrainingData()) {
937     td->as_MethodTrainingData()->iterate_all_compiles([&](CompileTrainingData* ctd) {
938       ResourceMark rm;
939       _st->print_raw("  C ");
940       ctd->print_on(_st);
941       _st->cr();
942     });
943   } else if (td->is_CompileTrainingData()) {
944     // ?
945   }
946 }
947 
948 
949 #if INCLUDE_CDS
950 void KlassTrainingData::remove_unshareable_info() {
951   TrainingData::remove_unshareable_info();
952   _holder_mirror = nullptr;
953   _comp_deps.remove_unshareable_info();
954 }
955 
956 void MethodTrainingData::remove_unshareable_info() {
957   TrainingData::remove_unshareable_info();
958   if (_final_counters != nullptr) {
959     _final_counters->remove_unshareable_info();
960   }
961   if (_final_profile != nullptr) {
962     _final_profile->remove_unshareable_info();
963   }
964 }
965 
966 void CompileTrainingData::remove_unshareable_info() {
967   TrainingData::remove_unshareable_info();
968   _init_deps.remove_unshareable_info();
969   _ci_records.remove_unshareable_info();
970   _init_deps_left = compute_init_deps_left(true);
971 }
972 
973 #endif // INCLUDE_CDS