< prev index next >

src/hotspot/share/code/aotCodeCache.hpp

Print this page

  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 "runtime/stubInfo.hpp"



 29 
 30 /*
 31  * AOT Code Cache collects code from Code Cache and corresponding metadata
 32  * during application training run.
 33  * In following "production" runs this code and data can be loaded into
 34  * Code Cache skipping its generation.


 35  */
 36 
 37 class CodeBuffer;
 38 class RelocIterator;
 39 class AOTCodeCache;
 40 class AdapterBlob;
 41 class ExceptionBlob;
 42 class ImmutableOopMapSet;
 43 class AsmRemarks;






 44 class DbgStrings;



















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

 52   Fn(SharedBlob) \
 53   Fn(C1Blob) \
 54   Fn(C2Blob) \

 55 
 56 // Descriptor of AOT Code Cache's entry
 57 class AOTCodeEntry {

 58 public:
 59   enum Kind : s1 {
 60 #define DECL_KIND_ENUM(kind) kind,
 61     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 62 #undef DECL_KIND_ENUM
 63     Kind_count
 64   };
 65 
 66 private:
 67   AOTCodeEntry* _next;
 68   Kind   _kind;
 69   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or name's hash for nmethod
 70   uint   _offset;      // Offset to entry
 71   uint   _size;        // Entry size
 72   uint   _name_offset; // Code blob name
 73   uint   _name_size;
 74   uint   _blob_offset; // Start of code in cache





 75   bool   _has_oop_maps;





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


























 79   AOTCodeEntry(Kind kind,         uint id,
 80                uint offset,       uint size,
 81                uint name_offset,  uint name_size,
 82                uint blob_offset,  bool has_oop_maps,
 83                address dumptime_content_start_addr) {
 84     _next         = nullptr;



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

 93     _dumptime_content_start_addr = dumptime_content_start_addr;














 94   }

 95   void* operator new(size_t x, AOTCodeCache* cache);
 96   // Delete is a NOP
 97   void operator delete( void *ptr ) {}
 98 
 99   AOTCodeEntry* next()        const { return _next; }
100   void set_next(AOTCodeEntry* next) { _next = next; }
101 
102   Kind kind()         const { return _kind; }
103   uint id()           const { return _id; }
104 
105   uint offset()       const { return _offset; }
106   void set_offset(uint off) { _offset = off; }
107 
108   uint size()         const { return _size; }
109   uint name_offset()  const { return _name_offset; }
110   uint name_size()    const { return _name_size; }
111   uint blob_offset()  const { return _blob_offset; }


112   bool has_oop_maps() const { return _has_oop_maps; }
113   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }



















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

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

127   uint     _extrs_length;
128   uint     _stubs_length;
129   uint     _shared_blobs_length;
130   uint     _C1_blobs_length;

131 
132   bool _extrs_complete;
133   bool _early_stubs_complete;
134   bool _shared_blobs_complete;
135   bool _early_c1_complete;


136   bool _complete;
137 
138 public:
139   AOTCodeAddressTable() :
140     _extrs_addr(nullptr),
141     _stubs_addr(nullptr),
142     _shared_blobs_addr(nullptr),
143     _C1_blobs_addr(nullptr),

144     _extrs_length(0),
145     _stubs_length(0),
146     _shared_blobs_length(0),
147     _C1_blobs_length(0),

148     _extrs_complete(false),
149     _early_stubs_complete(false),
150     _shared_blobs_complete(false),
151     _early_c1_complete(false),


152     _complete(false)
153   { }
154   ~AOTCodeAddressTable();
155   void init_extrs();
156   void init_early_stubs();
157   void init_shared_blobs();

158   void init_early_c1();


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






















164 };
165 


