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
|