< prev index next >

src/hotspot/share/code/aotCodeCache.hpp

Print this page

  1 /*
  2  * Copyright (c) 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 /*
 29  * AOT Code Cache collects code from Code Cache and corresponding metadata
 30  * during application training run.
 31  * In following "production" runs this code and data can be loaded into
 32  * Code Cache skipping its generation.


 33  */
 34 
 35 class CodeBuffer;
 36 class RelocIterator;
 37 class AOTCodeCache;
 38 class AdapterBlob;
 39 class ExceptionBlob;











 40 class ImmutableOopMapSet;












 41 
 42 enum class vmIntrinsicID : int;
 43 enum CompLevel : signed char;
 44 
 45 // Descriptor of AOT Code Cache's entry







 46 class AOTCodeEntry {
 47 public:
 48   enum Kind {
 49     None    = 0,
 50     Adapter = 1,
 51     Blob    = 2

 52   };
 53 
 54 private:
 55   AOTCodeEntry* _next;

 56   Kind   _kind;
 57   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod

 58   uint   _offset;      // Offset to entry
 59   uint   _size;        // Entry size
 60   uint   _name_offset; // Code blob name
 61   uint   _name_size;
 62   uint   _blob_offset; // Start of code in cache








 63   bool   _has_oop_maps;
 64   address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
 65 






 66 public:







































 67   AOTCodeEntry(Kind kind,         uint id,
 68                uint offset,       uint size,
 69                uint name_offset,  uint name_size,
 70                uint blob_offset,  bool has_oop_maps,
 71                address dumptime_content_start_addr) {
 72     _next         = nullptr;

 73     _kind         = kind;
 74     _id           = id;
 75     _offset       = offset;
 76     _size         = size;
 77     _name_offset  = name_offset;
 78     _name_size    = name_size;
 79     _blob_offset  = blob_offset;
 80     _has_oop_maps = has_oop_maps;



 81     _dumptime_content_start_addr = dumptime_content_start_addr;












 82   }

 83   void* operator new(size_t x, AOTCodeCache* cache);
 84   // Delete is a NOP
 85   void operator delete( void *ptr ) {}
 86 
 87   AOTCodeEntry* next()        const { return _next; }





 88   void set_next(AOTCodeEntry* next) { _next = next; }
 89 




 90   Kind kind()         const { return _kind; }
 91   uint id()           const { return _id; }
 92 
 93   uint offset()       const { return _offset; }
 94   void set_offset(uint off) { _offset = off; }
 95 
 96   uint size()         const { return _size; }
 97   uint name_offset()  const { return _name_offset; }
 98   uint name_size()    const { return _name_size; }
 99   uint blob_offset()  const { return _blob_offset; }
100   bool has_oop_maps() const { return _has_oop_maps; }



101   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
102 
























103   static bool is_valid_entry_kind(Kind kind) { return kind == Adapter || kind == Blob; }
104 };
105 
106 // Addresses of stubs, blobs and runtime finctions called from compiled code.
107 class AOTCodeAddressTable : public CHeapObj<mtCode> {
108 private:
109   address* _extrs_addr;

110   address* _blobs_addr;


111   uint     _extrs_length;

112   uint     _blobs_length;


113 
114   bool _extrs_complete;

115   bool _shared_blobs_complete;
116   bool _complete;


117 
118 public:
119   AOTCodeAddressTable() :
120     _extrs_addr(nullptr),
121     _blobs_addr(nullptr),
122     _extrs_length(0),
123     _blobs_length(0),
124     _extrs_complete(false),
125     _shared_blobs_complete(false),
126     _complete(false)
127   { }


128   ~AOTCodeAddressTable();
129   void init_extrs();

130   void init_shared_blobs();



131   const char* add_C_string(const char* str);
132   int  id_for_C_string(address str);
133   address address_for_C_string(int idx);
134   int  id_for_address(address addr, RelocIterator iter, CodeBlob* code_blob);
135   address address_for_id(int id);

























136 };
137 
138 class AOTCodeCache : public CHeapObj<mtCode> {
139 
140 // Classes used to describe AOT code cache.
141 protected:
142   class Config {
143     uint _compressedOopShift;
144     uint _compressedKlassShift;
145     uint _contendedPaddingWidth;
146     uint _objectAlignment;
147     uint _gc;
148     enum Flags {
149       none                     = 0,
150       debugVM                  = 1,
151       compressedOops           = 2,
152       compressedClassPointers  = 4,
153       useTLAB                  = 8,
154       systemClassAssertions    = 16,
155       userClassAssertions      = 32,
156       enableContendedPadding   = 64,
157       restrictContendedPadding = 128

158     };
159     uint _flags;
160 
161   public:
162     void record();
163     bool verify() const;


164   };
165 
166   class Header : public CHeapObj<mtCode> {
167   private:

168     enum {
169       AOT_CODE_VERSION = 1
170     };
171     uint   _version;         // AOT code version (should match when reading code cache)
172     uint   _cache_size;      // cache size in bytes
173     uint   _strings_count;   // number of recorded C strings
174     uint   _strings_offset;  // offset to recorded C strings
175     uint   _entries_count;   // number of recorded entries
176     uint   _entries_offset;  // offset of AOTCodeEntry array describing entries
177     uint   _adapters_count;
178     uint   _blobs_count;



179     Config _config;
180 
181 public:
182     void init(uint cache_size,
183               uint strings_count,  uint strings_offset,
184               uint entries_count,  uint entries_offset,
185               uint adapters_count, uint blobs_count) {


186       _version        = AOT_CODE_VERSION;
187       _cache_size     = cache_size;
188       _strings_count  = strings_count;
189       _strings_offset = strings_offset;
190       _entries_count  = entries_count;
191       _entries_offset = entries_offset;


192       _adapters_count = adapters_count;
193       _blobs_count    = blobs_count;

194 
195       _config.record();
196     }
197 
198 
199     uint cache_size()     const { return _cache_size; }
200     uint strings_count()  const { return _strings_count; }
201     uint strings_offset() const { return _strings_offset; }
202     uint entries_count()  const { return _entries_count; }
203     uint entries_offset() const { return _entries_offset; }


204     uint adapters_count() const { return _adapters_count; }
205     uint blobs_count()    const { return _blobs_count; }



206 
207     bool verify_config(uint load_size)  const;
208     bool verify_vm_config() const { // Called after Universe initialized
209       return _config.verify();
210     }
211   };
212 
213 // Continue with AOTCodeCache class definition.
214 private:
215   Header* _load_header;
216   char*   _load_buffer;    // Aligned buffer for loading cached code
217   char*   _store_buffer;   // Aligned buffer for storing cached code
218   char*   _C_store_buffer; // Original unaligned buffer
219 
220   uint   _write_position;  // Position in _store_buffer
221   uint   _load_size;       // Used when reading cache
222   uint   _store_size;      // Used when writing cache
223   bool   _for_use;         // AOT cache is open for using AOT code
224   bool   _for_dump;        // AOT cache is open for dumping AOT code
225   bool   _closing;         // Closing cache file
226   bool   _failed;          // Failed read/write to/from cache (cache is broken?)
227   bool   _lookup_failed;   // Failed to lookup for info (skip only this code load)
228 






229   AOTCodeAddressTable* _table;
230 
231   AOTCodeEntry* _load_entries;   // Used when reading cache
232   uint*         _search_entries; // sorted by ID table [id, index]
233   AOTCodeEntry* _store_entries;  // Used when writing cache
234   const char*   _C_strings_buf;  // Loaded buffer for _C_strings[] table
235   uint          _store_entries_cnt;
236 





237   static AOTCodeCache* open_for_use();
238   static AOTCodeCache* open_for_dump();
239 
240   bool set_write_position(uint pos);
241   bool align_write();

242   address reserve_bytes(uint nbytes);
243   uint write_bytes(const void* buffer, uint nbytes);
244   const char* addr(uint offset) const { return _load_buffer + offset; }
245   static AOTCodeAddressTable* addr_table() {
246     return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
247   }
248 
249   void set_lookup_failed()     { _lookup_failed = true; }
250   void clear_lookup_failed()   { _lookup_failed = false; }
251   bool lookup_failed()   const { return _lookup_failed; }
252 





















253 public:
254   AOTCodeCache(bool is_dumping, bool is_using);
255   ~AOTCodeCache();
256 
257   const char* cache_buffer() const { return _load_buffer; }
258   bool failed() const { return _failed; }
259   void set_failed()   { _failed = true; }
260 

261   static uint max_aot_code_size();
262 
263   uint load_size() const { return _load_size; }
264   uint write_position() const { return _write_position; }
265 
266   void load_strings();
267   int store_strings();
268 
269   static void init_extrs_table() NOT_CDS_RETURN;

270   static void init_shared_blobs_table() NOT_CDS_RETURN;



271 
272   address address_for_id(int id) const { return _table->address_for_id(id); }
273 
274   bool for_use()  const { return _for_use  && !_failed; }
275   bool for_dump() const { return _for_dump && !_failed; }
276 
277   bool closing()          const { return _closing; }


278 
279   AOTCodeEntry* add_entry() {
280     _store_entries_cnt++;
281     _store_entries -= 1;
282     return _store_entries;
283   }

284 
285   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id);