166 class AOTCodeCache : public CHeapObj<mtCode> {
167 
168 // Classes used to describe AOT code cache.
169 protected:
170   class Config {

171     address _compressedOopBase;

172     uint _compressedOopShift;
173     uint _compressedKlassShift;
174     uint _contendedPaddingWidth;


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

186     };
187     uint _flags;

188 
189   public:
190     void record();
191     bool verify() const;
192   };
193 
194   class Header : public CHeapObj<mtCode> {
195   private:

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

204     uint   _entries_offset;  // offset of AOTCodeEntry array describing entries


205     uint   _adapters_count;
206     uint   _shared_blobs_count;
207     uint   _C1_blobs_count;
208     uint   _C2_blobs_count;
209     Config _config;

210 
211   public:
212     void init(uint cache_size,
213               uint strings_count,  uint strings_offset,
214               uint entries_count,  uint entries_offset,

215               uint adapters_count, uint shared_blobs_count,
216               uint C1_blobs_count, uint C2_blobs_count) {

217       _version        = AOT_CODE_VERSION;
218       _cache_size     = cache_size;
219       _strings_count  = strings_count;
220       _strings_offset = strings_offset;
221       _entries_count  = entries_count;

222       _entries_offset = entries_offset;


223       _adapters_count = adapters_count;
224       _shared_blobs_count = shared_blobs_count;
225       _C1_blobs_count = C1_blobs_count;
226       _C2_blobs_count = C2_blobs_count;
227       _config.record();
228     }
229 


230 
231     uint cache_size()     const { return _cache_size; }
232     uint strings_count()  const { return _strings_count; }
233     uint strings_offset() const { return _strings_offset; }
234     uint entries_count()  const { return _entries_count; }

235     uint entries_offset() const { return _entries_offset; }


236     uint adapters_count() const { return _adapters_count; }
237     uint shared_blobs_count()    const { return _shared_blobs_count; }
238     uint C1_blobs_count() const { return _C1_blobs_count; }
239     uint C2_blobs_count() const { return _C2_blobs_count; }








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



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





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

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





















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

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

305   static void init_early_c1_table() NOT_CDS_RETURN;


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

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



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









326   bool write_oop_map_set(CodeBlob& cb);











327 #ifndef PRODUCT
328   bool write_asm_remarks(CodeBlob& cb);
329   bool write_dbg_strings(CodeBlob& cb);
330 #endif // PRODUCT
331 
332   // save and restore API for non-enumerable code blobs
333   static bool store_code_blob(CodeBlob& blob,
334                               AOTCodeEntry::Kind entry_kind,
335                               uint id, const char* name) NOT_CDS_RETURN_(false);
336 
337   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
338                                   uint id, const char* name) NOT_CDS_RETURN_(nullptr);
339 



340   // save and restore API for enumerable code blobs
341   static bool store_code_blob(CodeBlob& blob,
342                               AOTCodeEntry::Kind entry_kind,
343                               BlobId id) NOT_CDS_RETURN_(false);
344 
345   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
346                                   BlobId id) NOT_CDS_RETURN_(nullptr);
347 
348   static uint store_entries_cnt() {
349     if (is_on_for_dump()) {
350       return cache()->_store_entries_cnt;
351     }
352     return -1;
353   }
354 
355 // Static access
356 
357 private:
358   static AOTCodeCache* _cache;
359   DEBUG_ONLY( static bool _passed_init2; )
360 
361   static bool open_cache(bool is_dumping, bool is_using);
362   bool verify_config() {

363     if (for_use()) {
364       return _load_header->verify_config();
365     }
366     return true;
367   }
368 public:
369   static AOTCodeCache* cache() { assert(_passed_init2, "Too early to ask"); return _cache; }
370   static void initialize() NOT_CDS_RETURN;
371   static void init2() NOT_CDS_RETURN;
372   static void close() NOT_CDS_RETURN;
373   static bool is_on() CDS_ONLY({ return cache() != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);

374   static bool is_on_for_use()  CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
375   static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);

376   static bool is_dumping_stub() NOT_CDS_RETURN_(false);
377   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);

378   static bool is_using_stub() NOT_CDS_RETURN_(false);
379   static bool is_using_adapter() NOT_CDS_RETURN_(false);
380   static void enable_caching() NOT_CDS_RETURN;
381   static void disable_caching() NOT_CDS_RETURN;
382   static bool is_caching_enabled() NOT_CDS_RETURN_(false);
383 






























