< 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(Code) \
 86 
 87 // Descriptor of AOT Code Cache's entry
 88 class AOTCodeEntry {
 89 public:
 90   enum Kind : s1 {
 91 #define DECL_KIND_ENUM(kind) kind,
 92     DO_AOTCODEENTRY_KIND(DECL_KIND_ENUM)
 93 #undef DECL_KIND_ENUM
 94     Kind_count
 95   };
 96 
 97 private:

 98   Kind   _kind;
 99   uint   _id;          // Adapter's id, vmIntrinsic::ID for stub or Method's offset in AOTCache for nmethod
100   uint   _offset;      // Offset to entry
101   uint   _size;        // Entry size
102   uint   _name_offset; // Method's or intrinsic name
103   uint   _name_size;
104   uint   _num_inlined_bytecodes;
105   uint   _code_offset; // Start of code in cache
106   uint   _code_size;   // Total size of all code sections
107 
108   uint   _comp_level;  // compilation level
109   uint   _comp_id;     // compilation id
110   bool   _has_oop_maps;
111   bool   _has_clinit_barriers; // Generated code has class init checks
112   bool   _for_preload; // Code can be used for preload
113   bool   _loaded;      // Code was loaded
114   bool   _not_entrant; // Deoptimized
115   bool   _load_fail;   // Failed to load due to some klass state
116   address _dumptime_content_start_addr; // CodeBlob::content_begin() at dump time; used for applying relocations
117 
118 public:
119   // this constructor is used only by AOTCodeEntry::Stub
120   AOTCodeEntry(uint offset, uint size, uint name_offset, uint name_size,
121                uint code_offset, uint code_size,
122                Kind kind, uint id) {
123     assert(kind == AOTCodeEntry::Stub, "sanity check");
124     _kind         = kind;
125     _id           = id;
126     _offset       = offset;
127     _size         = size;
128     _name_offset  = name_offset;
129     _name_size    = name_size;
130     _code_offset  = code_offset;
131     _code_size    = code_size;
132 
133     _dumptime_content_start_addr = nullptr;
134     _num_inlined_bytecodes = 0;
135     _comp_level   = 0;
136     _comp_id      = 0;
137     _has_oop_maps = false; // unused here
138     _has_clinit_barriers = false;
139     _for_preload  = false;
140     _loaded       = false;
141     _not_entrant  = false;
142     _load_fail    = false;
143   }
144 
145   AOTCodeEntry(Kind kind,         uint id,
146                uint offset,       uint size,
147                uint name_offset,  uint name_size,
148                uint blob_offset,  bool has_oop_maps,
149                address dumptime_content_start_addr,
150                uint comp_level = 0,
151                uint comp_id = 0,
152                bool has_clinit_barriers = false,
153                bool for_preload = false) {
154     _kind         = kind;
155     _id           = id;
156     _offset       = offset;
157     _size         = size;
158     _name_offset  = name_offset;
159     _name_size    = name_size;
160     _code_offset  = blob_offset;
161     _code_size    = 0; // unused
162 
163     _dumptime_content_start_addr = dumptime_content_start_addr;
164     _num_inlined_bytecodes = 0;
165 
166     _comp_level   = comp_level;
167     _comp_id      = comp_id;
168     _has_oop_maps = has_oop_maps;
169     _has_clinit_barriers = has_clinit_barriers;
170     _for_preload  = for_preload;
171     _loaded       = false;
172     _not_entrant  = false;
173     _load_fail    = false;
174 
175     _loaded       = false;
176     _not_entrant  = false;
177     _load_fail    = false;
178   }
179 
180   void* operator new(size_t x, AOTCodeCache* cache);
181   // Delete is a NOP
182   void operator delete( void *ptr ) {}
183 
184   Method* method();

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

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

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