< 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 class AsmRemarks;






 42 class DbgStrings;



















 43 
 44 enum class vmIntrinsicID : int;
 45 enum CompLevel : signed char;
 46 
 47 #define DO_AOTCODEENTRY_KIND(Fn) \
 48   Fn(None) \
 49   Fn(Adapter) \

 50   Fn(SharedBlob) \
 51   Fn(C1Blob) \
 52   Fn(C2Blob) \

 53 
 54 // Descriptor of AOT Code Cache's entry
 55 class AOTCodeEntry {
 56 public:
 57   enum Kind : s1 {
 58 #define DECL_KIND_ENUM(kind) kind,
 59     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 60 #undef DECL_KIND_ENUM
 61     Kind_count
 62   };
 63 
 64 private:
 65   AOTCodeEntry* _next;


 66   Kind   _kind;
 67   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
 68   uint   _offset;      // Offset to entry
 69   uint   _size;        // Entry size
 70   uint   _name_offset; // Code blob name
 71   uint   _name_size;
 72   uint   _blob_offset; // Start of code in cache






 73   bool   _has_oop_maps;





 74   address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
 75 
 76 public:




























 77   AOTCodeEntry(Kind kind,         uint id,
 78                uint offset,       uint size,
 79                uint name_offset,  uint name_size,
 80                uint blob_offset,  bool has_oop_maps,
 81                address dumptime_content_start_addr) {




 82     _next         = nullptr;

 83     _kind         = kind;
 84     _id           = id;
 85     _offset       = offset;
 86     _size         = size;
 87     _name_offset  = name_offset;
 88     _name_size    = name_size;
 89     _blob_offset  = blob_offset;
 90     _has_oop_maps = has_oop_maps;

 91     _dumptime_content_start_addr = dumptime_content_start_addr;














 92   }

 93   void* operator new(size_t x, AOTCodeCache* cache);
 94   // Delete is a NOP
 95   void operator delete( void *ptr ) {}
 96 
 97   AOTCodeEntry* next()        const { return _next; }
 98   void set_next(AOTCodeEntry* next) { _next = next; }
 99 





100   Kind kind()         const { return _kind; }
101   uint id()           const { return _id; }
102 
103   uint offset()       const { return _offset; }
104   void set_offset(uint off) { _offset = off; }
105 
106   uint size()         const { return _size; }
107   uint name_offset()  const { return _name_offset; }
108   uint name_size()    const { return _name_size; }
109   uint blob_offset()  const { return _blob_offset; }


110   bool has_oop_maps() const { return _has_oop_maps; }
111   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }



















112 
113   static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; }
114   static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; }
115   static bool is_adapter(Kind kind) { return kind == Adapter; }