286 
287   bool finish_write();
288 








289   bool write_relocations(CodeBlob& code_blob);


290   bool write_oop_map_set(CodeBlob& cb);















291 
292   static bool store_code_blob(CodeBlob& blob,
293                               AOTCodeEntry::Kind entry_kind,
294                               uint id, const char* name,
295                               int entry_offset_count,
296                               int* entry_offsets) NOT_CDS_RETURN_(false);
297 
298   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
299                                   uint id, const char* name,
300                                   int entry_offset_count,
301                                   int* entry_offsets) NOT_CDS_RETURN_(nullptr);



302 
303   static uint store_entries_cnt() {
304     if (is_on_for_dump()) {
305       return cache()->_store_entries_cnt;
306     }
307     return -1;
308   }
309 
310 // Static access
311 
312 private:
313   static AOTCodeCache*  _cache;
314 
315   static bool open_cache(bool is_dumping, bool is_using);
316   static bool verify_vm_config() {
317     if (is_on_for_use()) {
318       return _cache->_load_header->verify_vm_config();
319     }
320     return true;
321   }
322 public:
323   static AOTCodeCache* cache() { return _cache; }
324   static void initialize() NOT_CDS_RETURN;
325   static void init2() NOT_CDS_RETURN;
326   static void close() NOT_CDS_RETURN;
327   static bool is_on() CDS_ONLY({ return _cache != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
328   static bool is_on_for_use()  { return is_on() && _cache->for_use(); }
329   static bool is_on_for_dump() { return is_on() && _cache->for_dump(); }
330 
331   static bool is_dumping_adapters() NOT_CDS_RETURN_(false);
332   static bool is_using_adapters() NOT_CDS_RETURN_(false);





































333 
334   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
335 
336   static void print_on(outputStream* st) NOT_CDS_RETURN;



337 };
338 
339 // Concurent AOT code reader
340 class AOTCodeReader {
341 private:
342   const AOTCodeCache*  _cache;
343   const AOTCodeEntry*  _entry;
344   const char*          _load_buffer; // Loaded cached code buffer
345   uint  _read_position;              // Position in _load_buffer
346   uint  read_position() const { return _read_position; }
347   void  set_read_position(uint pos);
348   const char* addr(uint offset) const { return _load_buffer + offset; }
349 






350   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
351   void set_lookup_failed()     { _lookup_failed = true; }
352   void clear_lookup_failed()   { _lookup_failed = false; }
353   bool lookup_failed()   const { return _lookup_failed; }
354 
355   AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
356 public:
357   AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);






358 
359   CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets);
360 













