1 /*
  2  * Copyright (c) 2023, 2025, 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_CODE_AOTCODECACHE_HPP
 26 #define SHARE_CODE_AOTCODECACHE_HPP
 27 
 28 #include "compiler/compilerDefinitions.hpp"
 29 #include "memory/allocation.hpp"
 30 #include "nmt/memTag.hpp"
 31 #include "oops/oopsHierarchy.hpp"
 32 #include "utilities/exceptions.hpp"
 33 
 34 /*
 35  * AOT Code Cache collects code from Code Cache and corresponding metadata
 36  * during application training run.
 37  * In following "production" runs this code and data can me loaded into
 38  * Code Cache skipping its generation.
 39  * Additionaly special compiled code "preload" is generated with class initialization
 40  * barriers which can be called on first Java method invocation.
 41  */
 42 
 43 class AbstractCompiler;
 44 class ciConstant;
 45 class ciEnv;
 46 class ciMethod;
 47 class CodeBuffer;
 48 class CodeOffsets;
 49 class CompileTask;
 50 class DebugInformationRecorder;
 51 class Dependencies;
 52 class ExceptionTable;
 53 class ExceptionHandlerTable;
 54 template<typename E>
 55 class GrowableArray;
 56 class ImmutableOopMapSet;
 57 class ImplicitExceptionTable;
 58 class JavaThread;
 59 class Klass;
 60 class methodHandle;
 61 class Metadata;
 62 class Method;
 63 class nmethod;
 64 class OopMapSet;
 65 class OopRecorder;
 66 class outputStream;
 67 class RelocIterator;
 68 class AOTCodeCache;
 69 class StubCodeGenerator;
 70 
 71 enum class vmIntrinsicID : int;
 72 
 73 #define DO_AOTCODEENTRY_KIND(Fn) \
 74   Fn(None) \
 75   Fn(Adapter) \
 76   Fn(Stub) \
 77   Fn(Blob) \
 78   Fn(Code) \
 79 
 80 // Code Cache's entry contain information from CodeBuffer
 81 class AOTCodeEntry {
 82 public:
 83   enum Kind : s1 {
 84 #define DECL_KIND_ENUM(kind) kind,
 85     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 86 #undef DECL_KIND_ENUM
 87     Kind_count
 88   };
 89 
 90 private:
 91   AOTCodeEntry* _next;
 92   Method*   _method;
 93   Kind   _kind;        //
 94   uint   _id;          // vmIntrinsic::ID for stub or name's hash for nmethod
 95 
 96   uint   _offset;      // Offset to entry
 97   uint   _size;        // Entry size
 98   uint   _name_offset; // Method's or intrinsic name
 99   uint   _name_size;
100   uint   _code_offset; // Start of code in cache
101   uint   _code_size;   // Total size of all code sections
102   uint   _reloc_offset;// Relocations
103   uint   _reloc_size;  // Max size of relocations per code section
104   uint   _num_inlined_bytecodes;
105 
106   uint   _comp_level;  // compilation level
107   uint   _comp_id;     // compilation id
108   uint   _decompile;   // Decompile count for this nmethod
109   bool   _has_clinit_barriers; // Generated code has class init checks
110   bool   _for_preload; // Code can be used for preload
111   bool   _loaded;      // Code was loaded
112   bool   _not_entrant; // Deoptimized
113   bool   _load_fail;   // Failed to load due to some klass state
114   bool   _ignore_decompile; // ignore decompile counter if compilation is done
115                             // during "assembly" phase without running application
116   address _dumptime_content_start_addr;
117 public:
118   AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size,
119            uint code_offset, uint code_size,
120            uint reloc_offset, uint reloc_size,
121            Kind kind, uint id,
122            address dumptime_content_start_addr = nullptr,
123            uint comp_level = 0,
124            uint comp_id = 0, uint decomp = 0,
125            bool has_clinit_barriers = false,
126            bool for_preload = false,
127            bool ignore_decompile = false) {
128     _next         = nullptr;
129     _method       = nullptr;
130     _kind         = kind;
131     _id           = id;
132 
133     _offset       = offset;
134     _size         = size;
135     _name_offset  = name_offset;
136     _name_size    = name_size;
137     _code_offset  = code_offset;
138     _code_size    = code_size;
139     _reloc_offset = reloc_offset;
140     _reloc_size   = reloc_size;
141 
142     _dumptime_content_start_addr = dumptime_content_start_addr;
143 
144     _num_inlined_bytecodes = 0;
145 
146     _comp_level   = comp_level;
147     _comp_id      = comp_id;
148     _decompile    = decomp;
149     _has_clinit_barriers = has_clinit_barriers;
150     _for_preload  = for_preload;
151     _loaded       = false;
152     _not_entrant  = false;
153     _load_fail    = false;
154     _ignore_decompile = ignore_decompile;
155   }
156   void* operator new(size_t x, AOTCodeCache* cache);
157   // Delete is a NOP
158   void operator delete( void *ptr ) {}
159 
160   bool is_adapter() { return _kind == Adapter; }
161   bool is_stub() { return _kind == Stub; }
162   bool is_blob() { return _kind == Blob; }
163   bool is_code() { return _kind == Code; }
164 
165   AOTCodeEntry* next()    const { return _next; }
166   void set_next(AOTCodeEntry* next) { _next = next; }
167 
168   Method*   method()  const { return _method; }
169   void set_method(Method* method) { _method = method; }
170   void update_method_for_writing();
171 
172   Kind kind()         const { return _kind; }
173   uint id()           const { return _id; }
174 
175   uint offset()       const { return _offset; }
176   void set_offset(uint off) { _offset = off; }
177 
178   uint size()         const { return _size; }
179   uint name_offset()  const { return _name_offset; }
180   uint name_size()    const { return _name_size; }
181   uint code_offset()  const { return _code_offset; }
182   uint code_size()    const { return _code_size; }
183   uint reloc_offset() const { return _reloc_offset; }
184   uint reloc_size()   const { return _reloc_size; }
185 
186   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
187 
188   uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
189   void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
190 
191   uint comp_level()   const { return _comp_level; }
192   uint comp_id()      const { return _comp_id; }
193 
194   uint decompile()    const { return _decompile; }
195   bool has_clinit_barriers() const { return _has_clinit_barriers; }
196   bool for_preload()  const { return _for_preload; }
197   bool is_loaded()    const { return _loaded; }
198   void set_loaded()         { _loaded = true; }
199   bool ignore_decompile() const { return _ignore_decompile; }
200 
201   bool not_entrant()  const { return _not_entrant; }
202   void set_not_entrant()    { _not_entrant = true; }
203   void set_entrant()        { _not_entrant = false; }
204 
205   bool load_fail()  const { return _load_fail; }
206   void set_load_fail()    { _load_fail = true; }
207 
208   void print(outputStream* st) const;
209 };
210 
211 // Addresses of stubs, blobs and runtime finctions called from compiled code.
212 class AOTCodeAddressTable : public CHeapObj<mtCode> {
213 private:
214   address* _extrs_addr;
215   address* _stubs_addr;
216   address* _blobs_addr;
217   address* _C1_blobs_addr;
218   address* _C2_blobs_addr;
219   uint     _extrs_length;
220   uint     _stubs_length;
221   uint     _blobs_length;
222   uint     _C1_blobs_length;
223   uint     _C2_blobs_length;
224 
225   bool _extrs_complete;
226   bool _early_stubs_complete;
227   bool _shared_blobs_complete;
228   bool _complete;
229   bool _opto_complete;
230   bool _c1_complete;
231 
232 public:
233   AOTCodeAddressTable() {
234     _extrs_addr = nullptr;
235     _stubs_addr = nullptr;
236     _blobs_addr = nullptr;
237     _extrs_complete = false;
238     _early_stubs_complete = false;
239     _shared_blobs_complete = false;
240     _complete = false;
241     _opto_complete = false;
242     _c1_complete = false;
243   }
244   ~AOTCodeAddressTable();
245   void init_extrs();
246   void init_early_stubs();
247   void init_shared_blobs();
248   void init_stubs();
249   void init_opto();
250   void init_c1();
251   void add_C_string(const char* str);
252   int  id_for_C_string(address str);
253   address address_for_C_string(int idx);
254   int  id_for_address(address addr, RelocIterator iter, CodeBuffer* buffer);
255   address address_for_id(int id);
256   bool opto_complete() const { return _opto_complete; }
257   bool c1_complete() const { return _c1_complete; }
258 };
259 
260 struct AOTCodeSection {
261 public:
262   address _origin_address;
263   uint _size;
264   uint _offset;
265 };
266 
267 enum class DataKind: int {
268   No_Data   = -1,
269   Null      = 0,
270   Klass     = 1,
271   Method    = 2,
272   String    = 3,
273   Primitive = 4, // primitive Class object
274   SysLoader = 5, // java_system_loader
275   PlaLoader = 6, // java_platform_loader
276   MethodCnts= 7,
277   Klass_Shared  = 8,
278   Method_Shared = 9,
279   String_Shared = 10,
280   MH_Oop_Shared = 11
281 };
282 
283 // Concurent AOT code reader
284 class AOTCodeReader {
285 private:
286   const AOTCodeCache* _cache;
287   const AOTCodeEntry* _entry;
288   const char*         _load_buffer; // Loaded cached code buffer
289   uint  _read_position;             // Position in _load_buffer
290   uint  read_position() const { return _read_position; }
291   void  set_read_position(uint pos);
292   const char* addr(uint offset) const { return _load_buffer + offset; }
293 
294   uint _compile_id;
295   uint _comp_level;
296   uint compile_id() const { return _compile_id; }
297   uint comp_level() const { return _comp_level; }
298 
299   bool _preload;             // Preloading code before method execution
300   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
301   void set_lookup_failed()     { _lookup_failed = true; }
302   void clear_lookup_failed()   { _lookup_failed = false; }
303   bool lookup_failed()   const { return _lookup_failed; }
304 
305 public:
306   AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry, CompileTask* task);
307 
308   AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
309 
310   // convenience method to convert offset in AOTCodeEntry data to its address
311   bool compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompiler* compiler);
312   bool compile_blob(CodeBuffer* buffer, int* pc_offset);
313 
314   bool compile_adapter(CodeBuffer* buffer, const char* name, uint32_t offsets[4]);
315 
316   Klass* read_klass(const methodHandle& comp_method, bool shared);
317   Method* read_method(const methodHandle& comp_method, bool shared);
318 
319   bool read_code(CodeBuffer* buffer, CodeBuffer* orig_buffer, uint code_offset);
320   bool read_relocations(CodeBuffer* buffer, CodeBuffer* orig_buffer, OopRecorder* oop_recorder, ciMethod* target);
321   DebugInformationRecorder* read_debug_info(OopRecorder* oop_recorder);
322   OopMapSet* read_oop_maps();
323   bool read_dependencies(Dependencies* dependencies);
324 
325   oop read_oop(JavaThread* thread, const methodHandle& comp_method);
326   Metadata* read_metadata(const methodHandle& comp_method);
327   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
328   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
329 
330   bool read_oop_metadata_list(JavaThread* thread, ciMethod* target, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list, OopRecorder* oop_recorder);
331   void apply_relocations(nmethod* nm, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list) NOT_CDS_RETURN;
332 
333   ImmutableOopMapSet* read_oop_map_set();
334 
335   void print_on(outputStream* st);
336 };
337 
338 class AOTCodeCache : public CHeapObj<mtCode> {
339 
340 // Classes used to describe AOT code cache.
341 protected:
342 class Config {
343     uint _compressedOopShift;
344     uint _compressedKlassShift;
345     uint _contendedPaddingWidth;
346     uint _objectAlignment;
347     uint _gc;
348     enum Flags {
349       none                     = 0,
350       metadataPointers         = 1,
351       debugVM                  = 2,
352       compressedOops           = 4,
353       compressedClassPointers  = 8,
354       useTLAB                  = 16,
355       systemClassAssertions    = 32,
356       userClassAssertions      = 64,
357       enableContendedPadding   = 128,
358       restrictContendedPadding = 256,
359     };
360     uint _flags;
361 
362   public:
363     void record(bool use_meta_ptrs);
364     bool verify() const;
365 
366     bool has_meta_ptrs()  const { return (_flags & metadataPointers) != 0; }
367   };
368 
369   class Header : public CHeapObj<mtCode> {
370   private:
371     // Here should be version and other verification fields
372     enum {
373       AOT_CODE_VERSION = 1
374     };
375     uint _version;           // AOT code version (should match when reading code cache)
376     uint _cache_size;        // cache size in bytes
377     uint _strings_count;     // number of recorded C strings
378     uint _strings_offset;    // offset to recorded C strings
379     uint _entries_count;     // number of recorded entries in cache
380     uint _entries_offset;    // offset of AOTCodeEntry array describing entries
381     uint _preload_entries_count; // entries for pre-loading code
382     uint _preload_entries_offset;
383     Config _config;
384 
385   public:
386     void init(uint cache_size,
387               uint strings_count, uint strings_offset,
388               uint entries_count, uint entries_offset,
389               uint preload_entries_count, uint preload_entries_offset,
390               bool use_meta_ptrs) {
391       _version        = AOT_CODE_VERSION;
392       _cache_size     = cache_size;
393       _strings_count  = strings_count;
394       _strings_offset = strings_offset;
395       _entries_count  = entries_count;
396       _entries_offset = entries_offset;
397       _preload_entries_count  = preload_entries_count;
398       _preload_entries_offset = preload_entries_offset;
399 
400       _config.record(use_meta_ptrs);
401     }
402 
403     uint cache_size()     const { return _cache_size; }
404     uint strings_count()  const { return _strings_count; }
405     uint strings_offset() const { return _strings_offset; }
406     uint entries_count()  const { return _entries_count; }
407     uint entries_offset() const { return _entries_offset; }
408     uint preload_entries_count()  const { return _preload_entries_count; }
409     uint preload_entries_offset() const { return _preload_entries_offset; }
410     bool has_meta_ptrs()  const { return _config.has_meta_ptrs(); }
411 
412     bool verify_config(uint load_size)  const;
413     bool verify_vm_config() const { // Called after Universe initialized
414       return _config.verify();
415     }
416   };
417 
418 // Continue with AOTCodeCache class definition.
419 private:
420   Header*     _load_header;
421   char*       _load_buffer;    // Aligned buffer for loading cached code
422   char*       _store_buffer;   // Aligned buffer for storing cached code
423   char*       _C_store_buffer; // Original unaligned buffer
424 
425   uint        _write_position; // Position in _store_buffer
426   uint        _load_size;      // Used when reading cache
427   uint        _store_size;     // Used when writing cache
428   bool _for_read;              // Open for read
429   bool _for_write;             // Open for write
430   bool _use_meta_ptrs;         // Store metadata pointers
431   bool _for_preload;           // Code for preload
432   bool _gen_preload_code;      // Generate pre-loading code
433   bool _has_clinit_barriers;   // Code with clinit barriers
434   bool _closing;               // Closing cache file
435   bool _failed;                // Failed read/write to/from cache (cache is broken?)
436 
437   AOTCodeAddressTable* _table;
438 
439   AOTCodeEntry* _load_entries;     // Used when reading cache
440   uint*         _search_entries;   // sorted by ID table [id, index]
441   AOTCodeEntry* _store_entries;    // Used when writing cache
442   const char*   _C_strings_buf;    // Loaded buffer for _C_strings[] table
443   uint          _store_entries_cnt;
444 
445   uint _compile_id;
446   uint _comp_level;
447   uint compile_id() const { return _compile_id; }
448   uint comp_level() const { return _comp_level; }
449 
450   static AOTCodeCache* open_for_read();
451   static AOTCodeCache* open_for_write();
452 
453   bool set_write_position(uint pos);
454   bool align_write();
455   uint write_bytes(const void* buffer, uint nbytes);
456   const char* addr(uint offset) const { return _load_buffer + offset; }
457 
458   static AOTCodeAddressTable* addr_table() {
459     return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
460   }
461 
462   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
463   void set_lookup_failed()     { _lookup_failed = true; }
464   void clear_lookup_failed()   { _lookup_failed = false; }
465   bool lookup_failed()   const { return _lookup_failed; }
466 
467   address reserve_bytes(uint nbytes);
468 
469   AOTCodeEntry* write_nmethod(nmethod* nm, bool for_preload);
470 
471   // States:
472   //   S >= 0: allow new readers, S readers are currently active
473   //   S <  0: no new readers are allowed; (-S-1) readers are currently active
474   //     (special case: S = -1 means no readers are active, and would never be active again)
475   static volatile int _nmethod_readers;
476 
477   static void wait_for_no_nmethod_readers();
478 
479   class ReadingMark {
480   private:
481     bool _failed;
482   public:
483     ReadingMark();
484     ~ReadingMark();
485     bool failed() {
486       return _failed;
487     }
488   };
489 
490 public:
491   AOTCodeCache();
492   ~AOTCodeCache();
493 
494   const char* cache_buffer() const { return _load_buffer; }
495   bool failed() const { return _failed; }
496   void set_failed()   { _failed = true; }
497 
498   static bool is_address_in_aot_cache(address p) NOT_CDS_RETURN_(false);
499   static uint max_aot_code_size();
500 
501   uint load_size() const { return _load_size; }
502   uint write_position() const { return _write_position; }
503 
504   void load_strings();
505   int store_strings();
506 
507   static void init_extrs_table() NOT_CDS_RETURN;
508   static void init_early_stubs_table() NOT_CDS_RETURN;
509   static void init_shared_blobs_table() NOT_CDS_RETURN;
510   static void init_stubs_table() NOT_CDS_RETURN;
511   static void init_opto_table() NOT_CDS_RETURN;
512   static void init_c1_table() NOT_CDS_RETURN;
513   address address_for_id(int id) const { return _table->address_for_id(id); }
514 
515   bool for_read()  const { return _for_read  && !_failed; }
516   bool for_write() const { return _for_write && !_failed; }
517 
518   bool closing()          const { return _closing; }
519   bool use_meta_ptrs()    const { return _use_meta_ptrs; }
520   bool gen_preload_code() const { return _gen_preload_code; }
521 
522   void add_new_C_string(const char* str);
523 
524   AOTCodeEntry* add_entry() {
525     _store_entries_cnt++;
526     _store_entries -= 1;
527     return _store_entries;
528   }
529   void preload_startup_code(TRAPS);
530 
531   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id, uint comp_level = 0, uint decomp = 0);
532   void invalidate_entry(AOTCodeEntry* entry);
533 
534   bool finish_write();
535 
536   void log_stats_on_exit();
537 
538   static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
539   static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
540 
541   bool write_klass(Klass* klass);
542   bool write_method(Method* method);
543 
544   bool write_code(CodeBuffer* buffer, uint& code_size);
545   bool write_relocations(CodeBuffer* buffer, uint& reloc_size);
546   bool write_debug_info(DebugInformationRecorder* recorder);
547   bool write_oop_maps(OopMapSet* oop_maps);
548 
549   bool write_oop_map_set(nmethod* nm);
550   bool write_nmethod_reloc_immediates(GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
551   bool write_nmethod_loadtime_relocations(JavaThread* thread, nmethod* nm, GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
552 
553   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
554   Metadata* read_metadata(const methodHandle& comp_method);
555   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
556   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
557 
558   bool write_oop(jobject& jo);
559   bool write_oop(oop obj);
560   bool write_oops(OopRecorder* oop_recorder);
561   bool write_metadata(Metadata* m);
562   bool write_metadata(OopRecorder* oop_recorder);
563   bool write_oops(nmethod* nm);
564   bool write_metadata(nmethod* nm);
565 
566   static bool load_exception_blob(CodeBuffer* buffer, int* pc_offset) NOT_CDS_RETURN_(false);
567   static bool store_exception_blob(CodeBuffer* buffer, int pc_offset) NOT_CDS_RETURN_(false);
568 
569   static bool load_adapter(CodeBuffer* buffer, uint32_t id, const char* basic_sig, uint32_t offsets[4]) NOT_CDS_RETURN_(false);
570   static bool store_adapter(CodeBuffer* buffer, uint32_t id, const char* basic_sig, uint32_t offsets[4]) NOT_CDS_RETURN_(false);
571 
572   static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level) NOT_CDS_RETURN_(false);
573   static AOTCodeEntry* store_nmethod(nmethod* nm, AbstractCompiler* compiler, bool for_preload) NOT_CDS_RETURN_(nullptr);
574 
575   static uint store_entries_cnt() {
576     if (is_on_for_write()) {
577       return cache()->_store_entries_cnt;
578     }
579     return -1;
580   }
581 
582 // Static access
583 
584 private:
585   static AOTCodeCache*  _cache;
586 
587   static bool open_cache();
588   static bool verify_vm_config() {
589     if (is_on_for_read()) {
590       return _cache->_load_header->verify_vm_config();
591     }
592     return true;
593   }
594 public:
595   static AOTCodeCache* cache() { return _cache; }
596   static void initialize() NOT_CDS_RETURN;
597   static void init2() NOT_CDS_RETURN;
598   static void close() NOT_CDS_RETURN;
599   static bool is_on() CDS_ONLY({ return _cache != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
600   static bool is_C3_on() NOT_CDS_RETURN_(false);
601   static bool is_code_load_thread_on() NOT_CDS_RETURN_(false);
602   static bool is_on_for_read()  { return is_on() && _cache->for_read(); }
603   static bool is_on_for_write() { return is_on() && _cache->for_write(); }
604   static bool gen_preload_code(ciMethod* m, int entry_bci) NOT_CDS_RETURN_(false);
605   static bool allow_const_field(ciConstant& value) NOT_CDS_RETURN_(false);
606   static void invalidate(AOTCodeEntry* entry) NOT_CDS_RETURN;
607   static bool is_loaded(AOTCodeEntry* entry);
608   static AOTCodeEntry* find_code_entry(const methodHandle& method, uint comp_level);
609   static void preload_code(JavaThread* thread) NOT_CDS_RETURN;
610 
611   template<typename Function>
612   static void iterate(Function function) { // lambda enabled API
613     AOTCodeCache* cache = open_for_read();
614     if (cache != nullptr) {
615       ReadingMark rdmk;
616       if (rdmk.failed()) {
617         // Cache is closed, cannot touch anything.
618         return;
619       }
620 
621       uint count = cache->_load_header->entries_count();
622       uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
623       AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count);
624 
625       for (uint i = 0; i < count; i++) {
626         int index = search_entries[2*i + 1];
627         AOTCodeEntry* entry = &(load_entries[index]);
628         function(entry);
629       }
630     }
631   }
632 
633   static void add_C_string(const char* str) NOT_CDS_RETURN;
634 
635   static void print_on(outputStream* st) NOT_CDS_RETURN;
636   static void print_statistics_on(outputStream* st) NOT_CDS_RETURN;
637   static void print_timers_on(outputStream* st) NOT_CDS_RETURN;
638   static void print_unused_entries_on(outputStream* st) NOT_CDS_RETURN;
639 };
640 
641 // +1 for preload code
642 const int AOTCompLevel_count = CompLevel_count + 1; // 6 levels indexed from 0 to 5
643 
644 struct AOTCodeStats {
645 private:
646   struct {
647     uint _kind_cnt[AOTCodeEntry::Kind_count];
648     uint _nmethod_cnt[AOTCompLevel_count];
649     uint _clinit_barriers_cnt;
650   } ccstats; // ccstats = cached code stats
651 
652   void check_kind(uint kind) { assert(kind >= AOTCodeEntry::None && kind < AOTCodeEntry::Kind_count, "Invalid AOTCodeEntry kind %d", kind); }
653   void check_complevel(uint lvl) { assert(lvl >= CompLevel_none && lvl < AOTCompLevel_count, "Invalid compilation level %d", lvl); }
654 
655 public:
656   void inc_entry_cnt(uint kind) { check_kind(kind); ccstats._kind_cnt[kind] += 1; }
657   void inc_nmethod_cnt(uint lvl) { check_complevel(lvl); ccstats._nmethod_cnt[lvl] += 1; }
658   void inc_preload_cnt() { ccstats._nmethod_cnt[AOTCompLevel_count-1] += 1; }
659   void inc_clinit_barriers_cnt() { ccstats._clinit_barriers_cnt += 1; }
660 
661   void collect_entry_stats(AOTCodeEntry* entry) {
662     inc_entry_cnt(entry->kind());
663     if (entry->is_code()) {
664       entry->for_preload() ? inc_nmethod_cnt(AOTCompLevel_count-1)
665                            : inc_nmethod_cnt(entry->comp_level());
666       if (entry->has_clinit_barriers()) {
667         inc_clinit_barriers_cnt();
668       }
669     }
670   }
671 
672   uint entry_count(uint kind) { check_kind(kind); return ccstats._kind_cnt[kind]; }
673   uint nmethod_count(uint lvl) { check_complevel(lvl); return ccstats._nmethod_cnt[lvl]; }
674   uint preload_count() { return ccstats._nmethod_cnt[AOTCompLevel_count-1]; }
675   uint clinit_barriers_count() { return ccstats._clinit_barriers_cnt; }
676 
677   uint total_count() {
678     uint total = 0;
679     for (int kind = AOTCodeEntry::None; kind < AOTCodeEntry::Kind_count; kind++) {
680       total += ccstats._kind_cnt[kind];
681     }
682     return total;
683   }
684 
685   static AOTCodeStats add_cached_code_stats(AOTCodeStats stats1, AOTCodeStats stats2);
686 
687   // Runtime stats of the AOT code
688 private:
689   struct {
690     struct {
691       uint _loaded_cnt;
692       uint _invalidated_cnt;
693       uint _load_failed_cnt;
694     } _entry_kinds[AOTCodeEntry::Kind_count],
695       _nmethods[AOTCompLevel_count];
696   } rs; // rs = runtime stats
697 
698 public:
699   void inc_entry_loaded_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._loaded_cnt += 1; }
700   void inc_entry_invalidated_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._invalidated_cnt += 1; }
701   void inc_entry_load_failed_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._load_failed_cnt += 1; }
702 
703   void inc_nmethod_loaded_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._loaded_cnt += 1; }
704   void inc_nmethod_invalidated_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._invalidated_cnt += 1; }
705   void inc_nmethod_load_failed_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._load_failed_cnt += 1; }
706 
707   uint entry_loaded_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._loaded_cnt; }
708   uint entry_invalidated_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._invalidated_cnt; }
709   uint entry_load_failed_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._load_failed_cnt; }
710 
711   uint nmethod_loaded_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._loaded_cnt; }
712   uint nmethod_invalidated_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._invalidated_cnt; }
713   uint nmethod_load_failed_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._load_failed_cnt; }
714 
715   void inc_loaded_cnt(AOTCodeEntry* entry) {
716     inc_entry_loaded_cnt(entry->kind());
717     if (entry->is_code()) {
718       entry->for_preload() ? inc_nmethod_loaded_cnt(AOTCompLevel_count-1)
719                            : inc_nmethod_loaded_cnt(entry->comp_level());
720     }
721   }
722 
723   void inc_invalidated_cnt(AOTCodeEntry* entry) {
724     inc_entry_invalidated_cnt(entry->kind());
725     if (entry->is_code()) {
726       entry->for_preload() ? inc_nmethod_invalidated_cnt(AOTCompLevel_count-1)
727                            : inc_nmethod_invalidated_cnt(entry->comp_level());
728     }
729   }
730 
731   void inc_load_failed_cnt(AOTCodeEntry* entry) {
732     inc_entry_load_failed_cnt(entry->kind());
733     if (entry->is_code()) {
734       entry->for_preload() ? inc_nmethod_load_failed_cnt(AOTCompLevel_count-1)
735                            : inc_nmethod_load_failed_cnt(entry->comp_level());
736     }
737   }
738 
739   void collect_entry_runtime_stats(AOTCodeEntry* entry) {
740     if (entry->is_loaded()) {
741       inc_loaded_cnt(entry);
742     }
743     if (entry->not_entrant()) {
744       inc_invalidated_cnt(entry);
745     }
746     if (entry->load_fail()) {
747       inc_load_failed_cnt(entry);
748     }
749   }
750 
751   void collect_all_stats(AOTCodeEntry* entry) {
752     collect_entry_stats(entry);
753     collect_entry_runtime_stats(entry);
754   }
755 
756   AOTCodeStats() {
757     memset(this, 0, sizeof(AOTCodeStats));
758   }
759 };
760 
761 // code cache internal runtime constants area used by AOT code
762 class AOTRuntimeConstants {
763  friend class AOTCodeCache;
764  private:
765   uint _grain_shift;
766   uint _card_shift;
767   static address _field_addresses_list[];
768   static AOTRuntimeConstants _aot_runtime_constants;
769   // private constructor for unique singleton
770   AOTRuntimeConstants() { }
771   // private for use by friend class AOTCodeCache
772   static void initialize_from_runtime();
773  public:
774 #if INCLUDE_CDS
775   static bool contains(address adr) {
776     address base = (address)&_aot_runtime_constants;
777     address hi = base + sizeof(AOTRuntimeConstants);
778     return (base <= adr && adr < hi);
779   }
780   static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; }
781   static address card_shift_address() { return (address)&_aot_runtime_constants._card_shift; }
782   static address* field_addresses_list() {
783     return _field_addresses_list;
784   }
785 #else
786   static bool contains(address adr)      { return false; }
787   static address grain_shift_address()   { return nullptr; }
788   static address card_shift_address()    { return nullptr; }
789   static address* field_addresses_list() { return nullptr; }
790 #endif
791 };
792 
793 #endif // SHARE_CODE_AOTCODECACHE_HPP