116 };
117 
118 // Addresses of stubs, blobs and runtime finctions called from compiled code.
119 class AOTCodeAddressTable : public CHeapObj<mtCode> {
120 private:
121   address* _extrs_addr;
122   address* _stubs_addr;
123   address* _shared_blobs_addr;
124   address* _C1_blobs_addr;

125   uint     _extrs_length;
126   uint     _stubs_length;
127   uint     _shared_blobs_length;
128   uint     _C1_blobs_length;

129 
130   bool _extrs_complete;
131   bool _early_stubs_complete;
132   bool _shared_blobs_complete;
133   bool _early_c1_complete;


134   bool _complete;
135 
136 public:
137   AOTCodeAddressTable() :
138     _extrs_addr(nullptr),

139     _shared_blobs_addr(nullptr),
140     _C1_blobs_addr(nullptr),

141     _extrs_length(0),
142     _stubs_length(0),
143     _shared_blobs_length(0),
144     _C1_blobs_length(0),

145     _extrs_complete(false),
146     _early_stubs_complete(false),
147     _shared_blobs_complete(false),
148     _early_c1_complete(false),


149     _complete(false)
150   { }
151   ~AOTCodeAddressTable();
152   void init_extrs();
153   void init_early_stubs();
154   void init_shared_blobs();

155   void init_early_c1();


156   const char* add_C_string(const char* str);
157   int  id_for_C_string(address str);
158   address address_for_C_string(int idx);
159   int  id_for_address(address addr, RelocIterator iter, CodeBlob* code_blob);
160   address address_for_id(int id);






















161 };
162 
163 class AOTCodeCache : public CHeapObj<mtCode> {
164 
165 // Classes used to describe AOT code cache.
166 protected:
167   class Config {

168     address _compressedOopBase;

169     uint _compressedOopShift;
170     uint _compressedKlassShift;
171     uint _contendedPaddingWidth;
172     uint _objectAlignment;
173     uint _gc;




174     enum Flags {
175       none                     = 0,
176       debugVM                  = 1,
177       compressedOops           = 2,
178       compressedClassPointers  = 4,
179       useTLAB                  = 8,
180       systemClassAssertions    = 16,
181       userClassAssertions      = 32,
182       enableContendedPadding   = 64,
183       restrictContendedPadding = 128

184     };
185     uint _flags;
186 
187   public:
188     void record();
189     bool verify() const;
190   };
191 
192   class Header : public CHeapObj<mtCode> {
193   private:

194     enum {
195       AOT_CODE_VERSION = 1
196     };
197     uint   _version;         // AOT code version (should match when reading code cache)
198     uint   _cache_size;      // cache size in bytes
199     uint   _strings_count;   // number of recorded C strings
200     uint   _strings_offset;  // offset to recorded C strings
201     uint   _entries_count;   // number of recorded entries
202     uint   _entries_offset;  // offset of AOTCodeEntry array describing entries


203     uint   _adapters_count;
204     uint   _shared_blobs_count;
205     uint   _C1_blobs_count;
206     uint   _C2_blobs_count;

207     Config _config;
208 
209 public:
210     void init(uint cache_size,
211               uint strings_count,  uint strings_offset,
212               uint entries_count,  uint entries_offset,

213               uint adapters_count, uint shared_blobs_count,
214               uint C1_blobs_count, uint C2_blobs_count) {
215       _version        = AOT_CODE_VERSION;
216       _cache_size     = cache_size;
217       _strings_count  = strings_count;
218       _strings_offset = strings_offset;
219       _entries_count  = entries_count;
220       _entries_offset = entries_offset;


221       _adapters_count = adapters_count;
222       _shared_blobs_count = shared_blobs_count;
223       _C1_blobs_count = C1_blobs_count;
224       _C2_blobs_count = C2_blobs_count;


225       _config.record();
226     }
227 
228 
229     uint cache_size()     const { return _cache_size; }
230     uint strings_count()  const { return _strings_count; }
231     uint strings_offset() const { return _strings_offset; }
232     uint entries_count()  const { return _entries_count; }
233     uint entries_offset() const { return _entries_offset; }


234     uint adapters_count() const { return _adapters_count; }
235     uint shared_blobs_count()    const { return _shared_blobs_count; }
236     uint C1_blobs_count() const { return _C1_blobs_count; }
237     uint C2_blobs_count() const { return _C2_blobs_count; }
238 
239     bool verify_config(uint load_size)  const;
240     bool verify_vm_config() const { // Called after Universe initialized







241       return _config.verify();
242     }
243   };
244 
245 // Continue with AOTCodeCache class definition.
246 private:
247   Header* _load_header;
248   char*   _load_buffer;    // Aligned buffer for loading cached code
249   char*   _store_buffer;   // Aligned buffer for storing cached code
250   char*   _C_store_buffer; // Original unaligned buffer
251 
252   uint   _write_position;  // Position in _store_buffer
253   uint   _load_size;       // Used when reading cache
254   uint   _store_size;      // Used when writing cache
255   bool   _for_use;         // AOT cache is open for using AOT code
256   bool   _for_dump;        // AOT cache is open for dumping AOT code
257   bool   _closing;         // Closing cache file
258   bool   _failed;          // Failed read/write to/from cache (cache is broken?)
259   bool   _lookup_failed;   // Failed to lookup for info (skip only this code load)
260 



261   AOTCodeAddressTable* _table;
262 
263   AOTCodeEntry* _load_entries;   // Used when reading cache
264   uint*         _search_entries; // sorted by ID table [id, index]
265   AOTCodeEntry* _store_entries;  // Used when writing cache
266   const char*   _C_strings_buf;  // Loaded buffer for _C_strings[] table
267   uint          _store_entries_cnt;
268 





269   static AOTCodeCache* open_for_use();
270   static AOTCodeCache* open_for_dump();
271 
272   bool set_write_position(uint pos);
273   bool align_write();

274   address reserve_bytes(uint nbytes);
275   uint write_bytes(const void* buffer, uint nbytes);
276   const char* addr(uint offset) const { return _load_buffer + offset; }
277   static AOTCodeAddressTable* addr_table() {
278     return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
279   }
280 
281   void set_lookup_failed()     { _lookup_failed = true; }
282   void clear_lookup_failed()   { _lookup_failed = false; }
283   bool lookup_failed()   const { return _lookup_failed; }
284 





















285 public:
286   AOTCodeCache(bool is_dumping, bool is_using);
287   ~AOTCodeCache();
288 
289   const char* cache_buffer() const { return _load_buffer; }
290   bool failed() const { return _failed; }
291   void set_failed()   { _failed = true; }
292 

293   static uint max_aot_code_size();
294 
295   uint load_size() const { return _load_size; }
296   uint write_position() const { return _write_position; }
297 
298   void load_strings();
299   int store_strings();
300 
301   static void init_extrs_table() NOT_CDS_RETURN;
302   static void init_early_stubs_table() NOT_CDS_RETURN;
303   static void init_shared_blobs_table() NOT_CDS_RETURN;

304   static void init_early_c1_table() NOT_CDS_RETURN;


305 
306   address address_for_C_string(int idx) const { return _table->address_for_C_string(idx); }
307   address address_for_id(int id) const { return _table->address_for_id(id); }
308 
309   bool for_use()  const { return _for_use  && !_failed; }
310   bool for_dump() const { return _for_dump && !_failed; }
311 
312   bool closing()          const { return _closing; }
313 
314   AOTCodeEntry* add_entry() {
315     _store_entries_cnt++;
316     _store_entries -= 1;
317     return _store_entries;
318   }

319 
320   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id);