384   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
385 
386   static void print_on(outputStream* st) NOT_CDS_RETURN;



387 };
388 
389 // Concurent AOT code reader
390 class AOTCodeReader {
391 private:
392   const AOTCodeCache*  _cache;
393   const AOTCodeEntry*  _entry;
394   const char*          _load_buffer; // Loaded cached code buffer
395   uint  _read_position;              // Position in _load_buffer
396   uint  read_position() const { return _read_position; }
397   void  set_read_position(uint pos);
398   const char* addr(uint offset) const { return _load_buffer + offset; }
399 






400   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
401   void set_lookup_failed()     { _lookup_failed = true; }
402   void clear_lookup_failed()   { _lookup_failed = false; }
403   bool lookup_failed()   const { return _lookup_failed; }
404 
405   AOTCodeEntry* aot_code_entry() { return (AOTCodeEntry*)_entry; }
406 public:
407   AOTCodeReader(AOTCodeCache* cache, AOTCodeEntry* entry);





408 
409   CodeBlob* compile_code_blob(const char* name);
410 











411   ImmutableOopMapSet* read_oop_map_set();
412 
413   void fix_relocations(CodeBlob* code_blob);
414 #ifndef PRODUCT
415   void read_asm_remarks(AsmRemarks& asm_remarks);
416   void read_dbg_strings(DbgStrings& dbg_strings);
417 #endif // PRODUCT


























































































































































418 };
419 
420 #endif // SHARE_CODE_AOTCODECACHE_HPP

  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 "runtime/stubInfo.hpp"
 33 #include "runtime/vm_version.hpp"
 34 #include "utilities/exceptions.hpp"
 35 #include "utilities/sizes.hpp"
 36 
 37 /*
 38  * AOT Code Cache collects code from Code Cache and corresponding metadata
 39  * during application training run.
 40  * In following "production" runs this code and data can be loaded into
 41  * Code Cache skipping its generation.
 42  * Additionaly special compiled code "preload" is generated with class initialization
 43  * barriers which can be called on first Java method invocation.
 44  */
 45 
 46 class AbstractCompiler;

 47 class AOTCodeCache;



 48 class AsmRemarks;
 49 class ciConstant;
 50 class ciEnv;
 51 class ciMethod;
 52 class CodeBlob;
 53 class CodeOffsets;
 54 class CompileTask;
 55 class DbgStrings;
 56 class DebugInformationRecorder;
 57 class Dependencies;
 58 class ExceptionTable;
 59 class ExceptionHandlerTable;
 60 template<typename E>
 61 class GrowableArray;
 62 class ImmutableOopMapSet;
 63 class ImplicitExceptionTable;
 64 class JavaThread;
 65 class Klass;
 66 class methodHandle;
 67 class Metadata;
 68 class Method;
 69 class nmethod;
 70 class OopMapSet;
 71 class OopRecorder;
 72 class outputStream;
 73 class RelocIterator;
 74 class StubCodeGenerator;
 75 
 76 enum class vmIntrinsicID : int;

 77 
 78 #define DO_AOTCODEENTRY_KIND(Fn) \
 79   Fn(None) \
 80   Fn(Adapter) \
 81   Fn(Stub) \
 82   Fn(SharedBlob) \
 83   Fn(C1Blob) \
 84   Fn(C2Blob) \
 85   Fn(Nmethod) \
 86 
 87 // Descriptor of AOT Code Cache's entry
 88 class AOTCodeEntry {
 89   friend class VMStructs;
 90 public:
 91   enum Kind : s1 {
 92 #define DECL_KIND_ENUM(kind) kind,
 93     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 94 #undef DECL_KIND_ENUM
 95     Kind_count
 96   };
 97 
 98 private:

 99   Kind   _kind;
100   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or Method's offset in AOTCache for nmethod
101   uint   _offset;      // Offset to entry
102   uint   _size;        // Entry size
103   uint   _name_offset; // Method's or intrinsic name
104   uint   _name_size;
105   uint   _num_inlined_bytecodes;
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     _kind         = kind;
126     _id           = id;
127     _offset       = offset;
128     _size         = size;
129     _name_offset  = name_offset;
130     _name_size    = name_size;
131     _code_offset  = code_offset;
132     _code_size    = code_size;
133 
134     _dumptime_content_start_addr = nullptr;
135     _num_inlined_bytecodes = 0;
136     _comp_level   = 0;
137     _comp_id      = 0;
138     _has_oop_maps = false; // unused here
139     _has_clinit_barriers = false;
140     _for_preload  = false;
141     _loaded       = false;
142     _not_entrant  = false;
143     _load_fail    = false;
144   }
145 
146   AOTCodeEntry(Kind kind,         uint id,
147                uint offset,       uint size,
148                uint name_offset,  uint name_size,
149                uint blob_offset,  bool has_oop_maps,
150                address dumptime_content_start_addr,
151                uint comp_level = 0,
152                uint comp_id = 0,
153                bool has_clinit_barriers = false,
154                bool for_preload = false) {
155     _kind         = kind;
156     _id           = id;
157     _offset       = offset;
158     _size         = size;
159     _name_offset  = name_offset;
160     _name_size    = name_size;
161     _code_offset  = blob_offset;
162     _code_size    = 0; // unused
163 
164     _dumptime_content_start_addr = dumptime_content_start_addr;
165     _num_inlined_bytecodes = 0;
166 
167     _comp_level   = comp_level;
168     _comp_id      = comp_id;
169     _has_oop_maps = has_oop_maps;
170     _has_clinit_barriers = has_clinit_barriers;
171     _for_preload  = for_preload;
172     _loaded       = false;
173     _not_entrant  = false;
174     _load_fail    = false;
175 
176     _loaded       = false;
177     _not_entrant  = false;
178     _load_fail    = false;
179   }
180 
181   void* operator new(size_t x, AOTCodeCache* cache);
182   // Delete is a NOP
183   void operator delete( void *ptr ) {}
184 
185   Method* method();

