1 /*
  2  * Copyright (c) 2023, 2026, 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 "gc/shared/gc_globals.hpp"
 29 #include "runtime/stubInfo.hpp"
 30 
 31 /*
 32  * AOT Code Cache collects code from Code Cache and corresponding metadata
 33  * during application training run.
 34  * In following "production" runs this code and data can be loaded into
 35  * Code Cache skipping its generation.
 36  */
 37 
 38 class CodeBuffer;
 39 class RelocIterator;
 40 class AOTCodeCache;
 41 class AdapterBlob;
 42 class ExceptionBlob;
 43 class ImmutableOopMapSet;
 44 class AsmRemarks;
 45 class DbgStrings;
 46 
 47 enum class vmIntrinsicID : int;
 48 enum CompLevel : signed char;
 49 
 50 #define DO_AOTCODEENTRY_KIND(Fn) \
 51   Fn(None) \
 52   Fn(Adapter) \
 53   Fn(SharedBlob) \
 54   Fn(C1Blob) \
 55   Fn(C2Blob) \
 56 
 57 // Descriptor of AOT Code Cache's entry
 58 class AOTCodeEntry {
 59 public:
 60   enum Kind : s1 {
 61 #define DECL_KIND_ENUM(kind) kind,
 62     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 63 #undef DECL_KIND_ENUM
 64     Kind_count
 65   };
 66 
 67 private:
 68   AOTCodeEntry* _next;
 69   Kind   _kind;
 70   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
 71   uint   _offset;      // Offset to entry
 72   uint   _size;        // Entry size
 73   uint   _name_offset; // Code blob name
 74   uint   _name_size;
 75   uint   _blob_offset; // Start of code in cache
 76   bool   _has_oop_maps;
 77   address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
 78 
 79 public:
 80   AOTCodeEntry(Kind kind,         uint id,
 81                uint offset,       uint size,
 82                uint name_offset,  uint name_size,
 83                uint blob_offset,  bool has_oop_maps,
 84                address dumptime_content_start_addr) {
 85     _next         = nullptr;
 86     _kind         = kind;
 87     _id           = id;
 88     _offset       = offset;
 89     _size         = size;
 90     _name_offset  = name_offset;
 91     _name_size    = name_size;
 92     _blob_offset  = blob_offset;
 93     _has_oop_maps = has_oop_maps;
 94     _dumptime_content_start_addr = dumptime_content_start_addr;
 95   }
 96   void* operator new(size_t x, AOTCodeCache* cache);
 97   // Delete is a NOP
 98   void operator delete( void *ptr ) {}
 99 
100   AOTCodeEntry* next()        const { return _next; }
101   void set_next(AOTCodeEntry* next) { _next = next; }
102 
103   Kind kind()         const { return _kind; }
104   uint id()           const { return _id; }
105 
106   uint offset()       const { return _offset; }
107   void set_offset(uint off) { _offset = off; }
108 
109   uint size()         const { return _size; }
110   uint name_offset()  const { return _name_offset; }
111   uint name_size()    const { return _name_size; }
112   uint blob_offset()  const { return _blob_offset; }
113   bool has_oop_maps() const { return _has_oop_maps; }
114   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
115 
116   static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; }
117   static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; }
118   static bool is_adapter(Kind kind) { return kind == Adapter; }
119 };
120 
121 // Addresses of stubs, blobs and runtime finctions called from compiled code.
122 class AOTCodeAddressTable : public CHeapObj<mtCode> {
123 private:
124   address* _extrs_addr;
125   address* _stubs_addr;
126   address* _shared_blobs_addr;
127   address* _C1_blobs_addr;
128   uint     _extrs_length;
129   uint     _stubs_length;
130   uint     _shared_blobs_length;
131   uint     _C1_blobs_length;
132 
133   bool _extrs_complete;
134   bool _early_stubs_complete;
135   bool _shared_blobs_complete;
136   bool _early_c1_complete;
137   bool _complete;
138 
139 public:
140   AOTCodeAddressTable() :
141     _extrs_addr(nullptr),
142     _stubs_addr(nullptr),
143     _shared_blobs_addr(nullptr),
144     _C1_blobs_addr(nullptr),
145     _extrs_length(0),
146     _stubs_length(0),
147     _shared_blobs_length(0),
148     _C1_blobs_length(0),
149     _extrs_complete(false),
150     _early_stubs_complete(false),
151     _shared_blobs_complete(false),
152     _early_c1_complete(false),
153     _complete(false)
154   { }
155   ~AOTCodeAddressTable();
156   void init_extrs();
157   void init_early_stubs();
158   void init_shared_blobs();
159   void init_early_c1();
160   const char* add_C_string(const char* str);
161   int  id_for_C_string(address str);
162   address address_for_C_string(int idx);
163   int  id_for_address(address addr, RelocIterator iter, CodeBlob* code_blob);
164   address address_for_id(int id);
165 };
166 
167 class AOTCodeCache : public CHeapObj<mtCode> {
168 
169 // Classes used to describe AOT code cache.
170 protected:
171   class Config {
172     address _compressedOopBase;
173     uint _compressedOopShift;
174     uint _compressedKlassShift;
175     uint _contendedPaddingWidth;
176     uint _gc;
177     enum Flags {
178       none                     = 0,
179       debugVM                  = 1,
180       compressedOops           = 2,
181       compressedClassPointers  = 4,
182       useTLAB                  = 8,
183       systemClassAssertions    = 16,
184       userClassAssertions      = 32,
185       enableContendedPadding   = 64,
186       restrictContendedPadding = 128
187     };
188     uint _flags;
189     uint _cpu_features_offset; // offset in the cache where cpu features are stored
190 
191   public:
192     void record(uint cpu_features_offset);
193     bool verify_cpu_features(AOTCodeCache* cache) const;
194     bool verify(AOTCodeCache* cache) const;
195   };
196 
197   class Header : public CHeapObj<mtCode> {
198   private:
199     enum {
200       AOT_CODE_VERSION = 1
201     };
202     uint   _version;         // AOT code version (should match when reading code cache)
203     uint   _cache_size;      // cache size in bytes
204     uint   _strings_count;   // number of recorded C strings
205     uint   _strings_offset;  // offset to recorded C strings
206     uint   _entries_count;   // number of recorded entries
207     uint   _entries_offset;  // offset of AOTCodeEntry array describing entries
208     uint   _adapters_count;
209     uint   _shared_blobs_count;
210     uint   _C1_blobs_count;
211     uint   _C2_blobs_count;
212     Config _config; // must be the last element as there is trailing data stored immediately after Config
213 
214   public:
215     void init(uint cache_size,
216               uint strings_count,  uint strings_offset,
217               uint entries_count,  uint entries_offset,
218               uint adapters_count, uint shared_blobs_count,
219               uint C1_blobs_count, uint C2_blobs_count,
220               uint cpu_features_offset) {
221       _version        = AOT_CODE_VERSION;
222       _cache_size     = cache_size;
223       _strings_count  = strings_count;
224       _strings_offset = strings_offset;
225       _entries_count  = entries_count;
226       _entries_offset = entries_offset;
227       _adapters_count = adapters_count;
228       _shared_blobs_count = shared_blobs_count;
229       _C1_blobs_count = C1_blobs_count;
230       _C2_blobs_count = C2_blobs_count;
231       _config.record(cpu_features_offset);
232     }
233 
234 
235     uint cache_size()     const { return _cache_size; }
236     uint strings_count()  const { return _strings_count; }
237     uint strings_offset() const { return _strings_offset; }
238     uint entries_count()  const { return _entries_count; }
239     uint entries_offset() const { return _entries_offset; }
240     uint adapters_count() const { return _adapters_count; }
241     uint shared_blobs_count()    const { return _shared_blobs_count; }
242     uint C1_blobs_count() const { return _C1_blobs_count; }
243     uint C2_blobs_count() const { return _C2_blobs_count; }
244 
245     bool verify(uint load_size)  const;
246     bool verify_config(AOTCodeCache* cache) const { // Called after Universe initialized
247       return _config.verify(cache);
248     }
249   };
250 
251 // Continue with AOTCodeCache class definition.
252 private:
253   Header* _load_header;
254   char*   _load_buffer;    // Aligned buffer for loading cached code
255   char*   _store_buffer;   // Aligned buffer for storing cached code
256   char*   _C_store_buffer; // Original unaligned buffer
257 
258   uint   _write_position;  // Position in _store_buffer
259   uint   _load_size;       // Used when reading cache
260   uint   _store_size;      // Used when writing cache
261   bool   _for_use;         // AOT cache is open for using AOT code
262   bool   _for_dump;        // AOT cache is open for dumping AOT code
263   bool   _closing;         // Closing cache file
264   bool   _failed;          // Failed read/write to/from cache (cache is broken?)
265   bool   _lookup_failed;   // Failed to lookup for info (skip only this code load)
266 
267   AOTCodeAddressTable* _table;
268 
269   AOTCodeEntry* _load_entries;   // Used when reading cache
270   uint*         _search_entries; // sorted by ID table [id, index]
271   AOTCodeEntry* _store_entries;  // Used when writing cache
272   const char*   _C_strings_buf;  // Loaded buffer for _C_strings[] table
273   uint          _store_entries_cnt;
274 
275   static AOTCodeCache* open_for_use();
276   static AOTCodeCache* open_for_dump();
277 
278   bool set_write_position(uint pos);
279   bool align_write();
280   address reserve_bytes(uint nbytes);
281   uint write_bytes(const void* buffer, uint nbytes);
282   const char* addr(uint offset) const { return _load_buffer + offset; }
283   static AOTCodeAddressTable* addr_table() {
284     return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
285   }
286 
287   void set_lookup_failed()     { _lookup_failed = true; }
288   void clear_lookup_failed()   { _lookup_failed = false; }
289   bool lookup_failed()   const { return _lookup_failed; }
290 
291 public:
292   AOTCodeCache(bool is_dumping, bool is_using);
293   ~AOTCodeCache();
294 
295   const char* cache_buffer() const { return _load_buffer; }
296   bool failed() const { return _failed; }
297   void set_failed()   { _failed = true; }
298 
299   static uint max_aot_code_size();
300 
301   uint load_size() const { return _load_size; }
302   uint write_position() const { return _write_position; }
303 
304   void load_strings();
305   int store_strings();
306 
307   static void init_early_stubs_table() NOT_CDS_RETURN;
308   static void init_shared_blobs_table() NOT_CDS_RETURN;
309   static void init_early_c1_table() NOT_CDS_RETURN;
310 
311   address address_for_C_string(int idx) const { return _table->address_for_C_string(idx); }
312   address address_for_id(int id) const { return _table->address_for_id(id); }
313 
314   bool for_use()  const { return _for_use  && !_failed; }
315   bool for_dump() const { return _for_dump && !_failed; }
316 
317   bool closing()          const { return _closing; }
318 
319   AOTCodeEntry* add_entry() {
320     _store_entries_cnt++;
321     _store_entries -= 1;
322     return _store_entries;
323   }
324 
325   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id);
326 
327   void store_cpu_features(char*& buffer, uint buffer_size);
328 
329   bool finish_write();
330 
331   bool write_relocations(CodeBlob& code_blob);
332   bool write_oop_map_set(CodeBlob& cb);
333 #ifndef PRODUCT
334   bool write_asm_remarks(CodeBlob& cb);
335   bool write_dbg_strings(CodeBlob& cb);
336 #endif // PRODUCT
337 
338   // save and restore API for non-enumerable code blobs
339   static bool store_code_blob(CodeBlob& blob,
340                               AOTCodeEntry::Kind entry_kind,
341                               uint id, const char* name) NOT_CDS_RETURN_(false);
342 
343   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
344                                   uint id, const char* name) NOT_CDS_RETURN_(nullptr);
345 
346   // save and restore API for enumerable code blobs
347   static bool store_code_blob(CodeBlob& blob,
348                               AOTCodeEntry::Kind entry_kind,
349                               BlobId id) NOT_CDS_RETURN_(false);
350 
351   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
352                                   BlobId id) NOT_CDS_RETURN_(nullptr);
353 
354   static uint store_entries_cnt() {
355     if (is_on_for_dump()) {
356       return cache()->_store_entries_cnt;
357     }
358     return -1;
359   }
360 
361 // Static access
362 
363 private:
364   static AOTCodeCache* _cache;
365   DEBUG_ONLY( static bool _passed_init2; )
366 
367   static bool open_cache(bool is_dumping, bool is_using);
368   bool verify_config() {
369     if (for_use()) {
370       return _load_header->verify_config(this);
371     }
372     return true;
373   }
374 public:
375   static AOTCodeCache* cache() { assert(_passed_init2, "Too early to ask"); return _cache; }
376   static void initialize() NOT_CDS_RETURN;
377   static void init2() NOT_CDS_RETURN;
378   static void close() NOT_CDS_RETURN;
379   static bool is_on() CDS_ONLY({ return cache() != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
380   static bool is_on_for_use()  CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
381   static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
382   static bool is_dumping_stub() NOT_CDS_RETURN_(false);
383   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
384   static bool is_using_stub() NOT_CDS_RETURN_(false);
385   static bool is_using_adapter() NOT_CDS_RETURN_(false);
386   static void enable_caching() NOT_CDS_RETURN;
387   static void disable_caching() NOT_CDS_RETURN;
388   static bool is_caching_enabled() NOT_CDS_RETURN_(false);
389 
390   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
391 
392   static void print_on(outputStream* st) NOT_CDS_RETURN;
393 };
394 
395 // Concurent AOT code reader
396 class AOTCodeReader {
397 private:
398   const AOTCodeCache*  _cache;
399   const AOTCodeEntry*  _entry;
400   const char*          _load_buffer; // Loaded cached code buffer
401   uint  _read_position;              // Position in _load_buffer
402   uint  read_position() const { return _read_position; }
403   void  set_read_position(uint pos);
404   const char* addr(uint offset) const { return _load_buffer + offset; }
405 
406   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
407   void set_lookup_failed()     { _lookup_failed = true; }
408   void clear_lookup_failed()   { _lookup_failed = false; }
409   bool lookup_failed()   const { return _lookup_failed; }
410 
411   AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
412 public:
413   AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);
414 
415   CodeBlob* compile_code_blob(const char* name);
416 
417   ImmutableOopMapSet* read_oop_map_set();
418 
419   void fix_relocations(CodeBlob* code_blob);
420 #ifndef PRODUCT
421   void read_asm_remarks(AsmRemarks& asm_remarks);
422   void read_dbg_strings(DbgStrings& dbg_strings);
423 #endif // PRODUCT
424 };
425 
426 // code cache internal runtime constants area used by AOT code
427 class AOTRuntimeConstants {
428  friend class AOTCodeCache;
429  private:
430   address _card_table_base;
431   uint    _grain_shift;
432   static address _field_addresses_list[];
433   static AOTRuntimeConstants _aot_runtime_constants;
434   // private constructor for unique singleton
435   AOTRuntimeConstants() { }
436   // private for use by friend class AOTCodeCache
437   static void initialize_from_runtime();
438  public:
439 #if INCLUDE_CDS
440   static bool contains(address adr) {
441     address base = (address)&_aot_runtime_constants;
442     address hi = base + sizeof(AOTRuntimeConstants);
443     return (base <= adr && adr < hi);
444   }
445   static address card_table_base_address();
446   static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; }
447   static address* field_addresses_list() {
448     return _field_addresses_list;
449   }
450 #else
451   static bool contains(address adr)        { return false; }
452   static address card_table_base_address() { return nullptr; }
453   static address grain_shift_address()     { return nullptr; }
454   static address* field_addresses_list()   { return nullptr; }
455 #endif
456 };
457 
458 #endif // SHARE_CODE_AOTCODECACHE_HPP