321 
322   bool finish_write();
323 
324   bool write_relocations(CodeBlob& code_blob);









325   bool write_oop_map_set(CodeBlob& cb);











326 #ifndef PRODUCT
327   bool write_asm_remarks(CodeBlob& cb);
328   bool write_dbg_strings(CodeBlob& cb);
329 #endif // PRODUCT
330 
331   static bool store_code_blob(CodeBlob& blob,
332                               AOTCodeEntry::Kind entry_kind,
333                               uint id, const char* name,
334                               int entry_offset_count = 0,
335                               int* entry_offsets = nullptr) NOT_CDS_RETURN_(false);
336 
337   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
338                                   uint id, const char* name,
339                                   int entry_offset_count = 0,
340                                   int* entry_offsets = nullptr) NOT_CDS_RETURN_(nullptr);
341 



342   static uint store_entries_cnt() {
343     if (is_on_for_dump()) {
344       return cache()->_store_entries_cnt;
345     }
346     return -1;
347   }
348 
349 // Static access
350 
351 private:
352   static AOTCodeCache*  _cache;

353 
354   static bool open_cache(bool is_dumping, bool is_using);
355   static bool verify_vm_config() {
356     if (is_on_for_use()) {
357       return _cache->_load_header->verify_vm_config();

358     }
359     return true;
360   }
361 public:
362   static AOTCodeCache* cache() { return _cache; }
363   static void initialize() NOT_CDS_RETURN;
364   static void init2() NOT_CDS_RETURN;
365   static void close() NOT_CDS_RETURN;
366   static bool is_on() CDS_ONLY({ return _cache != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
367   static bool is_on_for_use()  { return is_on() && _cache->for_use(); }
368   static bool is_on_for_dump() { return is_on() && _cache->for_dump(); }
369 
370   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
371   static bool is_using_adapter() NOT_CDS_RETURN_(false);
372 
373   static bool is_dumping_stub() NOT_CDS_RETURN_(false);


374   static bool is_using_stub() NOT_CDS_RETURN_(false);




































375 
376   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
377 
378   static void print_on(outputStream* st) NOT_CDS_RETURN;



379 };
380 
381 // Concurent AOT code reader
382 class AOTCodeReader {
383 private:
384   const AOTCodeCache*  _cache;
385   const AOTCodeEntry*  _entry;
386   const char*          _load_buffer; // Loaded cached code buffer
387   uint  _read_position;              // Position in _load_buffer
388   uint  read_position() const { return _read_position; }
389   void  set_read_position(uint pos);
390   const char* addr(uint offset) const { return _load_buffer + offset; }
391 






392   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
393   void set_lookup_failed()     { _lookup_failed = true; }
394   void clear_lookup_failed()   { _lookup_failed = false; }
395   bool lookup_failed()   const { return _lookup_failed; }
396 
397   AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
398 public:
399   AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);





400 
401   CodeBlob* compile_code_blob(const char* name, int entry_offset_count, int* entry_offsets);
402 











403   ImmutableOopMapSet* read_oop_map_set();
404 
405   void fix_relocations(CodeBlob* code_blob);
406 #ifndef PRODUCT
407   void read_asm_remarks(AsmRemarks& asm_remarks);
408   void read_dbg_strings(DbgStrings& dbg_strings);
409 #endif // PRODUCT


























































































































































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

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

397     uint cache_size()     const { return _cache_size; }
398     uint strings_count()  const { return _strings_count; }
399     uint strings_offset() const { return _strings_offset; }
400     uint entries_count()  const { return _entries_count; }
401     uint entries_offset() const { return _entries_offset; }
402     uint preload_entries_count()  const { return _preload_entries_count; }
403     uint preload_entries_offset() const { return _preload_entries_offset; }
404     uint adapters_count() const { return _adapters_count; }
405     uint shared_blobs_count()    const { return _shared_blobs_count; }
406     uint C1_blobs_count() const { return _C1_blobs_count; }
407     uint C2_blobs_count() const { return _C2_blobs_count; }
408     uint stubs_count()    const { return _stubs_count; }
409     uint nmethods_count() const { return _entries_count
410                                        - _stubs_count
411                                        - _shared_blobs_count
412                                        - _C1_blobs_count
413                                        - _C2_blobs_count
414                                        - _adapters_count; }
415 
416     bool verify(uint load_size)  const;
417     bool verify_config() const { // Called after Universe initialized
418       return _config.verify();
419     }
420   };
421 
422 // Continue with AOTCodeCache class definition.
423 private:
424   Header* _load_header;
425   char*   _load_buffer;    // Aligned buffer for loading cached code
426   char*   _store_buffer;   // Aligned buffer for storing cached code
427   char*   _C_store_buffer; // Original unaligned buffer
428 
429   uint   _write_position;  // Position in _store_buffer
430   uint   _load_size;       // Used when reading cache
431   uint   _store_size;      // Used when writing cache
432   bool   _for_use;         // AOT cache is open for using AOT code
433   bool   _for_dump;        // AOT cache is open for dumping AOT code
434   bool   _closing;         // Closing cache file
435   bool   _failed;          // Failed read/write to/from cache (cache is broken?)
436   bool   _lookup_failed;   // Failed to lookup for info (skip only this code load)
437 
438   bool   _for_preload;         // Code for preload
439   bool   _has_clinit_barriers; // Code with clinit barriers
440 
441   AOTCodeAddressTable* _table;
442 
443   AOTCodeEntry* _load_entries;   // Used when reading cache
444   uint*         _search_entries; // sorted by ID table [id, index]
445   AOTCodeEntry* _store_entries;  // Used when writing cache
446   const char*   _C_strings_buf;  // Loaded buffer for _C_strings[] table
447   uint          _store_entries_cnt;
448 
449   uint _compile_id;
450   uint _comp_level;
451   uint compile_id() const { return _compile_id; }
452   uint comp_level() const { return _comp_level; }
453 
454   static AOTCodeCache* open_for_use();
455   static AOTCodeCache* open_for_dump();
456 
457   bool set_write_position(uint pos);
458   bool align_write();
459 
460   address reserve_bytes(uint nbytes);
461   uint write_bytes(const void* buffer, uint nbytes);
462   const char* addr(uint offset) const { return _load_buffer + offset; }
463   static AOTCodeAddressTable* addr_table() {
464     return is_on() && (cache()->_table != nullptr) ? cache()->_table : nullptr;
465   }
466 
467   void set_lookup_failed()     { _lookup_failed = true; }
468   void clear_lookup_failed()   { _lookup_failed = false; }
469   bool lookup_failed()   const { return _lookup_failed; }
470 
471   AOTCodeEntry* write_nmethod(nmethod* nm, bool for_preload);
472 
473   // States:
474   //   S >= 0: allow new readers, S readers are currently active
475   //   S <  0: no new readers are allowed; (-S-1) readers are currently active
476   //     (special case: S = -1 means no readers are active, and would never be active again)
477   static volatile int _nmethod_readers;
478 
479   static void wait_for_no_nmethod_readers();
480 
481   class ReadingMark {
482   private:
483     bool _failed;
484   public:
485     ReadingMark();
486     ~ReadingMark();
487     bool failed() {
488       return _failed;
489     }
490   };
491 
492 public:
493   AOTCodeCache(bool is_dumping, bool is_using);
494   ~AOTCodeCache();
495 
496   const char* cache_buffer() const { return _load_buffer; }
497   bool failed() const { return _failed; }
498   void set_failed()   { _failed = true; }
499 
500   static bool is_address_in_aot_cache(address p) NOT_CDS_RETURN_(false);
501   static uint max_aot_code_size();
502 
503   uint load_size() const { return _load_size; }
504   uint write_position() const { return _write_position; }
505 
506   void load_strings();
507   int store_strings();
508 

