1 /*
  2  * Copyright (c) 2023, 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 #ifndef SHARE_OOPS_TRAININGDATA_HPP
 26 #define SHARE_OOPS_TRAININGDATA_HPP
 27 
 28 #include "cds/archiveUtils.hpp"
 29 #include "classfile/compactHashtable.hpp"
 30 #include "compiler/compilerDefinitions.hpp"
 31 #include "compiler/compiler_globals.hpp"
 32 #include "memory/allocation.hpp"
 33 #include "memory/metaspaceClosure.hpp"
 34 #include "oops/instanceKlass.hpp"
 35 #include "oops/symbolHandle.hpp"
 36 #include "runtime/fieldDescriptor.inline.hpp"
 37 #include "runtime/handles.hpp"
 38 #include "runtime/mutexLocker.hpp"
 39 #include "utilities/count_leading_zeros.hpp"
 40 #include "utilities/resizeableResourceHash.hpp"
 41 
 42 class ciEnv;
 43 class ciBaseObject;
 44 class CompileTask;
 45 class xmlStream;
 46 class CompileTrainingData;
 47 class KlassTrainingData;
 48 class MethodTrainingData;
 49 class TrainingDataDumper;
 50 class TrainingDataSetLocker;
 51 class DumpTimeTrainingDataInfo;
 52 class TrainingDataDictionary;
 53 class RunTimeClassInfo;
 54 class RunTimeMethodDataInfo;
 55 
 56 
 57 class TrainingData : public Metadata {
 58   friend KlassTrainingData;
 59   friend MethodTrainingData;
 60   friend CompileTrainingData;
 61  public:
 62   class Key {
 63     Symbol* _name1;   // Klass::name or Method::name
 64     Symbol* _name2;   // class_loader_name_and_id or signature
 65     const TrainingData* const _holder; // TD for containing klass or method
 66 
 67     // These guys can get to my constructors:
 68     friend TrainingData;
 69     friend KlassTrainingData;
 70     friend MethodTrainingData;
 71     friend CompileTrainingData;
 72 
 73     // The empty key
 74     Key() : Key(nullptr, nullptr) { }
 75     bool is_empty() const {
 76       return _name1 == nullptr && _name2 == nullptr && _holder == nullptr;
 77     }
 78 
 79   public:
 80     Key(Symbol* name1, Symbol* name2,
 81         const TrainingData* holder = nullptr)
 82       : _name1(name1), _name2(name2), _holder(holder)
 83       // Since we are using SymbolHandles here, the reference counts
 84       // are incremented here, in this constructor.  We assume that
 85       // the symbols are already kept alive by some other means, but
 86       // after this point the Key object keeps them alive as well.
 87     { }
 88     Key(const KlassTrainingData* klass, Symbol* method_name, Symbol* signature);
 89     Key(const InstanceKlass* klass);
 90     Key(const Method* method);
 91 
 92     static unsigned cds_hash(const Key* const& k);
 93     static bool can_compute_cds_hash(const Key* const& k);
 94     static unsigned hash(const Key* const& k) {
 95       // A symmetric hash code is usually a bad idea, except in cases
 96       // like this where it is very unlikely that any one string might
 97       // appear in two positions, and even less likely that two
 98       // strings might trade places in two otherwise equal keys.
 99       return (Symbol::identity_hash(k->name1()) +
100               Symbol::identity_hash(k->name2()) +
101               (k->holder() == nullptr ? 0 : hash(k->holder()->key())));
102     }
103     static bool equals(const Key* const& k1, const Key* const& k2) {
104       // We assume that all Symbols come for SymbolTable and therefore are unique.
105       // Hence pointer comparison is enough to prove equality.
106       return (k1->name1()   == k2->name1() &&
107               k1->name2()   == k2->name2() &&
108               k1->holder()  == k2->holder());
109     }
110     static inline bool equals(TrainingData* value, const TrainingData::Key* key, int unused) {
111       return equals(value->key(), key);
112     }
113     int cmp(const Key* that) const {
114       auto h1 = this->holder();
115       auto h2 = that->holder();
116       #define NULL_CHECKS(x1, x2, cmpx1x2)                      \
117         ((x1) == nullptr ? -1 : (x2) == nullptr ? +1 : cmpx1x2)
118       if (h1 != h2) {
119         return NULL_CHECKS(h1, h2, h1->key()->cmp(h2->key()));
120       }
121       Symbol* k1; Symbol* k2;
122       #define CHECK_COMPONENT(name)                             \
123         if ((k1 = this->name()) != (k2 = that->name()))         \
124           return NULL_CHECKS(k1, k2, k1->cmp(k2))
125       CHECK_COMPONENT(name1);
126       CHECK_COMPONENT(name2);
127       #undef CHECK_COMPONENT
128       #undef NULL_CHECKS
129       return 0; // no pair of differing components
130     }
131     Symbol* name1() const       { return _name1; }
132     Symbol* name2() const       { return _name2; }
133     const TrainingData* holder() const { return _holder; }
134 
135     void metaspace_pointers_do(MetaspaceClosure *iter);
136   };
137   class TrainingDataLocker {
138     static int _lock_mode;
139     static void lock() {
140       assert(_lock_mode != 0, "Forgot to call TrainingDataLocker::initialize()");
141       if (_lock_mode > 0) {
142         TrainingData_lock->lock();
143       }
144     }
145     static void unlock() {
146       if (_lock_mode > 0) {
147         TrainingData_lock->unlock();
148       }
149     }
150     static bool safely_locked() {
151       assert(_lock_mode != 0, "Forgot to call TrainingDataLocker::initialize()");
152       if (_lock_mode > 0) {
153         return TrainingData_lock->owned_by_self();
154       } else {
155         return true;
156       }
157     }
158   public:
159     static void initialize() {
160       _lock_mode = need_data() ? +1 : -1;   // if -1, we go lock-free
161     }
162     static void assert_locked() {
163       assert(TrainingDataLocker::safely_locked(), "use under TrainingDataLocker");
164     }
165     TrainingDataLocker() {
166       lock();
167     }
168     ~TrainingDataLocker() {
169       unlock();
170     }
171   };
172   class TrainingDataSet {
173     friend TrainingData;
174     ResizeableResourceHashtable<const Key*, TrainingData*,
175                                 AnyObj::C_HEAP, MEMFLAGS::mtCompiler,
176                                 &TrainingData::Key::hash,
177                                 &TrainingData::Key::equals>
178       _table;
179 
180   public:
181     template<typename... Arg>
182     TrainingDataSet(Arg... arg)
183       : _table(arg...) {
184     }
185     TrainingData* find(const Key* key) const {
186       TrainingDataLocker::assert_locked();
187       auto res = _table.get(key);
188       return res == nullptr ? nullptr : *res;
189     }
190     bool remove(const Key* key) {
191       return _table.remove(key);
192     }
193     TrainingData* install(TrainingData* tdata) {
194       TrainingDataLocker::assert_locked();
195       auto key = tdata->key();
196       if (key->is_empty())   return tdata;  // unkeyed TD not installed
197       bool created = false;
198       auto prior = _table.put_if_absent(key, tdata, &created);
199       if (prior == nullptr || *prior == tdata) {
200         return tdata;
201       }
202       assert(false, "no pre-existing elements allowed");
203       return *prior;
204     }
205     template<typename FN>
206     void iterate_all(FN fn) const { // lambda enabled API
207       return _table.iterate_all(fn);
208     }
209     int size() const { return _table.number_of_entries(); }
210   };
211 
212   class Visitor {
213     ResizeableResourceHashtable<TrainingData*, bool> _visited;
214   public:
215     Visitor(unsigned size) : _visited(size, 0x3fffffff) { }
216     bool is_visited(TrainingData* td) {
217       return _visited.contains(td);
218     }
219     void visit(TrainingData* td) {
220       bool created;
221       _visited.put_if_absent(td, &created);
222     }
223   };
224 
225 private:
226   Key _key;
227 
228   // just forward all constructor arguments to the embedded key
229   template<typename... Arg>
230   TrainingData(Arg... arg)
231     : _key(arg...) { }
232 
233   static TrainingDataSet _training_data_set;
234   static TrainingDataDictionary _archived_training_data_dictionary;
235   static TrainingDataDictionary _archived_training_data_dictionary_for_dumping;
236   static GrowableArrayCHeap<DumpTimeTrainingDataInfo, mtClassShared>* _dumptime_training_data_dictionary;
237   static Array<MethodTrainingData*>* _recompilation_schedule;
238   static Array<MethodTrainingData*>* _recompilation_schedule_for_dumping;
239   static volatile bool* _recompilation_status;
240   static void prepare_recompilation_schedule(TRAPS);
241 
242 public:
243   // Returns the key under which this TD is installed, or else
244   // Key::EMPTY if it is not installed.
245   const Key* key() const { return &_key; }
246 
247   static bool have_data() { return ReplayTraining;  } // Going to read
248   static bool need_data() { return RecordTraining;  } // Going to write
249 
250   static TrainingDataSet* training_data_set() { return &_training_data_set; }
251   static TrainingDataDictionary* archived_training_data_dictionary() { return &_archived_training_data_dictionary; }
252   static bool have_recompilation_schedule() { return _recompilation_schedule != nullptr; }
253   static Array<MethodTrainingData*>* recompilation_schedule() { return _recompilation_schedule; }
254   static volatile bool* recompilation_status() { return _recompilation_status; }
255 
256   virtual MethodTrainingData*   as_MethodTrainingData()  const { return nullptr; }
257   virtual KlassTrainingData*    as_KlassTrainingData()   const { return nullptr; }
258   virtual CompileTrainingData*  as_CompileTrainingData() const { return nullptr; }
259   bool is_MethodTrainingData()  const { return as_MethodTrainingData() != nullptr; }
260   bool is_KlassTrainingData()   const { return as_KlassTrainingData()  != nullptr; }
261   bool is_CompileTrainingData() const { return as_CompileTrainingData()  != nullptr; }
262 
263   virtual void prepare(Visitor& visitor) = 0;
264   virtual void cleanup(Visitor& visitor) = 0;
265 
266   static void initialize();
267 
268   // Widget for recording dependencies, as an N-to-M graph relation,
269   // possibly cyclic.
270   template<typename E>
271   class DepList : public StackObj {
272     GrowableArrayCHeap<E, mtCompiler>* _deps_dyn;
273     Array<E>*                          _deps;
274     // (hmm, could we have state-selected union of these two?)
275   public:
276     DepList() {
277       _deps_dyn = nullptr;
278       _deps = nullptr;
279     }
280 
281     int length() const {
282       return (_deps_dyn != nullptr ? _deps_dyn->length()
283               : _deps   != nullptr ? _deps->length()
284               : 0);
285     }
286     E* adr_at(int i) const {
287       return (_deps_dyn != nullptr ? _deps_dyn->adr_at(i)
288               : _deps   != nullptr ? _deps->adr_at(i)
289               : nullptr);
290     }
291     E at(int i) const {
292       assert(i >= 0 && i < length(), "oob");
293       return *adr_at(i);
294     }
295     bool append_if_missing(E dep) {
296       //assert(_deps == nullptr, "must be growable");
297       if (_deps_dyn == nullptr) {
298         _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(10);
299         _deps_dyn->append(dep);
300         return true;
301       } else {
302         return _deps_dyn->append_if_missing(dep);
303       }
304     }
305     void append(E dep) {
306       //assert(_deps == nullptr, "must be growable");
307       if (_deps_dyn == nullptr) {
308         _deps_dyn = new GrowableArrayCHeap<E, mtCompiler>(10);
309       }
310       _deps_dyn->append(dep);
311     }
312     bool contains(E dep) {
313       for (int i = 0; i < length(); i++) {
314         if (dep == at(i)) {
315           return true; // found
316         }
317       }
318       return false; // not found
319     }
320 
321 #if INCLUDE_CDS
322     void remove_unshareable_info() {
323       _deps_dyn = nullptr;
324     }
325     void restore_unshareable_info(TRAPS) {}
326 #endif
327     void prepare(ClassLoaderData* loader_data);
328     void metaspace_pointers_do(MetaspaceClosure *iter);
329   };
330 
331   virtual void metaspace_pointers_do(MetaspaceClosure *iter);
332 
333 #if INCLUDE_CDS
334   virtual void remove_unshareable_info() {}
335   virtual void restore_unshareable_info(TRAPS) {}
336   static void restore_all_unshareable_info(TRAPS);
337 #endif
338   static void init_dumptime_table(TRAPS);
339   static void iterate_roots(MetaspaceClosure* it);
340   static void dump_training_data();
341   static void cleanup_training_data();
342   static void serialize_training_data(SerializeClosure* soc);
343   static void adjust_training_data_dictionary();
344   static void print_archived_training_data_on(outputStream* st);
345   static void write_training_data_dictionary(TrainingDataDictionary* dictionary);
346   static size_t estimate_size_for_archive();
347 
348   static TrainingData* lookup_archived_training_data(const Key* k);
349 
350   static KlassTrainingData*  lookup_for(InstanceKlass* ik);
351   static MethodTrainingData* lookup_for(Method* m);
352 };
353 
354 
355 
356 class KlassTrainingData : public TrainingData {
357   friend TrainingData;
358   friend CompileTrainingData;
359 
360   // Used by CDS. These classes need to access the private default constructor.
361   template <class T> friend class CppVtableTesterA;
362   template <class T> friend class CppVtableTesterB;
363   template <class T> friend class CppVtableCloner;
364 
365  public:
366   // Tracking field initialization, when RecordTraining is enabled.
367   struct FieldData {
368     Symbol*   _name;    // name of field, for making reports (no refcount)
369     int      _index;    // index in the field stream (a unique id)
370     BasicType _type;    // what kind of field is it?
371     int     _offset;    // offset of field storage, within mirror
372     int _fieldinit_sequence_index;  // 1-based local initialization order
373     void init_from(fieldDescriptor& fd) {
374       _name = fd.name();
375       _index = fd.index();
376       _offset = fd.offset();
377       _type = fd.field_type();
378       _fieldinit_sequence_index = 0;
379     }
380   };
381 
382  private:
383   // cross-link to live klass, or null if not loaded or encountered yet
384   InstanceKlass* _holder;
385   jobject _holder_mirror;   // extra link to prevent unloading by GC
386 
387   // initialization tracking state
388   bool _has_initialization_touch;
389   int _clinit_sequence_index;       // 1-based global initialization order
390   GrowableArrayCHeap<FieldData, mtCompiler>* _static_fields;  //do not CDS
391   int _fieldinit_count;  // count <= _static_fields.length()
392   bool _clinit_is_done;
393   DepList<KlassTrainingData*> _init_deps;  // classes to initialize before me
394   DepList<CompileTrainingData*> _comp_deps; // compiles that depend on me
395   static GrowableArrayCHeap<FieldData, mtCompiler>* _no_static_fields;
396   static int _clinit_count;  // global count (so far) of clinit events
397 
398   void init() {
399     _holder_mirror = nullptr;
400     _holder = nullptr;
401     _has_initialization_touch = false;
402     _clinit_sequence_index = 0;
403     _static_fields = nullptr;
404     _fieldinit_count = 0;
405     _clinit_is_done = false;
406   }
407 
408   KlassTrainingData();
409   KlassTrainingData(Symbol* klass_name, Symbol* loader_name)
410     : TrainingData(klass_name, loader_name)
411   {
412     init();
413   }
414   KlassTrainingData(InstanceKlass* klass)
415     : TrainingData(klass)
416   {
417     init();
418   }
419 
420   int init_dep_count() const {
421     TrainingDataLocker::assert_locked();
422     return _init_deps.length();
423   }
424   KlassTrainingData* init_dep(int i) const {
425     TrainingDataLocker::assert_locked();
426     return _init_deps.at(i);
427   }
428   void add_init_dep(KlassTrainingData* ktd) {
429     TrainingDataLocker::assert_locked();
430     guarantee(ktd != this, "");
431     _init_deps.append_if_missing(ktd);
432   }
433 
434   int comp_dep_count() const {
435     TrainingDataLocker::assert_locked();
436     return _comp_deps.length();
437   }
438   CompileTrainingData* comp_dep(int i) const {
439     TrainingDataLocker::assert_locked();
440     return _comp_deps.at(i);
441   }
442   void add_comp_dep(CompileTrainingData* ctd) {
443     TrainingDataLocker::assert_locked();
444      _comp_deps.append_if_missing(ctd);
445   }
446 
447   static GrowableArrayCHeap<FieldData, mtCompiler>* no_static_fields();
448   static int next_clinit_count() {
449     return Atomic::add(&_clinit_count, 1);
450   }
451   int next_fieldinit_count() {
452     return Atomic::add(&_fieldinit_count, 1);
453   }
454   void log_initialization(bool is_start);
455 
456   bool record_static_field_init(FieldData* fdata, const char* reason);
457 
458  public:
459   Symbol* name()                const { return _key.name1(); }
460   Symbol* loader_name()         const { return _key.name2(); }
461   bool    has_holder()          const { return _holder != nullptr; }
462   InstanceKlass* holder()       const { return _holder; }
463 
464   // This sets up the mirror as well, and may scan for field metadata.
465   void init_holder(const InstanceKlass* klass);
466 
467   // Update any copied data.
468   void refresh_from(const InstanceKlass* klass);
469 
470   // factories from live class and from symbols:
471   static KlassTrainingData* make(Symbol* name, Symbol* loader_name);
472   static KlassTrainingData* make(const char* name, const char* loader_name);
473   static KlassTrainingData* make(InstanceKlass* holder,
474                                  bool null_if_not_found = false);
475   static KlassTrainingData* find(InstanceKlass* holder) {
476     return make(holder, true);
477   }
478 
479   virtual KlassTrainingData* as_KlassTrainingData() const { return const_cast<KlassTrainingData*>(this); };
480 
481   ClassLoaderData* class_loader_data() {
482     assert(has_holder(), "");
483     return holder()->class_loader_data();
484   }
485   void setup_static_fields(const InstanceKlass* holder);
486   bool field_state_is_clean(FieldData* fdata);
487   FieldData* check_field_states_and_find_field(Symbol* name);
488   bool all_field_states_done() {
489     return _static_fields != nullptr && _static_fields->length() == _fieldinit_count;
490   }
491   static void print_klass_attrs(xmlStream* xtty,
492                                 Klass* klass, const char* prefix = "");
493   static void print_iclock_attr(InstanceKlass* klass,
494                                 xmlStream* xtty,
495                                 int fieldinit_index = -1,
496                                 const char* prefix = "");
497 
498   // A 1-based global order in which <clinit> was called, or zero if
499   // that never did happen, or has not yet happened.
500   int clinit_sequence_index_or_zero() const {
501     return _clinit_sequence_index;
502   }
503 
504   // Has this class been the subject of an initialization touch?
505   bool has_initialization_touch() { return _has_initialization_touch; }
506   // Add such a touch to the history of this class.
507   bool add_initialization_touch(Klass* requester);
508 
509   // For some reason, somebody is touching my class (this->holder())
510   // and that might be relevant to my class's initialization state.
511   // We collect these events even after my class is fully initialized.
512   //
513   // The requesting class, if not null, is the class which is causing
514   // the event, somehow (depending on the reason).
515   //
516   // The name and signature, if not null, are somehow relevant to
517   // the event; depending on the reason, they might refer to a
518   // member of my class, or else to a member of the requesting class.
519   //
520   // The context is a little extra information.
521   //
522   // The record that will be emitted records all this information,
523   // plus extra stuff, notably whether there is a <clinit> execution
524   // on stack, and if so, who that is.  Often, the class running its
525   // <clinit> is even more interesting than the requesting class.
526   void record_initialization_touch(const char* reason,
527                                    Symbol* name,
528                                    Symbol* sig,
529                                    Klass* requesting_klass,
530                                    const char* context,
531                                    TRAPS);
532 
533   void record_initialization_start();
534   void record_initialization_end();
535   void notice_fully_initialized();
536   // Record that we have witnessed the initialization of the name.
537   // This is called when we know we are doing a `putstatic` or equivalent.
538   // It can be called either just before or just after.  It is only
539   // safe to call this inside the initializing thread.
540   bool record_static_field_init(fieldDescriptor* fd, const char* reason);
541 
542   void print_on(outputStream* st, bool name_only) const;
543   virtual void print_on(outputStream* st) const { print_on(st, false); }
544   virtual void print_value_on(outputStream* st) const { print_on(st, true); }
545 
546   virtual void prepare(Visitor& visitor);
547   virtual void cleanup(Visitor& visitor);
548 
549   MetaspaceObj::Type type() const {
550     return KlassTrainingDataType;
551   }
552 
553 #if INCLUDE_CDS
554   virtual void remove_unshareable_info();
555   virtual void restore_unshareable_info(TRAPS);
556 #endif
557 
558   void metaspace_pointers_do(MetaspaceClosure *iter);
559 
560   int size() const {
561     return (int)align_metadata_size(align_up(sizeof(KlassTrainingData), BytesPerWord)/BytesPerWord);
562   }
563 
564   const char* internal_name() const {
565     return "{ klass training data }";
566   };
567 
568   static KlassTrainingData* allocate(InstanceKlass* holder);
569   static KlassTrainingData* allocate(Symbol* name, Symbol* loader_name);
570 
571   template<typename FN>
572   void iterate_all_comp_deps(FN fn) const { // lambda enabled API
573     TrainingDataLocker l;
574     for (int i = 0; i < comp_dep_count(); i++) {
575       fn(comp_dep(i));
576     }
577   }
578 };
579 
580 // Information about particular JIT tasks.
581 class CompileTrainingData : public TrainingData {
582   // Used by CDS. These classes need to access the private default constructor.
583   template <class T> friend class CppVtableTesterA;
584   template <class T> friend class CppVtableTesterB;
585   template <class T> friend class CppVtableCloner;
586 
587   MethodTrainingData* _method;
588   CompileTrainingData* _next;   // singly linked list, latest first
589   const short _level;
590   const int _compile_id;
591   int _nm_total_size;
592   float _qtime, _stime, _etime;   // time queued, started, ended
593 
594   // classes that should be initialized before this JIT task runs
595   DepList<KlassTrainingData*> _init_deps;
596   volatile int _init_deps_left;
597 
598 public:
599   class ciRecords {
600     template <typename... Ts> class Arguments {
601     public:
602       bool operator==(const Arguments<>&) const { return true; }
603       void metaspace_pointers_do(MetaspaceClosure *iter) { }
604     };
605     template <typename T, typename... Ts> class Arguments<T, Ts...> {
606     private:
607       T _first;
608       Arguments<Ts...> _remaining;
609 
610     public:
611       constexpr Arguments(const T& first, const Ts&... remaining) noexcept
612         : _first(first), _remaining(remaining...) {}
613       constexpr Arguments() noexcept : _first(), _remaining() {}
614       bool operator==(const Arguments<T, Ts...>& that) const {
615         return _first == that._first && _remaining == that._remaining;
616       }
617       template<typename U = T, std::enable_if_t<std::is_pointer<U>::value && std::is_base_of<MetaspaceObj, typename std::remove_pointer<U>::type>::value, int> = 0>
618       void metaspace_pointers_do(MetaspaceClosure *iter) {
619         iter->push(&_first);
620         _remaining.metaspace_pointers_do(iter);
621       }
622       template<typename U = T, std::enable_if_t<!(std::is_pointer<U>::value && std::is_base_of<MetaspaceObj, typename std::remove_pointer<U>::type>::value), int> = 0>
623       void metaspace_pointers_do(MetaspaceClosure *iter) {
624         _remaining.metaspace_pointers_do(iter);
625       }
626     };
627 
628     template <typename ReturnType, typename... Args> class ciMemoizedFunction : public StackObj {
629     public:
630       class OptionalReturnType {
631         bool _valid;
632         ReturnType _result;
633       public:
634         OptionalReturnType(bool valid, const ReturnType& result) : _valid(valid), _result(result) {}
635         bool is_valid() const { return _valid; }
636         ReturnType result() const { return _result; }
637       };
638     private:
639       typedef Arguments<Args...> ArgumentsType;
640       class Record : public MetaspaceObj {
641         ReturnType    _result;
642         ArgumentsType _arguments;
643       public:
644         Record(const ReturnType& result, const ArgumentsType& arguments) : _result(result), _arguments(arguments) {}
645         Record() { }
646         ReturnType result() const { return _result; }
647         ArgumentsType arguments() const { return _arguments; }
648         bool operator==(const Record& that) { return _arguments == that._arguments; }
649         void metaspace_pointers_do(MetaspaceClosure *iter) { _arguments.metaspace_pointers_do(iter); }
650       };
651       DepList<Record> _data;
652     public:
653       OptionalReturnType find(const Args&... args) {
654         ArgumentsType a(args...);
655         for (int i = 0; i < _data.length(); i++) {
656           if (_data.at(i).arguments() == a) {
657             return OptionalReturnType(true, _data.at(i).result());
658           }
659         }
660         return OptionalReturnType(false, ReturnType());
661       }
662       bool append_if_missing(const ReturnType& result, const Args&... args) {
663         return _data.append_if_missing(Record(result, ArgumentsType(args...)));
664       }
665 #if INCLUDE_CDS
666       void remove_unshareable_info() { _data.remove_unshareable_info(); }
667       void restore_unshareable_info(TRAPS) { _data.restore_unshareable_info(THREAD); }
668 #endif
669       void prepare(ClassLoaderData* loader_data) {
670         _data.prepare(loader_data);
671       }
672       void metaspace_pointers_do(MetaspaceClosure *iter) {
673         _data.metaspace_pointers_do(iter);
674       }
675     };
676 
677 
678 public:
679     typedef ciMemoizedFunction<int, MethodTrainingData*> ciMethod__inline_instructions_size_type;
680     ciMethod__inline_instructions_size_type ciMethod__inline_instructions_size;
681 #if INCLUDE_CDS
682     void remove_unshareable_info() {
683       ciMethod__inline_instructions_size.remove_unshareable_info();
684     }
685     void restore_unshareable_info(TRAPS) {
686       ciMethod__inline_instructions_size.restore_unshareable_info(THREAD);
687     }
688 #endif
689     void prepare(ClassLoaderData* loader_data) {
690       ciMethod__inline_instructions_size.prepare(loader_data);
691     }
692     void metaspace_pointers_do(MetaspaceClosure *iter) {
693       ciMethod__inline_instructions_size.metaspace_pointers_do(iter);
694     }
695   };
696 
697 private:
698   ciRecords _ci_records;
699 
700   CompileTrainingData();
701   // (should we also capture counters or MDO state or replay data?)
702   CompileTrainingData(MethodTrainingData* method,
703                       int level,
704                       int compile_id)
705       : TrainingData(),  // empty key
706         _method(method), _level(level), _compile_id(compile_id)
707   {
708     _next = nullptr;
709     _qtime = _stime = _etime = 0;
710     _nm_total_size = 0;
711     _init_deps_left = 0;
712   }
713 
714 public:
715   ciRecords& ci_records() { return _ci_records; }
716   // Record a use of a method in a given task.  If non-null, the given
717   // method is not the top-level method of the task, but instead it is
718   // inlined into the top-level method.
719   static CompileTrainingData* make(CompileTask* task);
720   static CompileTrainingData* make(MethodTrainingData* m, int level, int compile_id);
721 
722   virtual CompileTrainingData* as_CompileTrainingData() const { return const_cast<CompileTrainingData*>(this); };
723 
724   MethodTrainingData* method()      const { return _method; }
725 
726   CompileTrainingData* next() const { return _next; }
727 
728   int level() const { return _level; }
729   //void set_level(int level) { _level = level; }
730 
731   int compile_id() const { return _compile_id; }
732 
733   int init_dep_count() const {
734     TrainingDataLocker::assert_locked();
735     return _init_deps.length();
736   }
737   KlassTrainingData* init_dep(int i) const {
738     TrainingDataLocker::assert_locked();
739     return _init_deps.at(i);
740   }
741   void add_init_dep(KlassTrainingData* ktd) {
742     TrainingDataLocker::assert_locked();
743     ktd->add_comp_dep(this);
744     _init_deps.append_if_missing(ktd);
745   }
746   void dec_init_deps_left(KlassTrainingData* ktd);
747   int init_deps_left() const {
748     return _init_deps_left;
749   }
750   void initialize_deps_tracking() {
751     for (int i = 0; i < _init_deps.length(); i++) {
752       KlassTrainingData* dep = _init_deps.at(i);
753       if (dep->has_holder() && !dep->holder()->is_initialized()) {
754         _init_deps_left++; // ignore symbolic refs && already initialized classes
755       }
756     }
757   }
758   void record_compilation_queued(CompileTask* task);
759   void record_compilation_start(CompileTask* task);
760   void record_compilation_end(CompileTask* task);
761   void notice_inlined_method(CompileTask* task, const methodHandle& method);
762 
763   // The JIT looks at classes and objects too and can depend on their state.
764   // These simple calls just report the *possibility* of an observation.
765   void notice_jit_observation(ciEnv* env, ciBaseObject* what);
766 
767   virtual void prepare(Visitor& visitor);
768   virtual void cleanup(Visitor& visitor);
769 
770   void print_on(outputStream* st, bool name_only) const;
771   virtual void print_on(outputStream* st) const { print_on(st, false); }
772   virtual void print_value_on(outputStream* st) const { print_on(st, true); }
773 
774 #if INCLUDE_CDS
775   virtual void remove_unshareable_info();
776   virtual void restore_unshareable_info(TRAPS);
777 #endif
778 
779   virtual void metaspace_pointers_do(MetaspaceClosure* iter);
780   virtual MetaspaceObj::Type type() const { return CompileTrainingDataType; }
781 
782   virtual const char* internal_name() const {
783     return "{ compile training data }";
784   };
785 
786   virtual int size() const {
787     return (int)align_metadata_size(align_up(sizeof(CompileTrainingData), BytesPerWord)/BytesPerWord);
788   }
789 
790 
791   static CompileTrainingData* allocate(MethodTrainingData* mtd, int level, int compile_id);
792 };
793 
794 // Record information about a method at the time compilation is requested.
795 class MethodTrainingData : public TrainingData {
796   friend TrainingData;
797   friend CompileTrainingData;
798 
799   // Used by CDS. These classes need to access the private default constructor.
800   template <class T> friend class CppVtableTesterA;
801   template <class T> friend class CppVtableTesterB;
802   template <class T> friend class CppVtableCloner;
803 
804   KlassTrainingData* _klass;
805   const Method* _holder;  // can be null
806   CompileTrainingData* _compile;   // singly linked list, latest first
807   CompileTrainingData* _last_toplevel_compiles[CompLevel_count];
808   int _highest_top_level;
809   int _level_mask;  // bit-set of all possible levels
810   bool _was_inlined;
811   bool _was_toplevel;
812   // metadata snapshots of final state:
813   MethodCounters* _final_counters;
814   MethodData*     _final_profile;
815 
816   MethodTrainingData();
817   MethodTrainingData(KlassTrainingData* klass,
818                      Symbol* name, Symbol* signature)
819     : TrainingData(klass, name, signature)
820   {
821     _klass = klass;
822     _holder = nullptr;
823     _compile = nullptr;
824     for (int i = 0; i < CompLevel_count; i++) {
825       _last_toplevel_compiles[i] = nullptr;
826     }
827     _highest_top_level = CompLevel_none;
828     _level_mask = 0;
829     _was_inlined = _was_toplevel = false;
830   }
831 
832   static int level_mask(int level) {
833     return ((level & 0xF) != level ? 0 : 1 << level);
834   }
835   static CompLevel highest_level(int mask) {
836     if (mask == 0)  return (CompLevel) 0;
837     int diff = (count_leading_zeros(level_mask(0)) - count_leading_zeros(mask));
838     return (CompLevel) diff;
839   }
840 
841  public:
842   KlassTrainingData* klass()  const { return _klass; }
843   CompileTrainingData* compile() const { return _compile; }
844   bool has_holder()           const { return _holder != nullptr; }
845   const Method* holder()      const { return _holder; }
846   Symbol* name()              const { return _key.name1(); }
847   Symbol* signature()         const { return _key.name2(); }
848   bool only_inlined()         const { return !_was_toplevel; }
849   bool never_inlined()        const { return !_was_inlined; }
850   bool saw_level(CompLevel l) const { return (_level_mask & level_mask(l)) != 0; }
851   int highest_level()         const { return highest_level(_level_mask); }
852   int highest_top_level()     const { return _highest_top_level; }
853   MethodData* final_profile() const { return _final_profile; }
854 
855   CompileTrainingData* last_toplevel_compile(int level) const {
856     if (level > CompLevel_none) {
857       return _last_toplevel_compiles[level - 1];
858     }
859     return nullptr;
860   }
861 
862   inline int last_compile_id() const;
863 
864   void notice_compilation(int level, bool inlined = false) {
865     if (inlined) {
866       _was_inlined = true;
867     } else {
868       _was_toplevel = true;
869     }
870     _level_mask |= level_mask(level);
871   }
872 
873   // Update any copied data.
874   void refresh_from(const Method* method);
875 
876   static MethodTrainingData* make(KlassTrainingData* klass,
877                                   Symbol* name, Symbol* signature);
878   static MethodTrainingData* make(KlassTrainingData* klass,
879                                   const char* name, const char* signature);
880   static MethodTrainingData* make(const methodHandle& method,
881                                   bool null_if_not_found = false);
882   static MethodTrainingData* find(const methodHandle& method) {
883     return make(method, true);
884   }
885 
886   virtual MethodTrainingData* as_MethodTrainingData() const {
887     return const_cast<MethodTrainingData*>(this);
888   };
889 
890   void print_on(outputStream* st, bool name_only) const;
891   virtual void print_on(outputStream* st) const { print_on(st, false); }
892   virtual void print_value_on(outputStream* st) const { print_on(st, true); }
893 
894   virtual void prepare(Visitor& visitor);
895   virtual void cleanup(Visitor& visitor);
896 
897   template<typename FN>
898   void iterate_all_compiles(FN fn) const { // lambda enabled API
899     for (CompileTrainingData* ctd = _compile; ctd != nullptr; ctd = ctd->next()) {
900       fn(ctd);
901     }
902   }
903 
904   void initialize_deps_tracking() {
905     iterate_all_compiles([](CompileTrainingData* ctd) { ctd->initialize_deps_tracking(); });
906   }
907 
908   virtual void metaspace_pointers_do(MetaspaceClosure* iter);
909   virtual MetaspaceObj::Type type() const { return MethodTrainingDataType; }
910 
911 #if INCLUDE_CDS
912   virtual void remove_unshareable_info();
913   virtual void restore_unshareable_info(TRAPS);
914 #endif
915 
916   virtual int size() const {
917     return (int)align_metadata_size(align_up(sizeof(MethodTrainingData), BytesPerWord)/BytesPerWord);
918   }
919 
920   virtual const char* internal_name() const {
921     return "{ method training data }";
922   };
923 
924   static MethodTrainingData* allocate(KlassTrainingData* ktd, Method* m);
925   static MethodTrainingData* allocate(KlassTrainingData* ktd, Symbol* name, Symbol* signature);
926 };
927 
928 inline int MethodTrainingData::last_compile_id() const {
929   return (_compile == nullptr) ? 0 : _compile->compile_id();
930 }
931 
932 // CDS support
933 
934 class DumpTimeTrainingDataInfo {
935   TrainingData* _training_data;
936 public:
937   DumpTimeTrainingDataInfo() : DumpTimeTrainingDataInfo(nullptr) {}
938 
939   DumpTimeTrainingDataInfo(TrainingData* training_data)
940       : _training_data(training_data) {}
941 
942   void metaspace_pointers_do(MetaspaceClosure* it) {
943     it->push(&_training_data);
944   }
945 
946   TrainingData* training_data() {
947     return _training_data;
948   }
949 };
950 
951 class TrainingDataDictionary : public OffsetCompactHashtable<
952     const TrainingData::Key*, TrainingData*,
953     TrainingData::Key::equals> {};
954 
955 class TrainingDataPrinter : StackObj {
956   outputStream* _st;
957   int _index;
958 
959 public:
960   TrainingDataPrinter(outputStream* st) : _st(st), _index(0) {}
961 
962   void do_value(TrainingData* record);
963   void do_value(const RunTimeClassInfo* record);
964   void do_value(const RunTimeMethodDataInfo* record);
965 };
966 
967 #endif // SHARE_OOPS_TRAININGDATA_HPP