< 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     uint _cpu_features_offset; // offset in the cache where cpu features are stored
189 
190   public:
191     void record(uint cpu_features_offset);
192     bool verify_cpu_features(AOTCodeCache* cache) const;
193     bool verify(AOTCodeCache* cache) const;
194   };
195 
196   class Header : public CHeapObj<mtCode> {
197   private:

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

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




207     uint   _adapters_count;
208     uint   _shared_blobs_count;
209     uint   _C1_blobs_count;
210     uint   _C2_blobs_count;

211     Config _config; // must be the last element as there is trailing data stored immediately after Config
212 
213   public:
214     void init(uint cache_size,
215               uint strings_count,  uint strings_offset,
216               uint entries_count,  uint entries_offset,


217               uint adapters_count, uint shared_blobs_count,
218               uint C1_blobs_count, uint C2_blobs_count,
219               uint cpu_features_offset) {
220       _version        = AOT_CODE_VERSION;
221       _cache_size     = cache_size;
222       _strings_count  = strings_count;
223       _strings_offset = strings_offset;
224       _entries_count  = entries_count;

225       _entries_offset = entries_offset;




226       _adapters_count = adapters_count;
227       _shared_blobs_count = shared_blobs_count;
228       _C1_blobs_count = C1_blobs_count;
229       _C2_blobs_count = C2_blobs_count;

230       _config.record(cpu_features_offset);
231     }
232 
233 
234     uint cache_size()     const { return _cache_size; }
235     uint strings_count()  const { return _strings_count; }
236     uint strings_offset() const { return _strings_offset; }
237     uint entries_count()  const { return _entries_count; }

238     uint entries_offset() const { return _entries_offset; }




239     uint adapters_count() const { return _adapters_count; }
240     uint shared_blobs_count()    const { return _shared_blobs_count; }
241     uint C1_blobs_count() const { return _C1_blobs_count; }
242     uint C2_blobs_count() const { return _C2_blobs_count; }








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



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






273 
274   static AOTCodeCache* open_for_use();
275   static AOTCodeCache* open_for_dump();
276 
277   bool set_write_position(uint pos);
278   bool align_write();

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





















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

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

308   static void init_early_c1_table() NOT_CDS_RETURN;


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

323 
324   AOTCodeEntry* find_entry(AOTCodeEntry::Kind kind, uint id);





325 
326   void store_cpu_features(char*& buffer, uint buffer_size);
327 
328   bool finish_write();
329 
330   bool write_relocations(CodeBlob& code_blob);









331   bool write_oop_map_set(CodeBlob& cb);











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



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

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

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

381   static bool is_dumping_stub() NOT_CDS_RETURN_(false);
382   static bool is_dumping_adapter() NOT_CDS_RETURN_(false);

383   static bool is_using_stub() NOT_CDS_RETURN_(false);
384   static bool is_using_adapter() NOT_CDS_RETURN_(false);
385   static void enable_caching() NOT_CDS_RETURN;
386   static void disable_caching() NOT_CDS_RETURN;
387   static bool is_caching_enabled() NOT_CDS_RETURN_(false);
388 































389   static const char* add_C_string(const char* str) NOT_CDS_RETURN_(str);
390 
391   static void print_on(outputStream* st) NOT_CDS_RETURN;



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






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





413 
414   CodeBlob* compile_code_blob(const char* name);
415 











416   ImmutableOopMapSet* read_oop_map_set();
417 
418   void fix_relocations(CodeBlob* code_blob);
419 #ifndef PRODUCT
420   void read_asm_remarks(AsmRemarks& asm_remarks);
421   void read_dbg_strings(DbgStrings& dbg_strings);
422 #endif // PRODUCT


























































































































































423 };
424 
425 #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   union {
118     uint* _clinit_dependencies;  // list of initialized classes referenced during AOT compilation
119     struct { // Next values are used during production run
120       uint      _clinit_dependencies_offset;  // offset in common class init dependencies list
121       uint16_t  _clinit_dependencies_cnt;     // count of class init dependencies
122       uint16_t  _clinit_dependencies_left;    // left class init dependencies
123     };
124   };
125 public:
126   // this constructor is used only by AOTCodeEntry::Stub
127   AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size,
128                uint code_offset, uint code_size,
129                Kind kind, uint id) {
130     assert(kind == AOTCodeEntry::Stub, "sanity check");
131     _kind         = kind;
132     _id           = id;
133     _offset       = offset;
134     _size         = size;
135     _name_offset  = name_offset;
136     _name_size    = name_size;
137     _code_offset  = code_offset;
138     _code_size    = code_size;
139 
140     _clinit_dependencies = nullptr;
141 
142     _num_inlined_bytecodes = 0;
143     _comp_level   = 0;
144     _comp_id      = 0;
145     _has_oop_maps = false; // unused here
146     _has_clinit_barriers = false;
147     _for_preload  = false;
148     _loaded       = false;
149     _not_entrant  = false;
150     _load_fail    = false;
151   }
152 
153   AOTCodeEntry(Kind kind,         uint id,
154                uint offset,       uint size,
155                uint name_offset,  uint name_size,
156                uint blob_offset,  bool has_oop_maps,
157                address dumptime_content_start_addr,
158                uint comp_level = 0,
159                uint comp_id = 0,
160                bool has_clinit_barriers = false,
161                bool for_preload = false) {
162     _kind         = kind;
163     _id           = id;
164     _offset       = offset;
165     _size         = size;
166     _name_offset  = name_offset;
167     _name_size    = name_size;
168     _code_offset  = blob_offset;
169     _code_size    = 0; // unused
170 
171     _clinit_dependencies = nullptr;
172 
173     _num_inlined_bytecodes = 0;
174     _comp_level   = comp_level;
175     _comp_id      = comp_id;
176     _has_oop_maps = has_oop_maps;
177     _has_clinit_barriers = has_clinit_barriers;
178     _for_preload  = for_preload;
179     _loaded       = false;
180     _not_entrant  = false;
181     _load_fail    = false;
182 
183     _loaded       = false;
184     _not_entrant  = false;
185     _load_fail    = false;
186   }
187 
188   void* operator new(size_t x, AOTCodeCache* cache);
189   // Delete is a NOP
190   void operator delete( void *ptr ) {}
191 
192   Method* method();

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

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

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