509   static void init_early_stubs_table() NOT_CDS_RETURN;
510   static void init_shared_blobs_table() NOT_CDS_RETURN;
511   static void init_stubs_table() NOT_CDS_RETURN;
512   static void init_early_c1_table() NOT_CDS_RETURN;
513   static void init_c1_table() NOT_CDS_RETURN;
514   static void init_c2_table() NOT_CDS_RETURN;
515 
516   address address_for_C_string(int idx) const { return _table->address_for_C_string(idx); }
517   address address_for_id(int id) const { return _table->address_for_id(id); }
518 
519   bool for_use()  const { return _for_use  && !_failed; }
520   bool for_dump() const { return _for_dump && !_failed; }
521 
522   bool closing()          const { return _closing; }
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);
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_relocations(CodeBlob& code_blob, GrowableArray<Handle>* oop_list = nullptr, GrowableArray<Metadata*>* metadata_list = nullptr);
545 
546   bool write_oop_map_set(CodeBlob& cb);
547   bool write_nmethod_reloc_immediates(GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
548 
549   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
550   Metadata* read_metadata(const methodHandle& comp_method);
551 
552   bool write_oop(jobject& jo);
553   bool write_oop(oop obj);
554   bool write_metadata(Metadata* m);
555   bool write_oops(nmethod* nm);
556   bool write_metadata(nmethod* nm);
557 
558 #ifndef PRODUCT
559   bool write_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table);
560   bool write_dbg_strings(DbgStrings& dbg_strings, bool use_string_table);
561 #endif // PRODUCT
562 
563   static bool store_code_blob(CodeBlob& blob,
564                               AOTCodeEntry::Kind entry_kind,
565                               uint id, const char* name,
566                               int entry_offset_count = 0,
567                               int* entry_offsets = nullptr) NOT_CDS_RETURN_(false);
568 
569   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
570                                   uint id, const char* name,
571                                   int entry_offset_count = 0,
572                                   int* entry_offsets = nullptr) NOT_CDS_RETURN_(nullptr);
573 
574   static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level) NOT_CDS_RETURN_(false);
575   static AOTCodeEntry* store_nmethod(nmethod* nm, AbstractCompiler* compiler, bool for_preload) NOT_CDS_RETURN_(nullptr);
576 
577   static uint store_entries_cnt() {
578     if (is_on_for_dump()) {
579       return cache()->_store_entries_cnt;
580     }
581     return -1;
582   }
583 
584 // Static access
585 
586 private:
587   static AOTCodeCache* _cache;
588   DEBUG_ONLY( static bool _passed_init2; )
589 
590   static bool open_cache(bool is_dumping, bool is_using);
591 
592   bool verify_config_on_use() {
593     if (for_use()) {
594       return _load_header->verify_config();
595     }
596     return true;
597   }
598 public:
599   static AOTCodeCache* cache() { assert(_passed_init2, "Too early to ask"); return _cache; }
600   static void initialize() NOT_CDS_RETURN;
601   static void init2() NOT_CDS_RETURN;
602   static void close() NOT_CDS_RETURN;
603   static bool is_on() CDS_ONLY({ return cache() != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
604   static bool is_C3_on() NOT_CDS_RETURN_(false);
605   static bool is_code_load_thread_on() NOT_CDS_RETURN_(false);
606   static bool is_on_for_use()  CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
607   static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
608   static bool is_dumping_code() NOT_CDS_RETURN_(false);

609   static bool is_dumping_stub() NOT_CDS_RETURN_(false);
610   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
611   static bool is_using_code() NOT_CDS_RETURN_(false);
612   static bool is_using_stub() NOT_CDS_RETURN_(false);
613   static bool is_using_adapter() NOT_CDS_RETURN_(false);
614   static void enable_caching() NOT_CDS_RETURN;
615   static void disable_caching() NOT_CDS_RETURN;
616   static bool is_caching_enabled() NOT_CDS_RETURN_(false);
617 
618   // It is used before AOTCodeCache is initialized.
619   static bool maybe_dumping_code() NOT_CDS_RETURN_(false);
620 
621   static bool gen_preload_code(ciMethod* m, int entry_bci) NOT_CDS_RETURN_(false);
622   static bool allow_const_field(ciConstant& value) NOT_CDS_RETURN_(false);
623   static void invalidate(AOTCodeEntry* entry) NOT_CDS_RETURN;
624   static bool is_loaded(AOTCodeEntry* entry);
625   static AOTCodeEntry* find_code_entry(const methodHandle& method, uint comp_level);
626   static void preload_code(JavaThread* thread) NOT_CDS_RETURN;
627 
628   template<typename Function>
629   static void iterate(Function function) { // lambda enabled API
630     AOTCodeCache* cache = open_for_use();
631     if (cache != nullptr) {
632       ReadingMark rdmk;
633       if (rdmk.failed()) {
634         // Cache is closed, cannot touch anything.
635         return;
636       }
637 
638       uint count = cache->_load_header->entries_count();
639       uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
640       AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count);
641 
642       for (uint i = 0; i < count; i++) {
643         int index = search_entries[2*i + 1];
644         AOTCodeEntry* entry = &(load_entries[index]);
645         function(entry);
646       }
647     }
648   }
649 
650   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
651 
652   static void print_on(outputStream* st) NOT_CDS_RETURN;
653   static void print_statistics_on(outputStream* st) NOT_CDS_RETURN;
654   static void print_timers_on(outputStream* st) NOT_CDS_RETURN;
655   static void print_unused_entries_on(outputStream* st) NOT_CDS_RETURN;
656 };
657 
658 // Concurent AOT code reader
659 class AOTCodeReader {
660 private:
661   const AOTCodeCache*  _cache;
662   const AOTCodeEntry*  _entry;
663   const char*          _load_buffer; // Loaded cached code buffer
664   uint  _read_position;              // Position in _load_buffer
665   uint  read_position() const { return _read_position; }
666   void  set_read_position(uint pos);
667   const char* addr(uint offset) const { return _load_buffer + offset; }
668 
669   uint _compile_id;
670   uint _comp_level;
671   uint compile_id() const { return _compile_id; }
672   uint comp_level() const { return _comp_level; }
673 
674   bool _preload;             // Preloading code before method execution
675   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
676   void set_lookup_failed()     { _lookup_failed = true; }
677   void clear_lookup_failed()   { _lookup_failed = false; }
678   bool lookup_failed()   const { return _lookup_failed; }
679 

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