361   ImmutableOopMapSet* read_oop_map_set();
362 
363   void fix_relocations(CodeBlob* code_blob);


























































































































364 };
365 #endif // SHARE_CODE_AOTCODECACH_HPP


































  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 AOTCodeCache;
 45 class ciConstant;
 46 class ciEnv;
 47 class ciMethod;
 48 class CodeBuffer;
 49 class CodeBlob;
 50 class CodeOffsets;
 51 class CompileTask;
 52 class DebugInformationRecorder;
 53 class Dependencies;
 54 class ExceptionTable;
 55 class ExceptionHandlerTable;
 56 template<typename E>
 57 class GrowableArray;
 58 class ImmutableOopMapSet;
 59 class ImplicitExceptionTable;
 60 class JavaThread;
 61 class Klass;
 62 class methodHandle;
 63 class Metadata;
 64 class Method;
 65 class nmethod;
 66 class OopMapSet;
 67 class OopRecorder;
 68 class outputStream;
 69 class RelocIterator;
 70 class StubCodeGenerator;
 71 
 72 enum class vmIntrinsicID : int;

 73 
 74 #define DO_AOTCODEENTRY_KIND(Fn) \
 75   Fn(None) \
 76   Fn(Adapter) \
 77   Fn(Stub) \
 78   Fn(Blob) \
 79   Fn(Code) \
 80 
 81 // Code Cache's entry contain information from CodeBuffer
 82 class AOTCodeEntry {
 83 public:
 84   enum Kind : s1 {
 85 #define DECL_KIND_ENUM(kind) kind,
 86     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 87 #undef DECL_KIND_ENUM
 88     Kind_count
 89   };
 90 
 91 private:
 92   AOTCodeEntry* _next;
 93   Method*       _method;
 94   Kind   _kind;
 95   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
 96 
 97   uint   _offset;      // Offset to entry
 98   uint   _size;        // Entry size
 99   uint   _name_offset; // Method's or intrinsic name
100   uint   _name_size;
101   uint   _code_offset; // Start of code in cache
102   uint   _code_size;   // Total size of all code sections
103   uint   _reloc_offset;// Relocations
104   uint   _reloc_size;  // Max size of relocations per code section
105   uint   _num_inlined_bytecodes;
106 
107   uint   _comp_level;  // compilation level
108   uint   _comp_id;     // compilation id
109   uint   _decompile;   // Decompile count for this nmethod
110   bool   _has_oop_maps;
111   bool   _has_clinit_barriers; // Generated code has class init checks
112   bool   _for_preload; // Code can be used for preload
113   bool   _loaded;      // Code was loaded
114   bool   _not_entrant; // Deoptimized
115   bool   _load_fail;   // Failed to load due to some klass state
116   bool   _ignore_decompile; // ignore decompile counter if compilation is done
117                             // during "assembly" phase without running application
118   address _dumptime_content_start_addr;
119 public:
120   AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size,
121            uint code_offset, uint code_size,
122            uint reloc_offset, uint reloc_size,
123            Kind kind, uint id,
124            address dumptime_content_start_addr = nullptr,
125            uint comp_level = 0,
126            uint comp_id = 0, uint decomp = 0,
127            bool has_clinit_barriers = false,
128            bool for_preload = false,
129            bool ignore_decompile = false) {
130     _next         = nullptr;
131     _method       = nullptr;
132     _kind         = kind;
133     _id           = id;
134 
135     _offset       = offset;
136     _size         = size;
137     _name_offset  = name_offset;
138     _name_size    = name_size;
139     _code_offset  = code_offset;
140     _code_size    = code_size;
141     _reloc_offset = reloc_offset;
142     _reloc_size   = reloc_size;
143 
144     _dumptime_content_start_addr = dumptime_content_start_addr;
145     _num_inlined_bytecodes = 0;
146 
147     _comp_level   = comp_level;
148     _comp_id      = comp_id;
149     _decompile    = decomp;
150     _has_oop_maps = false; // unused here
151     _has_clinit_barriers = has_clinit_barriers;
152     _for_preload  = for_preload;
153     _loaded       = false;
154     _not_entrant  = false;
155     _load_fail    = false;
156     _ignore_decompile = ignore_decompile;
157   }
158 
159   AOTCodeEntry(Kind kind,         uint id,
160                uint offset,       uint size,
161                uint name_offset,  uint name_size,
162                uint blob_offset,  bool has_oop_maps,
163                address dumptime_content_start_addr) {
164     _next         = nullptr;
165     _method       = nullptr;
166     _kind         = kind;
167     _id           = id;
168     _offset       = offset;
169     _size         = size;
170     _name_offset  = name_offset;
171     _name_size    = name_size;
172     _code_offset  = blob_offset;
173     _code_size    = 0;
174     _reloc_offset = 0;
175     _reloc_size   = 0;
176 
177     _dumptime_content_start_addr = dumptime_content_start_addr;
178     _num_inlined_bytecodes = 0;
179 
180     _comp_level   = 0;
181     _comp_id      = 0;
182     _decompile    = 0;
183     _has_oop_maps = has_oop_maps;
184     _has_clinit_barriers = false;
185     _for_preload  = false;
186     _loaded       = false;
187     _not_entrant  = false;
188     _load_fail    = false;
189     _ignore_decompile = true;
190   }
191 
192   void* operator new(size_t x, AOTCodeCache* cache);
193   // Delete is a NOP
194   void operator delete( void *ptr ) {}
195 
196   bool is_adapter() { return _kind == Adapter; }
197   bool is_stub() { return _kind == Stub; }
198   bool is_blob() { return _kind == Blob; }
199   bool is_code() { return _kind == Code; }
200 
201   AOTCodeEntry* next()    const { return _next; }
202   void set_next(AOTCodeEntry* next) { _next = next; }
203 
204   Method*   method()  const { return _method; }
205   void set_method(Method* method) { _method = method; }
206   void update_method_for_writing();
207 
208   Kind kind()         const { return _kind; }
209   uint id()           const { return _id; }
210 
211   uint offset()       const { return _offset; }
212   void set_offset(uint off) { _offset = off; }
213 
214   uint size()         const { return _size; }
215   uint name_offset()  const { return _name_offset; }
216   uint name_size()    const { return _name_size; }
217   uint code_offset()  const { return _code_offset; }
218   uint code_size()    const { return _code_size; }
219   uint reloc_offset() const { return _reloc_offset; }
220   uint reloc_size()   const { return _reloc_size; }
221 
222   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
223 
224   uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
225   void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
226 
227   uint comp_level()   const { return _comp_level; }
228   uint comp_id()      const { return _comp_id; }
229 
230   uint decompile()    const { return _decompile; }
231   bool has_clinit_barriers() const { return _has_clinit_barriers; }
232   bool for_preload()  const { return _for_preload; }
233   bool is_loaded()    const { return _loaded; }
234   void set_loaded()         { _loaded = true; }
235   bool ignore_decompile() const { return _ignore_decompile; }
236 
237   bool not_entrant()  const { return _not_entrant; }
238   void set_not_entrant()    { _not_entrant = true; }
239   void set_entrant()        { _not_entrant = false; }
240 
241   bool load_fail()  const { return _load_fail; }
242   void set_load_fail()    { _load_fail = true; }
243 
244   void print(outputStream* st) const;
245   uint blob_offset()  const { return _code_offset; }
246   bool has_oop_maps() const { return _has_oop_maps; }
247 
248   static bool is_valid_entry_kind(Kind kind) { return kind == Adapter || kind == Blob; }
249 };
250 
251 // Addresses of stubs, blobs and runtime finctions called from compiled code.
252 class AOTCodeAddressTable : public CHeapObj<mtCode> {
253 private:
254   address* _extrs_addr;
255   address* _stubs_addr;
256   address* _blobs_addr;
257   address* _C1_blobs_addr;
258   address* _C2_blobs_addr;
259   uint     _extrs_length;
260   uint     _stubs_length;
261   uint     _blobs_length;
262   uint     _C1_blobs_length;
263   uint     _C2_blobs_length;
264 
265   bool _extrs_complete;
266   bool _early_stubs_complete;
267   bool _shared_blobs_complete;
268   bool _complete;
269   bool _opto_complete;
270   bool _c1_complete;
271 
272 public:
273   AOTCodeAddressTable() {
274     _extrs_addr = nullptr;
275     _stubs_addr = nullptr;
276     _blobs_addr = nullptr;
277     _extrs_complete = false;
278     _early_stubs_complete = false;
279     _shared_blobs_complete = false;
280     _complete = false;
281     _opto_complete = false;
282     _c1_complete = false;
283   }
284   ~AOTCodeAddressTable();
285   void init_extrs();
286   void init_early_stubs();
287   void init_shared_blobs();
288   void init_stubs();
289   void init_opto();
290   void init_c1();
291   const char* add_C_string(const char* str);
292   int  id_for_C_string(address str);
293   address address_for_C_string(int idx);
294   int  id_for_address(address addr, RelocIterator iter, CodeBuffer* buffer, CodeBlob* blob = nullptr);
295   address address_for_id(int id);
296   bool opto_complete() const { return _opto_complete; }
297   bool c1_complete() const { return _c1_complete; }
298 };
299 
300 struct AOTCodeSection {
301 public:
302   address _origin_address;
303   uint _size;
304   uint _offset;
305 };
306 
307 enum class DataKind: int {
308   No_Data   = -1,
309   Null      = 0,
310   Klass     = 1,
311   Method    = 2,
312   String    = 3,
313   Primitive = 4, // primitive Class object
314   SysLoader = 5, // java_system_loader
315   PlaLoader = 6, // java_platform_loader
316   MethodCnts= 7,
317   Klass_Shared  = 8,
318   Method_Shared = 9,
319   String_Shared = 10,
320   MH_Oop_Shared = 11
321 };
322 
323 class AOTCodeCache : public CHeapObj<mtCode> {
324 
325 // Classes used to describe AOT code cache.
326 protected:
327   class Config {
328     uint _compressedOopShift;
329     uint _compressedKlassShift;
330     uint _contendedPaddingWidth;
331     uint _objectAlignment;
332     uint _gc;
333     enum Flags {
334       none                     = 0,
335       metadataPointers         = 1,
336       debugVM                  = 2,
337       compressedOops           = 4,
338       compressedClassPointers  = 8,
339       useTLAB                  = 16,
340       systemClassAssertions    = 32,
341       userClassAssertions      = 64,
342       enableContendedPadding   = 128,
343       restrictContendedPadding = 256,
344     };
345     uint _flags;
346 
347   public:
348     void record(bool use_meta_ptrs);
349     bool verify() const;
350 
351     bool has_meta_ptrs()  const { return (_flags & metadataPointers) != 0; }
352   };
353 
354   class Header : public CHeapObj<mtCode> {
355   private:
356     // Here should be version and other verification fields
357     enum {
358       AOT_CODE_VERSION = 1
359     };
360     uint _version;           // AOT code version (should match when reading code cache)
361     uint _cache_size;        // cache size in bytes
362     uint _strings_count;     // number of recorded C strings
363     uint _strings_offset;    // offset to recorded C strings
364     uint _entries_count;     // number of recorded entries in cache
365     uint _entries_offset;    // offset of AOTCodeEntry array describing entries
366     uint _preload_entries_count; // entries for pre-loading code
367     uint _preload_entries_offset;
368     uint _adapters_count;
369     uint _blobs_count;
370     uint _stubs_count;
371     Config _config;
372 
373   public:
374     void init(uint cache_size,
375               uint strings_count, uint strings_offset,
376               uint entries_count, uint entries_offset,
377               uint preload_entries_count, uint preload_entries_offset,
378               uint adapters_count, uint blobs_count, uint stubs_count,
379               bool use_meta_ptrs) {
380       _version        = AOT_CODE_VERSION;
381       _cache_size     = cache_size;
382       _strings_count  = strings_count;
383       _strings_offset = strings_offset;
384       _entries_count  = entries_count;
385       _entries_offset = entries_offset;
386       _preload_entries_count  = preload_entries_count;
387       _preload_entries_offset = preload_entries_offset;
388       _adapters_count = adapters_count;
389       _blobs_count    = blobs_count;
390       _stubs_count    = stubs_count;
391 
392       _config.record(use_meta_ptrs);
393     }
394 

395     uint cache_size()     const { return _cache_size; }
396     uint strings_count()  const { return _strings_count; }
397     uint strings_offset() const { return _strings_offset; }
398     uint entries_count()  const { return _entries_count; }
399     uint entries_offset() const { return _entries_offset; }
400     uint preload_entries_count()  const { return _preload_entries_count; }
401     uint preload_entries_offset() const { return _preload_entries_offset; }
402     uint adapters_count() const { return _adapters_count; }
403     uint blobs_count()    const { return _blobs_count; }
404     uint stubs_count()    const { return _stubs_count; }
405     uint nmethods_count() const { return _entries_count - _stubs_count - _blobs_count - _adapters_count; }
406     bool has_meta_ptrs()  const { return _config.has_meta_ptrs(); }
407 
408     bool verify_config(uint load_size)  const;
409     bool verify_vm_config() const { // Called after Universe initialized
410       return _config.verify();
411     }
412   };
413 
414 // Continue with AOTCodeCache class definition.
415 private:
416   Header* _load_header;
417   char*   _load_buffer;    // Aligned buffer for loading cached code
418   char*   _store_buffer;   // Aligned buffer for storing cached code
419   char*   _C_store_buffer; // Original unaligned buffer
420 
421   uint   _write_position;  // Position in _store_buffer
422   uint   _load_size;       // Used when reading cache
423   uint   _store_size;      // Used when writing cache
424   bool   _for_use;         // AOT cache is open for using AOT code
425   bool   _for_dump;        // AOT cache is open for dumping AOT code
426   bool   _closing;         // Closing cache file
427   bool   _failed;          // Failed read/write to/from cache (cache is broken?)
428   bool   _lookup_failed;   // Failed to lookup for info (skip only this code load)
429 
430   bool   _for_preload;         // Code for preload
431   bool   _gen_preload_code;    // Generate pre-loading code
432   bool   _has_clinit_barriers; // Code with clinit barriers
433 
434   bool   _use_meta_ptrs;   // Store metadata pointers
435 
436   AOTCodeAddressTable* _table;
437 
438   AOTCodeEntry* _load_entries;     // Used when reading cache
439   uint*         _search_entries;   // sorted by ID table [id, index]
440   AOTCodeEntry* _store_entries;    // Used when writing cache
441   const char*   _C_strings_buf;    // Loaded buffer for _C_strings[] table
442   uint          _store_entries_cnt;
443 
444   uint _compile_id;
445   uint _comp_level;
446   uint compile_id() const { return _compile_id; }
447   uint comp_level() const { return _comp_level; }
448 
449   static AOTCodeCache* open_for_use();
450   static AOTCodeCache* open_for_dump();
451 
452   bool set_write_position(uint pos);
453   bool align_write();
454 
455   address reserve_bytes(uint nbytes);
456   uint write_bytes(const void* buffer, uint nbytes);
457   const char* addr(uint offset) const { return _load_buffer + offset; }
458   static AOTCodeAddressTable* addr_table() {
459     return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
460   }
461 
462   void set_lookup_failed()     { _lookup_failed = true; }
463   void clear_lookup_failed()   { _lookup_failed = false; }
464   bool lookup_failed()   const { return _lookup_failed; }
465 
466   AOTCodeEntry* write_nmethod(nmethod* nm, bool for_preload);
467 
468   // States:
469   //   S >= 0: allow new readers, S readers are currently active
470   //   S <  0: no new readers are allowed; (-S-1) readers are currently active
471   //     (special case: S = -1 means no readers are active, and would never be active again)
472   static volatile int _nmethod_readers;
473 
474   static void wait_for_no_nmethod_readers();
475 
476   class ReadingMark {
477   private:
478     bool _failed;
479   public:
480     ReadingMark();
481     ~ReadingMark();
482     bool failed() {
483       return _failed;
484     }
485   };
486 
487 public:
488   AOTCodeCache(bool is_dumping, bool is_using);
489   ~AOTCodeCache();
490 
491   const char* cache_buffer() const { return _load_buffer; }
492   bool failed() const { return _failed; }
493   void set_failed()   { _failed = true; }
494 
495   static bool is_address_in_aot_cache(address p) NOT_CDS_RETURN_(false);
496   static uint max_aot_code_size();
497 
498   uint load_size() const { return _load_size; }
499   uint write_position() const { return _write_position; }
500 
501   void load_strings();
502   int store_strings();
503 
504   static void init_extrs_table() NOT_CDS_RETURN;
505   static void init_early_stubs_table() NOT_CDS_RETURN;
506   static void init_shared_blobs_table() NOT_CDS_RETURN;
507   static void init_stubs_table() NOT_CDS_RETURN;
508   static void init_opto_table() NOT_CDS_RETURN;
509   static void init_c1_table() NOT_CDS_RETURN;
510 
511   address address_for_id(int id) const { return _table->address_for_id(id); }
512 
513   bool for_use()  const { return _for_use  && !_failed; }
514   bool for_dump() const { return _for_dump && !_failed; }
515 
516   bool closing()          const { return _closing; }
517   bool use_meta_ptrs()    const { return _use_meta_ptrs; }
518   bool gen_preload_code() const { return _gen_preload_code; }
519 
520   AOTCodeEntry* add_entry() {
521     _store_entries_cnt++;
522     _store_entries -= 1;
523     return _store_entries;
524   }
525   void preload_startup_code(TRAPS);
526 
527   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id, uint comp_level = 0, uint decomp = 0);
528   void invalidate_entry(AOTCodeEntry* entry);
529 
530   bool finish_write();
531 
532   void log_stats_on_exit();
533 
534   static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
535   static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
536 
537   bool write_klass(Klass* klass);
538   bool write_method(Method* method);
539 
540   bool write_relocations(CodeBlob& code_blob);
541   bool write_debug_info(DebugInformationRecorder* recorder);
542 
543   bool write_oop_map_set(CodeBlob& cb);
544   bool write_nmethod_reloc_immediates(GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
545   bool write_nmethod_loadtime_relocations(JavaThread* thread, nmethod* nm, GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
546 
547   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
548   Metadata* read_metadata(const methodHandle& comp_method);
549   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
550   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
551 
552   bool write_oop(jobject& jo);
553   bool write_oop(oop obj);
554   bool write_oops(OopRecorder* oop_recorder);
555   bool write_metadata(Metadata* m);
556   bool write_metadata(OopRecorder* oop_recorder);
557   bool write_oops(nmethod* nm);
558   bool write_metadata(nmethod* nm);
559 
560   static bool store_code_blob(CodeBlob& blob,
561                               AOTCodeEntry::Kind entry_kind,
562                               uint id, const char* name,
563                               int entry_offset_count = 0,
564                               int* entry_offsets = nullptr) NOT_CDS_RETURN_(false);
565 
566   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
567                                   uint id, const char* name,
568                                   int entry_offset_count = 0,
569                                   int* entry_offsets = nullptr) NOT_CDS_RETURN_(nullptr);
570 
571   static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level) NOT_CDS_RETURN_(false);
572   static AOTCodeEntry* store_nmethod(nmethod* nm, AbstractCompiler* compiler, bool for_preload) NOT_CDS_RETURN_(nullptr);
573 
574   static uint store_entries_cnt() {
575     if (is_on_for_dump()) {
576       return cache()->_store_entries_cnt;
577     }
578     return -1;
579   }
580 
581 // Static access
582 
583 private:
584   static AOTCodeCache*  _cache;
585 
586   static bool open_cache(bool is_dumping, bool is_using);
587   static bool verify_vm_config() {
588     if (is_on_for_use()) {
589       return _cache->_load_header->verify_vm_config();
590     }
591     return true;
592   }
593 public:
594   static AOTCodeCache* cache() { return _cache; }
595   static void initialize() NOT_CDS_RETURN;
596   static void init2() NOT_CDS_RETURN;
597   static void close() NOT_CDS_RETURN;
598   static bool is_on() CDS_ONLY({ return _cache != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
599   static bool is_C3_on() NOT_CDS_RETURN_(false);
600   static bool is_code_load_thread_on() NOT_CDS_RETURN_(false);
601   static bool is_on_for_use()  CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
602   static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
603   static bool is_dumping_code() NOT_CDS_RETURN_(false);
604   static bool is_dumping_stub() NOT_CDS_RETURN_(false);
605   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
606   static bool is_using_code() NOT_CDS_RETURN_(false);
607   static bool is_using_stub() NOT_CDS_RETURN_(false);
608   static bool is_using_adapter() NOT_CDS_RETURN_(false);
609   static void enable_caching() NOT_CDS_RETURN;
610   static void disable_caching() NOT_CDS_RETURN;
611   static bool is_caching_enabled() NOT_CDS_RETURN_(false);
612 
613   static bool gen_preload_code(ciMethod* m, int entry_bci) NOT_CDS_RETURN_(false);
614   static bool allow_const_field(ciConstant& value) NOT_CDS_RETURN_(false);
615   static void invalidate(AOTCodeEntry* entry) NOT_CDS_RETURN;
616   static bool is_loaded(AOTCodeEntry* entry);
617   static AOTCodeEntry* find_code_entry(const methodHandle& method, uint comp_level);
618   static void preload_code(JavaThread* thread) NOT_CDS_RETURN;
619 
620   template<typename Function>
621   static void iterate(Function function) { // lambda enabled API
622     AOTCodeCache* cache = open_for_use();
623     if (cache != nullptr) {
624       ReadingMark rdmk;
625       if (rdmk.failed()) {
626         // Cache is closed, cannot touch anything.
627         return;
628       }
629 
630       uint count = cache->_load_header->entries_count();
631       uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
632       AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count);
633 
634       for (uint i = 0; i < count; i++) {
635         int index = search_entries[2*i + 1];
636         AOTCodeEntry* entry = &(load_entries[index]);
637         function(entry);
638       }
639     }
640   }
641 
642   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
643 
644   static void print_on(outputStream* st) NOT_CDS_RETURN;
645   static void print_statistics_on(outputStream* st) NOT_CDS_RETURN;
646   static void print_timers_on(outputStream* st) NOT_CDS_RETURN;
647   static void print_unused_entries_on(outputStream* st) NOT_CDS_RETURN;
648 };
649 
650 // Concurent AOT code reader
651 class AOTCodeReader {
652 private:
653   const AOTCodeCache* _cache;
654   const AOTCodeEntry* _entry;
655   const char*         _load_buffer; // Loaded cached code buffer
656   uint  _read_position;             // Position in _load_buffer
657   uint  read_position() const { return _read_position; }
658   void  set_read_position(uint pos);
659   const char* addr(uint offset) const { return _load_buffer + offset; }
660 
661   uint _compile_id;
662   uint _comp_level;
663   uint compile_id() const { return _compile_id; }
664   uint comp_level() const { return _comp_level; }
665 
666   bool _preload;             // Preloading code before method execution
667   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
668   void set_lookup_failed()     { _lookup_failed = true; }
669   void clear_lookup_failed()   { _lookup_failed = false; }
670   bool lookup_failed()   const { return _lookup_failed; }
671 

672 public:
673   AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry, CompileTask* task);
674 
675   AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
676 
677   // convenience method to convert offset in AOTCodeEntry data to its address
678   bool compile_nmethod(ciEnv* env, ciMethod* target, AbstractCompiler* compiler);
679   bool compile_blob(CodeBuffer* buffer, int* pc_offset);
680 
681   CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets);
682 
683   Klass* read_klass(const methodHandle& comp_method, bool shared);
684   Method* read_method(const methodHandle& comp_method, bool shared);
685 
686   DebugInformationRecorder* read_debug_info(OopRecorder* oop_recorder);
687 
688   oop read_oop(JavaThread* thread, const methodHandle& comp_method);
689   Metadata* read_metadata(const methodHandle& comp_method);
690   bool read_oops(OopRecorder* oop_recorder, ciMethod* target);
691   bool read_metadata(OopRecorder* oop_recorder, ciMethod* target);
692 
693   bool read_oop_metadata_list(JavaThread* thread, ciMethod* target, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list, OopRecorder* oop_recorder);
694   void apply_relocations(nmethod* nm, GrowableArray<Handle> &oop_list, GrowableArray<Metadata*> &metadata_list) NOT_CDS_RETURN;
695 
696   ImmutableOopMapSet* read_oop_map_set();
697 
698   void fix_relocations(CodeBlob* code_blob);
699 
700   void print_on(outputStream* st);
701 };
702 
703 // +1 for preload code
704 const int AOTCompLevel_count = CompLevel_count + 1; // 6 levels indexed from 0 to 5
705 
706 struct AOTCodeStats {
707 private:
708   struct {
709     uint _kind_cnt[AOTCodeEntry::Kind_count];
710     uint _nmethod_cnt[AOTCompLevel_count];
711     uint _clinit_barriers_cnt;
712   } ccstats; // ccstats = cached code stats
713 
714   void check_kind(uint kind) { assert(kind >= AOTCodeEntry::None && kind < AOTCodeEntry::Kind_count, "Invalid AOTCodeEntry kind %d", kind); }
715   void check_complevel(uint lvl) { assert(lvl >= CompLevel_none && lvl < AOTCompLevel_count, "Invalid compilation level %d", lvl); }
716 
717 public:
718   void inc_entry_cnt(uint kind) { check_kind(kind); ccstats._kind_cnt[kind] += 1; }
719   void inc_nmethod_cnt(uint lvl) { check_complevel(lvl); ccstats._nmethod_cnt[lvl] += 1; }
720   void inc_preload_cnt() { ccstats._nmethod_cnt[AOTCompLevel_count-1] += 1; }
721   void inc_clinit_barriers_cnt() { ccstats._clinit_barriers_cnt += 1; }
722 
723   void collect_entry_stats(AOTCodeEntry* entry) {
724     inc_entry_cnt(entry->kind());
725     if (entry->is_code()) {
726       entry->for_preload() ? inc_nmethod_cnt(AOTCompLevel_count-1)
727                            : inc_nmethod_cnt(entry->comp_level());
728       if (entry->has_clinit_barriers()) {
729         inc_clinit_barriers_cnt();
730       }
731     }
732   }
733 
734   uint entry_count(uint kind) { check_kind(kind); return ccstats._kind_cnt[kind]; }
735   uint nmethod_count(uint lvl) { check_complevel(lvl); return ccstats._nmethod_cnt[lvl]; }
736   uint preload_count() { return ccstats._nmethod_cnt[AOTCompLevel_count-1]; }
737   uint clinit_barriers_count() { return ccstats._clinit_barriers_cnt; }
738 
739   uint total_count() {
740     uint total = 0;
741     for (int kind = AOTCodeEntry::None; kind < AOTCodeEntry::Kind_count; kind++) {
742       total += ccstats._kind_cnt[kind];
743     }
744     return total;
745   }
746 
747   static AOTCodeStats add_aot_code_stats(AOTCodeStats stats1, AOTCodeStats stats2);
748 
749   // Runtime stats of the AOT code
750 private:
751   struct {
752     struct {
753       uint _loaded_cnt;
754       uint _invalidated_cnt;
755       uint _load_failed_cnt;
756     } _entry_kinds[AOTCodeEntry::Kind_count],
757       _nmethods[AOTCompLevel_count];
758   } rs; // rs = runtime stats
759 
760 public:
761   void inc_entry_loaded_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._loaded_cnt += 1; }
762   void inc_entry_invalidated_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._invalidated_cnt += 1; }
763   void inc_entry_load_failed_cnt(uint kind) { check_kind(kind); rs._entry_kinds[kind]._load_failed_cnt += 1; }
764 
765   void inc_nmethod_loaded_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._loaded_cnt += 1; }
766   void inc_nmethod_invalidated_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._invalidated_cnt += 1; }
767   void inc_nmethod_load_failed_cnt(uint lvl) { check_complevel(lvl); rs._nmethods[lvl]._load_failed_cnt += 1; }
768 
769   uint entry_loaded_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._loaded_cnt; }
770   uint entry_invalidated_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._invalidated_cnt; }
771   uint entry_load_failed_count(uint kind) { check_kind(kind); return rs._entry_kinds[kind]._load_failed_cnt; }
772 
773   uint nmethod_loaded_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._loaded_cnt; }
774   uint nmethod_invalidated_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._invalidated_cnt; }
775   uint nmethod_load_failed_count(uint lvl) { check_complevel(lvl); return rs._nmethods[lvl]._load_failed_cnt; }
776 
777   void inc_loaded_cnt(AOTCodeEntry* entry) {
778     inc_entry_loaded_cnt(entry->kind());
779     if (entry->is_code()) {
780       entry->for_preload() ? inc_nmethod_loaded_cnt(AOTCompLevel_count-1)
781                            : inc_nmethod_loaded_cnt(entry->comp_level());
782     }
783   }
784 
785   void inc_invalidated_cnt(AOTCodeEntry* entry) {
786     inc_entry_invalidated_cnt(entry->kind());
787     if (entry->is_code()) {
788       entry->for_preload() ? inc_nmethod_invalidated_cnt(AOTCompLevel_count-1)
789                            : inc_nmethod_invalidated_cnt(entry->comp_level());
790     }
791   }
792 
793   void inc_load_failed_cnt(AOTCodeEntry* entry) {
794     inc_entry_load_failed_cnt(entry->kind());
795     if (entry->is_code()) {
796       entry->for_preload() ? inc_nmethod_load_failed_cnt(AOTCompLevel_count-1)
797                            : inc_nmethod_load_failed_cnt(entry->comp_level());
798     }
799   }
800 
801   void collect_entry_runtime_stats(AOTCodeEntry* entry) {
802     if (entry->is_loaded()) {
803       inc_loaded_cnt(entry);
804     }
805     if (entry->not_entrant()) {
806       inc_invalidated_cnt(entry);
807     }
808     if (entry->load_fail()) {
809       inc_load_failed_cnt(entry);
810     }
811   }
812 
813   void collect_all_stats(AOTCodeEntry* entry) {
814     collect_entry_stats(entry);
815     collect_entry_runtime_stats(entry);
816   }
817 
818   AOTCodeStats() {
819     memset(this, 0, sizeof(AOTCodeStats));
820   }
821 };
822 
823 // code cache internal runtime constants area used by AOT code
824 class AOTRuntimeConstants {
825  friend class AOTCodeCache;
826  private:
827   uint _grain_shift;
828   uint _card_shift;
829   static address _field_addresses_list[];
830   static AOTRuntimeConstants _aot_runtime_constants;
831   // private constructor for unique singleton
832   AOTRuntimeConstants() { }
833   // private for use by friend class AOTCodeCache
834   static void initialize_from_runtime();
835  public:
836 #if INCLUDE_CDS
837   static bool contains(address adr) {
838     address base = (address)&_aot_runtime_constants;
839     address hi = base + sizeof(AOTRuntimeConstants);
840     return (base <= adr && adr < hi);
841   }
842   static address grain_shift_address() { return (address)&_aot_runtime_constants._grain_shift; }
843   static address card_shift_address() { return (address)&_aot_runtime_constants._card_shift; }
844   static address* field_addresses_list() {
845     return _field_addresses_list;
846   }
847 #else
848   static bool contains(address adr)      { return false; }
849   static address grain_shift_address()   { return nullptr; }
850   static address card_shift_address()    { return nullptr; }
851   static address* field_addresses_list() { return nullptr; }
852 #endif
853 };
854 
855 #endif // SHARE_CODE_AOTCODECACHE_HPP
< prev index next >