186 
187   Kind kind()         const { return _kind; }
188   uint id()           const { return _id; }
189 
190   uint offset()       const { return _offset; }
191   void set_offset(uint off) { _offset = off; }
192 
193   uint size()         const { return _size; }
194   uint name_offset()  const { return _name_offset; }
195   uint name_size()    const { return _name_size; }
196   uint code_offset()  const { return _code_offset; }
197   uint code_size()    const { return _code_size; }
198 
199   bool has_oop_maps() const { return _has_oop_maps; }
200   address dumptime_content_start_addr() const { return _dumptime_content_start_addr; }
201   uint num_inlined_bytecodes() const { return _num_inlined_bytecodes; }
202   void set_inlined_bytecodes(int bytes) { _num_inlined_bytecodes = bytes; }
203 
204   uint comp_level()   const { return _comp_level; }
205   uint comp_id()      const { return _comp_id; }
206 
207   bool has_clinit_barriers() const { return _has_clinit_barriers; }
208   bool for_preload()  const { return _for_preload; }
209   bool is_loaded()    const { return _loaded; }
210   void set_loaded()         { _loaded = true; }
211 
212   bool not_entrant()  const { return _not_entrant; }
213   void set_not_entrant()    { _not_entrant = true; }
214   void set_entrant()        { _not_entrant = false; }
215 
216   bool load_fail()  const { return _load_fail; }
217   void set_load_fail()    { _load_fail = true; }
218 
219   void print(outputStream* st) const NOT_CDS_RETURN;
220 
221   static bool is_valid_entry_kind(Kind kind) { return kind > None && kind < Kind_count; }
222   static bool is_blob(Kind kind) { return kind == SharedBlob || kind == C1Blob || kind == C2Blob; }
223   static bool is_adapter(Kind kind) { return kind == Adapter; }
224   bool is_nmethod()  { return _kind == Nmethod; }
225 };
226 
227 // Addresses of stubs, blobs and runtime finctions called from compiled code.
228 class AOTCodeAddressTable : public CHeapObj<mtCode> {
229 private:
230   address* _extrs_addr;
231   address* _stubs_addr;
232   address* _shared_blobs_addr;
233   address* _C1_blobs_addr;
234   address* _C2_blobs_addr;
235   uint     _extrs_length;
236   uint     _stubs_length;
237   uint     _shared_blobs_length;
238   uint     _C1_blobs_length;
239   uint     _C2_blobs_length;
240 
241   bool _extrs_complete;
242   bool _early_stubs_complete;
243   bool _shared_blobs_complete;
244   bool _early_c1_complete;
245   bool _c1_complete;
246   bool _c2_complete;
247   bool _complete;
248 
249 public:
250   AOTCodeAddressTable() :
251     _extrs_addr(nullptr),
252     _stubs_addr(nullptr),
253     _shared_blobs_addr(nullptr),
254     _C1_blobs_addr(nullptr),
255     _C2_blobs_addr(nullptr),
256     _extrs_length(0),
257     _stubs_length(0),
258     _shared_blobs_length(0),
259     _C1_blobs_length(0),
260     _C2_blobs_length(0),
261     _extrs_complete(false),
262     _early_stubs_complete(false),
263     _shared_blobs_complete(false),
264     _early_c1_complete(false),
265     _c1_complete(false),
266     _c2_complete(false),
267     _complete(false)
268   { }
269   ~AOTCodeAddressTable();
270   void init_extrs();
271   void init_early_stubs();
272   void init_shared_blobs();
273   void init_stubs();
274   void init_early_c1();
275   void init_c1();
276   void init_c2();
277   const char* add_C_string(const char* str);
278   int  id_for_C_string(address str);
279   address address_for_C_string(int idx);
280   int  id_for_address(address addr, RelocIterator iter, CodeBlob* blob);
281   address address_for_id(int id);
282   bool c2_complete() const { return _c2_complete; }
283   bool c1_complete() const { return _c1_complete; }
284 };
285 
286 struct AOTCodeSection {
287 public:
288   address _origin_address;
289   uint _size;
290   uint _offset;
291 };
292 
293 enum class DataKind: int {
294   No_Data   = -1,
295   Null      = 0,
296   Klass     = 1,
297   Method    = 2,
298   String    = 3,
299   MH_Oop    = 4,
300   Primitive = 5, // primitive Class object
301   SysLoader = 6, // java_system_loader
302   PlaLoader = 7, // java_platform_loader
303   MethodCnts= 8
304 };
305 
306 struct AOTCodeStats;
307 
308 class AOTCodeCache : public CHeapObj<mtCode> {
309 
310 // Classes used to describe AOT code cache.
311 protected:
312   class Config {
313     size_t  _codeCacheSize;
314     address _compressedOopBase;
315     address _compressedKlassBase;
316     uint _compressedOopShift;
317     uint _compressedKlassShift;
318     uint _contendedPaddingWidth;
319     uint _objectAlignment;
320     uint _gcCardSize;
321     uint _gc;
322     enum Flags {
323       none                     = 0,
324       debugVM                  = 2,
325       compressedOops           = 4,
326       compressedClassPointers  = 8,
327       useTLAB                  = 16,
328       systemClassAssertions    = 32,
329       userClassAssertions      = 64,
330       enableContendedPadding   = 128,
331       restrictContendedPadding = 256,
332       preserveFramePointer     = 512
333     };
334     uint _flags;
335     uint _cpu_features_offset; // offset in the cache where cpu features are stored
336 
337   public:
338     void record(uint cpu_features_offset);
339     bool verify(AOTCodeCache* cache) const;
340   };
341 
342   class Header : public CHeapObj<mtCode> {
343   private:
344     // Here should be version and other verification fields
345     enum {
346       AOT_CODE_VERSION = 1
347     };
348     uint   _version;         // AOT code version (should match when reading code cache)
349     uint   _cache_size;      // cache size in bytes
350     uint   _strings_count;   // number of recorded C strings
351     uint   _strings_offset;  // offset to recorded C strings
352     uint   _entries_count;   // number of recorded entries
353     uint   _search_table_offset; // offset of table for looking up an AOTCodeEntry
354     uint   _entries_offset;  // offset of AOTCodeEntry array describing entries
355     uint   _preload_entries_count; // entries for pre-loading code
356     uint   _preload_entries_offset;
357     uint   _adapters_count;
358     uint   _shared_blobs_count;
359     uint   _C1_blobs_count;
360     uint   _C2_blobs_count;
361     uint   _stubs_count;
362     Config _config; // must be the last element as there is trailing data stored immediately after Config
363 
364   public:
365     void init(uint cache_size,
366               uint strings_count,  uint strings_offset,
367               uint entries_count,  uint search_table_offset, uint entries_offset,
368               uint preload_entries_count, uint preload_entries_offset,
369               uint adapters_count, uint shared_blobs_count,
370               uint C1_blobs_count, uint C2_blobs_count,
371               uint stubs_count, uint cpu_features_offset) {
372       _version        = AOT_CODE_VERSION;
373       _cache_size     = cache_size;
374       _strings_count  = strings_count;
375       _strings_offset = strings_offset;
376       _entries_count  = entries_count;
377       _search_table_offset = search_table_offset;
378       _entries_offset = entries_offset;
379       _preload_entries_count  = preload_entries_count;
380       _preload_entries_offset = preload_entries_offset;
381       _adapters_count = adapters_count;
382       _shared_blobs_count = shared_blobs_count;
383       _C1_blobs_count = C1_blobs_count;
384       _C2_blobs_count = C2_blobs_count;
385       _stubs_count    = stubs_count;

386 
387       _config.record(cpu_features_offset);
388     }
389 
390     uint cache_size()     const { return _cache_size; }
391     uint strings_count()  const { return _strings_count; }
392     uint strings_offset() const { return _strings_offset; }
393     uint entries_count()  const { return _entries_count; }
394     uint search_table_offset() const { return _search_table_offset; }
395     uint entries_offset() const { return _entries_offset; }
396     uint preload_entries_count()  const { return _preload_entries_count; }
397     uint preload_entries_offset() const { return _preload_entries_offset; }
398     uint adapters_count() const { return _adapters_count; }
399     uint shared_blobs_count()    const { return _shared_blobs_count; }
400     uint C1_blobs_count() const { return _C1_blobs_count; }
401     uint C2_blobs_count() const { return _C2_blobs_count; }
402     uint stubs_count()    const { return _stubs_count; }
403     uint nmethods_count() const { return _preload_entries_count
404                                          + _entries_count
405                                          - _stubs_count
406                                          - _shared_blobs_count
407                                          - _C1_blobs_count
408                                          - _C2_blobs_count
409                                          - _adapters_count; }
410 
411     bool verify(uint load_size)  const;
412     bool verify_config(AOTCodeCache* cache) const { // Called after Universe initialized
413       return _config.verify(cache);
414     }
415   };
416 
417 // Continue with AOTCodeCache class definition.
418 private:
419   Header* _load_header;
420   char*   _load_buffer;    // Aligned buffer for loading AOT code
421   char*   _store_buffer;   // Aligned buffer for storing AOT code
422   char*   _C_store_buffer; // Original unaligned buffer
423 
424   uint   _write_position;  // Position in _store_buffer
425   uint   _load_size;       // Used when reading cache
426   uint   _store_size;      // Used when writing cache
427   bool   _for_use;         // AOT cache is open for using AOT code
428   bool   _for_dump;        // AOT cache is open for dumping AOT code
429   bool   _closing;         // Closing cache file
430   bool   _failed;          // Failed read/write to/from cache (cache is broken?)
431   bool   _lookup_failed;   // Failed to lookup for info (skip only this code load)
432 
433   bool   _for_preload;         // Code for preload
434   bool   _has_clinit_barriers; // Code with clinit barriers
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_early_stubs_table() NOT_CDS_RETURN;
505   static void init_shared_blobs_table() NOT_CDS_RETURN;
506   static void init_stubs_table() NOT_CDS_RETURN;
507   static void init_early_c1_table() NOT_CDS_RETURN;
508   static void init_c1_table() NOT_CDS_RETURN;
509   static void init_c2_table() NOT_CDS_RETURN;
510 
511   address address_for_C_string(int idx) const { return _table->address_for_C_string(idx); }
512   address address_for_id(int id) const { return _table->address_for_id(id); }
513 
514   bool for_use()  const { return _for_use  && !_failed; }
515   bool for_dump() const { return _for_dump && !_failed; }
516 
517   bool closing()          const { return _closing; }
518 
519   AOTCodeEntry* add_entry() {
520     _store_entries_cnt++;
521     _store_entries -= 1;
522     return _store_entries;
523   }
524   void preload_aot_code(TRAPS);
525 
526   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id, uint comp_level = 0);
527   void invalidate_entry(AOTCodeEntry* entry);
528 
529   void store_cpu_features(char*& buffer, uint buffer_size);
530 
531   bool finish_write();
532 
533   void log_stats_on_exit(AOTCodeStats& stats);
534 
535   static bool load_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
536   static bool store_stub(StubCodeGenerator* cgen, vmIntrinsicID id, const char* name, address start) NOT_CDS_RETURN_(false);
537 
538   bool write_klass(Klass* klass);
539   bool write_method(Method* method);
540 
541   bool write_relocations(CodeBlob& code_blob, GrowableArray<Handle>* oop_list = nullptr, GrowableArray<Metadata*>* metadata_list = nullptr);
542 
543   bool write_oop_map_set(CodeBlob& cb);
544   bool write_nmethod_reloc_immediates(GrowableArray<Handle>& oop_list, GrowableArray<Metadata*>& metadata_list);
545 
546   jobject read_oop(JavaThread* thread, const methodHandle& comp_method);
547   Metadata* read_metadata(const methodHandle& comp_method);
548 
549   bool write_oop(jobject& jo);
550   bool write_oop(oop obj);
551   bool write_metadata(Metadata* m);
552   bool write_oops(nmethod* nm);
553   bool write_metadata(nmethod* nm);
554 
555 #ifndef PRODUCT
556   bool write_asm_remarks(AsmRemarks& asm_remarks, bool use_string_table);
557   bool write_dbg_strings(DbgStrings& dbg_strings, bool use_string_table);
558 #endif // PRODUCT
559 
560   // save and restore API for non-enumerable code blobs
561   static bool store_code_blob(CodeBlob& blob,
562                               AOTCodeEntry::Kind entry_kind,
563                               uint id, const char* name) NOT_CDS_RETURN_(false);
564 
565   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
566                                   uint id, const char* name) NOT_CDS_RETURN_(nullptr);
567 
568   static bool load_nmethod(ciEnv* env, ciMethod* target, int entry_bci, AbstractCompiler* compiler, CompLevel comp_level) NOT_CDS_RETURN_(false);
569   static AOTCodeEntry* store_nmethod(nmethod* nm, AbstractCompiler* compiler, bool for_preload) NOT_CDS_RETURN_(nullptr);
570 
571   // save and restore API for enumerable code blobs
572   static bool store_code_blob(CodeBlob& blob,
573                               AOTCodeEntry::Kind entry_kind,
574                               BlobId id) NOT_CDS_RETURN_(false);
575 
576   static CodeBlob* load_code_blob(AOTCodeEntry::Kind kind,
577                                   BlobId id) NOT_CDS_RETURN_(nullptr);
578 
579   static uint store_entries_cnt() {
580     if (is_on_for_dump()) {
581       return cache()->_store_entries_cnt;
582     }
583     return -1;
584   }
585 
586 // Static access
587 
588 private:
589   static AOTCodeCache* _cache;
590   DEBUG_ONLY( static bool _passed_init2; )
591 
592   static bool open_cache(bool is_dumping, bool is_using);
593 
594   bool verify_config_on_use() {
595     if (for_use()) {
596       return _load_header->verify_config(this);
597     }
598     return true;
599   }
600 public:
601   static AOTCodeCache* cache() { assert(_passed_init2, "Too early to ask"); return _cache; }
602   static void initialize() NOT_CDS_RETURN;
603   static void init2() NOT_CDS_RETURN;
604   static void close() NOT_CDS_RETURN;
605   static bool is_on() CDS_ONLY({ return cache() != nullptr && !_cache->closing(); }) NOT_CDS_RETURN_(false);
606   static bool is_code_load_thread_on() NOT_CDS_RETURN_(false);
607   static bool is_on_for_use()  CDS_ONLY({ return is_on() && _cache->for_use(); }) NOT_CDS_RETURN_(false);
608   static bool is_on_for_dump() CDS_ONLY({ return is_on() && _cache->for_dump(); }) NOT_CDS_RETURN_(false);
609   static bool is_dumping_code() NOT_CDS_RETURN_(false);
610   static bool is_dumping_stub() NOT_CDS_RETURN_(false);
611   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);
612   static bool is_using_code() NOT_CDS_RETURN_(false);
613   static bool is_using_stub() NOT_CDS_RETURN_(false);
614   static bool is_using_adapter() NOT_CDS_RETURN_(false);
615   static void enable_caching() NOT_CDS_RETURN;
616   static void disable_caching() NOT_CDS_RETURN;
617   static bool is_caching_enabled() NOT_CDS_RETURN_(false);
618 
619   // It is used before AOTCodeCache is initialized.
620   static bool maybe_dumping_code() NOT_CDS_RETURN_(false);
621 
622   static bool allow_const_field(ciConstant& value) NOT_CDS_RETURN_(false);
623   static void invalidate(AOTCodeEntry* entry) NOT_CDS_RETURN;
624   static AOTCodeEntry* find_code_entry(const methodHandle& method, uint comp_level) NOT_CDS_RETURN_(nullptr);
625   static void preload_code(JavaThread* thread) NOT_CDS_RETURN;
626 
627   template<typename Function>
628   static void iterate(Function function) { // lambda enabled API
629     AOTCodeCache* cache = open_for_use();
630     if (cache != nullptr) {
631       ReadingMark rdmk;
632       if (rdmk.failed()) {
633         // Cache is closed, cannot touch anything.
634         return;
635       }
636 
637       uint count = cache->_load_header->entries_count();
638       uint* search_entries = (uint*)cache->addr(cache->_load_header->entries_offset()); // [id, index]
639       AOTCodeEntry* load_entries = (AOTCodeEntry*)(search_entries + 2 * count);
640 
641       for (uint i = 0; i < count; i++) {
642         int index = search_entries[2*i + 1];
643         AOTCodeEntry* entry = &(load_entries[index]);
644         function(entry);
645       }
646     }
647   }
648 
649   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
650 
651   static void print_on(outputStream* st) NOT_CDS_RETURN;
652   static void print_statistics_on(outputStream* st) NOT_CDS_RETURN;
653   static void print_timers_on(outputStream* st) NOT_CDS_RETURN;
654   static void print_unused_entries_on(outputStream* st) NOT_CDS_RETURN;
655 };
656 
657 // Concurent AOT code reader
658 class AOTCodeReader {
659 private:
660   const AOTCodeCache*  _cache;
661   const AOTCodeEntry*  _entry;
662   const char*          _load_buffer; // Loaded AOT code buffer
663   uint  _read_position;              // Position in _load_buffer
664   uint  read_position() const { return _read_position; }
665   void  set_read_position(uint pos);
666   const char* addr(uint offset) const { return _load_buffer + offset; }
667 
668   uint _compile_id;
669   uint _comp_level;
670   uint compile_id() const { return _compile_id; }
671   uint comp_level() const { return _comp_level; }
672 
673   bool _preload;             // Preloading code before method execution
674   bool _lookup_failed;       // Failed to lookup for info (skip only this code load)
675   void set_lookup_failed()     { _lookup_failed = true; }
676   void clear_lookup_failed()   { _lookup_failed = false; }
677   bool lookup_failed()   const { return _lookup_failed; }
678 

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